This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.models.impl-1.0.6 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git
commit 3ea34c4e394a95a3aa3fd75bc3f1082c76f48500 Author: Justin Edelson <[email protected]> AuthorDate: Tue Jun 24 18:37:50 2014 +0000 SLING-3696 - adding support for defining a default injection strategy of required or optional. Also adding a @Required annotation git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/models/impl@1605150 13f79535-47bb-0310-9956-ffa450edef68 --- .../sling/models/impl/ModelAdapterFactory.java | 27 ++++++++++------- .../models/impl/ResourceModelClassesTest.java | 34 ++++++++++++++++++++++ .../classes/ResourceModelWithRequiredField.java | 4 +-- ...rceModelWithRequiredFieldOptionalStrategy.java} | 18 +++++++++--- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java index bd0ca47..8532de4 100644 --- a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java +++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java @@ -61,8 +61,10 @@ import org.apache.sling.api.adapter.Adaptable; 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 implements AdapterFactory, Runnable { } 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 implements AdapterFactory, Runnable { } } 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 implements AdapterFactory, Runnable { } 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 implements AdapterFactory, Runnable { } // 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 implements AdapterFactory, Runnable { 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 implements AdapterFactory, Runnable { } @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 implements AdapterFactory, Runnable { 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 implements AdapterFactory, Runnable { } - 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, diff --git a/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java b/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java index 8f7485f..52d41f8 100644 --- a/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java +++ b/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java @@ -37,6 +37,7 @@ import org.apache.sling.models.testmodels.classes.ChildResourceModel; 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); diff --git a/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java b/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java index 8ebc5f6..adf6856 100644 --- a/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java +++ b/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java @@ -23,10 +23,10 @@ import org.apache.sling.models.annotations.Model; @Model(adaptables = Resource.class) public class ResourceModelWithRequiredField { - + @Inject private String required; - + public String getRequired() { return required; } diff --git a/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java b/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java similarity index 72% copy from src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java copy to src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java index 8ebc5f6..bf89785 100644 --- a/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredField.java +++ b/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java @@ -19,16 +19,26 @@ package org.apache.sling.models.testmodels.classes; 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; + } + } -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
