INT-1181 added support for bean resolution within the ExpressionEvaluatingMessageProcessor
This commit is contained in:
@@ -16,7 +16,12 @@
|
||||
|
||||
package org.springframework.integration.handler;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.ParseException;
|
||||
@@ -31,7 +36,7 @@ import org.springframework.integration.core.Message;
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ExpressionEvaluatingMessageProcessor extends AbstractMessageProcessor {
|
||||
public class ExpressionEvaluatingMessageProcessor extends AbstractMessageProcessor implements BeanFactoryAware {
|
||||
|
||||
private final ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
|
||||
@@ -40,6 +45,9 @@ public class ExpressionEvaluatingMessageProcessor extends AbstractMessageProcess
|
||||
private volatile Class<?> expectedType = null;
|
||||
|
||||
|
||||
/**
|
||||
* Create an {@link ExpressionEvaluatingMessageProcessor} for the given expression String.
|
||||
*/
|
||||
public ExpressionEvaluatingMessageProcessor(String expression) {
|
||||
try {
|
||||
this.expression = parser.parseExpression(expression);
|
||||
@@ -51,10 +59,30 @@ public class ExpressionEvaluatingMessageProcessor extends AbstractMessageProcess
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the result type expected from evaluation of the expression.
|
||||
*/
|
||||
public void setExpectedType(Class<?> expectedType) {
|
||||
this.expectedType = expectedType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a BeanFactory in order to enable resolution via <code>@beanName</code> in the expression.
|
||||
*/
|
||||
public void setBeanFactory(final BeanFactory beanFactory) {
|
||||
if (beanFactory != null) {
|
||||
this.getEvaluationContext().setBeanResolver(new BeanResolver() {
|
||||
public Object resolve(EvaluationContext context, String beanName) throws AccessException {
|
||||
return beanFactory.getBean(beanName);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the Message by evaluating the expression with that Message as the
|
||||
* root object. The expression evaluation result Object will be returned.
|
||||
*/
|
||||
public Object processMessage(Message<?> message) {
|
||||
return this.evaluateExpression(this.expression, message, this.expectedType);
|
||||
}
|
||||
|
||||
@@ -22,22 +22,28 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.internal.matchers.TypeSafeMatcher;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*
|
||||
*/
|
||||
public class ExpressionEvaluatingMessageProcessorTests {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ExpressionEvaluatingMessageProcessorTests.class);
|
||||
|
||||
|
||||
@Rule
|
||||
public ExpectedException expected = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void testProcessMessage() {
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("payload");
|
||||
@@ -45,12 +51,19 @@ public class ExpressionEvaluatingMessageProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessMessageWithDollar() {
|
||||
public void testProcessMessageWithDollarInBrackets() {
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("headers['$id']");
|
||||
StringMessage message = new StringMessage("foo");
|
||||
assertEquals(message.getHeaders().getId(), processor.processMessage(message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessMessageWithDollarPropertyAccess() {
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("headers.$id");
|
||||
StringMessage message = new StringMessage("foo");
|
||||
assertEquals(message.getHeaders().getId(), processor.processMessage(message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessMessageWithStaticKey() {
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("headers[headers.ID]");
|
||||
@@ -58,6 +71,30 @@ public class ExpressionEvaluatingMessageProcessorTests {
|
||||
assertEquals(message.getHeaders().getId(), processor.processMessage(message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessMessageWithBeanAsMethodArgument() {
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
BeanDefinition beanDefinition = new RootBeanDefinition(String.class);
|
||||
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("bar");
|
||||
context.registerBeanDefinition("testString", beanDefinition);
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("payload.concat(@testString)");
|
||||
processor.setBeanFactory(context);
|
||||
StringMessage message = new StringMessage("foo");
|
||||
assertEquals("foobar", processor.processMessage(message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessMessageWithMethodCallOnBean() {
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
BeanDefinition beanDefinition = new RootBeanDefinition(String.class);
|
||||
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("bar");
|
||||
context.registerBeanDefinition("testString", beanDefinition);
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("@testString.concat(payload)");
|
||||
processor.setBeanFactory(context);
|
||||
StringMessage message = new StringMessage("foo");
|
||||
assertEquals("barfoo", processor.processMessage(message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessMessageBadExpression() {
|
||||
expected.expect(new TypeSafeMatcher<Exception>(Exception.class) {
|
||||
@@ -90,8 +127,8 @@ public class ExpressionEvaluatingMessageProcessorTests {
|
||||
description.appendText("cause to be UnsupportedOperationException but was ").appendValue(cause);
|
||||
}
|
||||
});
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("payload.error()");
|
||||
assertEquals("foo", processor.processMessage(new GenericMessage<ExpressionEvaluatingMessageProcessorTests>(this)));
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("payload.throwRuntimeException()");
|
||||
assertEquals("foo", processor.processMessage(new GenericMessage<TestPayload>(new TestPayload())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,17 +145,23 @@ public class ExpressionEvaluatingMessageProcessorTests {
|
||||
description.appendText("cause to be CheckedException but was ").appendValue(cause);
|
||||
}
|
||||
});
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("payload.check()");
|
||||
assertEquals("foo", processor.processMessage(new GenericMessage<ExpressionEvaluatingMessageProcessorTests>(this)));
|
||||
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor("payload.throwCheckedException()");
|
||||
assertEquals("foo", processor.processMessage(new GenericMessage<TestPayload>(new TestPayload())));
|
||||
}
|
||||
|
||||
public String error() {
|
||||
throw new UnsupportedOperationException("Expected test exception");
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class TestPayload {
|
||||
|
||||
public String throwRuntimeException() {
|
||||
throw new UnsupportedOperationException("Expected test exception");
|
||||
}
|
||||
|
||||
public String throwCheckedException() throws Exception {
|
||||
throw new CheckedException("Expected test exception");
|
||||
}
|
||||
}
|
||||
|
||||
public String check() throws Exception {
|
||||
throw new CheckedException("Expected test exception");
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static final class CheckedException extends Exception {
|
||||
|
||||
Reference in New Issue
Block a user