CAMEL-11235: Resolved an issue where a method inherited from a superclass 
overrides a superinterface method


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/04c4de84
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/04c4de84
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/04c4de84

Branch: refs/heads/camel-2.19.x
Commit: 04c4de84687579b1f26fb536c21b0ad90d1fbeb1
Parents: 6d820de
Author: aldettinger <aldettin...@gmail.com>
Authored: Sat May 20 12:18:57 2017 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Sat May 20 15:53:49 2017 +0200

----------------------------------------------------------------------
 .../apache/camel/component/bean/BeanInfo.java   | 46 ++++++--------------
 .../org/apache/camel/util/ObjectHelper.java     | 20 ++++++++-
 .../camel/component/bean/MyOtherFooBean.java    | 17 ++++++++
 .../org/apache/camel/util/ObjectHelperTest.java | 15 +++++++
 4 files changed, 65 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/04c4de84/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java 
b/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
index 1efe61c..f87e4a4 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
@@ -328,7 +328,7 @@ public class BeanInfo {
             methods.addAll(extraMethods);
         }
 
-        Set<Method> overrides = new HashSet<Method>();
+        Set<Method> overriddenMethods = new HashSet<Method>();
 
         // do not remove duplicates form class from the Java itself as they 
have some "duplicates" we need
         boolean javaClass = clazz.getName().startsWith("java.") || 
clazz.getName().startsWith("javax.");
@@ -343,38 +343,17 @@ public class BeanInfo {
 
                 for (Method target : methods) {
                     // skip ourselves
-                    if (ObjectHelper.isOverridingMethod(source, target, true)) 
{
+                    if (ObjectHelper.isOverridingMethod(getType(), source, 
target, true)) {
                         continue;
                     }
                     // skip duplicates which may be assign compatible (favor 
keep first added method when duplicate)
-                    if (ObjectHelper.isOverridingMethod(source, target, 
false)) {
-                        overrides.add(target);
+                    if (ObjectHelper.isOverridingMethod(getType(), source, 
target, false)) {
+                        overriddenMethods.add(target);
                     }
                 }
             }
-            methods.removeAll(overrides);
-            overrides.clear();
-        }
-
-        // if we are a public class, then add non duplicate interface classes 
also
-        if (Modifier.isPublic(clazz.getModifiers())) {
-            // add additional interface methods
-            List<Method> extraMethods = getInterfaceMethods(clazz);
-            for (Method source : extraMethods) {
-                for (Method target : methods) {
-                    if (ObjectHelper.isOverridingMethod(source, target, 
false)) {
-                        overrides.add(source);
-                    }
-                }
-                for (Method target : methodMap.keySet()) {
-                    if (ObjectHelper.isOverridingMethod(source, target, 
false)) {
-                        overrides.add(source);
-                    }
-                }
-            }
-            // remove all the overrides methods
-            extraMethods.removeAll(overrides);
-            methods.addAll(extraMethods);
+            methods.removeAll(overriddenMethods);
+            overriddenMethods.clear();
         }
 
         // now introspect the methods and filter non valid methods
@@ -386,9 +365,12 @@ public class BeanInfo {
             }
         }
 
-        Class<?> superclass = clazz.getSuperclass();
-        if (superclass != null && !superclass.equals(Object.class)) {
-            introspect(superclass);
+        Class<?> superClass = clazz.getSuperclass();
+        if (superClass != null && !superClass.equals(Object.class)) {
+            introspect(superClass);
+        }
+        for (Class<?> superInterface : clazz.getInterfaces()) {
+            introspect(superInterface);
         }
     }
 
@@ -917,9 +899,9 @@ public class BeanInfo {
             Method alreadyRegisteredMethod = 
alreadyRegisteredMethodInfo.getMethod();
             Method proposedMethod = proposedMethodInfo.getMethod();
 
-            if (ObjectHelper.isOverridingMethod(proposedMethod, 
alreadyRegisteredMethod, false)) {
+            if (ObjectHelper.isOverridingMethod(getType(), proposedMethod, 
alreadyRegisteredMethod, false)) {
                 return alreadyRegisteredMethodInfo;
-            } else if 
(ObjectHelper.isOverridingMethod(alreadyRegisteredMethod, proposedMethod, 
false)) {
+            } else if (ObjectHelper.isOverridingMethod(getType(), 
alreadyRegisteredMethod, proposedMethod, false)) {
                 return proposedMethodInfo;
             }
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/04c4de84/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java 
b/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
index 07bb308..ebc3df8 100644
--- a/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java
@@ -1380,12 +1380,30 @@ public final class ObjectHelper {
      * @return <tt>true</tt> if it override, <tt>false</tt> otherwise
      */
     public static boolean isOverridingMethod(Method source, Method target, 
boolean exact) {
+        return isOverridingMethod(target.getDeclaringClass(), source, target, 
exact);
+    }
+
+    /**
+     * Tests whether the target method overrides the source method from the
+     * inheriting class.
+     * <p/>
+     * Tests whether they have the same name, return type, and parameter list.
+     *
+     * @param inheritingClass the class inheriting the target method overriding
+     *            the source method
+     * @param source the source method
+     * @param target the target method
+     * @param exact <tt>true</tt> if the override must be exact same types,
+     *            <tt>false</tt> if the types should be assignable
+     * @return <tt>true</tt> if it override, <tt>false</tt> otherwise
+     */
+    public static boolean isOverridingMethod(Class<?> inheritingClass, Method 
source, Method target, boolean exact) {
 
         if (source.equals(target)) {
             return true;
         } else if (source.getDeclaringClass() == target.getDeclaringClass()) {
             return false;
-        } else if 
(!source.getDeclaringClass().isAssignableFrom(target.getDeclaringClass())) {
+        } else if 
(!source.getDeclaringClass().isAssignableFrom(inheritingClass) || 
!target.getDeclaringClass().isAssignableFrom(inheritingClass)) {
             return false;
         }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/04c4de84/camel-core/src/test/java/org/apache/camel/component/bean/MyOtherFooBean.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/component/bean/MyOtherFooBean.java 
b/camel-core/src/test/java/org/apache/camel/component/bean/MyOtherFooBean.java
index fa2a519..4343812 100644
--- 
a/camel-core/src/test/java/org/apache/camel/component/bean/MyOtherFooBean.java
+++ 
b/camel-core/src/test/java/org/apache/camel/component/bean/MyOtherFooBean.java
@@ -33,4 +33,21 @@ public class MyOtherFooBean {
     public String toString(String input) {
         return "toString(String) was called";
     }
+
+    public interface InterfaceSize {
+        int size();
+    }
+
+    public abstract static class AbstractClassSize {
+        public abstract int size();
+    }
+
+    public static class SuperClazz extends AbstractClassSize implements 
InterfaceSize {
+        public int size() {
+            return 1;
+        }
+    }
+
+    public static class Clazz extends SuperClazz {
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/04c4de84/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java 
b/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
index 7997664..f0d60a5 100644
--- a/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
@@ -38,6 +38,9 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.component.bean.MyOtherFooBean;
+import org.apache.camel.component.bean.MyOtherFooBean.AbstractClassSize;
+import org.apache.camel.component.bean.MyOtherFooBean.Clazz;
+import org.apache.camel.component.bean.MyOtherFooBean.InterfaceSize;
 import org.apache.camel.component.bean.MyStaticClass;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.impl.DefaultMessage;
@@ -890,4 +893,16 @@ public class ObjectHelperTest extends TestCase {
         Method m2 = Number.class.getMethod("intValue");
         assertTrue(ObjectHelper.isOverridingMethod(m2, m1, false));
     }
+
+    public void testInheritedMethodCanOverrideInterfaceMethod() throws 
Exception {
+        Method m1 = AbstractClassSize.class.getMethod("size");
+        Method m2 = InterfaceSize.class.getMethod("size");
+        assertTrue(ObjectHelper.isOverridingMethod(Clazz.class, m2, m1, 
false));
+    }
+
+    public void testNonInheritedMethodCantOverrideInterfaceMethod() throws 
Exception {
+        Method m1 = AbstractClassSize.class.getMethod("size");
+        Method m2 = InterfaceSize.class.getMethod("size");
+        assertFalse(ObjectHelper.isOverridingMethod(InterfaceSize.class, m2, 
m1, false));
+    }
 }

Reply via email to