Exemplo n.º 1
0
  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;
  }
Exemplo n.º 2
0
  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;
  }