INT-565 removed @MessageMapping and added @Payload

This commit is contained in:
Mark Fisher
2009-11-02 17:03:33 +00:00
parent af5d6e0e30
commit 543ec6f5f6
4 changed files with 40 additions and 29 deletions

View File

@@ -24,10 +24,12 @@ import java.lang.annotation.Target;
/**
* This annotation allows you to specify a SpEL expression indicating that a method
* parameter's value should be mapped from the result of expression processing.
* The annotated parameter must be of the required type.
* Example: void foo(@MessageMapping("headers.day") String arg) - will map the value of
* the 'day' header to 'arg'.
* parameter's value should be mapped from the payload of a Message. The expression
* will be evaluated against the payload object as the root context. The annotated
* parameter type must match or be convertible from the evaluation result.
* <p>
* Example: void foo(@Payload("city.name") String cityName) - will map the value of
* the 'name' property of the 'city' property of the payload object.
*
* @author Oleg Zhurakousky
* @since 2.0
@@ -35,8 +37,11 @@ import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MessageMapping {
public @interface Payload {
String value();
/**
* Expression for matching against nested properties of the payload.
*/
String value() default "";
}

View File

@@ -40,7 +40,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Headers;
import org.springframework.integration.annotation.MessageMapping;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.InboundMessageMapper;
import org.springframework.integration.message.MessageBuilder;
@@ -168,8 +168,14 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
if (mappingAnnotation.annotationType().isAssignableFrom(Header.class)) {
value = this.mapHeaderThruAnnotation(mappingAnnotation, message, methodParameter, null)[1];
}
else if (mappingAnnotation.annotationType().isAssignableFrom(MessageMapping.class)) {
expressions = new String[] { (String) AnnotationUtils.getValue(mappingAnnotation) };
else if (mappingAnnotation.annotationType().isAssignableFrom(Payload.class)) {
String payloadExpression = ((Payload) mappingAnnotation).value();
if (payloadExpression.length() == 0) {
expressions = new String[] { "payload" };
}
else {
expressions = new String[] { "payload." + payloadExpression };
}
value = this.getValueFromMessageBasedOnEL(message, methodParameter.getParameterType(), true, expressions);
}
else if (mappingAnnotation.annotationType().isAssignableFrom(Headers.class)) {
@@ -186,7 +192,7 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
}
public Message<?> toMessage(Object[] arguments) {
Assert.notNull(arguments, "Can not map 'null' arguments to Message");
Assert.notNull(arguments, "cannot map null arguments to Message");
if (arguments.length > this.parameterList.size()) {
throw new IllegalArgumentException("Too many parameters provided for: " + method);
}
@@ -206,10 +212,10 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
Annotation match = null;
for (Annotation annotation : annotations) {
Class<? extends Annotation> type = annotation.annotationType();
if (type.equals(MessageMapping.class) || type.equals(Header.class) || type.equals(Headers.class)) {
if (type.equals(Payload.class) || type.equals(Header.class) || type.equals(Headers.class)) {
if (match != null) {
throw new IllegalArgumentException("at most one parameter annotation can be provided for message mapping, " +
"but found two [" + match.annotationType().getName() + "] and [" + annotation.annotationType().getName() + "]");
"but found two: [" + match.annotationType().getName() + "] and [" + annotation.annotationType().getName() + "]");
}
match = annotation;
}
@@ -250,9 +256,9 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
Object[] header = this.mapHeaderThruAnnotation(annotation, message, methodParam, argumentValue);
messageArgumentsMap.put((String) header[0], header[1]);
}
else if (annotation.annotationType().equals(MessageMapping.class)) {
else if (annotation.annotationType().equals(Payload.class)) {
// need to clarify what to do here
throw new IllegalArgumentException("@MessageMapping is not allowed when mapping from method to Message");
throw new IllegalArgumentException("@Payload is not allowed when mapping from method to Message");
}
}
Assert.isTrue(payloadExist, "Payload can not be determined from method: " + method);

View File

@@ -29,7 +29,7 @@ import org.junit.Test;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Headers;
import org.springframework.integration.annotation.MessageMapping;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.message.MessageHandlingException;
@@ -289,19 +289,19 @@ public class ArgumentArrayMessageMapperFromMessageTests {
}
@Test
public void headersWithExpressions() throws Exception {
public void fromMessageToHeadersWithExpressions() throws Exception {
Method method = TestService.class.getMethod("headersWithExpressions", String.class, String.class);
ArgumentArrayMessageMapper mapper = new ArgumentArrayMessageMapper(method);
Employee employee = new Employee("John", "Doe");
Message<?> message = MessageBuilder.withPayload("payload").setHeader("emp", employee).build();
Object[] args = mapper.fromMessage(message);
assertEquals("John", args[0]);
assertEquals("Doe", args[1]);
assertEquals("DOE", args[1]);
}
@SuppressWarnings("unused")
private static class MultipleMappingAnnotationTestBean {
public void test(@MessageMapping("payload") @Header("foo") String s) {
public void test(@Payload("payload") @Header("foo") String s) {
}
}
@@ -334,7 +334,8 @@ public class ArgumentArrayMessageMapperFromMessageTests {
return num;
}
public String headersWithExpressions(@Header("emp.fname") String firstName, @Header("emp.lname") String lastName) {
public String headersWithExpressions(@Header("emp.fname") String firstName,
@Header("emp.lname.toUpperCase()") String lastName) {
return lastName + ", " + firstName;
}
@@ -373,20 +374,20 @@ public class ArgumentArrayMessageMapperFromMessageTests {
return i;
}
public void fromMessageToArgWithConversion(@MessageMapping("headers.number") String sArg) {} //
public void fromMessageToArgWithConversion(@Header("number") String sArg) {} //
public void fromMessageToArgWithConversion(@MessageMapping("headers.number") Integer iArg) {} //
public void fromMessageToArgWithConversion(@Header("number") Integer iArg) {} //
public void fromMessageToArgWithConversion(@Header("numberA")Integer valueA, @Header("numberB") Integer valueB) {} //
public void fromMessageToMessageMappingAnnotation(@MessageMapping("headers.day") String value) {} //
public void fromMessageToMessageMappingAnnotation(@Header("day") String value) {} //
public void fromMessageToMessageMappingAnnotationMultiArguments(@MessageMapping("headers.day") String argA,
@MessageMapping("headers.month") String argB,
@MessageMapping("#this") Message<?> message,
@MessageMapping("payload") Employee payloadArg,
@MessageMapping("payload.fname") String value,
@MessageMapping("headers") Map<?,?> headers){} //
public void fromMessageToMessageMappingAnnotationMultiArguments(@Header("day") String argA,
@Header("month") String argB,
Message<?> message,
@Payload Employee payloadArg,
@Payload("fname") String value,
@Headers Map<?,?> headers){} //
public void fromMessageIrrelevantAnnotation(@BogusAnnotation() String value){} //
}

View File

@@ -27,7 +27,6 @@ import org.junit.Test;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Headers;
import org.springframework.integration.annotation.MessageMapping;
import org.springframework.integration.core.Message;
import org.springframework.integration.handler.ArgumentArrayMessageMapper;
import org.springframework.integration.message.MessageBuilder;