Extracted message-to-args mapping logic from AbstractMessageHandler to MethodArgumentMessageMapper. Defined a separate abstract method in AbstractMessageHandler for post-processing a return value that is already a Message. DefaultMethodInvoker catches an IllegalArgumentException in case the Method instance no longer matches after a Proxy and "resets" the correct Method if it can be determined from the 'methodName' property. Replaced AnnotationMethodTransformerAdapter with TransformerMessageHandler.
This commit is contained in:
@@ -29,7 +29,7 @@ import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.handler.DefaultMessageHandlerAdapter;
|
||||
import org.springframework.integration.handler.DefaultMessageHandler;
|
||||
import org.springframework.integration.handler.MessageHandlerChain;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -81,6 +81,7 @@ public class HandlerParser implements BeanDefinitionParser {
|
||||
return beanDefinition;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private BeanDefinition parseHandler(Element element, ParserContext parserContext, ManagedList handlers) {
|
||||
boolean isInnerHandler = (handlers != null);
|
||||
String ref = element.getAttribute("ref");
|
||||
@@ -113,15 +114,15 @@ public class HandlerParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
private BeanDefinitionHolder parseHandlerAdapter(String id, String handlerRef, String handlerMethod, ParserContext parserContext, boolean isInnerHandler) {
|
||||
BeanDefinition handlerAdapterDef = new RootBeanDefinition(DefaultMessageHandlerAdapter.class);
|
||||
handlerAdapterDef.getPropertyValues().addPropertyValue(OBJECT_PROPERTY, new RuntimeBeanReference(handlerRef));
|
||||
handlerAdapterDef.getPropertyValues().addPropertyValue(METHOD_NAME_PROPERTY, handlerMethod);
|
||||
String adapterBeanName = (StringUtils.hasText(id)) ? id :
|
||||
BeanDefinitionReaderUtils.generateBeanName(handlerAdapterDef, parserContext.getRegistry(), isInnerHandler);
|
||||
BeanDefinition handlerDef = new RootBeanDefinition(DefaultMessageHandler.class);
|
||||
handlerDef.getPropertyValues().addPropertyValue(OBJECT_PROPERTY, new RuntimeBeanReference(handlerRef));
|
||||
handlerDef.getPropertyValues().addPropertyValue(METHOD_NAME_PROPERTY, handlerMethod);
|
||||
String handlerBeanName = (StringUtils.hasText(id)) ? id :
|
||||
BeanDefinitionReaderUtils.generateBeanName(handlerDef, parserContext.getRegistry(), isInnerHandler);
|
||||
if (!isInnerHandler) {
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(handlerAdapterDef, adapterBeanName));
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(handlerDef, handlerBeanName));
|
||||
}
|
||||
return new BeanDefinitionHolder(handlerAdapterDef, adapterBeanName);
|
||||
return new BeanDefinitionHolder(handlerDef, handlerBeanName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,22 +20,17 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.integration.ConfigurationException;
|
||||
import org.springframework.integration.handler.annotation.Header;
|
||||
import org.springframework.integration.handler.annotation.MethodArgumentMessageMapper;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.integration.message.MessageHeaders;
|
||||
import org.springframework.integration.message.MessageMapper;
|
||||
import org.springframework.integration.util.DefaultMethodInvoker;
|
||||
import org.springframework.integration.util.MethodInvoker;
|
||||
import org.springframework.integration.util.NameResolvingMethodInvoker;
|
||||
@@ -54,9 +49,9 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public abstract class AbstractMessageHandler implements MessageHandler, InitializingBean {
|
||||
public abstract class AbstractMessageHandler implements MessageHandler, Ordered, InitializingBean {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AbstractMessageHandler.class);
|
||||
protected static final Log logger = LogFactory.getLog(AbstractMessageHandler.class);
|
||||
|
||||
private volatile boolean methodExpectsMessage;
|
||||
|
||||
@@ -66,11 +61,11 @@ public abstract class AbstractMessageHandler implements MessageHandler, Initiali
|
||||
|
||||
private volatile String methodName;
|
||||
|
||||
private volatile MessageMapper<Object, Object[]> methodArgumentMapper;
|
||||
|
||||
private volatile MethodInvoker invoker;
|
||||
|
||||
private volatile MethodParameterMetadata[] parameterMetadata;
|
||||
|
||||
private final ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
|
||||
private volatile int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
@@ -99,10 +94,11 @@ public abstract class AbstractMessageHandler implements MessageHandler, Initiali
|
||||
|
||||
public void setMethod(Method method) {
|
||||
Assert.notNull(method, "method must not be null");
|
||||
if (method.getParameterTypes().length == 0) {
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (parameterTypes.length == 0) {
|
||||
throw new ConfigurationException("method must accept at least one parameter");
|
||||
}
|
||||
if (method.getParameterTypes()[0].equals(Message.class)) {
|
||||
if (parameterTypes.length == 1 && Message.class.isAssignableFrom(parameterTypes[0])) {
|
||||
this.methodExpectsMessage = true;
|
||||
}
|
||||
this.method = method;
|
||||
@@ -117,6 +113,14 @@ public abstract class AbstractMessageHandler implements MessageHandler, Initiali
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
synchronized (this.initializationMonitor) {
|
||||
if (this.initialized) {
|
||||
@@ -145,42 +149,17 @@ public abstract class AbstractMessageHandler implements MessageHandler, Initiali
|
||||
}
|
||||
if (this.method != null) {
|
||||
this.invoker = new DefaultMethodInvoker(this.object, this.method);
|
||||
this.methodArgumentMapper = new MethodArgumentMessageMapper(this.method);
|
||||
}
|
||||
else {
|
||||
// TODO: resolve the candidate method and/or create a dynamic resolver
|
||||
this.invoker = new NameResolvingMethodInvoker(this.object, this.methodName);
|
||||
}
|
||||
this.configureParameterMetadata();
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void configureParameterMetadata() {
|
||||
if (this.method == null) {
|
||||
return;
|
||||
}
|
||||
Class<?>[] paramTypes = this.method.getParameterTypes();
|
||||
this.parameterMetadata = new MethodParameterMetadata[paramTypes.length];
|
||||
for (int i = 0; i < parameterMetadata.length; i++) {
|
||||
MethodParameter methodParam = new MethodParameter(this.method, i);
|
||||
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
GenericTypeResolver.resolveParameterType(methodParam, this.method.getDeclaringClass());
|
||||
Object[] paramAnnotations = methodParam.getParameterAnnotations();
|
||||
String headerName = null;
|
||||
for (int j = 0; j < paramAnnotations.length; j++) {
|
||||
if (Header.class.isInstance(paramAnnotations[j])) {
|
||||
Header headerAnnotation = (Header) paramAnnotations[j];
|
||||
headerName = this.resolveParameterNameIfNecessary(headerAnnotation.value(), methodParam);
|
||||
parameterMetadata[i] = new MethodParameterMetadata(Header.class, headerName, headerAnnotation.required());
|
||||
}
|
||||
}
|
||||
if (headerName == null) {
|
||||
parameterMetadata[i] = new MethodParameterMetadata(methodParam.getParameterType(), null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Message<?> handle(Message<?> requestMessage) {
|
||||
if (requestMessage == null || requestMessage.getPayload() == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -196,11 +175,25 @@ public abstract class AbstractMessageHandler implements MessageHandler, Initiali
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
if (result instanceof Message) {
|
||||
return this.postProcessReplyMessage((Message<?>) result, requestMessage);
|
||||
}
|
||||
return this.createReplyMessage(result, requestMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method to generate the reply Message.
|
||||
* Subclasses must implement this method to process a return value that
|
||||
* is already a Message instance.
|
||||
*
|
||||
* @param replyMessage the Message returned from an adapter method
|
||||
* @param requestMessage the original request Message
|
||||
* @return the Message to be sent to the reply MessageTarget
|
||||
*/
|
||||
protected abstract Message<?> postProcessReplyMessage(Message<?> replyMessage, Message<?> requestMessage);
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method to generate the reply Message when
|
||||
* the return value is not a Message instance.
|
||||
*
|
||||
* @param result the return value from an adapter method, or the Message payload if not acting as an adapter
|
||||
* @param requestMessage the original request Message
|
||||
@@ -210,9 +203,6 @@ public abstract class AbstractMessageHandler implements MessageHandler, Initiali
|
||||
|
||||
|
||||
private Object invokeHandlerMethod(Message<?> message) {
|
||||
if (this.invoker == null) {
|
||||
throw new IllegalStateException("cannot invoke method, invoker is null");
|
||||
}
|
||||
Object args[] = null;
|
||||
Object mappingResult = this.methodExpectsMessage ? message
|
||||
: this.mapMessageToMethodArguments(message);
|
||||
@@ -253,86 +243,11 @@ public abstract class AbstractMessageHandler implements MessageHandler, Initiali
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Object[] mapMessageToMethodArguments(Message<?> message) {
|
||||
if (message == null) {
|
||||
return null;
|
||||
private Object[] mapMessageToMethodArguments(Message message) {
|
||||
if (this.methodArgumentMapper != null) {
|
||||
return this.methodArgumentMapper.mapMessage(message);
|
||||
}
|
||||
if (message.getPayload() == null) {
|
||||
throw new IllegalArgumentException("Message payload must not be null.");
|
||||
}
|
||||
if (ObjectUtils.isEmpty(this.parameterMetadata)) {
|
||||
return new Object[] { message.getPayload() };
|
||||
}
|
||||
Object[] args = new Object[this.parameterMetadata.length];
|
||||
for (int i = 0; i < this.parameterMetadata.length; i++) {
|
||||
MethodParameterMetadata metadata = this.parameterMetadata[i];
|
||||
Class<?> expectedType = metadata.type;
|
||||
if (expectedType.equals(Header.class)) {
|
||||
Object value = message.getHeaders().get(metadata.key);
|
||||
if (value == null && metadata.required) {
|
||||
throw new MessageHandlingException(message,
|
||||
"required header '" + metadata.key + "' not available");
|
||||
}
|
||||
args[i] = value;
|
||||
}
|
||||
else if (expectedType.isAssignableFrom(message.getClass())) {
|
||||
args[i] = message;
|
||||
}
|
||||
else if (expectedType.isAssignableFrom(message.getPayload().getClass())) {
|
||||
args[i] = message.getPayload();
|
||||
}
|
||||
else if (expectedType.equals(Map.class)) {
|
||||
args[i] = message.getHeaders();
|
||||
}
|
||||
else if (expectedType.equals(Properties.class)) {
|
||||
args[i] = this.getStringTypedHeaders(message);
|
||||
}
|
||||
else {
|
||||
args[i] = message.getPayload();
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
private Properties getStringTypedHeaders(Message<?> message) {
|
||||
Properties properties = new Properties();
|
||||
MessageHeaders headers = message.getHeaders();
|
||||
for (String key : headers.keySet()) {
|
||||
Object value = headers.get(key);
|
||||
if (value instanceof String) {
|
||||
properties.setProperty(key, (String) value);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private String resolveParameterNameIfNecessary(String paramName, MethodParameter methodParam) {
|
||||
if (!StringUtils.hasText(paramName)) {
|
||||
paramName = methodParam.getParameterName();
|
||||
if (paramName == null) {
|
||||
throw new IllegalStateException("No parameter name specified and not available in class file.");
|
||||
}
|
||||
}
|
||||
return paramName;
|
||||
}
|
||||
|
||||
|
||||
private static class MethodParameterMetadata {
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
private final String key;
|
||||
|
||||
private final boolean required;
|
||||
|
||||
|
||||
MethodParameterMetadata(Class<?> type, String key, boolean required) {
|
||||
this.type = type;
|
||||
this.key = key;
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
return new Object[] { message.getPayload() };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.handler;
|
||||
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageHeaders;
|
||||
|
||||
/**
|
||||
* The default MessageHandler implementation. Creates a Message for the reply payload.
|
||||
@@ -30,9 +31,17 @@ public class DefaultMessageHandler extends AbstractMessageHandler {
|
||||
|
||||
@Override
|
||||
protected Message<?> createReplyMessage(Object result, Message<?> requestMessage) {
|
||||
return MessageBuilder.fromPayload(result)
|
||||
.copyHeaders(requestMessage.getHeaders())
|
||||
.setCorrelationId(requestMessage.getHeaders().getId())
|
||||
return this.prepareReplyMessage(MessageBuilder.fromPayload(result), requestMessage.getHeaders());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message<?> postProcessReplyMessage(Message<?> replyMessage, Message<?> requestMessage) {
|
||||
return this.prepareReplyMessage(MessageBuilder.fromMessage(replyMessage), requestMessage.getHeaders());
|
||||
}
|
||||
|
||||
private Message<?> prepareReplyMessage(MessageBuilder<?> builder, MessageHeaders requestHeaders) {
|
||||
return builder.copyHeadersIfAbsent(requestHeaders)
|
||||
.setHeaderIfAbsent(MessageHeaders.CORRELATION_ID, requestHeaders.getId())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.handler;
|
||||
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageCreator;
|
||||
|
||||
/**
|
||||
* An implementation of {@link MessageHandler} that invokes the specified method and target object.
|
||||
* It will use the provided implementation of the {@link MessageCreator} strategy interface to convert
|
||||
* the method invocation's return value to a reply Message.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class DefaultMessageHandlerAdapter extends AbstractMessageHandlerAdapter {
|
||||
|
||||
protected Message<?> handleReturnValue(Object returnValue, Message<?> originalMessage) {
|
||||
return this.createReplyMessage(returnValue, originalMessage);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,11 +34,21 @@ public class MethodInvokingTarget extends AbstractMessageHandler implements Mess
|
||||
|
||||
@Override
|
||||
protected Message<?> createReplyMessage(Object result, Message<?> requestMessage) {
|
||||
if (result != null) {
|
||||
throw new MessagingException(requestMessage, "The target method returned a non-null Object. " +
|
||||
"MethodInvokingTarget should only be used for methods that return no value (preferably void).");
|
||||
}
|
||||
this.failIfNotNull(result, requestMessage);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message<?> postProcessReplyMessage(Message<?> replyMessage, Message<?> requestMessage) {
|
||||
this.failIfNotNull(replyMessage, requestMessage);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void failIfNotNull(Object result, Message<?> requestMessage) {
|
||||
if (result != null) {
|
||||
throw new MessagingException(requestMessage, "the MethodInvokingTarget method must have a void or null return, "
|
||||
+ "but '" + this + "' received a non-null value: [" + result + "]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,80 +29,50 @@ import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.integration.message.MessageHeaders;
|
||||
import org.springframework.integration.message.MessageMapper;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A {@link MessageMapper} implementation for annotated handler methods.
|
||||
* Method parameters are matched against the Message payload as well as its
|
||||
* headers. If a method parameter is annotated with {@link Header @Header},
|
||||
* the annotation's value will be used as a header name. If such an annotation
|
||||
* contains no value, then the parameter name will be used as long as
|
||||
* the information is available in the class file (requires compilation with
|
||||
* debug settings for parameter names). If neither annotation is present, then
|
||||
* the parameter will typically match the Message payload. However, if a Map or
|
||||
* Properties object is expected, and the paylaod is not itself assignable to
|
||||
* that type, then the MessageHeaders' values will be passed in the case of
|
||||
* a Map-typed parameter, or the MessageHeaders' String-based values will be
|
||||
* passed in the case of a Properties-typed parameter.
|
||||
* Prepares arguments for handler methods. The method parameters are matched
|
||||
* against the Message payload as well as its headers. If a method parameter
|
||||
* is annotated with {@link Header @Header}, the annotation's value will be
|
||||
* used as a header name. If such an annotation contains no value, then the
|
||||
* parameter name will be used as long as the information is available in the
|
||||
* class file (requires compilation with debug settings for parameter names).
|
||||
* If the {@link Header @Header} annotation is not present, then the parameter
|
||||
* will typically match the Message payload. However, if a Map or Properties
|
||||
* object is expected, and the paylaod is not itself assignable to that type,
|
||||
* then the MessageHeaders' values will be passed in the case of a Map-typed
|
||||
* parameter, or the MessageHeaders' String-based values will be passed in the
|
||||
* case of a Properties-typed parameter.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class AnnotationMethodMessageMapper implements MessageMapper {
|
||||
|
||||
private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
|
||||
public class MethodArgumentMessageMapper<T extends Object> implements MessageMapper<T, Object[]> {
|
||||
|
||||
private final Method method;
|
||||
|
||||
private MethodParameterMetadata[] parameterMetadata;
|
||||
private volatile MethodParameterMetadata[] parameterMetadata;
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
private final Object initializationMonitor = new Object();
|
||||
private final ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
|
||||
|
||||
|
||||
public AnnotationMethodMessageMapper(Method method) {
|
||||
public MethodArgumentMessageMapper(Method method) {
|
||||
Assert.notNull(method, "method must not be null");
|
||||
this.method = method;
|
||||
this.initializeParameterMetadata();
|
||||
}
|
||||
|
||||
|
||||
public void initialize() {
|
||||
synchronized (this.initializationMonitor) {
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
Class<?>[] paramTypes = this.method.getParameterTypes();
|
||||
this.parameterMetadata = new MethodParameterMetadata[paramTypes.length];
|
||||
for (int i = 0; i < parameterMetadata.length; i++) {
|
||||
MethodParameter methodParam = new MethodParameter(this.method, i);
|
||||
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
GenericTypeResolver.resolveParameterType(methodParam, this.method.getDeclaringClass());
|
||||
Object[] paramAnnotations = methodParam.getParameterAnnotations();
|
||||
String headerName = null;
|
||||
for (int j = 0; j < paramAnnotations.length; j++) {
|
||||
if (Header.class.isInstance(paramAnnotations[j])) {
|
||||
Header headerAnnotation = (Header) paramAnnotations[j];
|
||||
headerName = this.resolveParameterNameIfNecessary(headerAnnotation.value(), methodParam);
|
||||
parameterMetadata[i] = new MethodParameterMetadata(Header.class, headerName, headerAnnotation.required());
|
||||
}
|
||||
}
|
||||
if (headerName == null) {
|
||||
parameterMetadata[i] = new MethodParameterMetadata(methodParam.getParameterType(), null, false);
|
||||
}
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public Object[] mapMessage(Message message) {
|
||||
public Object[] mapMessage(Message<T> message) {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
if (message.getPayload() == null) {
|
||||
throw new IllegalArgumentException("Message payload must not be null.");
|
||||
}
|
||||
if (!this.initialized) {
|
||||
this.initialize();
|
||||
if (ObjectUtils.isEmpty(this.parameterMetadata)) {
|
||||
return new Object[] { message.getPayload() };
|
||||
}
|
||||
Object[] args = new Object[this.parameterMetadata.length];
|
||||
for (int i = 0; i < this.parameterMetadata.length; i++) {
|
||||
@@ -135,6 +105,28 @@ public class AnnotationMethodMessageMapper implements MessageMapper {
|
||||
return args;
|
||||
}
|
||||
|
||||
private void initializeParameterMetadata() {
|
||||
Class<?>[] paramTypes = this.method.getParameterTypes();
|
||||
this.parameterMetadata = new MethodParameterMetadata[paramTypes.length];
|
||||
for (int i = 0; i < parameterMetadata.length; i++) {
|
||||
MethodParameter methodParam = new MethodParameter(this.method, i);
|
||||
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
GenericTypeResolver.resolveParameterType(methodParam, this.method.getDeclaringClass());
|
||||
Object[] paramAnnotations = methodParam.getParameterAnnotations();
|
||||
String headerName = null;
|
||||
for (int j = 0; j < paramAnnotations.length; j++) {
|
||||
if (Header.class.isInstance(paramAnnotations[j])) {
|
||||
Header headerAnnotation = (Header) paramAnnotations[j];
|
||||
headerName = this.resolveParameterNameIfNecessary(headerAnnotation.value(), methodParam);
|
||||
parameterMetadata[i] = new MethodParameterMetadata(Header.class, headerName, headerAnnotation.required());
|
||||
}
|
||||
}
|
||||
if (headerName == null) {
|
||||
parameterMetadata[i] = new MethodParameterMetadata(methodParam.getParameterType(), null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Properties getStringTypedHeaders(Message<?> message) {
|
||||
Properties properties = new Properties();
|
||||
MessageHeaders headers = message.getHeaders();
|
||||
@@ -21,8 +21,8 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.integration.ConfigurationException;
|
||||
import org.springframework.integration.handler.AbstractMessageHandler;
|
||||
import org.springframework.integration.handler.MessageHandler;
|
||||
import org.springframework.integration.util.AbstractMethodInvokingAdapter;
|
||||
|
||||
/**
|
||||
* Base class for handler creators that generate a {@link MessageHandler}
|
||||
@@ -34,10 +34,10 @@ public abstract class AbstractMessageHandlerCreator implements MessageHandlerCre
|
||||
|
||||
public final MessageHandler createHandler(Object object, Method method, Map<String, ?> attributes) {
|
||||
MessageHandler handler = this.doCreateHandler(object, method, attributes);
|
||||
if (attributes != null && handler instanceof AbstractMethodInvokingAdapter) {
|
||||
if (attributes != null && handler instanceof AbstractMessageHandler) {
|
||||
Object order = attributes.get("order");
|
||||
if (order != null && order instanceof Integer) {
|
||||
((AbstractMethodInvokingAdapter) handler).setOrder(((Integer) order).intValue());
|
||||
((AbstractMessageHandler) handler).setOrder(((Integer) order).intValue());
|
||||
}
|
||||
}
|
||||
if (handler instanceof InitializingBean) {
|
||||
|
||||
@@ -19,32 +19,23 @@ package org.springframework.integration.handler.config;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.integration.ConfigurationException;
|
||||
import org.springframework.integration.handler.DefaultMessageHandlerAdapter;
|
||||
import org.springframework.integration.handler.DefaultMessageHandler;
|
||||
import org.springframework.integration.handler.MessageHandler;
|
||||
import org.springframework.integration.message.Message;
|
||||
|
||||
/**
|
||||
* Default implementation of the handler creator strategy that creates a
|
||||
* {@link DefaultMessageHandlerAdapter} for the provided object and method.
|
||||
* This version does not even consider the attributes. It does however respect
|
||||
* an {@link Order} annotation if present.
|
||||
* {@link DefaultMessageHandler} for the provided object and method.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class DefaultMessageHandlerCreator extends AbstractMessageHandlerCreator {
|
||||
|
||||
public MessageHandler doCreateHandler(Object object, Method method, Map<String, ?> attributes) {
|
||||
Class<?>[] types = method.getParameterTypes();
|
||||
if (types.length != 1) {
|
||||
throw new ConfigurationException("exactly one method parameter is required");
|
||||
}
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(object);
|
||||
adapter.setMethodName(method.getName());
|
||||
adapter.setMethodExpectsMessage(Message.class.isAssignableFrom(types[0]));
|
||||
return adapter;
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(object);
|
||||
handler.setMethod(method);
|
||||
handler.afterPropertiesSet();
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.integration.handler.AbstractMessageHandler;
|
||||
import org.springframework.integration.message.CompositeMessage;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.integration.message.MessageTarget;
|
||||
|
||||
/**
|
||||
@@ -101,4 +102,10 @@ public class RouterMessageHandler extends AbstractMessageHandler {
|
||||
return new CompositeMessage(replies);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message<?> postProcessReplyMessage(Message<?> replyMessage, Message<?> requestMessage) {
|
||||
throw new MessageHandlingException(requestMessage,
|
||||
"router method must return type 'MessageChannel' or 'String', but a Message was returned: " + replyMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,6 +108,23 @@ public class SplitterMessageHandler extends AbstractMessageHandler {
|
||||
return new CompositeMessage(results);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message<?> postProcessReplyMessage(Message<?> replyMessage, Message<?> requestMessage) {
|
||||
Object requestId = requestMessage.getHeaders().getId();
|
||||
if (replyMessage instanceof CompositeMessage) {
|
||||
List<Message<?>> sequentialMessages = new ArrayList<Message<?>>();
|
||||
List<Message<?>> replyList = ((CompositeMessage) replyMessage).getPayload();
|
||||
int sequenceSize = replyList.size();
|
||||
int sequenceNumber = 0;
|
||||
for (Message<?> message : replyList) {
|
||||
sequentialMessages.add(this.setSplitMessageHeaders(
|
||||
MessageBuilder.fromMessage(message), requestId, ++sequenceNumber, sequenceSize));
|
||||
}
|
||||
return new CompositeMessage(sequentialMessages);
|
||||
}
|
||||
return this.setSplitMessageHeaders(MessageBuilder.fromMessage(replyMessage), requestId, 1, 1);
|
||||
}
|
||||
|
||||
private Message<?> createSplitMessage(Object item, MessageHeaders requestHeaders, int sequenceNumber, int sequenceSize) {
|
||||
if (item instanceof Message<?>) {
|
||||
return this.setSplitMessageHeaders(MessageBuilder.fromMessage((Message<?>) item),
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.transformer;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.integration.handler.MessageHandler;
|
||||
import org.springframework.integration.handler.annotation.AnnotationMethodMessageMapper;
|
||||
import org.springframework.integration.message.DefaultMessageMapper;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageMapper;
|
||||
import org.springframework.integration.message.MessagingException;
|
||||
import org.springframework.integration.util.AbstractMethodInvokingAdapter;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class AnnotationMethodTransformerAdapter extends AbstractMethodInvokingAdapter implements MessageHandler {
|
||||
|
||||
private volatile MessageMapper mapper;
|
||||
|
||||
private volatile boolean methodExpectsMessage;
|
||||
|
||||
|
||||
public void setMethodExpectsMessage(boolean methodExpectsMessage) {
|
||||
this.methodExpectsMessage = methodExpectsMessage;
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
this.mapper = (this.getMethod() != null)
|
||||
? new AnnotationMethodMessageMapper(this.getMethod())
|
||||
: new DefaultMessageMapper();
|
||||
}
|
||||
|
||||
public Message<?> handle(Message<?> message) {
|
||||
if (!this.isInitialized()) {
|
||||
this.afterPropertiesSet();
|
||||
}
|
||||
if (message.getPayload() == null) {
|
||||
return message;
|
||||
}
|
||||
Object param = (this.methodExpectsMessage) ? message : this.mapper.mapMessage(message);
|
||||
try {
|
||||
Object args[] = null;
|
||||
if (param != null && param.getClass().isArray()
|
||||
&& (Object.class.isAssignableFrom(param.getClass().getComponentType()))) {
|
||||
args = (Object[]) param;
|
||||
}
|
||||
else {
|
||||
args = new Object[] { param };
|
||||
}
|
||||
return this.invokeMethodAndReturnMessage(message, args);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MessagingException(message, "failed to transform message payload", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Message<?> invokeMethodAndReturnMessage(Message<?> message, Object[] args) throws Exception {
|
||||
Object result = null;
|
||||
try {
|
||||
result = this.invokeMethod(args);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
result = this.invokeMethod(message);
|
||||
this.methodExpectsMessage = true;
|
||||
}
|
||||
if (result == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("handler invocation returned a null result");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (result instanceof Properties && !(message.getPayload() instanceof Properties)) {
|
||||
Properties propertiesToSet = (Properties) result;
|
||||
MessageBuilder builder = MessageBuilder.fromMessage(message);
|
||||
for (Object keyObject : propertiesToSet.keySet()) {
|
||||
String key = (String) keyObject;
|
||||
builder.setHeader(key, propertiesToSet.getProperty(key));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
else if (result instanceof Map && !(message.getPayload() instanceof Map)) {
|
||||
Map<String, ?> attributesToSet = (Map) result;
|
||||
MessageBuilder builder = MessageBuilder.fromMessage(message);
|
||||
for (String key : attributesToSet.keySet()) {
|
||||
builder.setHeader(key, attributesToSet.get(key));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
else {
|
||||
return MessageBuilder.fromPayload(result).copyHeaders(message.getHeaders()).build();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.transformer;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.integration.handler.AbstractMessageHandler;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class TransformerMessageHandler extends AbstractMessageHandler {
|
||||
|
||||
@Override
|
||||
protected Message<?> createReplyMessage(Object result, Message<?> requestMessage) {
|
||||
if (result instanceof Properties && !(requestMessage.getPayload() instanceof Properties)) {
|
||||
Properties propertiesToSet = (Properties) result;
|
||||
MessageBuilder<?> builder = MessageBuilder.fromMessage(requestMessage);
|
||||
for (Object keyObject : propertiesToSet.keySet()) {
|
||||
String key = (String) keyObject;
|
||||
builder.setHeader(key, propertiesToSet.getProperty(key));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
else if (result instanceof Map && !(requestMessage.getPayload() instanceof Map)) {
|
||||
Map<?, ?> attributesToSet = (Map <?, ?>) result;
|
||||
MessageBuilder<?> builder = MessageBuilder.fromMessage(requestMessage);
|
||||
for (Object key : attributesToSet.keySet()) {
|
||||
if (!(key instanceof String)) {
|
||||
throw new MessageHandlingException(requestMessage,
|
||||
"Map returned from a Transformer method must have String-typed keys");
|
||||
}
|
||||
builder.setHeader((String) key, attributesToSet.get(key));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
else {
|
||||
return MessageBuilder.fromPayload(result).copyHeaders(requestMessage.getHeaders()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Message<?> postProcessReplyMessage(Message<?> replyMessage, Message<?> requestMessage) {
|
||||
return replyMessage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.integration.handler.MessageHandler;
|
||||
import org.springframework.integration.handler.config.AbstractMessageHandlerCreator;
|
||||
import org.springframework.integration.transformer.AnnotationMethodTransformerAdapter;
|
||||
import org.springframework.integration.transformer.TransformerMessageHandler;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
@@ -29,11 +29,11 @@ import org.springframework.integration.transformer.AnnotationMethodTransformerAd
|
||||
public class TransformerMessageHandlerCreator extends AbstractMessageHandlerCreator {
|
||||
|
||||
public MessageHandler doCreateHandler(Object object, Method method, Map<String, ?> attributes) {
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(object);
|
||||
adapter.setMethodName(method.getName());
|
||||
adapter.afterPropertiesSet();
|
||||
return adapter;
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(object);
|
||||
handler.setMethodName(method.getName());
|
||||
handler.afterPropertiesSet();
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class DefaultMethodInvoker implements MethodInvoker {
|
||||
|
||||
private final Object object;
|
||||
|
||||
private final Method method;
|
||||
private volatile Method method;
|
||||
|
||||
private volatile TypeConverter typeConverter;
|
||||
|
||||
@@ -85,7 +85,18 @@ public class DefaultMethodInvoker implements MethodInvoker {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
logger.debug("invoking method '" + this.method.getName() + "' with arguments " + ObjectUtils.nullSafeToString(convertedArgs));
|
||||
}
|
||||
return this.method.invoke(this.object, convertedArgs);
|
||||
try {
|
||||
return this.method.invoke(this.object, convertedArgs);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
org.springframework.util.MethodInvoker helper = new org.springframework.util.MethodInvoker();
|
||||
helper.setTargetObject(this.object);
|
||||
helper.setTargetMethod(this.method.getName());
|
||||
helper.setArguments(convertedArgs);
|
||||
helper.prepare();
|
||||
this.method = helper.getPreparedMethod();
|
||||
return this.method.invoke(this.object, convertedArgs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,22 +39,22 @@ public class CorrelationIdTests {
|
||||
Object correlationId = "123-ABC";
|
||||
Message<String> message = MessageBuilder.fromPayload("test")
|
||||
.setCorrelationId(correlationId).build();
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(new TestBean());
|
||||
adapter.setMethodName("upperCase");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> reply = adapter.handle(message);
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestBean());
|
||||
handler.setMethodName("upperCase");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> reply = handler.handle(message);
|
||||
assertEquals(correlationId, reply.getHeaders().getCorrelationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrelationIdCopiedFromMessageIdByDefault() {
|
||||
Message<String> message = MessageBuilder.fromPayload("test").build();
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(new TestBean());
|
||||
adapter.setMethodName("upperCase");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> reply = adapter.handle(message);
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestBean());
|
||||
handler.setMethodName("upperCase");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> reply = handler.handle(message);
|
||||
assertEquals(message.getHeaders().getId(), reply.getHeaders().getCorrelationId());
|
||||
}
|
||||
|
||||
@@ -62,11 +62,11 @@ public class CorrelationIdTests {
|
||||
public void testCorrelationIdCopiedFromMessageCorrelationIdIfAvailable() {
|
||||
Message<String> message = MessageBuilder.fromPayload("test")
|
||||
.setCorrelationId("correlationId").build();
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(new TestBean());
|
||||
adapter.setMethodName("upperCase");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> reply = adapter.handle(message);
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestBean());
|
||||
handler.setMethodName("upperCase");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> reply = handler.handle(message);
|
||||
assertEquals(message.getHeaders().getCorrelationId(), reply.getHeaders().getCorrelationId());
|
||||
assertTrue(message.getHeaders().getCorrelationId().equals(reply.getHeaders().getCorrelationId()));
|
||||
}
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class DefaultMessageHandlerAdapterTests {
|
||||
|
||||
@Test
|
||||
public void testPayloadAsMethodParameterAndObjectAsReturnValue() {
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(new TestHandler());
|
||||
adapter.setMethodName("acceptPayloadAndReturnObject");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> result = adapter.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-1", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPayloadAsMethodParameterAndMessageAsReturnValue() {
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(new TestHandler());
|
||||
adapter.setMethodName("acceptPayloadAndReturnMessage");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> result = adapter.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-2", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageAsMethodParameterAndObjectAsReturnValue() {
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setMethodExpectsMessage(true);
|
||||
adapter.setObject(new TestHandler());
|
||||
adapter.setMethodName("acceptMessageAndReturnObject");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> result = adapter.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-3", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageAsMethodParameterAndMessageAsReturnValue() {
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setMethodExpectsMessage(true);
|
||||
adapter.setObject(new TestHandler());
|
||||
adapter.setMethodName("acceptMessageAndReturnMessage");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> result = adapter.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-4", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageSubclassAsMethodParameterAndMessageAsReturnValue() {
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setMethodExpectsMessage(true);
|
||||
adapter.setObject(new TestHandler());
|
||||
adapter.setMethodName("acceptMessageSubclassAndReturnMessage");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> result = adapter.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-5", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageSubclassAsMethodParameterAndMessageSubclassAsReturnValue() {
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setMethodExpectsMessage(true);
|
||||
adapter.setObject(new TestHandler());
|
||||
adapter.setMethodName("acceptMessageSubclassAndReturnMessageSubclass");
|
||||
adapter.afterPropertiesSet();
|
||||
Message<?> result = adapter.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-6", result.getPayload());
|
||||
}
|
||||
|
||||
|
||||
private static class TestHandler {
|
||||
|
||||
public String acceptPayloadAndReturnObject(String s) {
|
||||
return s + "-1";
|
||||
}
|
||||
|
||||
public Message<?> acceptPayloadAndReturnMessage(String s) {
|
||||
return new StringMessage(s + "-2");
|
||||
}
|
||||
|
||||
public String acceptMessageAndReturnObject(Message<?> m) {
|
||||
return m.getPayload() + "-3";
|
||||
}
|
||||
|
||||
public Message<?> acceptMessageAndReturnMessage(Message<?> m) {
|
||||
return new StringMessage(m.getPayload() + "-4");
|
||||
}
|
||||
|
||||
public Message<?> acceptMessageSubclassAndReturnMessage(StringMessage m) {
|
||||
return new StringMessage(m.getPayload() + "-5");
|
||||
}
|
||||
|
||||
public StringMessage acceptMessageSubclassAndReturnMessageSubclass(StringMessage m) {
|
||||
return new StringMessage(m.getPayload() + "-6");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.handler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.annotation.Handler;
|
||||
import org.springframework.integration.handler.annotation.Header;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessagingException;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class DefaultMessageHandlerTests {
|
||||
|
||||
@Test
|
||||
public void payloadAsMethodParameterAndObjectAsReturnValue() {
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestHandler());
|
||||
handler.setMethodName("acceptPayloadAndReturnObject");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> result = handler.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-1", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void payloadAsMethodParameterAndMessageAsReturnValue() {
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestHandler());
|
||||
handler.setMethodName("acceptPayloadAndReturnMessage");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> result = handler.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-2", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageAsMethodParameterAndObjectAsReturnValue() {
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestHandler());
|
||||
handler.setMethodName("acceptMessageAndReturnObject");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> result = handler.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-3", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageAsMethodParameterAndMessageAsReturnValue() {
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestHandler());
|
||||
handler.setMethodName("acceptMessageAndReturnMessage");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> result = handler.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-4", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageSubclassAsMethodParameterAndMessageAsReturnValue() {
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestHandler());
|
||||
handler.setMethodName("acceptMessageSubclassAndReturnMessage");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> result = handler.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-5", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageSubclassAsMethodParameterAndMessageSubclassAsReturnValue() {
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestHandler());
|
||||
handler.setMethodName("acceptMessageSubclassAndReturnMessageSubclass");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> result = handler.handle(new StringMessage("testing"));
|
||||
assertEquals("testing-6", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void payloadAndHeaderAnnotationMethodParametersAndObjectAsReturnValue() {
|
||||
DefaultMessageHandler handler = new DefaultMessageHandler();
|
||||
handler.setObject(new TestHandler());
|
||||
handler.setMethodName("acceptPayloadAndHeaderAndReturnObject");
|
||||
handler.afterPropertiesSet();
|
||||
Message<?> request = MessageBuilder.fromPayload("testing")
|
||||
.setHeader("number", new Integer(123)).build();
|
||||
Message<?> result = handler.handle(request);
|
||||
assertEquals("testing-123", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageOnlyWithAnnotatedMethod() throws Exception {
|
||||
AnnotatedTestHandler handler = new AnnotatedTestHandler();
|
||||
Method method = handler.getClass().getMethod("messageOnly", Message.class);
|
||||
DefaultMessageHandler adapter = new DefaultMessageHandler();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
Message<?> result = adapter.handle(new StringMessage("foo"));
|
||||
assertEquals("foo", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void payloadWithAnnotatedMethod() throws Exception {
|
||||
AnnotatedTestHandler handler = new AnnotatedTestHandler();
|
||||
Method method = handler.getClass().getMethod("integerMethod", Integer.class);
|
||||
DefaultMessageHandler adapter = new DefaultMessageHandler();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
Message<?> result = adapter.handle(new GenericMessage<Integer>(new Integer(123)));
|
||||
assertEquals(new Integer(123), result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertedPayloadWithAnnotatedMethod() throws Exception {
|
||||
AnnotatedTestHandler handler = new AnnotatedTestHandler();
|
||||
Method method = handler.getClass().getMethod("integerMethod", Integer.class);
|
||||
DefaultMessageHandler adapter = new DefaultMessageHandler();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
Message<?> result = adapter.handle(new StringMessage("456"));
|
||||
assertEquals(new Integer(456), result.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected = MessagingException.class)
|
||||
public void conversionFailureWithAnnotatedMethod() throws Exception {
|
||||
AnnotatedTestHandler handler = new AnnotatedTestHandler();
|
||||
Method method = handler.getClass().getMethod("integerMethod", Integer.class);
|
||||
DefaultMessageHandler adapter = new DefaultMessageHandler();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
Message<?> result = adapter.handle(new StringMessage("foo"));
|
||||
assertEquals(new Integer(123), result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageAndHeaderWithAnnotatedMethod() throws Exception {
|
||||
AnnotatedTestHandler handler = new AnnotatedTestHandler();
|
||||
Method method = handler.getClass().getMethod("messageAndHeader", Message.class, Integer.class);
|
||||
DefaultMessageHandler adapter = new DefaultMessageHandler();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("number", 42).build();
|
||||
Message<?> result = adapter.handle(message);
|
||||
assertEquals("foo-42", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleHeadersWithAnnotatedMethod() throws Exception {
|
||||
AnnotatedTestHandler handler = new AnnotatedTestHandler();
|
||||
Method method = handler.getClass().getMethod("twoHeaders", String.class, Integer.class);
|
||||
DefaultMessageHandler adapter = new DefaultMessageHandler();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("prop", "bar")
|
||||
.setHeader("number", 42).build();
|
||||
Message<?> result = adapter.handle(message);
|
||||
assertEquals("bar-42", result.getPayload());
|
||||
}
|
||||
|
||||
|
||||
private static class TestHandler {
|
||||
|
||||
public String acceptPayloadAndReturnObject(String s) {
|
||||
return s + "-1";
|
||||
}
|
||||
|
||||
public Message<?> acceptPayloadAndReturnMessage(String s) {
|
||||
return new StringMessage(s + "-2");
|
||||
}
|
||||
|
||||
public String acceptMessageAndReturnObject(Message<?> m) {
|
||||
return m.getPayload() + "-3";
|
||||
}
|
||||
|
||||
public Message<?> acceptMessageAndReturnMessage(Message<?> m) {
|
||||
return new StringMessage(m.getPayload() + "-4");
|
||||
}
|
||||
|
||||
public Message<?> acceptMessageSubclassAndReturnMessage(StringMessage m) {
|
||||
return new StringMessage(m.getPayload() + "-5");
|
||||
}
|
||||
|
||||
public StringMessage acceptMessageSubclassAndReturnMessageSubclass(StringMessage m) {
|
||||
return new StringMessage(m.getPayload() + "-6");
|
||||
}
|
||||
|
||||
public String acceptPayloadAndHeaderAndReturnObject(String s, @Header("number") Integer n) {
|
||||
return s + "-" + n;
|
||||
}
|
||||
}
|
||||
|
||||
private static class AnnotatedTestHandler {
|
||||
|
||||
@Handler
|
||||
public String messageOnly(Message<?> message) {
|
||||
return (String) message.getPayload();
|
||||
}
|
||||
|
||||
@Handler
|
||||
public String messageAndHeader(Message<?> message, @Header("number") Integer num) {
|
||||
return (String) message.getPayload() + "-" + num.toString();
|
||||
}
|
||||
|
||||
@Handler
|
||||
public String twoHeaders(@Header String prop, @Header("number") Integer num) {
|
||||
return prop + "-" + num.toString();
|
||||
}
|
||||
|
||||
@Handler
|
||||
public Integer optionalHeader(@Header(required=false) Integer num) {
|
||||
return num;
|
||||
}
|
||||
|
||||
@Handler
|
||||
public Integer requiredHeader(@Header(value="num", required=true) Integer num) {
|
||||
return num;
|
||||
}
|
||||
|
||||
@Handler
|
||||
public String optionalAndRequiredHeader(@Header(required=false) String prop, @Header(value="num", required=true) Integer num) {
|
||||
return prop + num;
|
||||
}
|
||||
|
||||
@Handler
|
||||
public Properties propertiesMethod(Properties properties) {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Handler
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map mapMethod(Map map) {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Handler
|
||||
public Integer integerMethod(Integer i) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,23 +27,20 @@ import java.util.Properties;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.annotation.Handler;
|
||||
import org.springframework.integration.handler.DefaultMessageHandlerAdapter;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.integration.message.MessagingException;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class AnnotationMethodMessageMapperTests {
|
||||
public class MethodArgumentMessageMapperTests {
|
||||
|
||||
@Test
|
||||
public void testOptionalHeader() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("optionalHeader", Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<String> mapper = new MethodArgumentMessageMapper<String>(method);
|
||||
Object[] args = (Object[]) mapper.mapMessage(new StringMessage("foo"));
|
||||
assertEquals(1, args.length);
|
||||
assertNull(args[0]);
|
||||
@@ -52,14 +49,14 @@ public class AnnotationMethodMessageMapperTests {
|
||||
@Test(expected=MessageHandlingException.class)
|
||||
public void testRequiredHeaderNotProvided() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("requiredHeader", Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<String> mapper = new MethodArgumentMessageMapper<String>(method);
|
||||
mapper.mapMessage(new StringMessage("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequiredHeaderProvided() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("requiredHeader", Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<String> mapper = new MethodArgumentMessageMapper<String>(method);
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("num", new Integer(123)).build();
|
||||
Object[] args = (Object[]) mapper.mapMessage(message);
|
||||
@@ -70,7 +67,7 @@ public class AnnotationMethodMessageMapperTests {
|
||||
@Test(expected=MessageHandlingException.class)
|
||||
public void testOptionalAndRequiredHeaderWithOnlyOptionalHeaderProvided() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("optionalAndRequiredHeader", String.class, Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<String> mapper = new MethodArgumentMessageMapper<String>(method);
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("prop", "bar").build();
|
||||
mapper.mapMessage(message);
|
||||
@@ -79,7 +76,7 @@ public class AnnotationMethodMessageMapperTests {
|
||||
@Test
|
||||
public void testOptionalAndRequiredHeaderWithOnlyRequiredHeaderProvided() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("optionalAndRequiredHeader", String.class, Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<String> mapper = new MethodArgumentMessageMapper<String>(method);
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("num", new Integer(123)).build();
|
||||
Object[] args = (Object[]) mapper.mapMessage(message);
|
||||
@@ -91,7 +88,7 @@ public class AnnotationMethodMessageMapperTests {
|
||||
@Test
|
||||
public void testOptionalAndRequiredHeaderWithBothHeadersProvided() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("optionalAndRequiredHeader", String.class, Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<String> mapper = new MethodArgumentMessageMapper<String>(method);
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("num", new Integer(123))
|
||||
.setHeader("prop", "bar")
|
||||
@@ -105,7 +102,7 @@ public class AnnotationMethodMessageMapperTests {
|
||||
@Test
|
||||
public void testPropertiesMethodWithNonPropertiesPayload() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("propertiesMethod", Properties.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<String> mapper = new MethodArgumentMessageMapper<String>(method);
|
||||
Message<String> message = MessageBuilder.fromPayload("test")
|
||||
.setHeader("prop1", "foo").setHeader("prop2", "bar").build();
|
||||
Object[] args = (Object[]) mapper.mapMessage(message);
|
||||
@@ -118,7 +115,7 @@ public class AnnotationMethodMessageMapperTests {
|
||||
@Test
|
||||
public void testPropertiesMethodWithPropertiesPayload() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("propertiesMethod", Properties.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<Properties> mapper = new MethodArgumentMessageMapper<Properties>(method);
|
||||
Properties payload = new Properties();
|
||||
payload.setProperty("prop1", "foo");
|
||||
payload.setProperty("prop2", "bar");
|
||||
@@ -135,7 +132,7 @@ public class AnnotationMethodMessageMapperTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMapMethodWithNonMapPayload() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("mapMethod", Map.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<String> mapper = new MethodArgumentMessageMapper<String>(method);
|
||||
Message<String> message = MessageBuilder.fromPayload("test")
|
||||
.setHeader("attrib1", new Integer(123))
|
||||
.setHeader("attrib2", new Integer(456)).build();
|
||||
@@ -149,7 +146,7 @@ public class AnnotationMethodMessageMapperTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMapMethodWithMapPayload() throws Exception {
|
||||
Method method = TestHandler.class.getMethod("mapMethod", Map.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
MethodArgumentMessageMapper<Map<String,Integer>> mapper = new MethodArgumentMessageMapper<Map<String,Integer>>(method);
|
||||
Map<String, Integer> payload = new HashMap<String, Integer>();
|
||||
payload.put("attrib1", new Integer(123));
|
||||
payload.put("attrib2", new Integer(456));
|
||||
@@ -163,89 +160,6 @@ public class AnnotationMethodMessageMapperTests {
|
||||
assertEquals(new Integer(456), result.get("attrib2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageOnlyWithAdapter() throws Exception {
|
||||
TestHandler handler = new TestHandler();
|
||||
Method method = handler.getClass().getMethod("messageOnly", Message.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
adapter.setMessageMapper(mapper);
|
||||
Message<?> result = adapter.handle(new StringMessage("foo"));
|
||||
assertEquals("foo", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPayloadWithAdapter() throws Exception {
|
||||
TestHandler handler = new TestHandler();
|
||||
Method method = handler.getClass().getMethod("integerMethod", Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
adapter.setMessageMapper(mapper);
|
||||
Message<?> result = adapter.handle(new GenericMessage<Integer>(new Integer(123)));
|
||||
assertEquals(new Integer(123), result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertedPayloadWithAdapter() throws Exception {
|
||||
TestHandler handler = new TestHandler();
|
||||
Method method = handler.getClass().getMethod("integerMethod", Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
adapter.setMessageMapper(mapper);
|
||||
Message<?> result = adapter.handle(new StringMessage("456"));
|
||||
assertEquals(new Integer(456), result.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected=MessagingException.class)
|
||||
public void testConversionFailureWithAdapter() throws Exception {
|
||||
TestHandler handler = new TestHandler();
|
||||
Method method = handler.getClass().getMethod("integerMethod", Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
adapter.setMessageMapper(mapper);
|
||||
Message<?> result = adapter.handle(new StringMessage("foo"));
|
||||
assertEquals(new Integer(123), result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageAndHeaderWithAdapter() throws Exception {
|
||||
TestHandler handler = new TestHandler();
|
||||
Method method = handler.getClass().getMethod("messageAndHeader", Message.class, Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
adapter.setMessageMapper(mapper);
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("number", 42).build();
|
||||
Message<?> result = adapter.handle(message);
|
||||
assertEquals("foo-42", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleHeadersWithAdapter() throws Exception {
|
||||
TestHandler handler = new TestHandler();
|
||||
Method method = handler.getClass().getMethod("twoHeaders", String.class, Integer.class);
|
||||
AnnotationMethodMessageMapper mapper = new AnnotationMethodMessageMapper(method);
|
||||
DefaultMessageHandlerAdapter adapter = new DefaultMessageHandlerAdapter();
|
||||
adapter.setObject(handler);
|
||||
adapter.setMethod(method);
|
||||
adapter.setMessageMapper(mapper);
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("prop", "bar")
|
||||
.setHeader("number", 42).build();
|
||||
Message<?> result = adapter.handle(message);
|
||||
assertEquals("bar-42", result.getPayload());
|
||||
}
|
||||
|
||||
|
||||
private static class TestHandler {
|
||||
|
||||
@@ -294,7 +208,7 @@ public class AnnotationMethodMessageMapperTests {
|
||||
public Integer integerMethod(Integer i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -36,84 +36,95 @@ import org.springframework.integration.message.StringMessage;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class AnnotationMethodTransformerAdapterTests {
|
||||
public class TransformerMessageHandlerTests {
|
||||
|
||||
@Test
|
||||
public void testSimplePayload() throws Exception {
|
||||
public void simplePayload() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(testBean);
|
||||
adapter.setMethod(testBean.getClass().getMethod("exclaim", String.class));
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("exclaim", String.class));
|
||||
Message<?> message = new StringMessage("foo");
|
||||
Message<?> result = adapter.handle(message);
|
||||
Message<?> result = handler.handle(message);
|
||||
assertEquals("FOO!", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeConversion() throws Exception {
|
||||
public void typeConversion() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(testBean);
|
||||
adapter.setMethod(testBean.getClass().getMethod("exclaim", String.class));
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("exclaim", String.class));
|
||||
Message<?> message = new GenericMessage<Integer>(123);
|
||||
Message<?> result = adapter.handle(message);
|
||||
Message<?> result = handler.handle(message);
|
||||
assertEquals("123!", result.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected=MessagingException.class)
|
||||
public void testTypeConversionFailure() throws Exception {
|
||||
@Test(expected = MessagingException.class)
|
||||
public void typeConversionFailure() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(testBean);
|
||||
adapter.setMethod(testBean.getClass().getMethod("exclaim", String.class));
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("exclaim", String.class));
|
||||
Message<?> message = new GenericMessage<Date>(new Date());
|
||||
adapter.handle(message);
|
||||
handler.handle(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeaderAnnotation() throws Exception {
|
||||
public void headerAnnotation() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(testBean);
|
||||
adapter.setMethod(testBean.getClass().getMethod("headerTest", String.class, Integer.class));
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("headerTest", String.class, Integer.class));
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("number", 123).build();
|
||||
Message<?> result = adapter.handle(message);
|
||||
Message<?> result = handler.handle(message);
|
||||
assertEquals("foo123", result.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected=MessageHandlingException.class)
|
||||
public void testHeaderValueNotProvided() throws Exception {
|
||||
@Test(expected = MessageHandlingException.class)
|
||||
public void headerValueNotProvided() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(testBean);
|
||||
adapter.setMethod(testBean.getClass().getMethod("headerTest", String.class, Integer.class));
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("headerTest", String.class, Integer.class));
|
||||
Message<String> message = MessageBuilder.fromPayload("foo")
|
||||
.setHeader("wrong", 123).build();
|
||||
adapter.handle(message);
|
||||
handler.handle(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionalHeaderAnnotation() throws Exception {
|
||||
public void optionalHeaderAnnotation() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(testBean);
|
||||
adapter.setMethod(testBean.getClass().getMethod("optionalHeaderTest", String.class, Integer.class));
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("optionalHeaderTest", String.class, Integer.class));
|
||||
Message<String> message = MessageBuilder.fromPayload("foo").setHeader("number", 99).build();
|
||||
Message<?> result = handler.handle(message);
|
||||
assertEquals("foo99", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void optionalHeaderValueNotProvided() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("optionalHeaderTest", String.class, Integer.class));
|
||||
Message<String> message = MessageBuilder.fromPayload("foo").build();
|
||||
Message<?> result = adapter.handle(message);
|
||||
Message<?> result = handler.handle(message);
|
||||
assertEquals("foonull", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeaderEnricher() throws Exception {
|
||||
public void headerEnricher() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(testBean);
|
||||
adapter.setMethod(testBean.getClass().getMethod("propertyEnricherTest", String.class));
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("propertyEnricherTest", String.class));
|
||||
Message<String> message = MessageBuilder.fromPayload("test")
|
||||
.setHeader("prop1", "bad")
|
||||
.setHeader("prop3", "baz").build();
|
||||
Message<?> result = adapter.handle(message);
|
||||
Message<?> result = handler.handle(message);
|
||||
assertEquals("test", result.getPayload());
|
||||
assertEquals("foo", result.getHeaders().get("prop1"));
|
||||
assertEquals("bar", result.getHeaders().get("prop2"));
|
||||
@@ -122,16 +133,16 @@ public class AnnotationMethodTransformerAdapterTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testPropertiesPayload() throws Exception {
|
||||
public void propertiesPayload() throws Exception {
|
||||
TestBean testBean = new TestBean();
|
||||
AnnotationMethodTransformerAdapter adapter = new AnnotationMethodTransformerAdapter();
|
||||
adapter.setObject(testBean);
|
||||
adapter.setMethod(testBean.getClass().getMethod("propertyPayloadTest", Properties.class));
|
||||
TransformerMessageHandler handler = new TransformerMessageHandler();
|
||||
handler.setObject(testBean);
|
||||
handler.setMethod(testBean.getClass().getMethod("propertyPayloadTest", Properties.class));
|
||||
Properties props = new Properties();
|
||||
props.setProperty("prop1", "bad");
|
||||
props.setProperty("prop3", "baz");
|
||||
Message<Properties> message = new GenericMessage<Properties>(props);
|
||||
Message<Properties> result = (Message<Properties>) adapter.handle(message);
|
||||
Message<Properties> result = (Message<Properties>) handler.handle(message);
|
||||
assertEquals(Properties.class, result.getPayload().getClass());
|
||||
Properties payload = result.getPayload();
|
||||
assertEquals("foo", payload.getProperty("prop1"));
|
||||
Reference in New Issue
Block a user