diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/message/MethodParameterMessageMapper.java b/org.springframework.integration/src/main/java/org/springframework/integration/message/MethodParameterMessageMapper.java index 929e01793a..40f8e2c180 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/message/MethodParameterMessageMapper.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/message/MethodParameterMessageMapper.java @@ -65,10 +65,7 @@ public class MethodParameterMessageMapper implements MessageMapper { public Message toMessage(Object[] parameters) { - Assert.isTrue(!ObjectUtils.isEmpty(parameters), "parameters array is required"); - if (ObjectUtils.isEmpty(this.parameterMetadata)) { - return MessageBuilder.withPayload(parameters).build(); - } + Assert.isTrue(!ObjectUtils.isEmpty(parameters), "parameter array is required"); Assert.isTrue(parameters.length == this.parameterMetadata.length, "wrong number of parameters: expected " + this.parameterMetadata.length + ", received " + parameters.length); @@ -93,21 +90,20 @@ public class MethodParameterMessageMapper implements MessageMapper { } } else if (expectedType.equals(Message.class)) { - Assert.isNull(message, "more than one Message argument received"); message = (Message) value; } else { - Assert.isNull(payload, "unable to determine a single payload object, found: " - + "[" + payload + "] and [" + value + "]s"); + Assert.notNull(value, "payload object must not be null"); payload = value; } } if (message != null) { - Assert.isNull(payload, "cannot handle payload object [" + payload - + "] since a Message-typed parameter has also been provided"); + if (headers.isEmpty()) { + return message; + } return MessageBuilder.fromMessage(message).copyHeadersIfAbsent(headers).build(); } - Assert.notNull(payload, "payload object must not be null"); + Assert.notNull(payload, "no parameter available for Message or payload"); return MessageBuilder.withPayload(payload).copyHeaders(headers).build(); } @@ -115,12 +111,7 @@ public class MethodParameterMessageMapper implements MessageMapper { if (message == null) { return null; } - if (message.getPayload() == null) { - throw new IllegalArgumentException("Message payload must not be null."); - } - if (ObjectUtils.isEmpty(this.parameterMetadata)) { - return new Object[] { message.getPayload() }; - } + Assert.notNull(message.getPayload(), "Message payload must not be null."); Object[] args = new Object[this.parameterMetadata.length]; for (int i = 0; i < this.parameterMetadata.length; i++) { MethodParameterMetadata metadata = this.parameterMetadata[i]; @@ -153,6 +144,7 @@ public class MethodParameterMessageMapper implements MessageMapper { } private void initializeParameterMetadata() { + boolean foundMessageOrPayload = false; Class[] paramTypes = this.method.getParameterTypes(); this.parameterMetadata = new MethodParameterMetadata[paramTypes.length]; for (int i = 0; i < parameterMetadata.length; i++) { @@ -163,7 +155,7 @@ public class MethodParameterMessageMapper implements MessageMapper { for (int j = 0; j < paramAnnotations.length; j++) { if (Header.class.isInstance(paramAnnotations[j])) { Header headerAnnotation = (Header) paramAnnotations[j]; - String headerName = this.resolveParameterNameIfNecessary(headerAnnotation.value(), methodParam); + String headerName = this.resolveHeaderName(headerAnnotation, methodParam); parameterMetadata[i] = new MethodParameterMetadata(Header.class, headerName, headerAnnotation.required()); } else if (Headers.class.isInstance(paramAnnotations[j])) { @@ -173,6 +165,9 @@ public class MethodParameterMessageMapper implements MessageMapper { } } if (parameterMetadata[i] == null) { + // this is either a Message or the Object to be used as a Message payload + Assert.isTrue(!foundMessageOrPayload, "only one Message or payload parameter is allowed"); + foundMessageOrPayload = true; parameterMetadata[i] = new MethodParameterMetadata(methodParam.getParameterType(), null, false); } } @@ -190,12 +185,11 @@ public class MethodParameterMessageMapper implements MessageMapper { return properties; } - private String resolveParameterNameIfNecessary(String paramName, MethodParameter methodParam) { + private String resolveHeaderName(Header headerAnnotation, MethodParameter methodParam) { + String paramName = headerAnnotation.value(); if (!StringUtils.hasText(paramName)) { paramName = methodParam.getParameterName(); - if (paramName == null) { - throw new IllegalStateException("No parameter name specified and not available in class file."); - } + Assert.state(paramName != null, "No parameter name specified and not available in class file."); } return paramName; } diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/message/MethodParameterMessageMapperInitializationTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/message/MethodParameterMessageMapperInitializationTests.java new file mode 100644 index 0000000000..151f4d2a02 --- /dev/null +++ b/org.springframework.integration/src/test/java/org/springframework/integration/message/MethodParameterMessageMapperInitializationTests.java @@ -0,0 +1,57 @@ +/* + * 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.message; + +import java.lang.reflect.Method; + +import org.junit.Test; + +/** + * @author Mark Fisher + */ +public class MethodParameterMessageMapperInitializationTests { + + @Test(expected = IllegalArgumentException.class) + public void messageAndPayload() throws Exception { + Method method = TestService.class.getMethod("messageAndPayload", Message.class, String.class); + new MethodParameterMessageMapper(method); + } + + @Test(expected = IllegalArgumentException.class) + public void twoMessages() throws Exception { + Method method = TestService.class.getMethod("twoMessages", Message.class, Message.class); + new MethodParameterMessageMapper(method); + } + + @Test(expected = IllegalArgumentException.class) + public void twoPayloads() throws Exception { + Method method = TestService.class.getMethod("twoPayloads", String.class, String.class); + new MethodParameterMessageMapper(method); + } + + + private static interface TestService { + + void messageAndPayload(Message message, String foo); + + void twoMessages(Message message1, Message message2); + + void twoPayloads(String foo, String bar); + + } + +} diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/message/MethodParameterMessageMapperToMessageTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/message/MethodParameterMessageMapperToMessageTests.java index 56468c5367..a5dca38900 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/message/MethodParameterMessageMapperToMessageTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/message/MethodParameterMessageMapperToMessageTests.java @@ -173,6 +173,20 @@ public class MethodParameterMessageMapperToMessageTests { assertNull(message.getHeaders().get("foo")); } + @Test(expected = IllegalArgumentException.class) + public void noArgs() throws Exception { + Method method = TestService.class.getMethod("noArgs", new Class[] {}); + MethodParameterMessageMapper mapper = new MethodParameterMessageMapper(method); + mapper.toMessage(new Object[] {}); + } + + @Test(expected = IllegalArgumentException.class) + public void onlyHeaders() throws Exception { + Method method = TestService.class.getMethod("onlyHeaders", String.class, String.class); + MethodParameterMessageMapper mapper = new MethodParameterMessageMapper(method); + mapper.toMessage(new Object[] { "abc", "def" }); + } + private static interface TestService { @@ -190,6 +204,12 @@ public class MethodParameterMessageMapperToMessageTests { void sendMessageAndOptionalHeader(Message message, @Header(value="foo", required=false) String foo); + // invalid methods + + void noArgs(); + + void onlyHeaders(@Header("foo") String foo, @Header("bar") String bar); + } }