This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git
The following commit(s) were added to refs/heads/master by this push: new e8ca837 SLING-11917 Evaluate constructor parameter names via reflection (#45) e8ca837 is described below commit e8ca8371c1fbf264f7051eb2e6e5ca1d09796652 Author: Konrad Windszus <k...@apache.org> AuthorDate: Tue Jun 25 14:37:29 2024 +0200 SLING-11917 Evaluate constructor parameter names via reflection (#45) This is available if compiled accordingly (with javac flag -parameters, https://docs.oracle.com/en/java/javase/17/docs/specs/man/javac.html#option-parameters) Co-authored-by: Stefan Seifert <stefanseif...@users.noreply.github.com> --- .../sling/models/impl/ModelAdapterFactory.java | 22 +++++++++++-- .../models/impl/model/ConstructorParameter.java | 38 +++++++++++++++++----- .../models/impl/model/ModelClassConstructor.java | 22 ++++--------- .../models/impl/injectors/SelfInjectorTest.java | 2 ++ 4 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java index 9a73bac..44e8ca3 100644 --- a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java +++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java @@ -27,8 +27,24 @@ import javax.servlet.ServletRequestWrapper; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; -import java.lang.reflect.*; -import java.util.*; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Proxy; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -1103,7 +1119,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto ConstructorParameter constructorParameter, List<Object> parameterValues, Object value) { if (constructorParameter.getParameterType() instanceof Class<?>) { Result<Object> result = adaptIfNecessary( - value, (Class<?>) constructorParameter.getParameterType(), constructorParameter.getGenericType()); + value, (Class<?>) constructorParameter.getParameterType(), constructorParameter.getType()); if (result.wasSuccessful()) { parameterValues.set(constructorParameter.getParameterIndex(), result.getValue()); return null; diff --git a/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java b/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java index 5394dbd..0205098 100644 --- a/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java +++ b/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java @@ -20,10 +20,12 @@ package org.apache.sling.models.impl.model; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Parameter; import java.lang.reflect.Type; import java.util.Arrays; import org.apache.sling.models.annotations.DefaultInjectionStrategy; +import org.apache.sling.models.impl.ReflectionUtil; import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory; /** @@ -34,34 +36,54 @@ import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProces public class ConstructorParameter extends AbstractInjectableElement { private final Type parameterType; - private final Type genericType; private final boolean isPrimitive; private final int parameterIndex; + /** + * Try to extract parameter names according to https://openjdk.org/jeps/118 (requires javac flag -parameters) + * @param parameter + * @param parameterIndex + * @param processorFactories + * @param defaultInjectionStrategy + */ + public static ConstructorParameter of( + Parameter parameter, + int parameterIndex, + StaticInjectAnnotationProcessorFactory[] processorFactories, + DefaultInjectionStrategy defaultInjectionStrategy) { + Type genericType = ReflectionUtil.mapPrimitiveClasses(parameter.getParameterizedType()); + boolean isPrimitive = (parameter.getParameterizedType() != genericType); + return new ConstructorParameter( + parameter.getAnnotations(), + parameter.getType(), + genericType, + isPrimitive, + parameterIndex, + parameter.getName(), + processorFactories, + defaultInjectionStrategy); + } + public ConstructorParameter( Annotation[] annotations, Type parameterType, Type genericType, boolean isPrimitive, int parameterIndex, + String name, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) { super( new FakeAnnotatedElement(annotations, parameterIndex), genericType, - null, + name, processorFactories, defaultInjectionStrategy); this.parameterType = parameterType; - this.genericType = genericType; this.isPrimitive = isPrimitive; this.parameterIndex = parameterIndex; } - public Type getGenericType() { - return this.genericType; - } - public Type getParameterType() { return this.parameterType; } @@ -76,7 +98,7 @@ public class ConstructorParameter extends AbstractInjectableElement { @Override public String toString() { - return "Parameter" + this.parameterIndex + "[" + this.genericType.toString() + "]"; + return "Parameter" + this.parameterIndex + "[" + getType().toString() + "]"; } public static class FakeAnnotatedElement implements AnnotatedElement { diff --git a/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java b/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java index f93c6f8..35fed65 100644 --- a/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java +++ b/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java @@ -22,7 +22,8 @@ import javax.inject.Inject; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Type; +import java.lang.reflect.Parameter; +import java.util.stream.IntStream; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.impl.ReflectionUtil; @@ -41,21 +42,10 @@ public class ModelClassConstructor<M> { this.constructor = constructor; this.hasInjectAnnotation = constructor.isAnnotationPresent(Inject.class); - Type[] parameterTypes = constructor.getGenericParameterTypes(); - this.constructorParametersArray = new ConstructorParameter[parameterTypes.length]; - - for (int i = 0; i < parameterTypes.length; i++) { - Type genericType = ReflectionUtil.mapPrimitiveClasses(parameterTypes[i]); - boolean isPrimitive = (parameterTypes[i] != genericType); - this.constructorParametersArray[i] = new ConstructorParameter( - constructor.getParameterAnnotations()[i], - constructor.getParameterTypes()[i], - genericType, - isPrimitive, - i, - processorFactories, - defaultInjectionStrategy); - } + Parameter[] parameters = constructor.getParameters(); + this.constructorParametersArray = IntStream.range(0, parameters.length) + .mapToObj(i -> ConstructorParameter.of(parameters[i], i, processorFactories, defaultInjectionStrategy)) + .toArray(ConstructorParameter[]::new); } /** diff --git a/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java b/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java index 023a63c..6fd3886 100644 --- a/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java +++ b/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java @@ -71,6 +71,7 @@ public class SelfInjectorTest { Object.class, true, 0, + null, new StaticInjectAnnotationProcessorFactory[0], null); secondConstructorParameter = new ConstructorParameter( @@ -79,6 +80,7 @@ public class SelfInjectorTest { Object.class, true, 1, + null, new StaticInjectAnnotationProcessorFactory[0], null); }