diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java index 683a7ab239..fef9c98037 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java @@ -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)); + } } } } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java b/org.springframework.integration/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java index 9e4fd233d9..62d17b41bf 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java @@ -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); } } diff --git a/org.springframework.integration/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd b/org.springframework.integration/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd index 7123046c55..e96032c9c4 100644 --- a/org.springframework.integration/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd +++ b/org.springframework.integration/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd @@ -989,6 +989,13 @@ + + + + Name of a method to be invoked on the referenced target object. + + + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/HeaderEnricherTests-context.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/HeaderEnricherTests-context.xml index 9553385091..9b548d6eca 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/HeaderEnricherTests-context.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/HeaderEnricherTests-context.xml @@ -82,4 +82,12 @@
+ +
+ + + + + + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/HeaderEnricherTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/HeaderEnricherTests.java index 72745c3fbf..da469dfbc7 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/HeaderEnricherTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/HeaderEnricherTests.java @@ -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 {