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");