/**
  * 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());
 }
Exemple #2
0
 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();
     }
   }
 }
Exemple #3
0
 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();
     }
   }
 }
Exemple #4
0
  /**
   * 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;
  }
Exemple #5
0
 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();
     }
   }
 }
Exemple #6
0
  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;
  }