CAMEL-6752 Fixed the Bean binding to covariant methods issue with thanks to Guy
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f6f28b50 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f6f28b50 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f6f28b50 Branch: refs/heads/camel-2.12.x Commit: f6f28b50216901989765983e97febb4a83f1963e Parents: 6fa665b Author: Willem Jiang <ningji...@apache.org> Authored: Mon Sep 16 11:41:24 2013 +0800 Committer: Willem Jiang <ningji...@apache.org> Committed: Mon Sep 16 11:45:03 2013 +0800 ---------------------------------------------------------------------- .../apache/camel/component/bean/BeanInfo.java | 41 ++++++++++++++++---- .../apache/camel/component/bean/MethodInfo.java | 14 +++++++ 2 files changed, 47 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/f6f28b50/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 6f91720..98d0c8b 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 @@ -549,7 +549,11 @@ public class BeanInfo { answer = chooseMethodWithMatchingParameters(exchange, parameters, possibleOperations); } } - + + if (answer == null && possibleOperations.size() > 1) { + answer = getSingleCovariantMethod(possibleOperations); + } + if (answer == null) { throw new AmbiguousMethodCallException(exchange, possibleOperations); } else { @@ -611,11 +615,26 @@ public class BeanInfo { } if (candidates.size() > 1) { - throw new AmbiguousMethodCallException(exchange, candidates); + MethodInfo answer = getSingleCovariantMethod(candidates); + if (answer == null) { + throw new AmbiguousMethodCallException(exchange, candidates); + } + return answer; } return candidates.size() == 1 ? candidates.get(0) : null; } + private MethodInfo getSingleCovariantMethod(Collection<MethodInfo> candidates) { + // if all the candidates are actually covariant, it doesn't matter which one we call + MethodInfo firstCandidate = candidates.iterator().next(); + for (MethodInfo candidate: candidates) { + if (!firstCandidate.isCovariantWith(candidate)) { + return null; + } + } + return firstCandidate; + } + private MethodInfo chooseMethodWithMatchingBody(Exchange exchange, Collection<MethodInfo> operationList, List<MethodInfo> operationsWithCustomAnnotation) throws AmbiguousMethodCallException { @@ -711,8 +730,17 @@ public class BeanInfo { LOG.trace("There are only one method with annotations so we choose it: {}", answer); return answer; } - // phew try to choose among multiple methods with annotations - return chooseMethodWithCustomAnnotations(exchange, possibles); + // try to choose among multiple methods with annotations + MethodInfo chosen = chooseMethodWithCustomAnnotations(exchange, possibles); + if (chosen != null) { + return chosen; + } + // just make sure the methods aren't all actually the same + chosen = getSingleCovariantMethod(possibles); + if (chosen != null) { + return chosen; + } + throw new AmbiguousMethodCallException(exchange, possibles); } // cannot find a good method to use @@ -783,10 +811,7 @@ public class BeanInfo { } } } - if (chosen != null) { - return chosen; - } - throw new AmbiguousMethodCallException(exchange, possibles); + return chosen; } /** http://git-wip-us.apache.org/repos/asf/camel/blob/f6f28b50/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java b/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java index cc58c50..a4dd2e0 100644 --- a/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java +++ b/camel-core/src/main/java/org/apache/camel/component/bean/MethodInfo.java @@ -389,6 +389,20 @@ public class MethodInfo { public boolean isStaticMethod() { return Modifier.isStatic(method.getModifiers()); } + + /** + * Returns true if this method is covariant with the specified method + * (this method may above or below the specified method in the class hierarchy) + * @param method + * @return + */ + public boolean isCovariantWith(MethodInfo method) { + return + method.getMethod().getName().equals(this.getMethod().getName()) + && (method.getMethod().getReturnType().isAssignableFrom(this.getMethod().getReturnType()) + || this.getMethod().getReturnType().isAssignableFrom(method.getMethod().getReturnType())) + && Arrays.deepEquals(method.getMethod().getParameterTypes(), this.getMethod().getParameterTypes()); + } protected Object invoke(Method mth, Object pojo, Object[] arguments, Exchange exchange) throws InvocationTargetException { try {