harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mloe...@apache.org
Subject svn commit: r424236 - in /incubator/harmony/enhanced/classlib/trunk/modules/beans/src: main/java/java/beans/Statement.java test/java/org/apache/harmony/beans/tests/java/beans/StatementTest.java
Date Fri, 21 Jul 2006 08:57:49 GMT
Author: mloenko
Date: Fri Jul 21 01:57:49 2006
New Revision: 424236

URL: http://svn.apache.org/viewvc?rev=424236&view=rev
Log:
fixes for HARMONY-900
[classlib][beans] enabling of tests from StatementTest class (5)

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Statement.java
    incubator/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/StatementTest.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Statement.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Statement.java?rev=424236&r1=424235&r2=424236&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Statement.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/Statement.java
Fri Jul 21 01:57:49 2006
@@ -25,6 +25,10 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Vector;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
@@ -187,8 +191,8 @@
         // the code below reproduces exact RI exception throwing behavior 
         if (!methodName.equals("set") && !methodName.equals("get")) {
             throw new NoSuchMethodException("Unknown method name for array");
-        } else if (arguments.length > 0 &&
-                   arguments[0].getClass() != Integer.class) {
+        } else if (arguments.length > 0
+                && arguments[0].getClass() != Integer.class) {
             throw new ClassCastException(
                     "First parameter in array getter(setter) is not of "
                             + "Integer type");
@@ -198,14 +202,14 @@
         } else if (methodName.equals("set") && (arguments.length != 2)) {
             throw new ArrayIndexOutOfBoundsException(
                     "Illegal number of arguments in array setter");
-        } 
+        }
 
         if (methodName.equals("get")) {
-            return Array.class.getMethod("get",
-                    new Class[] { Object.class, int.class } );
+            return Array.class.getMethod("get", new Class[] { Object.class,
+                    int.class });
         } else {
-            return Array.class.getMethod("set",
-                    new Class[] { Object.class, int.class, Object.class } );
+            return Array.class.getMethod("set", new Class[] { Object.class,
+                    int.class, Object.class });
         }
     }
 
@@ -264,22 +268,22 @@
     }
 
     /**
-     * Method lookup is performed initially in the current class
-     * then in superclass, then in super class of super class and so on.
+     * Searches for best matching method for given name and argument types.
      */
     private static Method findMethod(Class<?> targetClass, String methodName,
             Object[] arguments, boolean methodIsStatic)
             throws NoSuchMethodException {
-        Class[] argClasses = getClasses(arguments);
 
-        Method result = null;
-        Method[] methods = targetClass.getDeclaredMethods();
+        Class[] argClasses = getClasses(arguments);
+        Method[] methods = targetClass.getMethods();
+        Vector<Method> foundMethods = new Vector<Method>();
+        Method[] foundMethodsArr;
 
         for (int i = 0; i < methods.length; ++i) {
             Method method = methods[i];
             int mods = method.getModifiers();
 
-            if (method.getName().equals(methodName) && Modifier.isPublic(mods)
+            if (method.getName().equals(methodName)
                     && (methodIsStatic ? Modifier.isStatic(mods) : true)) {
 
                 Class<?>[] parameterTypes = method.getParameterTypes();
@@ -306,27 +310,22 @@
                     }
 
                     if (found) {
-                        result = method;
-                        break;
+                        foundMethods.addElement(method);
                     }
                 }
             }
         }
 
-        if (result == null) {
-            // let's look for this method in the super class
-            Class<?> parent = targetClass.getSuperclass();
-
-            if (parent != null) {
-                result = findMethod(parent, methodName, arguments,
-                        methodIsStatic);
-            } else {
-                throw new NoSuchMethodException("No method with name "
-                        + methodName + " is found");
-            }
+        if (foundMethods.size() == 0) {
+            throw new NoSuchMethodException("No method with name " + methodName
+                    + " is found");
         }
 
-        return result;
+        foundMethodsArr = foundMethods.toArray(new Method[foundMethods.size()]);
+        Arrays.sort(foundMethodsArr, new MethodComparator(methodName,
+                argClasses));
+
+        return foundMethodsArr[0];
     }
 
     private static boolean isPrimitiveWrapper(Class<?> wrapper, Class<?> base)
{
@@ -340,12 +339,34 @@
                 || (base == double.class) && (wrapper == Double.class);
     }
 
+    private static Class getPrimitiveWrapper(Class base) {
+        Class res = null;
+
+        if (base == boolean.class) {
+            res = Boolean.class;
+        } else if (base == byte.class) {
+            res = Byte.class;
+        } else if (base == char.class) {
+            res = Character.class;
+        } else if (base == short.class) {
+            res = Short.class;
+        } else if (base == int.class) {
+            res = Integer.class;
+        } else if (base == long.class) {
+            res = Long.class;
+        } else if (base == float.class) {
+            res = Float.class;
+        } else if (base == double.class) {
+            res = Double.class;
+        }
+        return res;
+    }
+
     static String convertClassName(Class<?> type) {
         Class<?> componentType = type.getComponentType();
         Class<?> resultType = (componentType == null) ? type : componentType;
         String result = resultType.getName();
         int k = result.lastIndexOf('.');
-        ;
 
         if (k != -1 && k < result.length()) {
             result = result.substring(k + 1);
@@ -393,4 +414,126 @@
             return false;
         }
     }
+
+    /**
+     * Comparator to determine which of two methods is "closer" to the reference
+     * method.  
+     */
+    static class MethodComparator implements Comparator<Method> {
+
+        static int INFINITY = Integer.MAX_VALUE;
+
+        private String referenceMethodName;
+
+        private Class[] referenceMethodArgumentTypes;
+
+        private HashMap<Method, Integer> cache;
+
+        public MethodComparator(String refMethodName, Class[] refArgumentTypes) {
+            this.referenceMethodName = refMethodName;
+            this.referenceMethodArgumentTypes = refArgumentTypes;
+            cache = new HashMap<Method, Integer>();
+        }
+
+        public int compare(Method m1, Method m2) {
+            Integer norm1 = cache.get(m1);
+            Integer norm2 = cache.get(m2);
+
+            if (norm1 == null) {
+                norm1 = getNorm(m1);
+                cache.put(m1, norm1);
+            }
+            if (norm2 == null) {
+                norm2 = getNorm(m2);
+                cache.put(m2, norm2);
+            }
+            return (norm1 - norm2);
+        }
+
+        /**
+         * Returns the norm for given method. The norm is the "distance" from
+         * the reference method to the given method.
+         * @param m the method to calculate the norm for
+         * @return norm of given method
+         */
+        private int getNorm(Method m) {
+            String methodName = m.getName();
+            Class[] argumentTypes = m.getParameterTypes();
+            int totalNorm = 0;
+
+            if (!referenceMethodName.equals(methodName)
+                    || referenceMethodArgumentTypes.length != argumentTypes.length) {
+                return INFINITY;
+            }
+
+            for (int i = 0; i < referenceMethodArgumentTypes.length; i++) {
+
+                if (referenceMethodArgumentTypes[i] == null) {
+                    if (argumentTypes[i].isPrimitive()) {
+                        return INFINITY;
+                    } else {
+                        // doesn't affect the norm calculation if null
+                        continue;
+                    }
+                }
+
+                if (referenceMethodArgumentTypes[i].isPrimitive()) {
+                    referenceMethodArgumentTypes[i] = getPrimitiveWrapper(referenceMethodArgumentTypes[i]);
+                }
+
+                if (argumentTypes[i].isPrimitive()) {
+                    argumentTypes[i] = getPrimitiveWrapper(argumentTypes[i]);
+                }
+
+                totalNorm += getDistance(referenceMethodArgumentTypes[i],
+                        argumentTypes[i]);
+            }
+
+            return totalNorm;
+        }
+
+        /**
+         * Returns a "hierarchy distance" between two classes. 
+         * @param clz1
+         * @param clz2 should be superclass or superinterface of clz1
+         * @return hierarchy distance from clz1 to clz2, Integer.MAX_VALUE if
+         * clz2 is not assignable from clz1.
+         */
+        private static int getDistance(Class<?> clz1, Class<?> clz2) {
+            Class superClz;
+            int superDist = INFINITY;
+
+            if (!clz2.isAssignableFrom(clz1)) {
+                return INFINITY;
+            }
+            if (clz1.getName().equals(clz2.getName())) {
+                return 0;
+            }
+
+            superClz = clz1.getSuperclass();
+            if (superClz != null) {
+                superDist = getDistance(superClz, clz2);
+            }
+            if (clz2.isInterface()) {
+                Class[] interfaces = clz1.getInterfaces();
+                int bestDist = INFINITY;
+
+                for (int i = 0; i < interfaces.length; i++) {
+                    int curDist = getDistance(interfaces[i], clz2);
+
+                    if (curDist < bestDist) {
+                        bestDist = curDist;
+                    }
+                }
+
+                if (superDist < bestDist) {
+                    bestDist = superDist;
+                }
+                return (bestDist != INFINITY ? bestDist + 1 : INFINITY);
+            } else {
+                return (superDist != INFINITY ? superDist + 1 : INFINITY);
+            }
+        }
+    }
+
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/StatementTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/StatementTest.java?rev=424236&r1=424235&r2=424236&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/StatementTest.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/StatementTest.java
Fri Jul 21 01:57:49 2006
@@ -35,20 +35,6 @@
     private static int testId = -1;
 
     /**
-     * 
-     */
-    public StatementTest() {
-        super();
-    }
-
-    /**
-     * 
-     */
-    public StatementTest(String name) {
-        super(name);
-    }
-
-    /**
      * The test checks the method execute() for setter
      */
     public void testSetter() throws Exception {
@@ -241,7 +227,6 @@
         assertSame(oa, t.getArguments());
         assertSame(arg1, t.getArguments()[0]);
         assertSame(arg2, t.getArguments()[1]);
-        System.out.println(t.toString());
         assertEquals("Object.method(Object, \"string\");", t.toString());
     }
 
@@ -449,8 +434,11 @@
      */
     public void testExecute_OverloadedMethods() throws Exception {
         MockObject mo = new MockObject(false);
-        Object[] arguments = new Object[] { new Object() };
-        Statement t = new Statement(mo, "method", arguments);
+        Object[] arguments;
+        Statement t;
+
+        arguments = new Object[] { new Object() };
+        t = new Statement(mo, "method", arguments);
         t.execute();
         MockObject.assertCalled("method2", arguments);
 
@@ -458,6 +446,11 @@
         t = new Statement(mo, "method", arguments);
         t.execute();
         MockObject.assertCalled("method3", arguments);
+
+        arguments = new Object[] { new Integer(117) };
+        t = new Statement(mo, "method", arguments);
+        t.execute();
+        MockObject.assertCalled("method1-3", arguments);
     }
 
     /*
@@ -611,8 +604,8 @@
      */
     public void testExecute_ArrayGet() throws Exception {
         Object[] array = new Object[] { "test" };
-        Statement t = new Statement(array, "get", new Object[] {
-                new Integer(0)});
+        Statement t = new Statement(array, "get",
+                new Object[] { new Integer(0) });
         t.execute();
 
         array = new Object[] { "test" };
@@ -660,7 +653,7 @@
     public void testExecute_ArrayInvalidSet() throws Exception {
         Object[] array = new Object[] { "test" };
         Statement t = new Statement(array, "set", new Object[] {
-                new Integer(0), "test2"});
+                new Integer(0), "test2" });
         t.execute();
         assertEquals("test2", array[0]);
 
@@ -864,9 +857,15 @@
             receivedArguments.add(o);
         }
 
-        public void method(Integer o) {
+        public void method(Number n) {
             reset();
             calledMethod = "method1-2";
+            receivedArguments.add(n);
+        }
+
+        public void method(Integer o) {
+            reset();
+            calledMethod = "method1-3";
             receivedArguments.add(o);
         }
 



Mime
View raw message