You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2017/02/19 10:08:54 UTC

[2/3] camel git commit: CAMEL-10396: Corrected a bug where BeanInfo was missing a method overload

CAMEL-10396: Corrected a bug where BeanInfo was missing a method overload


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

Branch: refs/heads/master
Commit: 8889b827193d6c5b08c801a4dbb457a43af2f958
Parents: ec7ffa1
Author: aldettinger <al...@gmail.com>
Authored: Sat Feb 18 16:28:55 2017 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sun Feb 19 10:03:36 2017 +0100

----------------------------------------------------------------------
 .../apache/camel/component/bean/BeanInfo.java   | 34 +++++++++++---------
 .../org/apache/camel/util/ObjectHelper.java     |  9 ++++++
 .../camel/component/bean/MyOtherFooBean.java    | 11 +++++--
 .../org/apache/camel/util/ObjectHelperTest.java | 24 ++++++++++++++
 4 files changed, 59 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/8889b827/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 ffeea3e..1efe61c 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
@@ -405,10 +405,8 @@ public class BeanInfo {
 
         MethodInfo methodInfo = createMethodInfo(clazz, method);
 
-        // methods already registered should be preferred to use instead of super classes of existing methods
-        // we want to us the method from the sub class over super classes, so if we have already registered
-        // the method then use it (we are traversing upwards: sub (child) -> super (farther) )
-        MethodInfo existingMethodInfo = overridesExistingMethod(methodInfo);
+        // Foster the use of a potentially already registered most specific override
+        MethodInfo existingMethodInfo = findMostSpecificOverride(methodInfo);
         if (existingMethodInfo != null) {
             LOG.trace("This method is already overridden in a subclass, so the method from the sub class is preferred: {}", existingMethodInfo);
             return existingMethodInfo;
@@ -905,20 +903,24 @@ public class BeanInfo {
     }
 
     /**
-     * Does the given method info override an existing method registered before (from a subclass)
+     * Gets the most specific override of a given method, if any. Indeed,
+     * overrides may have already been found while inspecting sub classes. Or
+     * the given method could override an interface extra method.
      *
-     * @param methodInfo  the method to test
-     * @return the already registered method to use, null if not overriding any
+     * @param proposedMethodInfo the method for which a more specific override is
+     *            searched
+     * @return The already registered most specific override if any, otherwise
+     *         <code>null</code>
      */
-    private MethodInfo overridesExistingMethod(MethodInfo methodInfo) {
-        for (MethodInfo info : methodMap.values()) {
-            Method source = info.getMethod();
-            Method target = methodInfo.getMethod();
-
-            boolean override = ObjectHelper.isOverridingMethod(source, target);
-            if (override) {
-                // same name, same parameters, then its overrides an existing class
-                return info;
+    private MethodInfo findMostSpecificOverride(MethodInfo proposedMethodInfo) {
+        for (MethodInfo alreadyRegisteredMethodInfo : methodMap.values()) {
+            Method alreadyRegisteredMethod = alreadyRegisteredMethodInfo.getMethod();
+            Method proposedMethod = proposedMethodInfo.getMethod();
+
+            if (ObjectHelper.isOverridingMethod(proposedMethod, alreadyRegisteredMethod, false)) {
+                return alreadyRegisteredMethodInfo;
+            } else if (ObjectHelper.isOverridingMethod(alreadyRegisteredMethod, proposedMethod, false)) {
+                return proposedMethodInfo;
             }
         }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/8889b827/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 7331437..b87cbc6 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
@@ -1327,6 +1327,15 @@ 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) {
+
+        if (source.equals(target)) {
+            return true;
+        } else if (source.getDeclaringClass() == target.getDeclaringClass()) {
+            return false;
+        } else if (!source.getDeclaringClass().isAssignableFrom(target.getDeclaringClass())) {
+            return false;
+        }
+
         if (!source.getName().equals(target.getName())) {
             return false;
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/8889b827/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 0333478..fa2a519 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
@@ -16,9 +16,6 @@
  */
 package org.apache.camel.component.bean;
 
-/**
- * @version 
- */
 public class MyOtherFooBean {
 
     public String echo(String s) {
@@ -28,4 +25,12 @@ public class MyOtherFooBean {
     public Integer echo(Integer i) {
         return i.intValue() * i.intValue();
     }
+
+    public String toString(Object input) {
+        return "toString(Object) was called";
+    }
+
+    public String toString(String input) {
+        return "toString(String) was called";
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/8889b827/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 0253eca..7997664 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
@@ -37,6 +37,7 @@ import junit.framework.TestCase;
 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.MyStaticClass;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.impl.DefaultMessage;
@@ -866,4 +867,27 @@ public class ObjectHelperTest extends TestCase {
             assertEquals("expected2 must be specified on: holder", iae.getMessage());
         }
     }
+
+    public void testSameMethodIsOverride() throws Exception {
+        Method m = MyOtherFooBean.class.getMethod("toString", Object.class);
+        assertTrue(ObjectHelper.isOverridingMethod(m, m, false));
+    }
+
+    public void testOverloadIsNotOverride() throws Exception {
+        Method m1 = MyOtherFooBean.class.getMethod("toString", Object.class);
+        Method m2 = MyOtherFooBean.class.getMethod("toString", String.class);
+        assertFalse(ObjectHelper.isOverridingMethod(m2, m1, false));
+    }
+
+    public void testOverrideEquivalentSignatureFromSiblingClassIsNotOverride() throws Exception {
+        Method m1 = Double.class.getMethod("intValue");
+        Method m2 = Float.class.getMethod("intValue");
+        assertFalse(ObjectHelper.isOverridingMethod(m2, m1, false));
+    }
+
+    public void testOverrideEquivalentSignatureFromUpperClassIsOverride() throws Exception {
+        Method m1 = Double.class.getMethod("intValue");
+        Method m2 = Number.class.getMethod("intValue");
+        assertTrue(ObjectHelper.isOverridingMethod(m2, m1, false));
+    }
 }