You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2014/10/29 23:46:38 UTC
svn commit: r1635325 - in
/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl:
./ model/
Author: sseifert
Date: Wed Oct 29 22:46:38 2014
New Revision: 1635325
URL: http://svn.apache.org/r1635325
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/model/ModelClassConstructor.java (with props)
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ParameterCountInjectComparator.java
- copied, changed from r1635287, sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ParameterCountInjectComparator.java
Removed:
sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ParameterCountInjectComparator.java
Modified:
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/model/ModelClass.java
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=1635325&r1=1635324&r2=1635325&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:46:38 2014
@@ -19,7 +19,6 @@ package org.apache.sling.models.impl;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
@@ -44,7 +43,6 @@ import java.util.concurrent.ConcurrentHa
import java.util.concurrent.ConcurrentMap;
import javax.annotation.PostConstruct;
-import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.beanutils.PropertyUtils;
@@ -78,6 +76,7 @@ import org.apache.sling.models.impl.mode
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.impl.model.ModelClassConstructor;
import org.apache.sling.models.spi.AcceptsNullName;
import org.apache.sling.models.spi.DisposalCallback;
import org.apache.sling.models.spi.DisposalCallbackRegistry;
@@ -422,21 +421,21 @@ public class ModelAdapterFactory impleme
throws InstantiationException, InvocationTargetException, IllegalAccessException {
DisposalCallbackRegistryImpl registry = new DisposalCallbackRegistryImpl();
- Constructor<ModelType> constructorToUse = getBestMatchingConstructor(adaptable, modelClass.getType());
+ ModelClassConstructor<ModelType> constructorToUse = getBestMatchingConstructor(adaptable, modelClass);
if (constructorToUse == null) {
result.addFailure(FailureType.NO_USABLE_CONSTRUCTOR, modelClass.getType());
return null;
}
final ModelType object;
- if (constructorToUse.getParameterTypes().length == 0) {
+ if (constructorToUse.getConstructor().getParameterTypes().length == 0) {
// no parameters for constructor injection? instantiate it right away
- object = constructorToUse.newInstance();
+ object = constructorToUse.getConstructor().newInstance();
} else {
// 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, modelClass.getType(), modelClass.getModelAnnotation(), registry, result);
+ object = newInstanceWithConstructorInjection(constructorToUse, adaptable, modelClass, registry, result);
if (object == null) {
registry.onDisposed();
return null;
@@ -491,57 +490,50 @@ public class ModelAdapterFactory impleme
* @return Constructor or null if none found
*/
@SuppressWarnings("unchecked")
- private <ModelType> Constructor<ModelType> getBestMatchingConstructor(Object adaptable, Class<ModelType> type) {
- Constructor<?>[] constructors = type.getConstructors();
+ private <ModelType> ModelClassConstructor<ModelType> getBestMatchingConstructor(Object adaptable, ModelClass<ModelType> type) {
+ ModelClassConstructor[] constructors = type.getConstructors();
- // sort the constructor list in order from most params to least params, and constructors with @Inject annotation first
- Arrays.sort(constructors, new ParameterCountInjectComparator());
-
- for (Constructor<?> constructor : constructors) {
+ for (ModelClassConstructor constructor : constructors) {
// first try to find the constructor with most parameters and @Inject annotation
- if (constructor.isAnnotationPresent(Inject.class)) {
- return (Constructor<ModelType>) constructor;
+ if (constructor.hasInjectAnnotation()) {
+ return constructor;
}
// compatibility mode for sling models implementation <= 1.0.6:
// support constructor without @Inject if it has exactly one parameter matching the adaptable class
- final Class<?>[] paramTypes = constructor.getParameterTypes();
+ final Class<?>[] paramTypes = constructor.getConstructor().getParameterTypes();
if (paramTypes.length == 1) {
- Class<?> paramType = constructor.getParameterTypes()[0];
+ Class<?> paramType = constructor.getConstructor().getParameterTypes()[0];
if (paramType.isInstance(adaptable)) {
- return (Constructor<ModelType>) constructor;
+ return constructor;
}
}
// if no constructor for injection found use public constructor without any params
- if (constructor.getParameterTypes().length == 0) {
- return (Constructor<ModelType>) constructor;
+ if (constructor.getConstructor().getParameterTypes().length == 0) {
+ return constructor;
}
}
return null;
}
- private <ModelType> ModelType newInstanceWithConstructorInjection(final Constructor<ModelType> constructor, final Object adaptable,
- final Class<ModelType> type, final Model modelAnnotation, final DisposalCallbackRegistry registry,
- final Result<ModelType> result)
+ private <ModelType> ModelType newInstanceWithConstructorInjection(final ModelClassConstructor<ModelType> constructor, final Object adaptable,
+ final ModelClass<ModelType> modelClass, final DisposalCallbackRegistry registry, final Result<ModelType> result)
throws InstantiationException, InvocationTargetException, IllegalAccessException {
+ ConstructorParameter[] parameters = constructor.getConstructorParameters();
+
Set<ConstructorParameter> requiredParameters = new HashSet<ConstructorParameter>();
- Type[] parameterTypes = constructor.getGenericParameterTypes();
- List<Object> paramValues = new ArrayList<Object>(Arrays.asList(new Object[parameterTypes.length]));
+ List<Object> paramValues = new ArrayList<Object>(Arrays.asList(new Object[parameters.length]));
InjectCallback callback = new SetConstructorParameterCallback(paramValues);
- for (int i = 0; i < parameterTypes.length; i++) {
- Type genericType = ReflectionUtil.mapPrimitiveClasses(parameterTypes[i]);
- boolean isPrimitive = (parameterTypes[i] != genericType);
- ConstructorParameter constructorParameter = new ConstructorParameter(
- constructor.getParameterAnnotations()[i], constructor.getParameterTypes()[i], genericType, isPrimitive, i);
- if (!injectElement(constructorParameter, adaptable, modelAnnotation, registry, callback, result)) {
- requiredParameters.add(constructorParameter);
+ for (int i = 0; i < parameters.length; i++) {
+ if (!injectElement(parameters[i], adaptable, modelClass.getModelAnnotation(), registry, callback, result)) {
+ requiredParameters.add(parameters[i]);
}
}
if (!requiredParameters.isEmpty()) {
- result.addFailure(FailureType.MISSING_CONSTRUCTOR_PARAMS, requiredParameters, type);
+ result.addFailure(FailureType.MISSING_CONSTRUCTOR_PARAMS, requiredParameters, modelClass.getType());
return null;
}
- return constructor.newInstance(paramValues.toArray(new Object[paramValues.size()]));
+ return constructor.getConstructor().newInstance(paramValues.toArray(new Object[paramValues.size()]));
}
private boolean isOptional(AnnotatedElement point, Model modelAnnotation, InjectAnnotationProcessor annotationProcessor) {
Modified: 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=1635325&r1=1635324&r2=1635325&view=diff
==============================================================================
--- sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java (original)
+++ sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java Wed Oct 29 22:46:38 2014
@@ -18,8 +18,10 @@
*/
package org.apache.sling.models.impl.model;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.Arrays;
import java.util.List;
import org.apache.sling.models.annotations.Model;
@@ -29,24 +31,57 @@ public class ModelClass<ModelType> {
private final Class<ModelType> type;
private final Model modelAnnotation;
- private final InjectableField[] injectableFieldsArray;
- private final InjectableMethod[] injectableMethodsArray;
+ private final ModelClassConstructor[] constructors;
+ private final InjectableField[] injectableFields;
+ private final InjectableMethod[] injectableMethods;
public ModelClass(Class<ModelType> type) {
this.type = type;
this.modelAnnotation = type.getAnnotation(Model.class);
+ this.constructors = getConstructors(type);
+ this.injectableFields = getInjectableFields(type);
+ this.injectableMethods = getInjectableMethods(type);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static ModelClassConstructor[] getConstructors(Class<?> type) {
+ if (type.isInterface()) {
+ return new ModelClassConstructor[0];
+ }
+ Constructor<?>[] constructors = type.getConstructors();
+ // sort the constructor list in order from most params to least params, and constructors with @Inject annotation first
+ Arrays.sort(constructors, new ParameterCountInjectComparator());
+
+ ModelClassConstructor[] array = new ModelClassConstructor[constructors.length];
+ for (int i=0; i<array.length; i++) {
+ array[i] = new ModelClassConstructor(constructors[i]);
+ }
+ return array;
+ }
+
+ private static InjectableField[] getInjectableFields(Class<?> type) {
+ if (type.isInterface()) {
+ return new InjectableField[0];
+ }
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));
+ InjectableField[] array = new InjectableField[injectableFields.size()];
+ for (int i=0; i<array.length; i++) {
+ array[i] = new InjectableField(injectableFields.get(i));
+ }
+ return array;
+ }
+
+ private static InjectableMethod[] getInjectableMethods(Class<?> type) {
+ if (!type.isInterface()) {
+ return new InjectableMethod[0];
}
-
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));
+ InjectableMethod[] array = new InjectableMethod[injectableMethods.size()];
+ for (int i=0; i<array.length; i++) {
+ array[i] = new InjectableMethod(injectableMethods.get(i));
}
+ return array;
}
public Class<ModelType> getType() {
@@ -61,12 +96,16 @@ public class ModelClass<ModelType> {
return this.modelAnnotation != null;
}
+ public ModelClassConstructor[] getConstructors() {
+ return constructors;
+ }
+
public InjectableField[] getInjectableFields() {
- return this.injectableFieldsArray;
+ return this.injectableFields;
}
public InjectableMethod[] getInjectableMethods() {
- return this.injectableMethodsArray;
+ return this.injectableMethods;
}
}
Added: sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java?rev=1635325&view=auto
==============================================================================
--- sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java (added)
+++ sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java Wed Oct 29 22:46:38 2014
@@ -0,0 +1,61 @@
+/*
+ * 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.Constructor;
+import java.lang.reflect.Type;
+
+import javax.inject.Inject;
+
+import org.apache.sling.models.impl.ReflectionUtil;
+
+public class ModelClassConstructor<ModelType> {
+
+ private final Constructor<ModelType> constructor;
+ private final boolean hasInjectAnnotation;
+ private final ConstructorParameter[] constructorParametersArray;
+
+ public ModelClassConstructor(Constructor<ModelType> constructor) {
+ 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);
+ }
+ }
+
+ public Constructor<ModelType> getConstructor() {
+ return constructor;
+ }
+
+ public boolean hasInjectAnnotation() {
+ return hasInjectAnnotation;
+ }
+
+ public ConstructorParameter[] getConstructorParameters() {
+ return constructorParametersArray;
+ };
+
+}
Propchange: sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Wed Oct 29 22:46:38 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/ModelClassConstructor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Copied: sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ParameterCountInjectComparator.java (from r1635287, sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ParameterCountInjectComparator.java)
URL: http://svn.apache.org/viewvc/sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ParameterCountInjectComparator.java?p2=sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ParameterCountInjectComparator.java&p1=sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ParameterCountInjectComparator.java&r1=1635287&r2=1635325&rev=1635325&view=diff
==============================================================================
--- sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ParameterCountInjectComparator.java (original)
+++ sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/ParameterCountInjectComparator.java Wed Oct 29 22:46:38 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.reflect.Constructor;
import java.util.Comparator;