Author: sseifert
Date: Wed Oct 29 22:11:17 2014
New Revision: 1635314

URL: http://svn.apache.org/r1635314
Log:
SLING-4112 refactor to cache most of reflection inspection tasks

Added:
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
   (with props)
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java
      - copied, changed from r1635287, 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
   (with props)
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
   (with props)
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
   (with props)
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
   (with props)
Removed:
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java
Modified:
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/Result.java
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java
    
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java

Modified: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java?rev=1635314&r1=1635313&r2=1635314&view=diff
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java
 (original)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java
 Wed Oct 29 22:11:17 2014
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentMa
 import java.util.concurrent.ConcurrentNavigableMap;
 import java.util.concurrent.ConcurrentSkipListMap;
 
+import org.apache.sling.models.impl.model.ModelClass;
 import org.apache.sling.models.spi.ImplementationPicker;
 
 /**
@@ -33,8 +34,8 @@ import org.apache.sling.models.spi.Imple
  */
 final class AdapterImplementations {
     
-    private final 
ConcurrentMap<String,ConcurrentNavigableMap<String,Class<?>>> 
adapterImplementations
-            = new 
ConcurrentHashMap<String,ConcurrentNavigableMap<String,Class<?>>>();
+    private final 
ConcurrentMap<String,ConcurrentNavigableMap<String,ModelClass<?>>> 
adapterImplementations
+            = new 
ConcurrentHashMap<String,ConcurrentNavigableMap<String,ModelClass<?>>>();
 
     private volatile ImplementationPicker[] sortedImplementationPickers = new 
ImplementationPicker[0];
 
@@ -51,17 +52,18 @@ final class AdapterImplementations {
      * @param adapterType Adapter type
      * @param implType Implementation type
      */
+    @SuppressWarnings("unchecked")
     public void add(Class<?> adapterType, Class<?> implType) {
         // although we already use a ConcurrentMap synchronize explicitly 
because we apply non-atomic operations on it
         synchronized (adapterImplementations) {
             String key = adapterType.getName();
-            ConcurrentNavigableMap<String,Class<?>> implementations = 
adapterImplementations.get(key);
+            ConcurrentNavigableMap<String,ModelClass<?>> implementations = 
adapterImplementations.get(key);
             if (implementations == null) {
                 // to have a consistent ordering independent of bundle loading 
use a ConcurrentSkipListMap that sorts by class name
-                implementations = new ConcurrentSkipListMap<String,Class<?>>();
+                implementations = new 
ConcurrentSkipListMap<String,ModelClass<?>>();
                 adapterImplementations.put(key, implementations);
             }
-            implementations.put(implType.getName(), implType);
+            implementations.put(implType.getName(), new ModelClass(implType));
         }
     }
     
@@ -74,7 +76,7 @@ final class AdapterImplementations {
         // although we already use a ConcurrentMap synchronize explicitly 
because we apply non-atomic operations on it
         synchronized (adapterImplementations) {
             String key = adapterTypeName;
-            ConcurrentNavigableMap<String,Class<?>> implementations = 
adapterImplementations.get(key);
+            ConcurrentNavigableMap<String,ModelClass<?>> implementations = 
adapterImplementations.get(key);
             if (implementations != null) {
                 implementations.remove(implTypeName);
                 if (implementations.isEmpty()) {
@@ -97,20 +99,31 @@ final class AdapterImplementations {
      * @param adaptable Adaptable for reference
      * @return Implementation type or null if none detected
      */
-    public Class<?> lookup(Class<?> adapterType, Object adaptable) {
+    @SuppressWarnings("unchecked")
+    public <ModelType> ModelClass<ModelType> lookup(Class<ModelType> 
adapterType, Object adaptable) {
         String key = adapterType.getName();
 
-        ConcurrentNavigableMap<String,Class<?>> implementations = 
adapterImplementations.get(key);
+        ConcurrentNavigableMap<String,ModelClass<?>> implementations = 
adapterImplementations.get(key);
         if (implementations==null || implementations.isEmpty()) {
             return null;
         }
-        Collection<Class<?>> implementationsCollection = 
implementations.values();
-        Class<?>[] implementationsArray = 
implementationsCollection.toArray(new 
Class<?>[implementationsCollection.size()]);
+        Collection<ModelClass<?>> implementationsCollection = 
implementations.values();
+        ModelClass<?>[] implementationWrappersArray = 
implementationsCollection.toArray(new 
ModelClass<?>[implementationsCollection.size()]);
+        
+        // prepare array for implementation picker
+        Class<?>[] implementationsArray = new 
Class<?>[implementationsCollection.size()];
+        for (int i=0; i<implementationWrappersArray.length; i++) {
+            implementationsArray[i] = implementationWrappersArray[i].getType();
+        }
 
         for (ImplementationPicker picker : this.sortedImplementationPickers) {
             Class<?> implementation = picker.pick(adapterType, 
implementationsArray, adaptable);
             if (implementation != null) {
-                return implementation;
+                for (int i=0; i<implementationWrappersArray.length; i++) {
+                    if 
(implementation==implementationWrappersArray[i].getType()) {
+                        return 
(ModelClass<ModelType>)implementationWrappersArray[i];
+                    }
+                }
             }
         }
 

Modified: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java?rev=1635314&r1=1635313&r2=1635314&view=diff
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
 (original)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
 Wed Oct 29 22:11:17 2014
@@ -16,7 +16,6 @@
  */
 package org.apache.sling.models.impl;
 
-import java.lang.annotation.Annotation;
 import java.lang.ref.PhantomReference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.reflect.AnnotatedElement;
@@ -50,7 +49,6 @@ import javax.inject.Named;
 
 import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.ClassUtils;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -72,15 +70,19 @@ import org.apache.sling.models.annotatio
 import org.apache.sling.models.annotations.Via;
 import org.apache.sling.models.factory.InvalidAdaptableException;
 import org.apache.sling.models.factory.InvalidModelException;
-import org.apache.sling.models.factory.ModelFactory;
 import org.apache.sling.models.factory.MissingElementsException;
+import org.apache.sling.models.factory.ModelFactory;
 import org.apache.sling.models.impl.Result.FailureType;
+import org.apache.sling.models.impl.model.ConstructorParameter;
+import org.apache.sling.models.impl.model.InjectableElement;
+import org.apache.sling.models.impl.model.InjectableField;
+import org.apache.sling.models.impl.model.InjectableMethod;
+import org.apache.sling.models.impl.model.ModelClass;
 import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.DisposalCallback;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.ImplementationPicker;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotation;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
 import 
org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
 import org.osgi.framework.BundleContext;
@@ -183,14 +185,13 @@ public class ModelAdapterFactory impleme
         return innerCanCreateFromAdaptable(adaptable, modelClass);
     }
 
-    private boolean innerCanCreateFromAdaptable(Object adaptable, Class<?> 
modelClass) throws InvalidModelException {
-        modelClass = getImplementationTypeForAdapterType(modelClass, 
adaptable);
-        Model modelAnnotation = modelClass.getAnnotation(Model.class);
-        if (modelAnnotation == null) {
+    private boolean innerCanCreateFromAdaptable(Object adaptable, Class<?> 
requestedType) throws InvalidModelException {
+        ModelClass<?> modelClass = 
getImplementationTypeForAdapterType(requestedType, adaptable);
+        if (!modelClass.hasModelAnnotation()) {
             throw new InvalidModelException(String.format("Model class '%s' 
does not have a model annotation", modelClass));
         }
 
-        Class<?>[] declaredAdaptable = modelAnnotation.adaptables();
+        Class<?>[] declaredAdaptable = 
modelClass.getModelAnnotation().adaptables();
         for (Class<?> clazz : declaredAdaptable) {
             if (clazz.isInstance(adaptable)) {
                 return true;
@@ -200,9 +201,9 @@ public class ModelAdapterFactory impleme
     }
 
     @Override
-    public boolean isModelClass(Object adaptable, Class<?> type) {
-        type = getImplementationTypeForAdapterType(type, adaptable);
-        return type.getAnnotation(Model.class) != null;
+    public boolean isModelClass(Object adaptable, Class<?> requestedType) {
+        ModelClass<?> type = 
getImplementationTypeForAdapterType(requestedType, adaptable);
+        return type.hasModelAnnotation();
     }
 
     /**
@@ -214,38 +215,38 @@ public class ModelAdapterFactory impleme
      *      
href="http://sling.apache.org/documentation/bundles/models.html#specifying-an-alternate-adapter-class-since-sling-models-110";>Specifying
      *      an Alternate Adapter Class</a>
      */
-    private Class<?> getImplementationTypeForAdapterType(Class<?> type, Object 
adaptable) {
+    private <ModelType> ModelClass<ModelType> 
getImplementationTypeForAdapterType(Class<ModelType> requestedType, Object 
adaptable) {
         // check if a different implementation class was registered for this 
adapter type
-        Class<?> implementationType = this.adapterImplementations.lookup(type, 
adaptable);
-        if (implementationType != null) {
-            log.debug("Using implementation type {} for requested adapter type 
{}", implementationType, type);
-            return implementationType;
+        ModelClass<ModelType> modelClass = 
this.adapterImplementations.lookup(requestedType, adaptable);
+        if (modelClass != null) {
+            log.debug("Using implementation type {} for requested adapter type 
{}", modelClass, requestedType);
+            return modelClass;
         }
-        return type;
+        return new ModelClass<ModelType>(requestedType);
     }
 
     @SuppressWarnings("unchecked")
-    private <ModelType> Result<ModelType> internalCreateModel(Object 
adaptable, Class<ModelType> type) {
+    private <ModelType> Result<ModelType> internalCreateModel(Object 
adaptable, Class<ModelType> requestedType) {
         Result<ModelType> result = new Result<ModelType>();
         ThreadInvocationCounter threadInvocationCounter = 
invocationCountThreadLocal.get();
         if (threadInvocationCounter.isMaximumReached()) {
             String msg = String.format("Adapting %s to %s failed, too much 
recursive invocations (>=%s).",
-                    new Object[] { adaptable, type, 
threadInvocationCounter.maxRecursionDepth });
+                    new Object[] { adaptable, requestedType, 
threadInvocationCounter.maxRecursionDepth });
             result.addFailure(FailureType.OTHER, msg);
             return result;
         };
         threadInvocationCounter.increase();
         try {
             // check if a different implementation class was registered for 
this adapter type
-            type = (Class<ModelType>) 
getImplementationTypeForAdapterType(type, adaptable);
+            ModelClass<ModelType> modelClass = 
getImplementationTypeForAdapterType(requestedType, adaptable);
 
-            Model modelAnnotation = type.getAnnotation(Model.class);
-            if (modelAnnotation == null) {
-                result.addFailure(FailureType.NO_MODEL_ANNOTATION, type);
+            if (!modelClass.hasModelAnnotation()) {
+                result.addFailure(FailureType.NO_MODEL_ANNOTATION, 
modelClass.getType());
                 return result;
             }
             boolean isAdaptable = false;
 
+            Model modelAnnotation = modelClass.getModelAnnotation();
             Class<?>[] declaredAdaptable = modelAnnotation.adaptables();
             for (Class<?> clazz : declaredAdaptable) {
                 if (clazz.isInstance(adaptable)) {
@@ -253,16 +254,16 @@ public class ModelAdapterFactory impleme
                 }
             }
             if (!isAdaptable) {
-                result.addFailure(FailureType.ADAPTABLE_DOES_NOT_MATCH, type);
-            } else if (type.isInterface()) {
-                InvocationHandler handler = createInvocationHandler(adaptable, 
type, modelAnnotation, result);
+                result.addFailure(FailureType.ADAPTABLE_DOES_NOT_MATCH, 
modelClass.getType());
+            } else if (modelClass.getType().isInterface()) {
+                InvocationHandler handler = createInvocationHandler(adaptable, 
modelClass, result);
                 if (handler != null) {
-                    ModelType model = (ModelType) 
Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[] { type }, handler);
+                    ModelType model = (ModelType) 
Proxy.newProxyInstance(modelClass.getType().getClassLoader(), new Class<?>[] { 
modelClass.getType() }, handler);
                     result.setModel(model);
                 }
             } else {
                 try {
-                    ModelType model = createObject(adaptable, type, 
modelAnnotation, result);
+                    ModelType model = createObject(adaptable, modelClass, 
result);
                     result.setModel(model);
                     return result;
                 } catch (Exception e) {
@@ -275,40 +276,6 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    private Set<Field> collectInjectableFields(Class<?> type) {
-        Set<Field> result = new HashSet<Field>();
-        while (type != null) {
-            Field[] fields = type.getDeclaredFields();
-            addAnnotated(fields, result);
-            type = type.getSuperclass();
-        }
-        return result;
-    }
-
-    private Set<Method> collectInjectableMethods(Class<?> type) {
-        Set<Method> result = new HashSet<Method>();
-        while (type != null) {
-            Method[] methods = type.getDeclaredMethods();
-            addAnnotated(methods, result);
-            type = type.getSuperclass();
-        }
-        return result;
-    }
-
-    private <T extends AnnotatedElement> void addAnnotated(T[] elements, 
Set<T> set) {
-        for (T element : elements) {
-            Inject injection = getAnnotation(element, Inject.class);
-            if (injection != null) {
-                set.add(element);
-            } else {
-                InjectAnnotation modelInject = getAnnotation(element, 
InjectAnnotation.class);
-                if (modelInject != null) {
-                    set.add(element);
-                }
-            }
-        }
-    }
-
     private static interface InjectCallback {
         /**
          * Is called each time when the given value should be injected into 
the given element
@@ -362,32 +329,32 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    private boolean injectElement(final AnnotatedElement element, final Object 
adaptable, final Type type,
-            final boolean injectPrimitiveInitialValue, final Model 
modelAnnotation, final DisposalCallbackRegistry registry,
+    private boolean injectElement(final InjectableElement element, final 
Object adaptable, 
+            final Model modelAnnotation, final DisposalCallbackRegistry 
registry,
             final InjectCallback callback, Result<?> result) {
 
         InjectAnnotationProcessor annotationProcessor = null;
-        String source = getSource(element);
+        String source = getSource(element.getAnnotatedElement());
         boolean wasInjectionSuccessful = false;
 
         // find an appropriate annotation processor
         for (InjectAnnotationProcessorFactory factory : 
sortedInjectAnnotationProcessorFactories) {
-            annotationProcessor = factory.createAnnotationProcessor(adaptable, 
element);
+            annotationProcessor = factory.createAnnotationProcessor(adaptable, 
element.getAnnotatedElement());
             if (annotationProcessor != null) {
                 break;
             }
         }
 
-        String name = getName(element, annotationProcessor);
-        Object injectionAdaptable = getAdaptable(adaptable, element, 
annotationProcessor);
+        String name = getName(element.getAnnotatedElement(), 
annotationProcessor);
+        Object injectionAdaptable = getAdaptable(adaptable, 
element.getAnnotatedElement(), annotationProcessor);
 
         if (injectionAdaptable != null) {
             // find the right injector
             for (Injector injector : sortedInjectors) {
                 if (source == null || source.equals(injector.getName())) {
                     if (name != null || injector instanceof AcceptsNullName) {
-                        Object value = injector.getValue(injectionAdaptable, 
name, type, element, registry);
-                        if (callback.inject(element, value, result)) {
+                        Object value = injector.getValue(injectionAdaptable, 
name, element.getType(), element.getAnnotatedElement(), registry);
+                        if (callback.inject(element.getAnnotatedElement(), 
value, result)) {
                             wasInjectionSuccessful = true;
                             break;
                         }
@@ -397,14 +364,14 @@ public class ModelAdapterFactory impleme
         }
         // if injection failed, use default
         if (!wasInjectionSuccessful) {
-            wasInjectionSuccessful = injectDefaultValue(element, type, 
annotationProcessor, callback, result);
+            wasInjectionSuccessful = 
injectDefaultValue(element.getAnnotatedElement(), element.getType(), 
annotationProcessor, callback, result);
         }
 
         // if default is not set, check if mandatory
         if (!wasInjectionSuccessful) {
-            if (isOptional(element, modelAnnotation, annotationProcessor)) {
-                if (injectPrimitiveInitialValue) {
-                    injectPrimitiveInitialValue(element, type, callback, 
result);
+            if (isOptional(element.getAnnotatedElement(), modelAnnotation, 
annotationProcessor)) {
+                if (element.isPrimitive()) {
+                    injectPrimitiveInitialValue(element.getAnnotatedElement(), 
element.getType(), callback, result);
                 }
             } else {
                 return false;
@@ -414,8 +381,8 @@ public class ModelAdapterFactory impleme
         return true;
     }
 
-    private <ModelType> InvocationHandler createInvocationHandler(final Object 
adaptable, final Class<ModelType> type, final Model modelAnnotation, final 
Result<ModelType> result) {
-        Set<Method> injectableMethods = collectInjectableMethods(type);
+    private <ModelType> InvocationHandler createInvocationHandler(final Object 
adaptable, final ModelClass<ModelType> modelClass, final Result<ModelType> 
result) {
+        InjectableMethod[] injectableMethods = 
modelClass.getInjectableMethods();
         final Map<Method, Object> methods = new HashMap<Method, Object>();
         SetMethodsCallback callback = new SetMethodsCallback(methods);
         MapBackedInvocationHandler handler = new 
MapBackedInvocationHandler(methods);
@@ -424,20 +391,14 @@ public class ModelAdapterFactory impleme
         registerCallbackRegistry(handler, registry);
         Set<Method> requiredMethods = new HashSet<Method>();
 
-        for (Method method : injectableMethods) {
-            Type genericReturnType = method.getGenericReturnType();
-            Type returnType = mapPrimitiveClasses(genericReturnType);
-            boolean isPrimitive = false;
-            if (returnType != genericReturnType) {
-                isPrimitive = true;
-            }
-            if (!injectElement(method, adaptable, returnType, isPrimitive, 
modelAnnotation, registry, callback, result)) {
-                requiredMethods.add(method);
+        for (InjectableMethod method : injectableMethods) {
+            if (!injectElement(method, adaptable, 
modelClass.getModelAnnotation(), registry, callback, result)) {
+                requiredMethods.add(method.getMethod());
             }
         }
         registry.seal();
         if (!requiredMethods.isEmpty()) {
-            result.addFailure(FailureType.MISSING_METHODS, requiredMethods, 
type);
+            result.addFailure(FailureType.MISSING_METHODS, requiredMethods, 
modelClass.getType());
             return null;
         }
         return handler;
@@ -449,7 +410,7 @@ public class ModelAdapterFactory impleme
     }
 
     private String getSource(AnnotatedElement element) {
-        Source source = getAnnotation(element, Source.class);
+        Source source = ReflectionUtil.getAnnotation(element, Source.class);
         if (source != null) {
             return source.value();
         } else {
@@ -457,36 +418,13 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    /**
-     * Get an annotation from either the element itself or on any of the
-     * element's annotations (meta-annotations).
-     * 
-     * @param element the element
-     * @param annotationClass the annotation class
-     * @return the found annotation or null
-     */
-    private <T extends Annotation> T getAnnotation(AnnotatedElement element, 
Class<T> annotationClass) {
-        T annotation = element.getAnnotation(annotationClass);
-        if (annotation != null) {
-            return annotation;
-        } else {
-            for (Annotation ann : element.getAnnotations()) {
-                annotation = 
ann.annotationType().getAnnotation(annotationClass);
-                if (annotation != null) {
-                    return annotation;
-                }
-            }
-        }
-        return null;
-    }
-
-    private <ModelType> ModelType createObject(final Object adaptable, final 
Class<ModelType> type, final Model modelAnnotation, final Result<ModelType> 
result)
+    private <ModelType> ModelType createObject(final Object adaptable, final 
ModelClass<ModelType> modelClass, final Result<ModelType> result)
             throws InstantiationException, InvocationTargetException, 
IllegalAccessException {
         DisposalCallbackRegistryImpl registry = new 
DisposalCallbackRegistryImpl();
 
-        Constructor<ModelType> constructorToUse = 
getBestMatchingConstructor(adaptable, type);
+        Constructor<ModelType> constructorToUse = 
getBestMatchingConstructor(adaptable, modelClass.getType());
         if (constructorToUse == null) {
-            result.addFailure(FailureType.NO_USABLE_CONSTRUCTOR, type);
+            result.addFailure(FailureType.NO_USABLE_CONSTRUCTOR, 
modelClass.getType());
             return null;
         }
 
@@ -498,7 +436,7 @@ public class ModelAdapterFactory impleme
             // instantiate with constructor injection
             // if this fails, make sure resources that may be claimed by 
injectors are cleared up again
             try {
-                object = newInstanceWithConstructorInjection(constructorToUse, 
adaptable, type, modelAnnotation, registry, result);
+                object = newInstanceWithConstructorInjection(constructorToUse, 
adaptable, modelClass.getType(), modelClass.getModelAnnotation(), registry, 
result);
                 if (object == null) {
                     registry.onDisposed();
                     return null;
@@ -521,17 +459,16 @@ public class ModelAdapterFactory impleme
 
         Set<Field> requiredFields = new HashSet<Field>();
 
-        Set<Field> injectableFields = collectInjectableFields(type);
-        for (Field field : injectableFields) {
-            Type fieldType = mapPrimitiveClasses(field.getGenericType());
-            if (!injectElement(field, adaptable, fieldType, false, 
modelAnnotation, registry, callback, result)) {
-                requiredFields.add(field);
+        InjectableField[] injectableFields = modelClass.getInjectableFields();
+        for (InjectableField field : injectableFields) {
+            if (!injectElement(field, adaptable, 
modelClass.getModelAnnotation(), registry, callback, result)) {
+                requiredFields.add(field.getField());
             }
         }
 
         registry.seal();
         if (!requiredFields.isEmpty()) {
-            result.addFailure(FailureType.MISSING_FIELDS, requiredFields, 
type);
+            result.addFailure(FailureType.MISSING_FIELDS, requiredFields, 
modelClass.getType());
             return null;
         }
         try {
@@ -592,15 +529,11 @@ public class ModelAdapterFactory impleme
         InjectCallback callback = new 
SetConstructorParameterCallback(paramValues);
 
         for (int i = 0; i < parameterTypes.length; i++) {
-            Type genericType = mapPrimitiveClasses(parameterTypes[i]);
-
-            boolean isPrimitive = false;
-            if (parameterTypes[i] != genericType) {
-                isPrimitive = true;
-            }
+            Type genericType = 
ReflectionUtil.mapPrimitiveClasses(parameterTypes[i]);
+            boolean isPrimitive = (parameterTypes[i] != genericType);
             ConstructorParameter constructorParameter = new 
ConstructorParameter(
-                    constructor.getParameterAnnotations()[i], 
constructor.getParameterTypes()[i], genericType, i);
-            if (!injectElement(constructorParameter, adaptable, genericType, 
isPrimitive, modelAnnotation, registry, callback, result)) {
+                    constructor.getParameterAnnotations()[i], 
constructor.getParameterTypes()[i], genericType, isPrimitive, i);
+            if (!injectElement(constructorParameter, adaptable, 
modelAnnotation, registry, callback, result)) {
                 requiredParameters.add(constructorParameter);
             }
         }
@@ -639,7 +572,7 @@ public class ModelAdapterFactory impleme
             return false;
         }
 
-        type = mapPrimitiveClasses(type);
+        type = ReflectionUtil.mapPrimitiveClasses(type);
         Object value = null;
 
         if (type instanceof Class) {
@@ -713,7 +646,7 @@ public class ModelAdapterFactory impleme
      * @param result
      */
     private void injectPrimitiveInitialValue(AnnotatedElement point, Type 
wrapperType, InjectCallback callback, Result<?> result) {
-        Type primitiveType = mapWrapperClasses(wrapperType);
+        Type primitiveType = ReflectionUtil.mapWrapperClasses(wrapperType);
         Object value = null;
         if (primitiveType == int.class) {
             value = Integer.valueOf(0);
@@ -837,22 +770,6 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    private static Type mapPrimitiveClasses(Type type) {
-        if (type instanceof Class<?>) {
-            return ClassUtils.primitiveToWrapper((Class<?>) type);
-        } else {
-            return type;
-        }
-    }
-
-    private static Type mapWrapperClasses(Type type) {
-        if (type instanceof Class<?>) {
-            return ClassUtils.wrapperToPrimitive((Class<?>) type);
-        } else {
-            return type;
-        }
-    }
-
     private boolean setField(Field field, Object createdObject, Object value, 
Result<?> result) {
         if (value != null) {
             value = adaptIfNecessary(value, field.getType(), 
field.getGenericType(), result);
@@ -895,8 +812,8 @@ public class ModelAdapterFactory impleme
     }
 
     private boolean setConstructorParameter(ConstructorParameter 
constructorParameter, List<Object> parameterValues, Object value, Result<?> 
result) {
-        if (value != null && constructorParameter.getType() instanceof 
Class<?>) {
-            value = adaptIfNecessary(value, (Class<?>) 
constructorParameter.getType(), constructorParameter.getGenericType(), result);
+        if (value != null && constructorParameter.getParameterType() 
instanceof Class<?>) {
+            value = adaptIfNecessary(value, (Class<?>) 
constructorParameter.getParameterType(), constructorParameter.getGenericType(), 
result);
             // value may now be null due to the adaptation done above
             if (value == null) {
                 return false;

Added: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java?rev=1635314&view=auto
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
 (added)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
 Wed Oct 29 22:11:17 2014
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.models.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.commons.lang.ClassUtils;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotation;
+
+/**
+ * Helper methods for inspecting classes via reflection.
+ */
+public final class ReflectionUtil {
+
+    private ReflectionUtil() {
+        // static methods only
+    }
+
+    public static List<Field> collectInjectableFields(Class<?> type) {
+        List<Field> result = new ArrayList<Field>();
+        while (type != null) {
+            Field[] fields = type.getDeclaredFields();
+            addAnnotated(fields, result);
+            type = type.getSuperclass();
+        }
+        return result;
+    }
+
+    public static List<Method> collectInjectableMethods(Class<?> type) {
+        List<Method> result = new ArrayList<Method>();
+        while (type != null) {
+            Method[] methods = type.getDeclaredMethods();
+            addAnnotated(methods, result);
+            type = type.getSuperclass();
+        }
+        return result;
+    }
+
+    public static <T extends AnnotatedElement> void addAnnotated(T[] elements, 
List<T> set) {
+        for (T element : elements) {
+            Inject injection = getAnnotation(element, Inject.class);
+            if (injection != null) {
+                set.add(element);
+            } else {
+                InjectAnnotation modelInject = getAnnotation(element, 
InjectAnnotation.class);
+                if (modelInject != null) {
+                    set.add(element);
+                }
+            }
+        }
+    }
+
+    /**
+     * Get an annotation from either the element itself or on any of the
+     * element's annotations (meta-annotations).
+     * 
+     * @param element the element
+     * @param annotationClass the annotation class
+     * @return the found annotation or null
+     */
+    public static <T extends Annotation> T getAnnotation(AnnotatedElement 
element, Class<T> annotationClass) {
+        T annotation = element.getAnnotation(annotationClass);
+        if (annotation != null) {
+            return annotation;
+        } else {
+            for (Annotation ann : element.getAnnotations()) {
+                annotation = 
ann.annotationType().getAnnotation(annotationClass);
+                if (annotation != null) {
+                    return annotation;
+                }
+            }
+        }
+        return null;
+    }
+
+    public static Type mapPrimitiveClasses(Type type) {
+        if (type instanceof Class<?>) {
+            return ClassUtils.primitiveToWrapper((Class<?>) type);
+        } else {
+            return type;
+        }
+    }
+
+    public static Type mapWrapperClasses(Type type) {
+        if (type instanceof Class<?>) {
+            return ClassUtils.wrapperToPrimitive((Class<?>) type);
+        } else {
+            return type;
+        }
+    }
+
+}

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Wed Oct 29 22:11:17 2014
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/Result.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/Result.java?rev=1635314&r1=1635313&r2=1635314&view=diff
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/Result.java
 (original)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/Result.java
 Wed Oct 29 22:11:17 2014
@@ -171,11 +171,7 @@ public class Result<ModelType> {
     public void setModel(ModelType model) {
         this.model = model;
     }
-/*
-    public void setType(Class<? extends ModelType> type) {
-        this.type = type;
-    }
-*/
+
     public void throwException(Logger log) {
         for (int i = 0; i < failures.size() - 1; i++) {
             failures.get(i).log(log);

Modified: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java?rev=1635314&r1=1635313&r2=1635314&view=diff
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
 (original)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
 Wed Oct 29 22:11:17 2014
@@ -23,7 +23,7 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.models.annotations.injectorspecific.Self;
-import org.apache.sling.models.impl.ConstructorParameter;
+import org.apache.sling.models.impl.model.ConstructorParameter;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.Injector;

Copied: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java
 (from r1635287, 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java)
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java?p2=sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java&p1=sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java&r1=1635287&r2=1635314&rev=1635314&view=diff
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java
 (original)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java
 Wed Oct 29 22:11:17 2014
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.models.impl;
+package org.apache.sling.models.impl.model;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
@@ -27,17 +27,19 @@ import java.lang.reflect.Type;
  * AnnotatedElement. This class acts as a facade to ease
  * compatibility with field and method injection.
  */
-public class ConstructorParameter implements AnnotatedElement {
+public class ConstructorParameter implements AnnotatedElement, 
InjectableElement {
 
     private final Annotation[] annotations;
-    private final Class<?> type;
+    private final Type parameterType;
     private final Type genericType;
+    private final boolean isPrimitive;
     private final int parameterIndex;
 
-    ConstructorParameter(Annotation[] annotations, Class<?> type, Type 
genericType, int parameterIndex) {
+    public ConstructorParameter(Annotation[] annotations, Type parameterType, 
Type genericType, boolean isPrimitive, int parameterIndex) {
         this.annotations = annotations;
-        this.type = type;
+        this.parameterType = parameterType;
         this.genericType = genericType;
+        this.isPrimitive = isPrimitive;
         this.parameterIndex = parameterIndex;
     }
 
@@ -67,14 +69,29 @@ public class ConstructorParameter implem
         return annotations;
     }
 
-    public Class<?> getType() {
-        return this.type;
+    public Type getGenericType() {
+        return this.genericType;
     }
 
-    public Type getGenericType() {
+    public Type getParameterType() {
+        return this.parameterType;
+    }
+
+    /**
+     * @return Type of injectable mapped to wrapper class
+     */
+    public Type getType() {
         return this.genericType;
     }
 
+    /**
+     * @return true if return type is a primitive type
+     */
+    public boolean isPrimitive() {
+        return isPrimitive;
+    }
+    
+
     public int getParameterIndex() {
         return this.parameterIndex;
     }
@@ -83,5 +100,10 @@ public class ConstructorParameter implem
     public String toString() {
         return "Parameter" + this.parameterIndex + "[" + 
this.genericType.toString() + "]";
     }
-    
-}
\ No newline at end of file
+
+    @Override
+    public AnnotatedElement getAnnotatedElement() {
+        return this;
+    }
+   
+}

Added: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java?rev=1635314&view=auto
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
 (added)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
 Wed Oct 29 22:11:17 2014
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.models.impl.model;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Type;
+
+public interface InjectableElement {
+    
+    AnnotatedElement getAnnotatedElement();
+
+    /**
+     * @return Type of injectable mapped to wrapper class
+     */
+    Type getType();
+    
+    /**
+     * @return true if original type of injectable is a primitive type
+     */
+    boolean isPrimitive();
+
+}

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Wed Oct 29 22:11:17 2014
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java?rev=1635314&view=auto
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
 (added)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
 Wed Oct 29 22:11:17 2014
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.models.impl.model;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+
+import org.apache.sling.models.impl.ReflectionUtil;
+
+public class InjectableField implements InjectableElement {
+    
+    private final Field field;
+    private final Type genericType;
+    
+    public InjectableField(Field field) {
+        this.field = field;
+        this.genericType = 
ReflectionUtil.mapPrimitiveClasses(field.getGenericType());
+    }
+    
+    public Field getField() {
+        return field;
+    }
+
+    @Override
+    public AnnotatedElement getAnnotatedElement() {
+        return field;
+    }
+
+    /**
+     * @return Type of injectable mapped to wrapper class
+     */
+    public Type getType() {
+        return genericType;
+    }
+
+    /**
+     * @return Always false for field
+     */
+    public boolean isPrimitive() {
+        return false;
+    }
+
+}

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Wed Oct 29 22:11:17 2014
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java?rev=1635314&view=auto
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
 (added)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
 Wed Oct 29 22:11:17 2014
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.models.impl.model;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+import org.apache.sling.models.impl.ReflectionUtil;
+
+public class InjectableMethod implements InjectableElement {
+    
+    private final Method method;
+    private final Type genericReturnType;
+    private final Type returnType;
+
+    public InjectableMethod(Method method) {
+        this.method = method;
+        this.genericReturnType = method.getGenericReturnType();
+        this.returnType = 
ReflectionUtil.mapPrimitiveClasses(this.genericReturnType);
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+
+    @Override
+    public AnnotatedElement getAnnotatedElement() {
+        return method;
+    }
+
+    /**
+     * @return Generic return type of method (may be primitive)
+     */
+    public Type getGenericReturnType() {
+        return this.genericReturnType;
+    }
+
+    /**
+     * @return Type of injectable mapped to wrapper class
+     */
+    public Type getType() {
+        return returnType;
+    }
+    
+    /**
+     * @return true if return type is a primitive type
+     */
+    public boolean isPrimitive() {
+        return this.returnType != this.genericReturnType;
+    }
+
+}

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Wed Oct 29 22:11:17 2014
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java?rev=1635314&view=auto
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
 (added)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
 Wed Oct 29 22:11:17 2014
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.models.impl.model;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.impl.ReflectionUtil;
+
+public class ModelClass<ModelType> {
+
+    private final Class<ModelType> type;
+    private final Model modelAnnotation;
+    private final InjectableField[] injectableFieldsArray;
+    private final InjectableMethod[] injectableMethodsArray;
+
+    public ModelClass(Class<ModelType> type) {
+        this.type = type;
+        this.modelAnnotation = type.getAnnotation(Model.class);
+        
+        List<Field> injectableFields = 
ReflectionUtil.collectInjectableFields(type);
+        this.injectableFieldsArray = new 
InjectableField[injectableFields.size()];
+        for (int i=0; i<this.injectableFieldsArray.length; i++) {
+            this.injectableFieldsArray[i] = new 
InjectableField(injectableFields.get(i));
+        }
+        
+        List<Method> injectableMethods = 
ReflectionUtil.collectInjectableMethods(type);
+        this.injectableMethodsArray = new 
InjectableMethod[injectableMethods.size()];
+        for (int i=0; i<this.injectableMethodsArray.length; i++) {
+            this.injectableMethodsArray[i] = new 
InjectableMethod(injectableMethods.get(i));
+        }
+    }
+
+    public Class<ModelType> getType() {
+        return this.type;
+    }
+    
+    public Model getModelAnnotation() {
+        return this.modelAnnotation;
+    }
+    
+    public boolean hasModelAnnotation() {
+        return this.modelAnnotation != null;
+    }
+    
+    public InjectableField[] getInjectableFields() {
+        return this.injectableFieldsArray;
+    }
+
+    public InjectableMethod[] getInjectableMethods() {
+        return this.injectableMethodsArray;
+    }
+
+}

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Wed Oct 29 22:11:17 2014
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java?rev=1635314&r1=1635313&r2=1635314&view=diff
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java
 (original)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java
 Wed Oct 29 22:11:17 2014
@@ -57,7 +57,7 @@ public class AdapterImplementationsTest 
     public void testSingleMapping() {
         underTest.add(SAMPLE_ADAPTER, String.class);
         
-        assertEquals(String.class, underTest.lookup(SAMPLE_ADAPTER, 
SAMPLE_ADAPTABLE));
+        assertEquals(String.class, underTest.lookup(SAMPLE_ADAPTER, 
SAMPLE_ADAPTABLE).getType());
         
         underTest.remove(SAMPLE_ADAPTER.getName(), String.class.getName());
 
@@ -70,11 +70,11 @@ public class AdapterImplementationsTest 
         underTest.add(SAMPLE_ADAPTER, Integer.class);
         underTest.add(SAMPLE_ADAPTER, Long.class);
         
-        assertEquals(Integer.class, underTest.lookup(SAMPLE_ADAPTER, 
SAMPLE_ADAPTABLE));
+        assertEquals(Integer.class, underTest.lookup(SAMPLE_ADAPTER, 
SAMPLE_ADAPTABLE).getType());
         
         underTest.remove(SAMPLE_ADAPTER.getName(), Integer.class.getName());
 
-        assertEquals(Long.class, underTest.lookup(SAMPLE_ADAPTER, 
SAMPLE_ADAPTABLE));
+        assertEquals(Long.class, underTest.lookup(SAMPLE_ADAPTER, 
SAMPLE_ADAPTABLE).getType());
 
         underTest.remove(SAMPLE_ADAPTER.getName(), Long.class.getName());
         underTest.remove(SAMPLE_ADAPTER.getName(), String.class.getName());
@@ -105,7 +105,7 @@ public class AdapterImplementationsTest 
         underTest.add(SAMPLE_ADAPTER, Integer.class);
         underTest.add(SAMPLE_ADAPTER, Long.class);
         
-        assertEquals(String.class, underTest.lookup(SAMPLE_ADAPTER, 
SAMPLE_ADAPTABLE));
+        assertEquals(String.class, underTest.lookup(SAMPLE_ADAPTER, 
SAMPLE_ADAPTABLE).getType());
     }
     
     static final class NoneImplementationPicker implements 
ImplementationPicker {

Modified: 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java?rev=1635314&r1=1635313&r2=1635314&view=diff
==============================================================================
--- 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java
 (original)
+++ 
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java
 Wed Oct 29 22:11:17 2014
@@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletReq
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.models.annotations.injectorspecific.Self;
-import org.apache.sling.models.impl.ConstructorParameter;
+import org.apache.sling.models.impl.model.ConstructorParameter;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;


Reply via email to