You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ma...@apache.org on 2010/06/05 11:39:47 UTC
svn commit: r951687 - in /incubator/aries/trunk/blueprint/blueprint-core/src:
main/java/org/apache/aries/blueprint/container/BeanRecipe.java
test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
Author: mahrwald
Date: Sat Jun 5 09:39:46 2010
New Revision: 951687
URL: http://svn.apache.org/viewvc?rev=951687&view=rev
Log:
ARIES-325: Add cross-JVM static factory method disambiguation.
Added:
incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
Modified:
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java?rev=951687&r1=951686&r2=951687&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java Sat Jun 5 09:39:46 2010
@@ -26,6 +26,7 @@ import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -287,6 +288,13 @@ public class BeanRecipe extends Abstract
it.remove();
}
}
+
+ // on some JVMs (J9) hidden static methods are returned by Class.getMethods so we need to weed them out
+ // to reduce ambiguity
+ if (!instance) {
+ methods = applyStaticHidingRules(methods);
+ }
+
// Find a direct match with assignment
if (matches.size() != 1) {
Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
@@ -374,8 +382,49 @@ public class BeanRecipe extends Abstract
matches = nmatches;
}
}
+
return matches;
}
+
+ private static List<Method> applyStaticHidingRules(Collection<Method> methods) {
+ List<Method> result = new ArrayList<Method>(methods.size());
+ for (Method m : methods) {
+ boolean toBeAdded = true;
+
+ Iterator<Method> it = result.iterator();
+ inner: while (it.hasNext()) {
+ Method other = it.next();
+ if (hasIdenticalParameters(m, other)) {
+ Class<?> mClass = m.getDeclaringClass();
+ Class<?> otherClass = other.getDeclaringClass();
+
+ if (mClass.isAssignableFrom(otherClass)) {
+ toBeAdded = false;
+ break inner;
+ } else if (otherClass.isAssignableFrom(mClass)) {
+ it.remove();
+ }
+ }
+ }
+
+ if (toBeAdded) result.add(m);
+ }
+
+ return result;
+ }
+
+ private static boolean hasIdenticalParameters(Method one, Method two) {
+ Class<?>[] oneTypes = one.getParameterTypes();
+ Class<?>[] twoTypes = two.getParameterTypes();
+
+ if (oneTypes.length != twoTypes.length) return false;
+
+ for (int i=0; i<oneTypes.length; i++) {
+ if (!oneTypes[i].equals(twoTypes[i])) return false;
+ }
+
+ return true;
+ }
private Map<Constructor, List<Object>> findMatchingConstructors(Class type, List<Object> args, List<ReifiedType> types) {
Map<Constructor, List<Object>> matches = new HashMap<Constructor, List<Object>>();
Added: incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java?rev=951687&view=auto
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java (added)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/BeanRecipeTest.java Sat Jun 5 09:39:46 2010
@@ -0,0 +1,135 @@
+/*
+ * 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.aries.blueprint.container;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class BeanRecipeTest {
+ static class Base {
+ public static Object getObject() { return null; }
+ public static Object getOne(Object o) { return null; }
+
+ public static Object getMany(Object o, String n, String n2) { return null; }
+ }
+
+ static class Middle extends Base {
+ public static Number getObject() { return null; }
+ public static Number getOne(Number n) { return null; }
+ public static Number getOne(Object o) { return null; }
+
+ public static Object getMany(Object o, String n, Number i) { return null; }
+ public static Object getBasic(int n) { return 0; }
+ }
+
+ static class Top extends Middle {
+ public static Integer getObject() { return null; }
+ public static Integer getOne(Integer n) { return null; }
+
+ public static Object getMany(Object o, String n, Number i) { return null; }
+ public static Object getBasic(int n) { return 0; }
+ }
+
+ static class Unrelated {
+ public static String getObject() { return null; }
+ public static Object getBasic(int n) { return 1; }
+ }
+
+ @Test
+ public void parameterLessHiding() throws Exception {
+ Set<Method> methods = new HashSet<Method>(
+ Arrays.asList(
+ Base.class.getMethod("getObject"),
+ Middle.class.getMethod("getObject"),
+ Top.class.getMethod("getObject"),
+ Unrelated.class.getMethod("getObject")
+ ));
+
+ methods = applyStaticHidingRules(methods);
+
+ assertEquals(2, methods.size());
+ assertTrue(methods.contains(Top.class.getMethod("getObject")));
+ assertTrue(methods.contains(Unrelated.class.getMethod("getObject")));
+ assertFalse(methods.contains(Middle.class.getMethod("getObject")));
+ }
+
+ @Test
+ public void parameterDistinction() throws Exception {
+ Set<Method> methods = new HashSet<Method>(
+ Arrays.asList(
+ Base.class.getMethod("getOne", Object.class),
+ Middle.class.getMethod("getOne", Number.class),
+ Middle.class.getMethod("getOne", Object.class),
+ Top.class.getMethod("getOne", Integer.class)
+ ));
+
+ methods = applyStaticHidingRules(methods);
+
+ assertEquals(3, methods.size());
+ assertFalse(methods.contains(Base.class.getMethod("getOne", Object.class)));
+ }
+
+ @Test
+ public void multiParameterTest() throws Exception {
+ Set<Method> methods = new HashSet<Method>(
+ Arrays.asList(
+ Base.class.getMethod("getMany", Object.class, String.class, String.class),
+ Middle.class.getMethod("getMany", Object.class, String.class, Number.class),
+ Top.class.getMethod("getMany", Object.class, String.class, Number.class)
+ ));
+
+ methods = applyStaticHidingRules(methods);
+
+ assertEquals(2, methods.size());
+ assertFalse(methods.contains(Middle.class.getMethod("getMany", Object.class, String.class, Number.class)));
+
+ }
+
+ @Test
+ public void baseTypeHiding() throws Exception {
+ Set<Method> methods = new HashSet<Method>(
+ Arrays.asList(
+ Middle.class.getMethod("getBasic", int.class),
+ Top.class.getMethod("getBasic", int.class),
+ Unrelated.class.getMethod("getBasic", int.class)
+ ));
+
+ methods = applyStaticHidingRules(methods);
+
+ assertEquals(2, methods.size());
+ assertFalse(methods.contains(Middle.class.getMethod("getBasic", int.class)));
+ }
+
+ private Set<Method> applyStaticHidingRules(Collection<Method> methods) {
+ try {
+ Method m = BeanRecipe.class.getDeclaredMethod("applyStaticHidingRules", Collection.class);
+ m.setAccessible(true);
+ return new HashSet<Method>((List<Method>) m.invoke(null, methods));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}