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/aebe5277 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/aebe5277 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/aebe5277 Branch: refs/heads/camel-2.11.x Commit: aebe527746df8babc943a33102d01ac71e6240ce Parents: 1d35c4c 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:48:41 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/aebe5277/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 59e9588..f288ace 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 @@ -535,7 +535,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 { @@ -597,11 +601,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 { @@ -697,8 +716,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 @@ -769,10 +797,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/aebe5277/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 68d4cc1..e72aec4 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 @@ -385,6 +385,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 {