Author: davsclaus
Date: Thu Nov  1 15:39:09 2012
New Revision: 1404645

URL: http://svn.apache.org/viewvc?rev=1404645&view=rev
Log:
CAMEL-5765: Better logic for choosing between overloaded methods with null 
body, and when parameter values provided in method name syntax

Modified:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanHelper.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanHelper.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanHelper.java?rev=1404645&r1=1404644&r2=1404645&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanHelper.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanHelper.java
 Thu Nov  1 15:39:09 2012
@@ -30,16 +30,15 @@ public final class BeanHelper {
     }
 
     /**
-     * Determines if the given value is valid according to the supported
+     * Determines and maps the given value is valid according to the supported
      * values by the bean component.
      *
      * @param value the value
-     * @return <tt>true</tt> if valid, <tt>false</tt> otherwise
+     * @return the parameter type the given value is being mapped as, or 
<tt>null</tt> if not valid.
      */
-    public static boolean isValidParameterValue(String value) {
+    public static Class<?> getValidParameterType(String value) {
         if (ObjectHelper.isEmpty(value)) {
-            // empty value is valid
-            return true;
+            return null;
         }
 
         // trim value
@@ -47,27 +46,27 @@ public final class BeanHelper {
 
         // single quoted is valid
         if (value.startsWith("'") && value.endsWith("'")) {
-            return true;
+            return String.class;
         }
 
         // double quoted is valid
         if (value.startsWith("\"") && value.endsWith("\"")) {
-            return true;
+            return String.class;
         }
 
         // true or false is valid (boolean)
         if (value.equals("true") || value.equals("false")) {
-            return true;
+            return Boolean.class;
         }
 
         // null is valid (to force a null value)
         if (value.equals("null")) {
-            return true;
+            return Object.class;
         }
 
         // simple language tokens is valid
         if (StringHelper.hasStartToken(value, "simple")) {
-            return true;
+            return Object.class;
         }
 
         // numeric is valid
@@ -78,7 +77,28 @@ public final class BeanHelper {
                 break;
             }
         }
-        return numeric;
+        if (numeric) {
+            return Number.class;
+        }
+
+        // not valid
+        return null;
+    }
+
+    /**
+     * Determines if the given value is valid according to the supported
+     * values by the bean component.
+     *
+     * @param value the value
+     * @return <tt>true</tt> if valid, <tt>false</tt> otherwise
+     */
+    public static boolean isValidParameterValue(String value) {
+        if (ObjectHelper.isEmpty(value)) {
+            // empty value is valid
+            return true;
+        }
+
+        return getValidParameterType(value) != null;
     }
 
     /**

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java?rev=1404645&r1=1404644&r2=1404645&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
 Thu Nov  1 15:39:09 2012
@@ -490,8 +490,18 @@ public class BeanInfo {
         possibleOperations.addAll(localOperationsWithCustomAnnotation);
 
         if (!possibleOperations.isEmpty()) {
-             // multiple possible operations so find the best suited if 
possible
+            // 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
+                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) {
                 throw new AmbiguousMethodCallException(exchange, 
possibleOperations);
             } else {
@@ -502,7 +512,62 @@ public class BeanInfo {
         // not possible to determine
         return null;
     }
-    
+
+    private MethodInfo chooseMethodWithMatchingParameters(Exchange exchange, 
String parameters, Collection<MethodInfo> operationList)
+            throws AmbiguousMethodCallException {
+        // we have hardcoded parameters so need to match that with the given 
operations
+        Iterator<?> it = ObjectHelper.createIterator(parameters);
+        int count = 0;
+        while (it.hasNext()) {
+            it.next();
+            count++;
+        }
+
+        List<MethodInfo> operations = new ArrayList<MethodInfo>();
+        for (MethodInfo info : operationList) {
+            if (info.getParameters().size() == count) {
+                operations.add(info);
+            }
+        }
+
+        if (operations.isEmpty()) {
+            return null;
+        } else if (operations.size() == 1) {
+            return operations.get(0);
+        }
+
+        // okay we still got multiple operations, so need to match the best one
+        List<MethodInfo> candidates = new ArrayList<MethodInfo>();
+        for (MethodInfo info : operations) {
+            it = ObjectHelper.createIterator(parameters);
+            int index = 0;
+            boolean matches = true;
+            while (it.hasNext()) {
+                String parameter = (String) it.next();
+                Class<?> parameterType = 
BeanHelper.getValidParameterType(parameter);
+                Class<?> expectedType = 
info.getParameters().get(index).getType();
+
+                if (parameterType != null && expectedType != null) {
+                    if (!parameterType.isAssignableFrom(expectedType)) {
+                        matches = false;
+                        break;
+                    }
+                }
+
+                index++;
+            }
+
+            if (matches) {
+                candidates.add(info);
+            }
+        }
+
+        if (candidates.size() > 1) {
+            throw new AmbiguousMethodCallException(exchange, candidates);
+        }
+        return candidates.size() == 1 ? candidates.get(0) : null;
+    }
+
     private MethodInfo chooseMethodWithMatchingBody(Exchange exchange, 
Collection<MethodInfo> operationList,
                                                     List<MethodInfo> 
operationsWithCustomAnnotation)
         throws AmbiguousMethodCallException {

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java?rev=1404645&r1=1404644&r2=1404645&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java
 Thu Nov  1 15:39:09 2012
@@ -54,6 +54,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static org.apache.camel.util.ObjectHelper.asString;
+
 /**
  * Information about a method to be used for invocation.
  *

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java?rev=1404645&r1=1404644&r2=1404645&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
 Thu Nov  1 15:39:09 2012
@@ -1086,6 +1086,21 @@ public class SimpleTest extends Language
         assertExpression("${body.substring(${header.min}, ${header.max})}", 
"me");
     }
 
+    public void testHeaderOgnlOnStringWithOgnlParams() throws Exception {
+        exchange.getIn().setBody(null);
+        exchange.getIn().setHeader("name", "Camel");
+        exchange.getIn().setHeader("max", 4);
+        exchange.getIn().setHeader("min", 2);
+
+        assertExpression("${header.name.substring(${header.min}, 
${header.max})}", "me");
+    }
+
+    public void testCamelContextStartRoute() throws Exception {
+        exchange.getIn().setBody(null);
+
+        assertExpression("${camelContext.startRoute('foo')}", null);
+    }
+
     public void testBodyOgnlReplace() throws Exception {
         exchange.getIn().setBody("Kamel is a cool Kamel");
 


Reply via email to