You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ju...@apache.org on 2014/06/24 20:37:50 UTC
svn commit: r1605150 - in /sling/trunk/bundles/extensions/models:
api/src/main/java/org/apache/sling/models/annotations/
impl/src/main/java/org/apache/sling/models/impl/
impl/src/test/java/org/apache/sling/models/impl/
impl/src/test/java/org/apache/sli...
Author: justin
Date: Tue Jun 24 18:37:50 2014
New Revision: 1605150
URL: http://svn.apache.org/r1605150
Log:
SLING-3696 - adding support for defining a default injection strategy of required or optional. Also adding a @Required annotation
Added:
sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/DefaultInjectionStrategy.java
- copied, changed from r1605101, sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java
sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Required.java
- copied, changed from r1605101, sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java
sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java
- copied, changed from r1605101, sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java
Modified:
sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java
sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java
sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java
sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java
Copied: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/DefaultInjectionStrategy.java (from r1605101, sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java)
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/DefaultInjectionStrategy.java?p2=sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/DefaultInjectionStrategy.java&p1=sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java&r1=1605101&r2=1605150&rev=1605150&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/DefaultInjectionStrategy.java Tue Jun 24 18:37:50 2014
@@ -14,7 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("1.0.0")
package org.apache.sling.models.annotations;
-import aQute.bnd.annotation.Version;
\ No newline at end of file
+public enum DefaultInjectionStrategy {
+
+ REQUIRED, OPTIONAL
+
+}
Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java?rev=1605150&r1=1605149&r2=1605150&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java Tue Jun 24 18:37:50 2014
@@ -31,4 +31,6 @@ public @interface Model {
public Class<?>[] adaptables();
+ public DefaultInjectionStrategy defaultInjectionStrategy() default DefaultInjectionStrategy.REQUIRED;
+
}
Copied: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Required.java (from r1605101, sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java)
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Required.java?p2=sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Required.java&p1=sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java&r1=1605101&r2=1605150&rev=1605150&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Model.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/Required.java Tue Jun 24 18:37:50 2014
@@ -22,13 +22,10 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.Target;
/**
- * Mark a class as adaptable via YAMF.
- *
+ * Marker annotation for required injections.
*/
-@Target(ElementType.TYPE)
+@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
-public @interface Model {
-
- public Class<?>[] adaptables();
+public @interface Required {
}
Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java?rev=1605150&r1=1605149&r2=1605150&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/package-info.java Tue Jun 24 18:37:50 2014
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("1.0.0")
+@Version("1.1.0")
package org.apache.sling.models.annotations;
import aQute.bnd.annotation.Version;
\ No newline at end of file
Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java?rev=1605150&r1=1605149&r2=1605150&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java Tue Jun 24 18:37:50 2014
@@ -61,8 +61,10 @@ import org.apache.sling.api.adapter.Adap
import org.apache.sling.api.adapter.AdapterFactory;
import org.apache.sling.commons.osgi.ServiceUtil;
import org.apache.sling.models.annotations.Default;
+import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Optional;
+import org.apache.sling.models.annotations.Required;
import org.apache.sling.models.annotations.Source;
import org.apache.sling.models.annotations.Via;
import org.apache.sling.models.spi.DisposalCallback;
@@ -187,7 +189,7 @@ public class ModelAdapterFactory impleme
}
if (type.isInterface()) {
- InvocationHandler handler = createInvocationHandler(adaptable, type);
+ InvocationHandler handler = createInvocationHandler(adaptable, type, modelAnnotation);
if (handler != null) {
return (AdapterType) Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[] { type }, handler);
} else {
@@ -195,7 +197,7 @@ public class ModelAdapterFactory impleme
}
} else {
try {
- return createObject(adaptable, type);
+ return createObject(adaptable, type, modelAnnotation);
} catch (Exception e) {
log.error("unable to create object", e);
return null;
@@ -276,7 +278,7 @@ public class ModelAdapterFactory impleme
}
private boolean injectFieldOrMethod(final AnnotatedElement element, final Object adaptable, final Type type,
- final DisposalCallbackRegistry registry, InjectCallback callback) {
+ final Model modelAnnotation, final DisposalCallbackRegistry registry, InjectCallback callback) {
InjectAnnotationProcessor annotationProcessor = null;
String source = getSource(element);
@@ -310,13 +312,13 @@ public class ModelAdapterFactory impleme
}
// if default is not set, check if mandatory
- if (!wasInjectionSuccessful && !isOptional(element, annotationProcessor)) {
+ if (!wasInjectionSuccessful && !isOptional(element, modelAnnotation, annotationProcessor)) {
return false;
}
return true;
}
- private InvocationHandler createInvocationHandler(final Object adaptable, final Class<?> type) {
+ private InvocationHandler createInvocationHandler(final Object adaptable, final Class<?> type, Model modelAnnotation) {
Set<Method> injectableMethods = collectInjectableMethods(type);
final Map<Method, Object> methods = new HashMap<Method, Object>();
SetMethodsCallback callback = new SetMethodsCallback(methods);
@@ -327,7 +329,7 @@ public class ModelAdapterFactory impleme
for (Method method : injectableMethods) {
Type returnType = mapPrimitiveClasses(method.getGenericReturnType());
- if (!injectFieldOrMethod(method, adaptable, returnType, registry, callback)) {
+ if (!injectFieldOrMethod(method, adaptable, returnType, modelAnnotation, registry, callback)) {
requiredMethods.add(method);
}
}
@@ -379,7 +381,7 @@ public class ModelAdapterFactory impleme
}
@SuppressWarnings("unchecked")
- private <AdapterType> AdapterType createObject(Object adaptable, Class<AdapterType> type)
+ private <AdapterType> AdapterType createObject(Object adaptable, Class<AdapterType> type, Model modelAnnotation)
throws InstantiationException, InvocationTargetException, IllegalAccessException {
Set<Field> injectableFields = collectInjectableFields(type);
@@ -431,7 +433,7 @@ public class ModelAdapterFactory impleme
for (Field field : injectableFields) {
Type fieldType = mapPrimitiveClasses(field.getGenericType());
- if (!injectFieldOrMethod(field, adaptable, fieldType, registry, callback)) {
+ if (!injectFieldOrMethod(field, adaptable, fieldType, modelAnnotation, registry, callback)) {
requiredFields.add(field);
}
}
@@ -451,14 +453,19 @@ public class ModelAdapterFactory impleme
}
- private boolean isOptional(AnnotatedElement point, InjectAnnotationProcessor annotationProcessor) {
+ private boolean isOptional(AnnotatedElement point, Model modelAnnotation, InjectAnnotationProcessor annotationProcessor) {
if (annotationProcessor != null) {
Boolean isOptional = annotationProcessor.isOptional();
if (isOptional != null) {
return isOptional.booleanValue();
}
}
- return (point.getAnnotation(Optional.class) != null);
+ if (modelAnnotation.defaultInjectionStrategy() == DefaultInjectionStrategy.REQUIRED) {
+ return (point.getAnnotation(Optional.class) != null);
+ } else {
+ return (point.getAnnotation(Required.class) == null);
+ }
+
}
private boolean injectDefaultValue(AnnotatedElement point, Type type, InjectAnnotationProcessor processor,
Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java?rev=1605150&r1=1605149&r2=1605150&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java Tue Jun 24 18:37:50 2014
@@ -37,6 +37,7 @@ import org.apache.sling.models.testmodel
import org.apache.sling.models.testmodels.classes.ChildValueMapModel;
import org.apache.sling.models.testmodels.classes.ParentModel;
import org.apache.sling.models.testmodels.classes.ResourceModelWithRequiredField;
+import org.apache.sling.models.testmodels.classes.ResourceModelWithRequiredFieldOptionalStrategy;
import org.apache.sling.models.testmodels.classes.SimplePropertyModel;
import org.junit.Before;
import org.junit.Test;
@@ -156,6 +157,39 @@ public class ResourceModelClassesTest {
}
@Test
+ public void testRequiredPropertyModelOptionalStrategyAvailable() {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("first", "first-value");
+ map.put("third", "third-value");
+ ValueMap vm = spy(new ValueMapDecorator(map));
+
+ Resource res = mock(Resource.class);
+ when(res.adaptTo(ValueMap.class)).thenReturn(vm);
+
+ ResourceModelWithRequiredFieldOptionalStrategy model = factory.getAdapter(res, ResourceModelWithRequiredFieldOptionalStrategy.class);
+ assertNull(model);
+
+ verify(vm).get("optional", String.class);
+ verify(vm).get("required", String.class);
+ }
+
+ @Test
+ public void testRequiredPropertyModelOptionalStrategyNotAvailable() {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("required", "first-value");
+ ValueMap vm = spy(new ValueMapDecorator(map));
+
+ Resource res = mock(Resource.class);
+ when(res.adaptTo(ValueMap.class)).thenReturn(vm);
+
+ ResourceModelWithRequiredFieldOptionalStrategy model = factory.getAdapter(res, ResourceModelWithRequiredFieldOptionalStrategy.class);
+ assertNotNull(model);
+
+ verify(vm).get("optional", String.class);
+ verify(vm).get("required", String.class);
+ }
+
+ @Test
public void testChildResource() {
Resource child = mock(Resource.class);
Resource secondChild = mock(Resource.class);
Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java?rev=1605150&r1=1605149&r2=1605150&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java Tue Jun 24 18:37:50 2014
@@ -23,10 +23,10 @@ import org.apache.sling.models.annotatio
@Model(adaptables = Resource.class)
public class ResourceModelWithRequiredField {
-
+
@Inject
private String required;
-
+
public String getRequired() {
return required;
}
Copied: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java (from r1605101, sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java)
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java?p2=sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java&p1=sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java&r1=1605101&r2=1605150&rev=1605150&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java Tue Jun 24 18:37:50 2014
@@ -19,16 +19,26 @@ package org.apache.sling.models.testmode
import javax.inject.Inject;
import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.Required;
+
+@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
+public class ResourceModelWithRequiredFieldOptionalStrategy {
+
+ @Inject
+ private String optional;
-@Model(adaptables = Resource.class)
-public class ResourceModelWithRequiredField {
-
@Inject
+ @Required
private String required;
-
+
public String getRequired() {
return required;
}
+ public String getOptional() {
+ return optional;
+ }
+
}