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/08/22 17:49:58 UTC

svn commit: r1619847 - in /sling/trunk/bundles/extensions/models/impl/src: main/java/org/apache/sling/models/impl/ main/java/org/apache/sling/models/impl/injectors/ test/java/org/apache/sling/models/impl/injectors/

Author: justin
Date: Fri Aug 22 15:49:57 2014
New Revision: 1619847

URL: http://svn.apache.org/r1619847
Log:
SLING-3876 - ensuring that class-based self injection only happens on the first constructor parameter. Otherwise the @Self annotation is necessary. Also changing the ranking so that other injectors have the opportunity to inject to the first constructor parameter before.

Modified:
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java?rev=1619847&r1=1619846&r2=1619847&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java Fri Aug 22 15:49:57 2014
@@ -27,7 +27,7 @@ import java.lang.reflect.Type;
  * AnnotatedElement. This class acts as a facade to ease
  * compatibility with field and method injection.
  */
-class ConstructorParameter implements AnnotatedElement {
+public class ConstructorParameter implements AnnotatedElement {
 
     private final Annotation[] annotations;
     private final Class<?> type;

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java?rev=1619847&r1=1619846&r2=1619847&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java Fri Aug 22 15:49:57 2014
@@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.models.annotations.injectorspecific.Self;
+import org.apache.sling.models.impl.ConstructorParameter;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.Injector;
@@ -36,7 +37,7 @@ import org.osgi.framework.Constants;
  */
 @Component
 @Service
-@Property(name = Constants.SERVICE_RANKING, intValue = 100)
+@Property(name = Constants.SERVICE_RANKING, intValue = Integer.MAX_VALUE)
 public class SelfInjector implements Injector, InjectAnnotationProcessorFactory, AcceptsNullName {
 
     @Override
@@ -49,11 +50,13 @@ public class SelfInjector implements Inj
         // if the @Self annotation is present return the adaptable to be inserted directly or to be adapted from
         if (element.isAnnotationPresent(Self.class)) {
             return adaptable;
-        }
-        // otherwise apply class-based injection only if class matches or is a superclass
-        else if (type instanceof Class<?>) {
-            Class<?> requestedClass = (Class<?>)type;
-            if (requestedClass.isAssignableFrom(adaptable.getClass())) {
+        } else {
+            // special handling for the first constructor parameter
+            // apply class-based injection only if class matches or is a superclass
+            if (element instanceof ConstructorParameter &&
+                    ((ConstructorParameter)element).getParameterIndex() == 0 &&
+                    type instanceof Class<?> &&
+                    ((Class<?>)type).isAssignableFrom(adaptable.getClass())) {
                 return adaptable;
             }
         }

Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java?rev=1619847&r1=1619846&r2=1619847&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java Fri Aug 22 15:49:57 2014
@@ -18,8 +18,7 @@
  */
 package org.apache.sling.models.impl.injectors;
 
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
+import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
 import java.lang.reflect.AnnotatedElement;
@@ -29,6 +28,8 @@ import javax.servlet.http.HttpServletReq
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.models.annotations.injectorspecific.Self;
+import org.apache.sling.models.impl.ConstructorParameter;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -39,40 +40,58 @@ import org.mockito.runners.MockitoJUnitR
 public class SelfInjectorTest {
 
     private SelfInjector injector = new SelfInjector();
-    
+
     @Mock
     private SlingHttpServletRequest request;
+
     @Mock
     private AnnotatedElement annotatedElement;
+    
+    @Mock
+    private ConstructorParameter firstConstructorParameter;
+    
+    @Mock
+    private ConstructorParameter secondConstructorParameter;
+    
+    @Before
+    public void setup() {
+        when(firstConstructorParameter.getParameterIndex()).thenReturn(0);
+        when(secondConstructorParameter.getParameterIndex()).thenReturn(1);
+    }
 
     @Test
     public void testMatchingClass() {
-        Object result = injector.getValue(request, "notRelevant", SlingHttpServletRequest.class, annotatedElement, null);
-        assertSame(request, result);
+        assertSame(request, injector.getValue(request, "notRelevant", SlingHttpServletRequest.class, firstConstructorParameter, null));
+        assertNull(injector.getValue(request, "notRelevant", SlingHttpServletRequest.class, secondConstructorParameter, null));
+        assertNull(injector.getValue(request, "notRelevant", SlingHttpServletRequest.class, annotatedElement, null));
     }
 
     @Test
     public void testMatchingSubClass() {
-        Object result = injector.getValue(request, "notRelevant", HttpServletRequest.class, annotatedElement, null);
-        assertSame(request, result);
+        assertSame(request, injector.getValue(request, "notRelevant", HttpServletRequest.class, firstConstructorParameter, null));
+        assertNull(injector.getValue(request, "notRelevant", HttpServletRequest.class, secondConstructorParameter, null));
+        assertNull(injector.getValue(request, "notRelevant", HttpServletRequest.class, annotatedElement, null));
     }
 
     @Test
     public void testNotMatchingClass() {
-        Object result = injector.getValue(request, "notRelevant", ResourceResolver.class, annotatedElement, null);
-        assertNull(result);
+        assertNull(injector.getValue(request, "notRelevant", ResourceResolver.class, firstConstructorParameter, null));
+        assertNull(injector.getValue(request, "notRelevant", ResourceResolver.class, secondConstructorParameter, null));
+        assertNull(injector.getValue(request, "notRelevant", ResourceResolver.class, annotatedElement, null));
     }
 
     @Test
     public void testWithNullName() {
-        Object result = injector.getValue(request, null, SlingHttpServletRequest.class, annotatedElement, null);
-        assertSame(request, result);
+        assertSame(request, injector.getValue(request, null, SlingHttpServletRequest.class, firstConstructorParameter, null));
+        assertNull(injector.getValue(request, null, SlingHttpServletRequest.class, secondConstructorParameter, null));
+        assertNull(injector.getValue(request, null, SlingHttpServletRequest.class, annotatedElement, null));
     }
 
     @Test
     public void testMatchingClassWithSelfAnnotation() {
         when(annotatedElement.isAnnotationPresent(Self.class)).thenReturn(true);
-        Object result = injector.getValue(request, "notRelevant", SlingHttpServletRequest.class, annotatedElement, null);
+        Object result = injector
+                .getValue(request, "notRelevant", SlingHttpServletRequest.class, annotatedElement, null);
         assertSame(request, result);
     }