private T processInternal(ParametersWrapper parameters) throws Exception { HandlerMethod candidate = this.findHandlerMethodForParameters(parameters); Assert.notNull(candidate, "No candidate methods found for messages."); Expression expression = candidate.getExpression(); Class<?> expectedType = this.expectedType != null ? this.expectedType : candidate.method.getReturnType(); try { @SuppressWarnings("unchecked") T result = (T) this.evaluateExpression(expression, parameters, expectedType); if (this.requiresReply) { Assert.notNull( result, "Expression evaluation result was null, but this processor requires a reply."); } return result; } catch (Exception e) { Throwable evaluationException = e; if ((e instanceof EvaluationException || e instanceof MessageHandlingException) && e.getCause() != null) { evaluationException = e.getCause(); } if (evaluationException instanceof Exception) { throw (Exception) evaluationException; } else { throw new IllegalStateException("Cannot process message", evaluationException); } } }
/** * Returns a map of the {@link HandlerMethod} objects to the corresponding message class. * * @param declaringClass the class that declares methods to scan * @param filter the predicate that defines rules for subscriber scanning * @return the map of message subscribers * @throws DuplicateHandlerMethodException if there are more than one handler for the same message * class are encountered */ private static Map<Class<? extends Message>, Method> scan( Class<?> declaringClass, Predicate<Method> filter) { final Map<Class<? extends Message>, Method> tempMap = Maps.newHashMap(); for (Method method : declaringClass.getDeclaredMethods()) { if (filter.apply(method)) { final Class<? extends Message> messageClass = HandlerMethod.getFirstParamType(method); if (tempMap.containsKey(messageClass)) { final Method alreadyPresent = tempMap.get(messageClass); throw new DuplicateHandlerMethodException( declaringClass, messageClass, alreadyPresent.getName(), method.getName()); } tempMap.put(messageClass, method); } } final ImmutableMap<Class<? extends Message>, Method> result = ImmutableMap.copyOf(tempMap); return result; }