@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; }
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; }