/** * Returns true if this method is covariant with the specified method (this method may above or * below the specified method in the class hierarchy) */ 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()); }
private void removeAllAbstractMethods(List<MethodInfo> methods) { Iterator<MethodInfo> it = methods.iterator(); while (it.hasNext()) { MethodInfo info = it.next(); // if the class is an interface then keep the method boolean isFromInterface = Modifier.isInterface(info.getMethod().getDeclaringClass().getModifiers()); if (!isFromInterface && Modifier.isAbstract(info.getMethod().getModifiers())) { // we cannot invoke an abstract method it.remove(); } } }
private static void removeAllSetterOrGetterMethods(List<MethodInfo> methods) { Iterator<MethodInfo> it = methods.iterator(); while (it.hasNext()) { MethodInfo info = it.next(); if (IntrospectionSupport.isGetter(info.getMethod())) { // skip getters it.remove(); } else if (IntrospectionSupport.isSetter(info.getMethod())) { // skip setters it.remove(); } } }
/** * Does the given method info override an existing method registered before (from a subclass) * * @param methodInfo the method to test * @return the already registered method to use, null if not overriding any */ private MethodInfo overridesExistingMethod(MethodInfo methodInfo) { for (MethodInfo info : methodMap.values()) { Method source = info.getMethod(); Method target = methodInfo.getMethod(); boolean override = ObjectHelper.isOverridingMethod(source, target); if (override) { // same name, same parameters, then its overrides an existing class return info; } } return null; }
private void removeNonMatchingMethods(List<MethodInfo> methods, String name) { Iterator<MethodInfo> it = methods.iterator(); while (it.hasNext()) { MethodInfo info = it.next(); if (!matchMethod(info.getMethod(), name)) { // method does not match so remove it it.remove(); } } }
private MethodInvocation createInvocation(Object pojo, Exchange exchange, Method explicitMethod) throws AmbiguousMethodCallException, MethodNotFoundException { MethodInfo methodInfo = null; // find the explicit method to invoke if (explicitMethod != null) { for (List<MethodInfo> infos : operations.values()) { for (MethodInfo info : infos) { if (explicitMethod.equals(info.getMethod())) { return info.createMethodInvocation(pojo, exchange); } } } throw new MethodNotFoundException(exchange, pojo, explicitMethod.getName()); } String methodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, String.class); if (methodName != null) { // do not use qualifier for name String name = methodName; if (methodName.contains("(")) { name = ObjectHelper.before(methodName, "("); // the must be a ending parenthesis if (!methodName.endsWith(")")) { throw new IllegalArgumentException( "Method should end with parenthesis, was " + methodName); } } boolean emptyParameters = methodName.endsWith("()"); // special for getClass, as we want the user to be able to invoke this method // for example to log the class type or the likes if ("class".equals(name) || "getClass".equals(name)) { try { Method method = pojo.getClass().getMethod("getClass"); methodInfo = new MethodInfo( exchange.getContext(), pojo.getClass(), method, Collections.<ParameterInfo>emptyList(), Collections.<ParameterInfo>emptyList(), false, false); } catch (NoSuchMethodException e) { throw new MethodNotFoundException(exchange, pojo, "getClass"); } // special for length on an array type } else if ("length".equals(name) && pojo.getClass().isArray()) { try { // need to use arrayLength method from ObjectHelper as Camel's bean OGNL support is method // invocation based // and not for accessing fields. And hence we need to create a MethodInfo instance with a // method to call // and therefore use arrayLength from ObjectHelper to return the array length field. Method method = ObjectHelper.class.getMethod("arrayLength", Object[].class); ParameterInfo pi = new ParameterInfo( 0, Object[].class, null, ExpressionBuilder.mandatoryBodyExpression(Object[].class, true)); List<ParameterInfo> lpi = new ArrayList<ParameterInfo>(1); lpi.add(pi); methodInfo = new MethodInfo( exchange.getContext(), pojo.getClass(), method, lpi, lpi, false, false); // Need to update the message body to be pojo for the invocation exchange.getIn().setBody(pojo); } catch (NoSuchMethodException e) { throw new MethodNotFoundException(exchange, pojo, "getClass"); } } else { List<MethodInfo> methods = getOperations(name); if (methods != null && methods.size() == 1) { // only one method then choose it methodInfo = methods.get(0); // validate that if we want an explicit no-arg method, then that's what we get if (emptyParameters && methodInfo.hasParameters()) { throw new MethodNotFoundException(exchange, pojo, methodName, "(with no parameters)"); } } else if (methods != null) { // there are more methods with that name so we cannot decide which to use // but first let's try to choose a method and see if that complies with the name // must use the method name which may have qualifiers methodInfo = chooseMethod(pojo, exchange, methodName); // validate that if we want an explicit no-arg method, then that's what we get if (emptyParameters) { if (methodInfo == null || methodInfo.hasParameters()) { // we could not find a no-arg method with that name throw new MethodNotFoundException(exchange, pojo, methodName, "(with no parameters)"); } } if (methodInfo == null || (name != null && !name.equals(methodInfo.getMethod().getName()))) { throw new AmbiguousMethodCallException(exchange, methods); } } else { // a specific method was given to invoke but not found throw new MethodNotFoundException(exchange, pojo, methodName); } } } if (methodInfo == null) { // no name or type methodInfo = chooseMethod(pojo, exchange, null); } if (methodInfo == null) { methodInfo = defaultMethod; } if (methodInfo != null) { LOG.trace("Chosen method to invoke: {} on bean: {}", methodInfo, pojo); return methodInfo.createMethodInvocation(pojo, exchange); } LOG.debug("Cannot find suitable method to invoke on bean: {}", pojo); return null; }