diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java index 89b31b224a..952d9430d1 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderEnricherParserSupport.java @@ -120,7 +120,7 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar "Exactly one of the 'ref', 'value', or 'expression' attributes is required.", element); } Object headerSource = parserContext.extractSource(headerElement); - BeanDefinitionBuilder valueHolderBuilder = null; + BeanDefinitionBuilder valueProcessorBuilder = null; if (isValue) { if (hasMethod) { parserContext.getReaderContext().error( @@ -128,19 +128,19 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar } Object headerValue = (headerType != null) ? new TypedStringValue(value, headerType) : value; - valueHolderBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$StaticValueHolder"); - valueHolderBuilder.addConstructorArgValue(headerValue); + valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition( + IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$StaticHeaderValueMessageProcessor"); + valueProcessorBuilder.addConstructorArgValue(headerValue); } else if (isExpression) { if (hasMethod) { parserContext.getReaderContext().error( "The 'method' attribute cannot be used with the 'expression' attribute.", element); } - valueHolderBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$ExpressionHolder"); - valueHolderBuilder.addConstructorArgValue(expression); - valueHolderBuilder.addConstructorArgValue(headerType); + valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition( + IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$ExpressionEvaluatingHeaderValueMessageProcessor"); + valueProcessorBuilder.addConstructorArgValue(expression); + valueProcessorBuilder.addConstructorArgValue(headerType); } else { if (StringUtils.hasText(headerElement.getAttribute("type"))) { @@ -148,22 +148,22 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar "The 'type' attribute cannot be used with the 'ref' attribute.", element); } if (hasMethod) { - valueHolderBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$MethodExpressionHolder"); - valueHolderBuilder.addConstructorArgReference(ref); - valueHolderBuilder.addConstructorArgValue(method); + valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition( + IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$MethodInvokingHeaderValueMessageProcessor"); + valueProcessorBuilder.addConstructorArgReference(ref); + valueProcessorBuilder.addConstructorArgValue(method); } else { - valueHolderBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$StaticValueHolder"); - valueHolderBuilder.addConstructorArgReference(ref); + valueProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition( + IntegrationNamespaceUtils.BASE_PACKAGE + ".transformer.HeaderEnricher$StaticHeaderValueMessageProcessor"); + valueProcessorBuilder.addConstructorArgReference(ref); } } - if (valueHolderBuilder == null) { + if (valueProcessorBuilder == null) { parserContext.getReaderContext().error("failed to parse header sub-element", headerSource); } - IntegrationNamespaceUtils.setValueIfAttributeDefined(valueHolderBuilder, headerElement, "overwrite"); - headers.put(headerName, valueHolderBuilder.getBeanDefinition()); + IntegrationNamespaceUtils.setValueIfAttributeDefined(valueProcessorBuilder, headerElement, "overwrite"); + headers.put(headerName, valueProcessorBuilder.getBeanDefinition()); } } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java index 2fb81b43c1..d2c2b4b5e0 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java @@ -22,16 +22,9 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -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; -import org.springframework.expression.ParseException; -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.ExpressionEvaluatingMessageProcessor; import org.springframework.integration.handler.MessageProcessor; import org.springframework.integration.handler.MethodInvokingMessageProcessor; import org.springframework.integration.message.MessageBuilder; @@ -49,7 +42,7 @@ public class HeaderEnricher implements Transformer { private static final Log logger = LogFactory.getLog(HeaderEnricher.class); - private final Map headersToAdd; + private final Map headersToAdd; private volatile MessageProcessor messageProcessor; @@ -65,8 +58,8 @@ public class HeaderEnricher implements Transformer { /** * Create a HeaderEnricher with the given map of headers. */ - public HeaderEnricher(Map headersToAdd) { - this.headersToAdd = (headersToAdd != null) ? headersToAdd : new HashMap(); + public HeaderEnricher(Map headersToAdd) { + this.headersToAdd = (headersToAdd != null) ? headersToAdd : new HashMap(); } @@ -91,14 +84,14 @@ public class HeaderEnricher implements Transformer { try { Map headerMap = new HashMap(message.getHeaders()); this.addHeadersFromMessageProcessor(message, headerMap); - for (Map.Entry entry : this.headersToAdd.entrySet()) { + for (Map.Entry entry : this.headersToAdd.entrySet()) { String key = entry.getKey(); - ValueHolder valueHolder = entry.getValue(); - Boolean shouldOverwrite = valueHolder.isOverwrite(); + HeaderValueMessageProcessor valueProcessor = entry.getValue(); + Boolean shouldOverwrite = valueProcessor.isOverwrite(); if (shouldOverwrite == null) { shouldOverwrite = this.defaultOverwrite; } - Object value = valueHolder.evaluate(message); + Object value = valueProcessor.processMessage(message); if ((value != null && shouldOverwrite) || headerMap.get(key) == null || (value == null && !this.shouldSkipNulls)) { headerMap.put(key, value); } @@ -133,16 +126,15 @@ public class HeaderEnricher implements Transformer { } } - public static interface ValueHolder { - Object evaluate(Message message); + public static interface HeaderValueMessageProcessor extends MessageProcessor { Boolean isOverwrite(); } - static abstract class AbstractValueHolder implements ValueHolder { + static abstract class AbstractHeaderValueMessageProcessor implements HeaderValueMessageProcessor { // null indicates no explicit setting; use header-enricher's 'default-overwrite' value private volatile Boolean overwrite = null; @@ -158,63 +150,52 @@ public class HeaderEnricher implements Transformer { } - static class StaticValueHolder extends AbstractValueHolder { + static class StaticHeaderValueMessageProcessor extends AbstractHeaderValueMessageProcessor { private final Object value; - public StaticValueHolder(Object value) { + public StaticHeaderValueMessageProcessor(Object value) { this.value = value; } - public Object evaluate(Message message) { + public Object processMessage(Message message) { return this.value; } } - static class ExpressionHolder extends AbstractValueHolder { - - private static final ExpressionParser parser = new SpelExpressionParser(); - - private final Class expectedType; - - private final Expression expression; - - private final EvaluationContext evaluationContext; + static class ExpressionEvaluatingHeaderValueMessageProcessor extends AbstractHeaderValueMessageProcessor { + private final ExpressionEvaluatingMessageProcessor targetProcessor; /** - * Create a holder object for the given expression String and the expected type + * Create a header value processor for the given expression String and the expected type * of the expression evaluation result. The expectedType may be null if unknown. */ - public ExpressionHolder(String expressionString, Class expectedType) { - this.expectedType = expectedType; - this.expression = parser.parseExpression(expressionString); - StandardEvaluationContext context = new StandardEvaluationContext(); - context.addPropertyAccessor(new MapAccessor()); - this.evaluationContext = context; + public ExpressionEvaluatingHeaderValueMessageProcessor(String expressionString, Class expectedType) { + this.targetProcessor = new ExpressionEvaluatingMessageProcessor(expressionString); + this.targetProcessor.setExpectedType(expectedType); } - - public Object evaluate(Message message) throws ParseException, EvaluationException { - return (this.expectedType != null) - ? this.expression.getValue(this.evaluationContext, message, this.expectedType) - : this.expression.getValue(this.evaluationContext, message); + public Object processMessage(Message message) { + return this.targetProcessor.processMessage(message); } + } - static class MethodExpressionHolder extends AbstractValueHolder { + static class MethodInvokingHeaderValueMessageProcessor extends AbstractHeaderValueMessageProcessor { - private final MethodInvokingMessageProcessor processor; + private final MethodInvokingMessageProcessor targetProcessor; - public MethodExpressionHolder(Object targetObject, String method) { - this.processor = new MethodInvokingMessageProcessor(targetObject, method); + public MethodInvokingHeaderValueMessageProcessor(Object targetObject, String method) { + this.targetProcessor = new MethodInvokingMessageProcessor(targetObject, method); } - public Object evaluate(Message message) { - return this.processor.processMessage(message); + public Object processMessage(Message message) { + return this.targetProcessor.processMessage(message); } + } } diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/enricher/XPathHeaderEnricher.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/enricher/XPathHeaderEnricher.java index f334e0b4d8..5719ea2052 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/enricher/XPathHeaderEnricher.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/enricher/XPathHeaderEnricher.java @@ -44,12 +44,12 @@ public class XPathHeaderEnricher extends HeaderEnricher { * Create an instance of XPathHeaderEnricher using a map with header names as keys * and XPathExpressionValueHolders to evaluate the values. */ - public XPathHeaderEnricher(Map expressionMap) { + public XPathHeaderEnricher(Map expressionMap) { super(expressionMap); } - public static class XPathExpressionValueHolder implements ValueHolder { + public static class XPathExpressionEvaluatingHeaderValueMessageProcessor implements HeaderValueMessageProcessor { private final XPathExpression expression; @@ -60,12 +60,12 @@ public class XPathHeaderEnricher extends HeaderEnricher { private volatile Boolean overwrite = null; - public XPathExpressionValueHolder(String expression) { + public XPathExpressionEvaluatingHeaderValueMessageProcessor(String expression) { Assert.hasText(expression, "expression must have text"); this.expression = XPathExpressionFactory.createXPathExpression(expression); } - public XPathExpressionValueHolder(XPathExpression expression) { + public XPathExpressionEvaluatingHeaderValueMessageProcessor(XPathExpression expression) { Assert.notNull(expression, "expression must not be null"); this.expression = expression; } @@ -78,7 +78,11 @@ public class XPathHeaderEnricher extends HeaderEnricher { this.overwrite = overwrite; } - public Object evaluate(Message message) { + public Boolean isOverwrite() { + return this.overwrite; + } + + public Object processMessage(Message message) { Node node = converter.convertToNode(message.getPayload()); Object result = this.evaluationType.evaluateXPath(this.expression, node); if (result instanceof String && ((String) result).length() == 0) { @@ -86,10 +90,6 @@ public class XPathHeaderEnricher extends HeaderEnricher { } return result; } - - public Boolean isOverwrite() { - return this.overwrite; - } } } diff --git a/spring-integration-xml/src/test/java/org/springframework/integration/xml/enricher/XPathHeaderEnricherTests.java b/spring-integration-xml/src/test/java/org/springframework/integration/xml/enricher/XPathHeaderEnricherTests.java index 1fbac683fa..30e1eff81d 100644 --- a/spring-integration-xml/src/test/java/org/springframework/integration/xml/enricher/XPathHeaderEnricherTests.java +++ b/spring-integration-xml/src/test/java/org/springframework/integration/xml/enricher/XPathHeaderEnricherTests.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessageHeaders; import org.springframework.integration.message.MessageBuilder; -import org.springframework.integration.xml.enricher.XPathHeaderEnricher.XPathExpressionValueHolder; +import org.springframework.integration.xml.enricher.XPathHeaderEnricher.XPathExpressionEvaluatingHeaderValueMessageProcessor; import org.springframework.integration.xml.xpath.XPathEvaluationType; /** @@ -39,9 +39,10 @@ public class XPathHeaderEnricherTests { @Test public void simpleStringEvaluation() { - Map expressionMap = new HashMap(); - expressionMap.put("one", new XPathExpressionValueHolder("/root/elementOne")); - expressionMap.put("two", new XPathExpressionValueHolder("/root/elementTwo")); + Map expressionMap = + new HashMap(); + expressionMap.put("one", new XPathExpressionEvaluatingHeaderValueMessageProcessor("/root/elementOne")); + expressionMap.put("two", new XPathExpressionEvaluatingHeaderValueMessageProcessor("/root/elementTwo")); String docAsString = "12"; XPathHeaderEnricher enricher = new XPathHeaderEnricher(expressionMap); Message result = enricher.transform(MessageBuilder.withPayload(docAsString).build()); @@ -52,8 +53,9 @@ public class XPathHeaderEnricherTests { @Test public void nullValuesSkippedByDefault() { - Map expressionMap = new HashMap(); - expressionMap.put("two", new XPathExpressionValueHolder("/root/elementTwo")); + Map expressionMap + = new HashMap(); + expressionMap.put("two", new XPathExpressionEvaluatingHeaderValueMessageProcessor("/root/elementTwo")); String docAsString = "1"; XPathHeaderEnricher enricher = new XPathHeaderEnricher(expressionMap); Message result = enricher.transform(MessageBuilder.withPayload(docAsString).build()); @@ -63,8 +65,9 @@ public class XPathHeaderEnricherTests { @Test public void notSkippingNullValues() { - Map expressionMap = new HashMap(); - expressionMap.put("two", new XPathExpressionValueHolder("/root/elementTwo")); + Map expressionMap = + new HashMap(); + expressionMap.put("two", new XPathExpressionEvaluatingHeaderValueMessageProcessor("/root/elementTwo")); String docAsString = "1"; XPathHeaderEnricher enricher = new XPathHeaderEnricher(expressionMap); enricher.setShouldSkipNulls(false); @@ -76,9 +79,12 @@ public class XPathHeaderEnricherTests { @Test public void numberEvaluationResult() { - Map expressionMap = new HashMap(); - XPathExpressionValueHolder expression1 = new XPathExpressionValueHolder("/root/elementOne"); - XPathExpressionValueHolder expression2 = new XPathExpressionValueHolder("/root/elementTwo"); + Map expressionMap = + new HashMap(); + XPathExpressionEvaluatingHeaderValueMessageProcessor expression1 = + new XPathExpressionEvaluatingHeaderValueMessageProcessor("/root/elementOne"); + XPathExpressionEvaluatingHeaderValueMessageProcessor expression2 = + new XPathExpressionEvaluatingHeaderValueMessageProcessor("/root/elementTwo"); expression2.setEvaluationType(XPathEvaluationType.NUMBER_RESULT); expressionMap.put("one", expression1); expressionMap.put("two", expression2);