Author: justin
Date: Mon Dec 23 16:27:50 2013
New Revision: 1553145

URL: http://svn.apache.org/r1553145
Log:
adding a source annotation which ties a specific injection point to a specific 
injector. also works as a meta annotation, see e.g. @Filter

Added:
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java
      - copied, changed from r1553144, 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java
Modified:
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java
    
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java

Modified: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
 (original)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
 Mon Dec 23 16:27:50 2013
@@ -26,6 +26,7 @@ import java.lang.annotation.Target;
  */
 @Target({ ElementType.FIELD, ElementType.METHOD })
 @Retention(RetentionPolicy.RUNTIME)
+@Source("osgi-services")
 public @interface Filter {
 
     public String value();

Copied: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java
 (from r1553144, 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java)
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java?p2=sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java&p1=sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java&r1=1553144&r2=1553145&rev=1553145&view=diff
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
 (original)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java
 Mon Dec 23 16:27:50 2013
@@ -22,12 +22,13 @@ import java.lang.annotation.RetentionPol
 import java.lang.annotation.Target;
 
 /**
- * Provide a filter on an @Inject.
+ * Annotation which indicates the specific injector which will populate this 
injection.
+ * Can also be used as a meta-annotation to declare that some other annotation 
implies
+ * a source.
  */
-@Target({ ElementType.FIELD, ElementType.METHOD })
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE })
 @Retention(RetentionPolicy.RUNTIME)
-public @interface Filter {
-
-    public String value();
+public @interface Source {
 
+    String value();
 }

Modified: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java
 (original)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java
 Mon Dec 23 16:27:50 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.sling.yamf.impl;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
@@ -49,8 +50,8 @@ import org.apache.sling.yamf.annotations
 import org.apache.sling.yamf.annotations.Model;
 import org.apache.sling.yamf.annotations.Optional;
 import org.apache.sling.yamf.annotations.Projection;
+import org.apache.sling.yamf.annotations.Source;
 import org.apache.sling.yamf.spi.Injector;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
@@ -157,13 +158,16 @@ public class YamfAdapterFactory implemen
             Iterator<Method> it = injectableMethods.iterator();
             while (it.hasNext()) {
                 Method method = it.next();
-                String name = getName(method);
-                Type returnType = 
mapPrimitiveClasses(method.getGenericReturnType());
-                Object injectionAdaptable = getAdaptable(adaptable, method);
-                if (injectionAdaptable != null) {
-                    Object value = injector.getValue(injectionAdaptable, name, 
returnType, method);
-                    if (setMethod(method, methods, value)) {
-                        it.remove();
+                String source = getSource(method);
+                if (source == null || source.equals(injector.getName())) {
+                    String name = getName(method);
+                    Type returnType = 
mapPrimitiveClasses(method.getGenericReturnType());
+                    Object injectionAdaptable = getAdaptable(adaptable, 
method);
+                    if (injectionAdaptable != null) {
+                        Object value = injector.getValue(injectionAdaptable, 
name, returnType, method);
+                        if (setMethod(method, methods, value)) {
+                            it.remove();
+                        }
                     }
                 }
             }
@@ -202,6 +206,21 @@ public class YamfAdapterFactory implemen
         }
     }
 
+    private String getSource(AnnotatedElement element) {
+        Source source = element.getAnnotation(Source.class);
+        if (source != null) {
+            return source.value();
+        } else {
+            for (Annotation ann : element.getAnnotations()) {
+                source = ann.annotationType().getAnnotation(Source.class);
+                if (source != null) {
+                    return source.value();
+                }
+            }
+        }
+        return null;
+    }
+
     private <AdapterType> AdapterType createObject(Object adaptable, 
Class<AdapterType> type)
             throws InstantiationException, IllegalAccessException {
         Set<Field> injectableFields = collectInjectableFields(type);
@@ -212,13 +231,16 @@ public class YamfAdapterFactory implemen
             Iterator<Field> it = injectableFields.iterator();
             while (it.hasNext()) {
                 Field field = it.next();
-                String name = getName(field);
-                Type fieldType = mapPrimitiveClasses(field.getGenericType());
-                Object injectionAdaptable = getAdaptable(adaptable, field);
-                if (injectionAdaptable != null) {
-                    Object value = injector.getValue(injectionAdaptable, name, 
fieldType, field);
-                    if (setField(field, object, value)) {
-                        it.remove();
+                String source = getSource(field);
+                if (source == null || source.equals(injector.getName())) {
+                    String name = getName(field);
+                    Type fieldType = 
mapPrimitiveClasses(field.getGenericType());
+                    Object injectionAdaptable = getAdaptable(adaptable, field);
+                    if (injectionAdaptable != null) {
+                        Object value = injector.getValue(injectionAdaptable, 
name, fieldType, field);
+                        if (setField(field, object, value)) {
+                            it.remove();
+                        }
                     }
                 }
             }

Modified: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java
 (original)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java
 Mon Dec 23 16:27:50 2013
@@ -34,6 +34,11 @@ public class BindingsInjector implements
 
     private static final Logger log = 
LoggerFactory.getLogger(BindingsInjector.class);
 
+    @Override
+    public String getName() {
+        return "script-bindings";
+    }
+
     private static Object getValue(SlingBindings bindings, String name, 
Class<?> type) {
         Object value = bindings.get(name);
         if (type.isInstance(value)) {

Modified: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java
 (original)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java
 Mon Dec 23 16:27:50 2013
@@ -27,8 +27,10 @@ import java.util.List;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.yamf.annotations.Filter;
+import org.apache.sling.yamf.annotations.Source;
 import org.apache.sling.yamf.spi.Injector;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
@@ -44,6 +46,11 @@ public class OSGiServiceInjector impleme
     private static final Logger log = 
LoggerFactory.getLogger(OSGiServiceInjector.class);
 
     private BundleContext bundleContext;
+    
+    @Override
+    public String getName() {
+        return "osgi-services";
+    }
 
     @Activate
     public void activate(ComponentContext ctx) {
@@ -98,9 +105,7 @@ public class OSGiServiceInjector impleme
     private Object getValue(Type type, String filterString) {
         if (type instanceof Class) {
             Class<?> injectedClass = (Class<?>) type;
-            if (injectedClass == BundleContext.class) {
-                return bundleContext;
-            } else if (injectedClass.isArray()) {
+            if (injectedClass.isArray()) {
                 Object[] services = 
getServices(injectedClass.getComponentType(), filterString);
                 Object arr = 
Array.newInstance(injectedClass.getComponentType(), services.length);
                 for (int i = 0; i < services.length; i++) {

Modified: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java
 (original)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java
 Mon Dec 23 16:27:50 2013
@@ -22,7 +22,9 @@ import java.lang.reflect.Type;
 import javax.servlet.ServletRequest;
 
 import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.yamf.annotations.Source;
 import org.apache.sling.yamf.spi.Injector;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,6 +34,11 @@ import org.slf4j.LoggerFactory;
 public class RequestAttributeInjector implements Injector {
 
     private static final Logger log = 
LoggerFactory.getLogger(RequestAttributeInjector.class);
+    
+    @Override
+    public String getName() {
+        return "request-attributes";
+    }
 
     @Override
     public Object getValue(Object adaptable, String name, Type declaredType, 
AnnotatedElement element) {

Modified: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java
 (original)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java
 Mon Dec 23 16:27:50 2013
@@ -32,6 +32,11 @@ import org.slf4j.LoggerFactory;
 public class ValueMapInjector implements Injector {
 
     private static final Logger log = 
LoggerFactory.getLogger(ValueMapInjector.class);
+    
+    @Override
+    public String getName() {
+        return "valuemap";
+    }
 
     public Object getValue(Object adaptable, String name, Type type, 
AnnotatedElement element) {
         ValueMap map = getMap(adaptable);

Modified: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java
 (original)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java
 Mon Dec 23 16:27:50 2013
@@ -21,5 +21,7 @@ import java.lang.reflect.Type;
 
 public interface Injector {
 
+    String getName();
+
     Object getValue(Object adaptable, String name, Type declaredType, 
AnnotatedElement element);
 }
\ No newline at end of file

Added: 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java
URL: 
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java?rev=1553145&view=auto
==============================================================================
--- 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java
 (added)
+++ 
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java
 Mon Dec 23 16:27:50 2013
@@ -0,0 +1,118 @@
+/*
+ * 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.yamf.impl;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Collections;
+
+import javax.inject.Inject;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.yamf.annotations.Model;
+import org.apache.sling.yamf.annotations.Source;
+import org.apache.sling.yamf.impl.injectors.BindingsInjector;
+import org.apache.sling.yamf.impl.injectors.RequestAttributeInjector;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.osgi.framework.Constants;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MultipleInjectorTest {
+
+    @Spy
+    private BindingsInjector bindingsInjector;
+
+    @Spy
+    private RequestAttributeInjector attributesInjector;
+
+    @Mock
+    private SlingHttpServletRequest request;
+
+    private YamfAdapterFactory factory;
+
+    private SlingBindings bindings;
+
+    @Before
+    public void setup() {
+        bindings = new SlingBindings();
+
+        factory = new YamfAdapterFactory();
+        factory.bindInjector(bindingsInjector, Collections.<String, Object> 
singletonMap(Constants.SERVICE_ID, 2L));
+        factory.bindInjector(attributesInjector,
+                Collections.<String, Object> 
singletonMap(Constants.SERVICE_ID, 1L));
+
+        
when(request.getAttribute(SlingBindings.class.getName())).thenReturn(bindings);
+    }
+
+    @Test
+    public void testInjectorOrder() {
+        String bindingsValue = "bindings value";
+        bindings.put("firstAttribute", bindingsValue);
+
+        String attributeValue = "attribute value";
+        
when(request.getAttribute("firstAttribute")).thenReturn(attributeValue);
+
+        ForTwoInjectors obj = factory.getAdapter(request, 
ForTwoInjectors.class);
+
+        assertNotNull(obj);
+        assertEquals(obj.firstAttribute, bindingsValue);
+
+        verifyNoMoreInteractions(attributesInjector);
+    }
+
+    @Test
+    public void testInjectorOrderWithSource() {
+        String bindingsValue = "bindings value";
+        bindings.put("firstAttribute", bindingsValue);
+
+        String attributeValue = "attribute value";
+        
when(request.getAttribute("firstAttribute")).thenReturn(attributeValue);
+
+        ForTwoInjectorsWithSource obj = factory.getAdapter(request, 
ForTwoInjectorsWithSource.class);
+
+        assertNotNull(obj);
+        assertEquals(obj.firstAttribute, attributeValue);
+
+        verify(bindingsInjector).getName();
+        verifyNoMoreInteractions(bindingsInjector);
+    }
+
+    @Model(adaptables = SlingHttpServletRequest.class)
+    public static class ForTwoInjectors {
+
+        @Inject
+        private String firstAttribute;
+
+    }
+
+    @Model(adaptables = SlingHttpServletRequest.class)
+    public static class ForTwoInjectorsWithSource {
+
+        @Inject
+        @Source("request-attributes")
+        private String firstAttribute;
+
+    }
+
+}


Reply via email to