INT-656 Added fallback for Map typed arguments when payload does not match at runtime. Fallback attempts to match headers if no ambiguities exist.

This commit is contained in:
Mark Fisher
2009-07-02 15:48:06 +00:00
parent 3675f8dd1b
commit eea4aacfd3
4 changed files with 493 additions and 22 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 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.
@@ -26,6 +26,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageHandlingException;
@@ -37,9 +40,6 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A base or helper class for any Messaging component that acts as an adapter
* by invoking a "plain" (not Message-aware) method on a given target object.
@@ -48,6 +48,7 @@ import org.apache.commons.logging.LogFactory;
*
* @author Mark Fisher
* @author Marius Bogoevici
* @see MethodParameterMessageMapper
*/
public class MessageMappingMethodInvoker {
@@ -130,7 +131,28 @@ public class MessageMappingMethodInvoker {
invoker = new DefaultMethodInvoker(this.object, method);
this.invokers.put(method, invoker);
}
result = invoker.invokeMethod(args);
try {
result = invoker.invokeMethod(args);
}
catch (NoSuchMethodException e) {
// fallback to replace the payload argument with headers if possible
boolean foundFallbackCandidate = false;
for (int i = 0; i < args.length; i++) {
if (message != null && message.getPayload().equals(args[i])
&& Map.class.isAssignableFrom(method.getParameterTypes()[i])) {
if (foundFallbackCandidate) {
// more than one, throw an Exception
throw new MessageHandlingException(message, "Failed to resolve ambiguity " +
"amongst multiple non-annotated candidates for matching Message headers.", e);
}
args[i] = message.getHeaders();
foundFallbackCandidate = true;
}
}
if (foundFallbackCandidate) {
result = invoker.invokeMethod(args);
}
}
}
catch (IllegalArgumentException e) {
try {
@@ -158,6 +180,22 @@ public class MessageMappingMethodInvoker {
else {
args = new Object[] { mappingResult };
}
if (args.length > 1 && message != null && message.getPayload() instanceof Map) {
int mapArgCount = 0;
boolean resolvedMapArg = false;
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (arg instanceof Map && Map.class.isAssignableFrom(method.getParameterTypes()[i])) {
mapArgCount++;
if (arg.equals(message.getPayload())) {
// resolved if there is exactly one match
resolvedMapArg = !resolvedMapArg;
}
}
}
Assert.isTrue(resolvedMapArg || mapArgCount <= 1,
"Unable to resolve argument for Map-typed payload on method [" + method + "].");
}
return args;
}

View File

@@ -63,12 +63,13 @@ import org.springframework.util.StringUtils;
* expecting multiple headers (with or without the @Headers annotation).
* <p/>
* If a Map or Properties object is expected, and the payload 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. In these cases
* multiple unannotated parameters are legal. If, however, the actual payload
* type is a Map or Properties instance, then this ambiguity cannot be
* resolved. For that reason, it is recommended to use the explicit
* assignable to that type or capable of being converted 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. In these cases multiple unannotated
* parameters are legal. If, however, the actual payload type is a Map or
* Properties instance, then this ambiguity cannot be resolved. For that
* reason, it is highly recommended to use the explicit
* {@link Headers @Headers} annotation whenever possible.
* <p/>
* Some examples of legal method signatures:<br/>
@@ -215,7 +216,7 @@ public class MethodParameterMessageMapper implements InboundMessageMapper<Object
MethodParameterMetadata metadata = this.parameterMetadata[i];
Class<?> expectedType = metadata.getParameterType();
Header headerAnnotation = metadata.getHeaderAnnotation();
if (metadata == payloadParameterMetadata) {
if (metadata == this.payloadParameterMetadata) {
args[i] = message.getPayload();
}
else if (headerAnnotation != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 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.
@@ -17,6 +17,7 @@
package org.springframework.integration.util;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -78,12 +79,19 @@ public class DefaultMethodInvoker implements MethodInvoker {
convertedArgs[i] = converter.convertIfNecessary(args[i], paramTypes[i]);
}
catch (TypeMismatchException e) {
throw new IllegalArgumentException("Failed to convert argument type.", e);
if (Map.class.isAssignableFrom(paramTypes[i])) {
// may be able to fallback to Message Headers for this argument
convertedArgs[i] = args[i];
}
else {
throw new IllegalArgumentException("Failed to convert argument type.", e);
}
}
}
this.method.setAccessible(true);
if (this.logger.isDebugEnabled()) {
logger.debug("invoking method '" + this.method.getName() + "' with arguments " + ObjectUtils.nullSafeToString(convertedArgs));
logger.debug("Invoking method [" + this.method + "] with arguments [" +
ObjectUtils.nullSafeToString(convertedArgs) + "]");
}
try {
return this.method.invoke(this.object, convertedArgs);
@@ -93,6 +101,10 @@ public class DefaultMethodInvoker implements MethodInvoker {
helper.setTargetObject(this.object);
helper.setTargetMethod(this.method.getName());
helper.setArguments(convertedArgs);
if (logger.isDebugEnabled()) {
logger.debug("Attempting fallback based on method name [" + this.method.getName() +
"] with arguments [" + ObjectUtils.nullSafeToString(convertedArgs) + "]");
}
helper.prepare();
this.method = helper.getPreparedMethod();
return this.method.invoke(this.object, convertedArgs);

View File

@@ -18,9 +18,11 @@ package org.springframework.integration.message;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@@ -35,6 +37,7 @@ import org.springframework.integration.handler.ServiceActivatingHandler;
/**
* @author Mark Fisher
* @since 1.0.3
*/
public class PayloadAndHeaderMappingTests {
@@ -204,6 +207,192 @@ public class PayloadAndHeaderMappingTests {
assertTrue(bean.lastHeaders.containsKey("baz"));
}
@Test
public void headerMapOnlyWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("headerMapOnly", Map.class);
String payload = "test";
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
headers.put("baz", 99);
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(payload, bean.lastPayload);
assertTrue(bean.lastHeaders.containsKey("foo"));
assertTrue(bean.lastHeaders.containsKey("bar"));
assertTrue(bean.lastHeaders.containsKey("baz"));
}
@Test
public void headerMapOnlyWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("headerMapOnly", Map.class);
Map<String, Object> payload = new HashMap<String, Object>();
payload.put("abc", 1);
payload.put("xyz", "test");
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
headers.put("baz", 99);
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertTrue(bean.lastHeaders.containsKey("foo"));
assertTrue(bean.lastHeaders.containsKey("bar"));
assertTrue(bean.lastHeaders.containsKey("baz"));
}
@Test
public void mapOnlyNoAnnotationsWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("mapOnlyNoAnnotations", Map.class);
Map<String, Object> payload = new HashMap<String, Object>();
payload.put("payload", 1);
Map<String, Object> headers = new HashMap<String, Object>();
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertEquals(payload, bean.lastPayload);
assertNull(bean.lastHeaders);
}
@Test
public void mapOnlyNoAnnotationsWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("mapOnlyNoAnnotations", Map.class);
String payload = "test";
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
headers.put("baz", 99);
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertTrue(bean.lastHeaders.containsKey("foo"));
assertTrue(bean.lastHeaders.containsKey("bar"));
assertTrue(bean.lastHeaders.containsKey("baz"));
}
@Test
public void mapOnlyNoAnnotationsWithIntegerPayload() throws Exception {
MessageHandler handler = this.getHandler("mapOnlyNoAnnotations", Map.class);
Integer payload = new Integer(123);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
headers.put("baz", 99);
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertTrue(bean.lastHeaders.containsKey("foo"));
assertTrue(bean.lastHeaders.containsKey("bar"));
assertTrue(bean.lastHeaders.containsKey("baz"));
}
@Test
public void propertiesOnlyNoAnnotationsWithPropertiesPayload() throws Exception {
MessageHandler handler = this.getHandler("propertiesOnlyNoAnnotations", Properties.class);
Properties payload = new Properties();
payload.setProperty("payload", "1");
Map<String, Object> headers = new HashMap<String, Object>();
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertEquals(payload, bean.lastPayload);
assertNull(bean.lastHeaders);
}
@Test
public void propertiesOnlyNoAnnotationsWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("propertiesOnlyNoAnnotations", Properties.class);
Map<String, Object> payload = new HashMap<String, Object>();
payload.put("payload", 1);
Map<String, Object> headers = new HashMap<String, Object>();
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertEquals(payload, bean.lastPayload);
assertNull(bean.lastHeaders);
}
@Test
public void propertiesOnlyNoAnnotationsWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("propertiesOnlyNoAnnotations", Properties.class);
String payload = "payload=abc";
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastHeaders);
// String payload should have been converted to Properties
assertNotNull(bean.lastPayload);
assertTrue(bean.lastPayload instanceof Properties);
Properties payloadProps = (Properties) bean.lastPayload;
assertTrue(payloadProps.containsKey("payload"));
assertEquals("abc", payloadProps.get("payload"));
}
@Test
public void propertiesOnlyNoAnnotationsWithIntegerPayload() throws Exception {
MessageHandler handler = this.getHandler("propertiesOnlyNoAnnotations", Properties.class);
Integer payload = new Integer(123);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertTrue(bean.lastHeaders.containsKey("foo"));
assertTrue(bean.lastHeaders.containsKey("bar"));
}
@Test
public void headerPropertiesOnlyWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("headerPropertiesOnly", Properties.class);
String payload = "test";
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
headers.put("baz", 99);
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertTrue(bean.lastHeaders.containsKey("foo"));
assertTrue(bean.lastHeaders.containsKey("bar"));
assertFalse(bean.lastHeaders.containsKey("baz"));
}
@Test
public void headerPropertiesOnlyWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("headerPropertiesOnly", Properties.class);
Map<String, Object> payload = new HashMap<String, Object>();
payload.put("abc", 1);
payload.put("xyz", "test");
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
headers.put("baz", 99);
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertTrue(bean.lastHeaders.containsKey("foo"));
assertTrue(bean.lastHeaders.containsKey("bar"));
assertFalse(bean.lastHeaders.containsKey("baz"));
}
@Test
public void headerPropertiesOnlyWithPropertiesPayload() throws Exception {
MessageHandler handler = this.getHandler("headerPropertiesOnly", Properties.class);
Properties payload = new Properties();
payload.setProperty("abc", "1");
payload.setProperty("xyz", "2");
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
headers.put("baz", 99);
Message<?> message = MessageBuilder.withPayload(payload).copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertTrue(bean.lastHeaders.containsKey("foo"));
assertTrue(bean.lastHeaders.containsKey("bar"));
assertFalse(bean.lastHeaders.containsKey("baz"));
}
@Test
public void payloadMapAndHeaderProperties() throws Exception {
MessageHandler handler = this.getHandler("payloadMapAndHeaderProperties", Map.class, Properties.class);
@@ -245,7 +434,7 @@ public class PayloadAndHeaderMappingTests {
}
@Test
public void twoMapsNoAnnotations() throws Exception {
public void twoMapsNoAnnotationsWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("twoMapsNoAnnotations", Map.class, Map.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
@@ -259,6 +448,45 @@ public class PayloadAndHeaderMappingTests {
assertEquals("2", bean.lastHeaders.get("bar2"));
}
@Test(expected = MessageHandlingException.class)
public void twoMapsNoAnnotationsWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("twoMapsNoAnnotations", Map.class, Map.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
Map<String, Object> payloadMap = new HashMap<String, Object>();
payloadMap.put("baz", "99");
Message<?> message = MessageBuilder.withPayload(payloadMap).copyHeaders(headers).build();
handler.handleMessage(message);
}
@Test
public void twoMapsWithAnnotationsWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("twoMapsWithAnnotations", Map.class, Map.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
Message<?> message = MessageBuilder.withPayload("test").copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals("1", bean.lastHeaders.get("foo"));
assertEquals("2", bean.lastHeaders.get("bar"));
assertEquals("1", bean.lastHeaders.get("foo2"));
assertEquals("2", bean.lastHeaders.get("bar2"));
}
@Test(expected = MessageHandlingException.class)
public void twoMapsWithAnnotationsWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("twoMapsWithAnnotations", Map.class, Map.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
Map<String, Object> payloadMap = new HashMap<String, Object>();
payloadMap.put("baz", "99");
Message<?> message = MessageBuilder.withPayload(payloadMap).copyHeaders(headers).build();
handler.handleMessage(message);
}
@Test
public void twoMapsNoAnnotationsAndObject() throws Exception {
MessageHandler handler = this.getHandler("twoMapsNoAnnotationsAndObject",
@@ -275,7 +503,7 @@ public class PayloadAndHeaderMappingTests {
assertEquals("2", bean.lastHeaders.get("bar2"));
}
@Test
@Test(expected = MessageHandlingException.class)
public void twoMapsNoAnnotationsAndObjectWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("twoMapsNoAnnotationsAndObject",
Map.class, Object.class, Map.class);
@@ -286,11 +514,6 @@ public class PayloadAndHeaderMappingTests {
Message<?> message = MessageBuilder.withPayload(payloadMap)
.copyHeaders(headers).build();
handler.handleMessage(message);
assertEquals(payloadMap, bean.lastPayload);
assertEquals("1", bean.lastHeaders.get("foo"));
assertEquals("2", bean.lastHeaders.get("bar"));
assertEquals("1", bean.lastHeaders.get("foo2"));
assertEquals("2", bean.lastHeaders.get("bar2"));
}
@Test
@@ -311,6 +534,150 @@ public class PayloadAndHeaderMappingTests {
assertEquals("1", bean.lastHeaders.get("foo3"));
}
@Test
public void singleStringHeaderOnlyWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("singleStringHeaderOnly", String.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
Message<?> message = MessageBuilder.withPayload("test")
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals("1", bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleStringHeaderOnlyWithIntegerPayload() throws Exception {
MessageHandler handler = this.getHandler("singleStringHeaderOnly", String.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
Message<?> message = MessageBuilder.withPayload(new Integer(123))
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals("1", bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleStringHeaderOnlyWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("singleStringHeaderOnly", String.class);
Map<String, Object> payload = new HashMap<String, Object>();
payload.put("foo", 99);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "1");
headers.put("bar", "2");
Message<?> message = MessageBuilder.withPayload(payload)
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals("1", bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleIntegerHeaderOnlyWithIntegerPayload() throws Exception {
MessageHandler handler = this.getHandler("singleIntegerHeaderOnly", Integer.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", new Integer(123));
headers.put("bar", new Integer(456));
Message<?> message = MessageBuilder.withPayload(new Integer(789))
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals(new Integer(123), bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleIntegerHeaderOnlyWithIntegerPayloadAndStringHeader() throws Exception {
MessageHandler handler = this.getHandler("singleIntegerHeaderOnly", Integer.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "999");
headers.put("bar", new Integer(456));
Message<?> message = MessageBuilder.withPayload(new Integer(789))
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals(new Integer(999), bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleIntegerHeaderOnlyWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("singleIntegerHeaderOnly", Integer.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", new Integer(123));
headers.put("bar", new Integer(456));
Message<?> message = MessageBuilder.withPayload("test")
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals(new Integer(123), bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleObjectHeaderOnlyWithStringPayload() throws Exception {
MessageHandler handler = this.getHandler("singleObjectHeaderOnly", Object.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "123");
headers.put("bar", "456");
Message<?> message = MessageBuilder.withPayload("test")
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals("123", bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleObjectHeaderOnlyWithObjectPayload() throws Exception {
MessageHandler handler = this.getHandler("singleObjectHeaderOnly", Object.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", "123");
headers.put("bar", "456");
Message<?> message = MessageBuilder.withPayload(new Object())
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals("123", bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleObjectHeaderOnlyWithIntegerPayload() throws Exception {
MessageHandler handler = this.getHandler("singleObjectHeaderOnly", Object.class);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", new Integer(123));
headers.put("bar", new Integer(456));
Message<?> message = MessageBuilder.withPayload(new Integer(789))
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals(new Integer(123), bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
@Test
public void singleObjectHeaderOnlyWithMapPayload() throws Exception {
MessageHandler handler = this.getHandler("singleObjectHeaderOnly", Object.class);
Map<String, Object> payload = new HashMap<String, Object>();
payload.put("foo", 99);
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("foo", new Integer(123));
headers.put("bar", new Integer(456));
Message<?> message = MessageBuilder.withPayload(payload)
.copyHeaders(headers).build();
handler.handleMessage(message);
assertNull(bean.lastPayload);
assertEquals(new Integer(123), bean.lastHeaders.get("foo"));
assertNull(bean.lastHeaders.get("bar"));
}
private ServiceActivatingHandler getHandler(String methodName, Class<?>... types) throws Exception {
return new ServiceActivatingHandler(bean, TestBean.class.getMethod(methodName, types));
@@ -389,6 +756,32 @@ public class PayloadAndHeaderMappingTests {
this.lastPayload = payload;
}
public void headerMapOnly(@Headers Map headers) {
this.lastHeaders = headers;
}
public void headerPropertiesOnly(@Headers Properties headers) {
this.lastHeaders = headers;
}
public void mapOnlyNoAnnotations(Map map) {
if (map.containsKey("payload")) {
this.lastPayload = map;
}
else {
this.lastHeaders = map;
}
}
public void propertiesOnlyNoAnnotations(Properties props) {
if (props.containsKey("payload")) {
this.lastPayload = props;
}
else {
this.lastHeaders = props;
}
}
public void twoMapsNoAnnotations(Map map1, Map<Object, Object> map2) {
this.lastHeaders = new HashMap(map1);
for (Map.Entry<Object, Object> entry : map2.entrySet()) {
@@ -396,6 +789,21 @@ public class PayloadAndHeaderMappingTests {
}
}
public void twoMapsWithAnnotations(@Headers Map map1, @Headers Map<Object, Object> map2) {
this.lastHeaders = new HashMap(map1);
for (Map.Entry<Object, Object> entry : map2.entrySet()) {
this.lastHeaders.put(entry.getKey() + "2", entry.getValue());
}
}
public void twoMapsWithAnnotationsAndObject(@Headers Map map1, Object o, @Headers Map<Object, Object> map2) {
this.lastPayload = o;
this.lastHeaders = new HashMap(map1);
for (Map.Entry<Object, Object> entry : map2.entrySet()) {
this.lastHeaders.put(entry.getKey() + "2", entry.getValue());
}
}
public void twoMapsNoAnnotationsAndObject(Map map1, Object o, Map<Object, Object> map2) {
this.lastPayload = o;
this.lastHeaders = new HashMap(map1);
@@ -411,6 +819,18 @@ public class PayloadAndHeaderMappingTests {
}
this.lastHeaders.put("foo3", s);
}
public void singleStringHeaderOnly(@Header("foo") String s) {
this.lastHeaders = Collections.singletonMap("foo", s);
}
public void singleIntegerHeaderOnly(@Header("foo") Integer n) {
this.lastHeaders = Collections.singletonMap("foo", n);
}
public void singleObjectHeaderOnly(@Header("foo") Object o) {
this.lastHeaders = Collections.singletonMap("foo", o);
}
}
}