You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:55:24 UTC

[sling-org-apache-sling-models-impl] 11/16: SLING-3696 - adding support for defining a default injection strategy of required or optional. Also adding a @Required annotation

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 <ju...@apache.org>
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
"commits@sling.apache.org" <co...@sling.apache.org>.