private Expression createParameterUnmarshalExpressionForAnnotation( Class<?> clazz, Method method, Class<?> parameterType, Annotation annotation) { if (annotation instanceof AttachmentObjects) { return ExpressionBuilder.attachmentObjectsExpression(); } else if (annotation instanceof Attachments) { return ExpressionBuilder.attachmentsExpression(); } else if (annotation instanceof Property) { Property propertyAnnotation = (Property) annotation; return ExpressionBuilder.exchangePropertyExpression(propertyAnnotation.value()); } else if (annotation instanceof ExchangeProperty) { ExchangeProperty propertyAnnotation = (ExchangeProperty) annotation; return ExpressionBuilder.exchangePropertyExpression(propertyAnnotation.value()); } else if (annotation instanceof Properties) { return ExpressionBuilder.propertiesExpression(); } else if (annotation instanceof Header) { Header headerAnnotation = (Header) annotation; return ExpressionBuilder.headerExpression(headerAnnotation.value()); } else if (annotation instanceof Headers) { return ExpressionBuilder.headersExpression(); } else if (annotation instanceof OutHeaders) { return ExpressionBuilder.outHeadersExpression(); } else if (annotation instanceof ExchangeException) { return ExpressionBuilder.exchangeExceptionExpression( CastUtils.cast(parameterType, Exception.class)); } else { LanguageAnnotation languageAnnotation = annotation.annotationType().getAnnotation(LanguageAnnotation.class); if (languageAnnotation != null) { Class<?> type = languageAnnotation.factory(); Object object = camelContext.getInjector().newInstance(type); if (object instanceof AnnotationExpressionFactory) { AnnotationExpressionFactory expressionFactory = (AnnotationExpressionFactory) object; return expressionFactory.createExpression( camelContext, annotation, languageAnnotation, parameterType); } else { LOG.warn( "Ignoring bad annotation: " + languageAnnotation + "on method: " + method + " which declares a factory: " + type.getName() + " which does not implement " + AnnotationExpressionFactory.class.getName()); } } } return null; }
private MethodInfo chooseBestPossibleMethodInfo( Exchange exchange, Collection<MethodInfo> operationList, Object body, List<MethodInfo> possibles, List<MethodInfo> possiblesWithException, List<MethodInfo> possibleWithCustomAnnotation) throws AmbiguousMethodCallException { Exception exception = ExpressionBuilder.exchangeExceptionExpression().evaluate(exchange, Exception.class); if (exception != null && possiblesWithException.size() == 1) { LOG.trace( "Exchange has exception set so we prefer method that also has exception as parameter"); // prefer the method that accepts exception in case we have an exception also return possiblesWithException.get(0); } else if (possibles.size() == 1) { return possibles.get(0); } else if (possibles.isEmpty()) { LOG.trace("No possible methods so now trying to convert body to parameter types"); // let's try converting Object newBody = null; MethodInfo matched = null; int matchCounter = 0; for (MethodInfo methodInfo : operationList) { if (methodInfo.getBodyParameterType() != null) { if (methodInfo.getBodyParameterType().isInstance(body)) { return methodInfo; } // we should only try to convert, as we are looking for best match Object value = exchange .getContext() .getTypeConverter() .tryConvertTo(methodInfo.getBodyParameterType(), exchange, body); if (value != null) { if (LOG.isTraceEnabled()) { LOG.trace( "Converted body from: {} to: {}", body.getClass().getCanonicalName(), methodInfo.getBodyParameterType().getCanonicalName()); } matchCounter++; newBody = value; matched = methodInfo; } } } if (matchCounter > 1) { throw new AmbiguousMethodCallException(exchange, Arrays.asList(matched, matched)); } if (matched != null) { LOG.trace("Setting converted body: {}", body); Message in = exchange.getIn(); in.setBody(newBody); return matched; } } else { // if we only have a single method with custom annotations, let's use that one if (possibleWithCustomAnnotation.size() == 1) { MethodInfo answer = possibleWithCustomAnnotation.get(0); LOG.trace("There are only one method with annotations so we choose it: {}", answer); return answer; } // 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 return null; }