aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r1367681 - in /aries/trunk/blueprint/blueprint-core/src: main/java/org/apache/aries/blueprint/container/ main/java/org/apache/aries/blueprint/utils/ test/java/org/apache/aries/blueprint/container/ test/java/org/apache/aries/blueprint/utils/
Date Tue, 31 Jul 2012 17:10:07 GMT
Author: gnodet
Date: Tue Jul 31 17:10:06 2012
New Revision: 1367681

URL: http://svn.apache.org/viewvc?rev=1367681&view=rev
Log:
[ARIES-894] Unable to access public methods overriden/implemented in a protected class

Modified:
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
    aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java
    aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
    aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/utils/ReflectionUtilsTest.java

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java?rev=1367681&r1=1367680&r2=1367681&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
(original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
Tue Jul 31 17:10:06 2012
@@ -18,8 +18,6 @@
  */
 package org.apache.aries.blueprint.container;
 
-import static org.apache.aries.blueprint.utils.ReflectionUtils.getRealCause;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -57,6 +55,9 @@ import org.osgi.service.blueprint.reflec
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.aries.blueprint.utils.ReflectionUtils.getPublicMethods;
+import static org.apache.aries.blueprint.utils.ReflectionUtils.getRealCause;
+
 /**
  * A <code>Recipe</code> to create POJOs.
  *
@@ -344,7 +345,7 @@ public class BeanRecipe extends Abstract
     private Map<Method, List<Object>> findMatchingMethods(Class type, String
name, boolean instance, List<Object> args, List<ReifiedType> types) {
         Map<Method, List<Object>> matches = new HashMap<Method, List<Object>>();
         // Get constructors
-        List<Method> methods = new ArrayList<Method>(Arrays.asList(type.getMethods()));
+        List<Method> methods = getPublicMethods(type);
         // Discard any signature with wrong cardinality
         for (Iterator<Method> it = methods.iterator(); it.hasNext();) {
             Method mth = it.next();

Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java?rev=1367681&r1=1367680&r2=1367681&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java
(original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/utils/ReflectionUtils.java
Tue Jul 31 17:10:06 2012
@@ -40,9 +40,9 @@ import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
 
-import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
 import org.apache.aries.blueprint.container.GenericType;
 import org.apache.aries.blueprint.di.ExecutionContext;
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
 import org.osgi.framework.BundleReference;
 import org.osgi.service.blueprint.container.ComponentDefinitionException;
 
@@ -110,21 +110,73 @@ public class ReflectionUtils {
 
     public static Method getLifecycleMethod(Class clazz, String name) {
         if (name != null) {
-            try {
-                Method method = clazz.getMethod(name);
-                if (Void.TYPE.equals(method.getReturnType())) {
+            for (Method method : getPublicMethods(clazz)) {
+                if (method.getName().equals(name)
+                        && method.getParameterTypes().length == 0
+                        && Void.TYPE.equals(method.getReturnType())) {
                     return method;
                 }
-            } catch (NoSuchMethodException e) {
-                // fall thru
             }
         }
         return null;
     }
-    
+
+    public static List<Method> getPublicMethods(Class clazz) {
+        ArrayList<Method> methods = new ArrayList<Method>();
+        doGetPublicMethods(clazz, methods);
+        return methods;
+    }
+
+    private static void doGetPublicMethods(Class clazz, ArrayList<Method> methods)
{
+        Class parent = clazz.getSuperclass();
+        if (parent != null) {
+            doGetPublicMethods(parent, methods);
+        }
+        for (Class interf : clazz.getInterfaces()) {
+            doGetPublicMethods(interf, methods);
+        }
+        if (Modifier.isPublic(clazz.getModifiers())) {
+            for (Method mth : clazz.getMethods()) {
+                removeByNameAndSignature(methods, mth);
+                methods.add(mth);
+            }
+        }
+    }
+
+    private static void removeByNameAndSignature(ArrayList<Method> methods, Method
toRemove) {
+        for (int i = 0; i < methods.size(); i++) {
+            Method m = methods.get(i);
+            if (m != null &&
+                    m.getReturnType() == toRemove.getReturnType() &&
+                    m.getName() == toRemove.getName() &&
+                    arrayContentsEq(m.getParameterTypes(),
+                            toRemove.getParameterTypes())) {
+                methods.remove(i--);
+            }
+        }
+    }
+
+    private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
+        if (a1 == null) {
+            return a2 == null || a2.length == 0;
+        }
+        if (a2 == null) {
+            return a1.length == 0;
+        }
+        if (a1.length != a2.length) {
+            return false;
+        }
+        for (int i = 0; i < a1.length; i++) {
+            if (a1[i] != a2[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     public static List<Method> findCompatibleMethods(Class clazz, String name, Class[]
paramTypes) {
         List<Method> methods = new ArrayList<Method>();
-        for (Method method : clazz.getMethods()) {
+        for (Method method : getPublicMethods(clazz)) {
             Class[] methodParams = method.getParameterTypes();
             if (name.equals(method.getName()) && Void.TYPE.equals(method.getReturnType())
&& methodParams.length == paramTypes.length && !method.isBridge()) {
                 boolean assignable = true;
@@ -154,7 +206,7 @@ public class ReflectionUtils {
             Map<String,List<Method>> setters = new HashMap<String, List<Method>>();
             Set<String> illegalProperties = new HashSet<String>();
             
-            for (Method method : clazz.getMethods()) {
+            for (Method method : getPublicMethods(clazz)) {
                 if (Modifier.isStatic(method.getModifiers()) || method.isBridge()) continue;
                 
                 String name = method.getName();
@@ -519,7 +571,8 @@ public class ReflectionUtils {
                 
                 builder.append(wcl.get());
             }
-            
+
+            builder.append(")");
             return builder.toString();
         }
     }

Modified: aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java?rev=1367681&r1=1367680&r2=1367681&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
(original)
+++ aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
Tue Jul 31 17:10:06 2012
@@ -26,7 +26,10 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.aries.blueprint.di.ExecutionContext;
+import org.apache.aries.blueprint.di.PassThroughRecipe;
 import org.junit.Test;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+
 import static org.junit.Assert.*;
 
 public class BeanRecipeTest {
@@ -65,6 +68,56 @@ public class BeanRecipeTest {
         public ExampleService(Example<String> e) {}
     }
 
+    static public interface A {
+        String getA();
+        void setA(String a);
+    }
+    static public interface B extends A {
+        String getB();
+        void setB(String b);
+        void init();
+    }
+    static public class C implements B {
+        String a = "a", b = "b", c = "c";
+        public String getA() {
+            return a;
+        }
+        public void setA(String a) {
+            this.a = a;
+        }
+        public String getB() {
+            return b;
+        }
+        public void setB(String b) {
+            this.b = b;
+        }
+        public String getC() {
+            return c;
+        }
+        public void setC(String c) {
+            this.c = c;
+        }
+        public void init() {
+        }
+    }
+    static public class Factory {
+        public B create() {
+            return new D();
+        }
+        private class D extends C {
+            String d = "d";
+            public String getD() {
+                return d;
+            }
+            public void setD(String d) {
+                this.d = d;
+            }
+            public void init() {
+            }
+        }
+    }
+
+
     @Test
     public void parameterWithGenerics() throws Exception {
         BlueprintContainerImpl container = new BlueprintContainerImpl(null, null, null, null,
null, null, null);
@@ -139,8 +192,83 @@ public class BeanRecipeTest {
 		assertEquals(2, methods.size());
 		assertFalse(methods.contains(Middle.class.getMethod("getBasic", int.class)));
 	}
-	
-	private Set<Method> applyStaticHidingRules(Collection<Method> methods) {
+
+    @Test
+    public void protectedClassAccess() throws Exception {
+        BlueprintContainerImpl container = new BlueprintContainerImpl(null, null, null, null,
null, null, null);
+        BeanRecipe recipe = new BeanRecipe("a", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory().create()));
+        recipe.setFactoryMethod("getA");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        assertNotNull(recipe.create());
+
+        recipe = new BeanRecipe("b", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory().create()));
+        recipe.setFactoryMethod("getB");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        assertNotNull(recipe.create());
+
+        recipe = new BeanRecipe("c", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory().create()));
+        recipe.setFactoryMethod("getC");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        assertNotNull(recipe.create());
+
+        recipe = new BeanRecipe("d", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory().create()));
+        recipe.setFactoryMethod("getD");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        try {
+            assertNotNull(recipe.create());
+            fail("Should have thrown an exception");
+        } catch (ComponentDefinitionException e) {
+            // ok
+        }
+
+        recipe = new BeanRecipe("a", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory()));
+        recipe.setFactoryMethod("create");
+        recipe.setProperty("a", "a");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        assertNotNull(recipe.create());
+
+        recipe = new BeanRecipe("b", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory()));
+        recipe.setFactoryMethod("create");
+        recipe.setProperty("b", "b");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        assertNotNull(recipe.create());
+
+        recipe = new BeanRecipe("c", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory()));
+        recipe.setFactoryMethod("create");
+        recipe.setProperty("c", "c");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        assertNotNull(recipe.create());
+
+        recipe = new BeanRecipe("d", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory()));
+        recipe.setFactoryMethod("create");
+        recipe.setProperty("d", "d");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        try {
+            assertNotNull(recipe.create());
+            fail("Should have thrown an exception");
+        } catch (ComponentDefinitionException e) {
+            // ok
+        }
+
+        recipe = new BeanRecipe("a", container, null, false);
+        recipe.setFactoryComponent(new PassThroughRecipe("factory", new Factory()));
+        recipe.setFactoryMethod("create");
+        recipe.setInitMethod("init");
+        ExecutionContext.Holder.setContext(new BlueprintRepository(container));
+        assertNotNull(recipe.create());
+
+    }
+
+
+    private Set<Method> applyStaticHidingRules(Collection<Method> methods) {
 		try {
 			Method m = BeanRecipe.class.getDeclaredMethod("applyStaticHidingRules", Collection.class);
 			m.setAccessible(true);

Modified: aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/utils/ReflectionUtilsTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/utils/ReflectionUtilsTest.java?rev=1367681&r1=1367680&r2=1367681&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/utils/ReflectionUtilsTest.java
(original)
+++ aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/utils/ReflectionUtilsTest.java
Tue Jul 31 17:10:06 2012
@@ -52,7 +52,7 @@ public class ReflectionUtilsTest {
             },            
             ExtendedBlueprintContainer.class);
     
-    static class GetterOnly {
+    public static class GetterOnly {
         public String getValue() { return "test"; }
     }
     
@@ -109,7 +109,7 @@ public class ReflectionUtilsTest {
         assertEquals("test", sut[1].get(new GetterOnly(), mockBlueprint));
     }
     
-    static class SetterOnly {
+    public static class SetterOnly {
         private String f;
         
         public void setField(String val) { f = val; }
@@ -131,7 +131,7 @@ public class ReflectionUtilsTest {
         assertEquals("trial", so.retrieve());
     }
     
-    static class SetterAndGetter {
+    public static class SetterAndGetter {
         private String f;
         
         public void setField(String val) { f = val; }
@@ -198,7 +198,7 @@ public class ReflectionUtilsTest {
         assertEquals("predicament", sut[2].get(fap, mockBlueprint));
     }
     
-    static class OverloadedSetters {
+    public static class OverloadedSetters {
         public Object field;
         
         public void setField(String val) { field = val; }
@@ -229,7 +229,7 @@ public class ReflectionUtilsTest {
         sut[1].set(new OverloadedSetters(), new Inconvertible(), mockBlueprint);
     }
     
-    static class MultipleMatchesByConversion {
+    public static class MultipleMatchesByConversion {
         public void setField(String s) {}
         public void setField(List<String> list) {}
     }
@@ -240,8 +240,8 @@ public class ReflectionUtilsTest {
         
         sut[1].set(new MultipleMatchesByConversion(), new HashSet<String>(), mockBlueprint);
     }
-    
-    static class MultipleMatchesByType {
+
+    public static class MultipleMatchesByType {
         public void setField(List<String> list) {}
         public void setField(Queue<String> list) {}
         
@@ -265,8 +265,8 @@ public class ReflectionUtilsTest {
         sut[2].set(new MultipleMatchesByType(), new ArrayList<String>(), mockBlueprint);
         assertEquals(2, MultipleMatchesByType.field);
     }
-    
-    static class NullSetterDisambiguation {
+
+    public static class NullSetterDisambiguation {
         public static int field;
         
         public void setField(int i) { field = i; }



Mime
View raw message