Repository: camel
Updated Branches:
  refs/heads/camel-2.16.x 85e8991f6 -> 8410c9985


CAMEL-9475: Simple - Calling method should favor best matching type


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

Branch: refs/heads/camel-2.16.x
Commit: 8410c99851b1d4822fac1d6f0d7bb353ee9a7729
Parents: 85e8991
Author: Claus Ibsen <davscl...@apache.org>
Authored: Fri Jan 15 11:34:20 2016 +0100
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Fri Jan 15 11:35:03 2016 +0100

----------------------------------------------------------------------
 .../apache/camel/component/bean/BeanInfo.java   | 43 +++++++++++++++-----
 .../camel/language/simple/SimpleTest.java       | 30 ++++++++++++++
 2 files changed, 63 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/8410c998/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 a2f6ce8..d185d1b 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
@@ -605,18 +605,21 @@ public class BeanInfo {
         possibleOperations.addAll(localOperationsWithCustomAnnotation);
 
         if (!possibleOperations.isEmpty()) {
-            // multiple possible operations so find the best suited if possible
-            MethodInfo answer = chooseMethodWithMatchingBody(exchange, 
possibleOperations, localOperationsWithCustomAnnotation);
 
-            if (answer == null && name != null) {
-                // do we have hardcoded parameters values provided from the 
method name then fallback and try that
+            MethodInfo answer = null;
+
+            if (name != null) {
+                // do we have hardcoded parameters values provided from the 
method name then use that for matching
                 String parameters = ObjectHelper.between(name, "(", ")");
                 if (parameters != null) {
                     // special as we have hardcoded parameters, so we need to 
choose method that matches those parameters the best
                     answer = chooseMethodWithMatchingParameters(exchange, 
parameters, possibleOperations);
                 }
             }
-            
+            if (answer == null) {
+                // multiple possible operations so find the best suited if 
possible
+                answer = chooseMethodWithMatchingBody(exchange, 
possibleOperations, localOperationsWithCustomAnnotation);
+            }
             if (answer == null && possibleOperations.size() > 1) {
                 answer = getSingleCovariantMethod(possibleOperations);
             }
@@ -657,6 +660,7 @@ public class BeanInfo {
 
         // okay we still got multiple operations, so need to match the best one
         List<MethodInfo> candidates = new ArrayList<MethodInfo>();
+        MethodInfo fallbackCandidate = null;
         for (MethodInfo info : operations) {
             it = ObjectHelper.createIterator(parameters);
             int index = 0;
@@ -667,7 +671,16 @@ public class BeanInfo {
                 Class<?> expectedType = 
info.getParameters().get(index).getType();
 
                 if (parameterType != null && expectedType != null) {
-                    if (!parameterType.isAssignableFrom(expectedType)) {
+
+                    // skip java.lang.Object type, when we have multiple 
possible methods we want to avoid it if possible
+                    if (Object.class.equals(expectedType)) {
+                        fallbackCandidate = info;
+                        matches = false;
+                        break;
+                    }
+
+                    boolean matchingTypes = 
isParameterMatchingType(parameterType, expectedType);
+                    if (!matchingTypes) {
                         matches = false;
                         break;
                     }
@@ -683,12 +696,22 @@ public class BeanInfo {
 
         if (candidates.size() > 1) {
             MethodInfo answer = getSingleCovariantMethod(candidates);
-            if (answer == null) {
-                throw new AmbiguousMethodCallException(exchange, candidates);
+            if (answer != null) {
+                return answer;
+            }
+        }
+        return candidates.size() == 1 ? candidates.get(0) : fallbackCandidate;
+    }
+
+    private boolean isParameterMatchingType(Class<?> parameterType, Class<?> 
expectedType) {
+        if (Number.class.equals(parameterType)) {
+            // number should match long/int/etc.
+            if (Integer.class.isAssignableFrom(expectedType) || 
Long.class.isAssignableFrom(expectedType)
+                    || int.class.isAssignableFrom(expectedType) || 
long.class.isAssignableFrom(expectedType)) {
+                return true;
             }
-            return answer;
         }
-        return candidates.size() == 1 ? candidates.get(0) : null;
+        return parameterType.isAssignableFrom(expectedType);
     }
 
     private MethodInfo getSingleCovariantMethod(Collection<MethodInfo> 
candidates) {

http://git-wip-us.apache.org/repos/asf/camel/blob/8410c998/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java 
b/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
index 95c7455..b0b5106 100644
--- a/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
+++ b/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
@@ -1473,6 +1473,36 @@ public class SimpleTest extends LanguageTestSupport {
         }
     }
 
+    public void testListRemoveByInstance() throws Exception {
+        List<Object> data = new ArrayList<Object>();
+        data.add("A");
+        data.add("B");
+        exchange.getIn().setBody(data);
+
+        assertEquals(2, data.size());
+
+        Expression expression = SimpleLanguage.simple("${body.remove('A')}");
+        expression.evaluate(exchange, Object.class);
+
+        assertEquals(1, data.size());
+        assertEquals("B", data.get(0));
+    }
+
+    public void testListRemoveIndex() throws Exception {
+        List<Object> data = new ArrayList<Object>();
+        data.add("A");
+        data.add("B");
+        exchange.getIn().setBody(data);
+
+        assertEquals(2, data.size());
+
+        Expression expression = SimpleLanguage.simple("${body.remove(0)}");
+        expression.evaluate(exchange, Object.class);
+
+        assertEquals(1, data.size());
+        assertEquals("B", data.get(0));
+    }
+
     protected String getLanguageName() {
         return "simple";
     }

Reply via email to