@SuppressWarnings("unchecked")
    public <T> T evaluate(Exchange exchange, Class<T> type) {
      Object body = exchange.getIn().getBody();
      boolean multiParameterArray = false;
      if (exchange.getIn().getHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY) != null) {
        multiParameterArray =
            exchange.getIn().getHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY, Boolean.class);
        if (multiParameterArray) {
          // Just change the message body to an Object array
          if (!(body instanceof Object[])) {
            body = exchange.getIn().getBody(Object[].class);
          }
        }
      }

      // if there was an explicit method name to invoke, then we should support using
      // any provided parameter values in the method name
      String methodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, "", String.class);
      // the parameter values is between the parenthesis
      String methodParameters = ObjectHelper.betweenOuterPair(methodName, '(', ')');
      // use an iterator to walk the parameter values
      Iterator<?> it = null;
      if (methodParameters != null) {
        // split the parameters safely separated by comma, but beware that we can have
        // quoted parameters which contains comma as well, so do a safe quote split
        String[] parameters = StringQuoteHelper.splitSafeQuote(methodParameters, ',', true);
        it = ObjectHelper.createIterator(parameters, ",", true);
      }

      // remove headers as they should not be propagated
      // we need to do this before the expressions gets evaluated as it may contain
      // a @Bean expression which would by mistake read these headers. So the headers
      // must be removed at this point of time
      exchange.getIn().removeHeader(Exchange.BEAN_MULTI_PARAMETER_ARRAY);
      exchange.getIn().removeHeader(Exchange.BEAN_METHOD_NAME);

      Object[] answer = evaluateParameterExpressions(exchange, body, multiParameterArray, it);
      return (T) answer;
    }
Beispiel #2
0
  private boolean matchMethod(Method method, String methodName) {
    if (methodName == null) {
      return true;
    }

    if (methodName.contains("(") && !methodName.endsWith(")")) {
      throw new IllegalArgumentException(
          "Name must have both starting and ending parenthesis, was: " + methodName);
    }

    // do not use qualifier for name matching
    String name = methodName;
    if (name.contains("(")) {
      name = ObjectHelper.before(name, "(");
    }

    // must match name
    if (name != null && !name.equals(method.getName())) {
      return false;
    }

    // is it a method with no parameters
    boolean noParameters = methodName.endsWith("()");
    if (noParameters) {
      return method.getParameterTypes().length == 0;
    }

    // match qualifier types which is used to select among overloaded methods
    String types = ObjectHelper.between(methodName, "(", ")");
    if (ObjectHelper.isNotEmpty(types)) {
      // we must qualify based on types to match method
      String[] parameters = StringQuoteHelper.splitSafeQuote(types, ',');
      Iterator<?> it = ObjectHelper.createIterator(parameters);
      for (int i = 0; i < method.getParameterTypes().length; i++) {
        if (it.hasNext()) {
          Class<?> parameterType = method.getParameterTypes()[i];

          String qualifyType = (String) it.next();
          if (ObjectHelper.isEmpty(qualifyType)) {
            continue;
          }
          // trim the type
          qualifyType = qualifyType.trim();

          if ("*".equals(qualifyType)) {
            // * is a wildcard so we accept and match that parameter type
            continue;
          }

          if (BeanHelper.isValidParameterValue(qualifyType)) {
            // its a parameter value, so continue to next parameter
            // as we should only check for FQN/type parameters
            continue;
          }

          // if qualify type indeed is a class, then it must be assignable with the parameter type
          Boolean assignable =
              BeanHelper.isAssignableToExpectedType(
                  getCamelContext().getClassResolver(), qualifyType, parameterType);
          // the method will return null if the qualifyType is not a class
          if (assignable != null && !assignable) {
            return false;
          }

        } else {
          // there method has more parameters than was specified in the method name qualifiers
          return false;
        }
      }

      // if the method has no more types then we can only regard it as matched
      // if there are no more qualifiers
      if (it.hasNext()) {
        return false;
      }
    }

    // the method matched
    return true;
  }