INT-931 header-enricher now supports method invocation
This commit is contained in:
@@ -28,7 +28,6 @@ import org.springframework.beans.factory.config.TypedStringValue;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.transformer.HeaderEnricher.ExpressionHolder;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -115,23 +114,50 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
|
||||
String value = headerElement.getAttribute("value");
|
||||
String ref = headerElement.getAttribute("ref");
|
||||
String expression = headerElement.getAttribute("expression");
|
||||
String method = headerElement.getAttribute("method");
|
||||
boolean isValue = StringUtils.hasText(value);
|
||||
boolean isRef = StringUtils.hasText(ref);
|
||||
boolean isExpression = StringUtils.hasText(expression);
|
||||
boolean hasMethod = StringUtils.hasText(method);
|
||||
if (!(isValue ^ (isRef ^ isExpression))) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Exactly one of the 'ref', 'value', or 'expression' attributes is required.", element);
|
||||
}
|
||||
if (isValue) {
|
||||
if (hasMethod) {
|
||||
parserContext.getReaderContext().error(
|
||||
"The 'method' attribute cannot be used with the 'value' attribute.", element);
|
||||
}
|
||||
Object headerValue = (headerType != null) ?
|
||||
new TypedStringValue(value, headerType) : value;
|
||||
headers.put(headerName, headerValue);
|
||||
}
|
||||
else if (isExpression) {
|
||||
headers.put(headerName, new ExpressionHolder(expression, headerType));
|
||||
if (hasMethod) {
|
||||
parserContext.getReaderContext().error(
|
||||
"The 'method' attribute cannot be used with the 'expression' attribute.", element);
|
||||
}
|
||||
BeanDefinitionBuilder expressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$ExpressionHolder");
|
||||
expressionBuilder.addConstructorArgValue(expression);
|
||||
expressionBuilder.addConstructorArgValue(headerType);
|
||||
headers.put(headerName, expressionBuilder.getBeanDefinition());
|
||||
}
|
||||
else {
|
||||
headers.put(headerName, new RuntimeBeanReference(ref));
|
||||
if (StringUtils.hasText(headerElement.getAttribute("type"))) {
|
||||
parserContext.getReaderContext().error(
|
||||
"The 'type' attribute cannot be used with the 'ref' attribute.", element);
|
||||
}
|
||||
if (hasMethod) {
|
||||
BeanDefinitionBuilder methodExpressionBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$MethodExpressionHolder");
|
||||
methodExpressionBuilder.addConstructorArgReference(ref);
|
||||
methodExpressionBuilder.addConstructorArgValue(method);
|
||||
headers.put(headerName, methodExpressionBuilder.getBeanDefinition());
|
||||
}
|
||||
else {
|
||||
headers.put(headerName, new RuntimeBeanReference(ref));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -20,6 +20,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
@@ -28,6 +29,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessagingException;
|
||||
import org.springframework.integration.handler.MethodInvokingMessageProcessor;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -69,6 +71,9 @@ public class HeaderEnricher implements Transformer {
|
||||
if (value instanceof ExpressionHolder) {
|
||||
value = ((ExpressionHolder) value).evaluate(message);
|
||||
}
|
||||
else if (value instanceof MethodExpressionHolder) {
|
||||
value = ((MethodExpressionHolder) value).evaluate(message);
|
||||
}
|
||||
headerMap.put(key, value);
|
||||
}
|
||||
}
|
||||
@@ -80,16 +85,15 @@ public class HeaderEnricher implements Transformer {
|
||||
}
|
||||
|
||||
|
||||
public static class ExpressionHolder {
|
||||
static class ExpressionHolder {
|
||||
|
||||
private static final ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
|
||||
private final String expressionString;
|
||||
|
||||
private final Class<?> expectedType;
|
||||
|
||||
private volatile Expression parsedExpression;
|
||||
private final Expression expression;
|
||||
|
||||
private final EvaluationContext evaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
@@ -97,22 +101,32 @@ public class HeaderEnricher implements Transformer {
|
||||
* of the expression evaluation result. The expectedType may be null if unknown.
|
||||
*/
|
||||
public ExpressionHolder(String expressionString, Class<?> expectedType) {
|
||||
this.expressionString = expressionString;
|
||||
this.expectedType = expectedType;
|
||||
this.expression = parser.parseExpression(expressionString);
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.addPropertyAccessor(new MapAccessor());
|
||||
this.evaluationContext = context;
|
||||
}
|
||||
|
||||
|
||||
private Object evaluate(Message<?> message) throws ParseException, EvaluationException {
|
||||
if (this.parsedExpression == null) {
|
||||
synchronized (this) {
|
||||
this.parsedExpression = parser.parseExpression(this.expressionString);
|
||||
}
|
||||
}
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(message);
|
||||
context.addPropertyAccessor(new MapAccessor());
|
||||
return (this.expectedType != null)
|
||||
? this.parsedExpression.getValue(context, this.expectedType)
|
||||
: this.parsedExpression.getValue(context);
|
||||
? this.expression.getValue(this.evaluationContext, message, this.expectedType)
|
||||
: this.expression.getValue(this.evaluationContext, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class MethodExpressionHolder {
|
||||
|
||||
private final MethodInvokingMessageProcessor processor;
|
||||
|
||||
public MethodExpressionHolder(Object targetObject, String method) {
|
||||
this.processor = new MethodInvokingMessageProcessor(targetObject, method);
|
||||
}
|
||||
|
||||
private Object evaluate(Message<?> message) {
|
||||
return this.processor.processMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -989,6 +989,13 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="method" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Name of a method to be invoked on the referenced target object.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="thread-pool-task-executor">
|
||||
|
||||
@@ -82,4 +82,12 @@
|
||||
<header name="number" expression="12345" type="java.lang.Long"/>
|
||||
</header-enricher>
|
||||
|
||||
<header-enricher input-channel="refWithMethod">
|
||||
<header name="testHeader" ref="testBean" method="getName"/>
|
||||
</header-enricher>
|
||||
|
||||
<beans:bean id="testBean" class="org.springframework.integration.config.xml.HeaderEnricherTests$TestBean">
|
||||
<beans:constructor-arg value="testBeanForMethodInvoker"/>
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -171,6 +171,16 @@ public class HeaderEnricherTests {
|
||||
assertEquals(new Long(12345), result.getHeaders().get("number"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refWithMethod() {
|
||||
SimpleMessagingGateway gateway = new SimpleMessagingGateway();
|
||||
gateway.setRequestChannel(context.getBean("refWithMethod", MessageChannel.class));
|
||||
Message<?> result = gateway.sendAndReceiveMessage("test");
|
||||
assertNotNull(result);
|
||||
assertEquals(String.class, result.getHeaders().get("testHeader").getClass());
|
||||
assertEquals("testBeanForMethodInvoker", result.getHeaders().get("testHeader"));
|
||||
}
|
||||
|
||||
|
||||
public static class TestBean {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user