INT-670 added support for SpEL expressions in parameter-level @Payload annotations on a Gateway

This commit is contained in:
Mark Fisher
2010-07-23 15:52:07 +00:00
parent 91bb24b102
commit 855d955fad
2 changed files with 61 additions and 12 deletions

View File

@@ -115,6 +115,10 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
private final Expression payloadExpression;
private final Map<String, Expression> parameterPayloadExpressions = new HashMap<String, Expression>();
private final StandardEvaluationContext staticEvaluationContext = new StandardEvaluationContext();
private volatile BeanResolver beanResolver;
@@ -138,6 +142,7 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
return beanFactory.getBean(beanName);
}
};
this.staticEvaluationContext.setBeanResolver(beanResolver);
}
}
@@ -173,12 +178,14 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
if (messageOrPayload != null) {
this.throwExceptionForMultipleMessageOrPayloadParameters(methodParameter);
}
if (((Payload) annotation).value().length() != 0) {
throw new MessagingException(
"The Payload annotation does not support an expression when mapping to a Message.");
String expression = ((Payload) annotation).value();
if (!StringUtils.hasText(expression)) {
messageOrPayload = argumentValue;
}
else {
messageOrPayload = this.evaluatePayloadExpression(expression, argumentValue);
}
foundPayloadAnnotation = true;
messageOrPayload = argumentValue;
}
else if (annotation.annotationType().equals(Header.class)) {
Header headerAnnotation = (Header) annotation;
@@ -227,6 +234,15 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
return builder.build();
}
private Object evaluatePayloadExpression(String expressionString, Object argumentValue) {
Expression expression = this.parameterPayloadExpressions.get(expressionString);
if (expression == null) {
expression = PARSER.parseExpression(expressionString);
this.parameterPayloadExpressions.put(expressionString, expression);
}
return expression.getValue(this.staticEvaluationContext, argumentValue);
}
private Annotation findMappingAnnotation(Annotation[] annotations) {
if (annotations == null || annotations.length == 0) {
return null;

View File

@@ -144,6 +144,35 @@ public class GatewayProxyMessageMappingTests {
assertEquals("FOO!!!", result.getPayload());
}
@Test
public void payloadAnnotationWithExpression() throws Exception {
gateway.payloadAnnotationWithExpression("foo");
Message<?> result = channel.receive(0);
assertNotNull(result);
assertEquals("FOO", result.getPayload());
}
@Test
public void payloadAnnotationWithExpressionUsingBeanResolver() throws Exception {
GenericApplicationContext context = new GenericApplicationContext();
RootBeanDefinition gatewayDefinition = new RootBeanDefinition(GatewayProxyFactoryBean.class);
gatewayDefinition.getPropertyValues().add("defaultRequestChannel", channel);
gatewayDefinition.getPropertyValues().add("serviceInterface", TestGateway.class);
context.registerBeanDefinition("testGateway", gatewayDefinition);
context.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
context.refresh();
TestGateway gateway = context.getBean("testGateway", TestGateway.class);
gateway.payloadAnnotationWithExpressionUsingBeanResolver("foo");
gateway.payloadAnnotationWithExpressionUsingBeanResolver("bar");
Message<?> fooResult = channel.receive(0);
assertNotNull(fooResult);
assertEquals(324, fooResult.getPayload());
Message<?> barResult = channel.receive(0);
assertNotNull(barResult);
assertEquals(309, barResult.getPayload());
assertNull(channel.receive(0));
}
@Test(expected = MessagingException.class)
public void twoMapsWithoutAnnotations() {
Map<String, Object> map1 = new HashMap<String, Object>();
@@ -168,11 +197,6 @@ public class GatewayProxyMessageMappingTests {
gateway.payloadAndHeadersAnnotationsOnSameParameter(new HashMap<String, Object>());
}
@Test(expected = MessagingException.class)
public void payloadWithExpression() throws Exception {
gateway.payloadWithExpression("test");
}
public static interface TestGateway {
@@ -192,6 +216,10 @@ public class GatewayProxyMessageMappingTests {
@Payload("@testBean.exclaim(#args[0])")
void payloadAnnotationAtMethodLevelUsingBeanResolver(String s);
void payloadAnnotationWithExpression(@Payload("toUpperCase()") String s);
void payloadAnnotationWithExpressionUsingBeanResolver(@Payload("@testBean.sum(#this)") String s);
// invalid
void twoMapsWithoutAnnotations(Map<String, Object> m1, Map<String, Object> m2);
@@ -204,9 +232,6 @@ public class GatewayProxyMessageMappingTests {
// invalid
void payloadAndHeadersAnnotationsOnSameParameter(@Payload @Headers Map<String, Object> map);
// invalid
void payloadWithExpression(@Payload("oops") String s);
}
@@ -215,6 +240,14 @@ public class GatewayProxyMessageMappingTests {
public String exclaim(String s) {
return s.toUpperCase() + "!!!";
}
public int sum(String s) {
int sum = 0;
for (byte b : s.getBytes()) {
sum += b;
}
return sum;
}
}
}