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 a8c5810c87..100e96b430 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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. @@ -23,6 +23,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.InitializingBean; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.SpelParserConfiguration; @@ -36,17 +38,17 @@ import org.springframework.integration.support.MessageBuilder; /** * A Transformer that adds statically configured header values to a Message. - * Accepts the boolean 'overwrite' property that specifies whether values - * should be overwritten. By default, any existing header values for - * a given key, will not be replaced. + * Accepts the boolean 'overwrite' property that specifies whether values should + * be overwritten. By default, any existing header values for a given key, will + * not be replaced. * * @author Mark Fisher + * @author David Turanski */ -public class HeaderEnricher implements Transformer { +public class HeaderEnricher implements Transformer, BeanNameAware, InitializingBean { private static final Log logger = LogFactory.getLog(HeaderEnricher.class); - private final Map> headersToAdd; private volatile MessageProcessor messageProcessor; @@ -55,6 +57,7 @@ public class HeaderEnricher implements Transformer { private volatile boolean shouldSkipNulls = true; + private Object beanName; public HeaderEnricher() { this(null); @@ -64,10 +67,10 @@ 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>(); + this.headersToAdd = (headersToAdd != null) ? headersToAdd + : new HashMap>(); } - public void setMessageProcessor(MessageProcessor messageProcessor) { this.messageProcessor = messageProcessor; } @@ -77,9 +80,11 @@ public class HeaderEnricher implements Transformer { } /** - * Specify whether null values, such as might be returned from an expression evaluation, - * should be skipped. The default value is true. Set this to false if a - * null value should trigger removal of the corresponding header instead. + * Specify whether null values, such as might be returned from + * an expression evaluation, should be skipped. The default value is + * true. Set this to false if a + * null value should trigger removal of the + * corresponding header instead. */ public void setShouldSkipNulls(boolean shouldSkipNulls) { this.shouldSkipNulls = shouldSkipNulls; @@ -92,27 +97,29 @@ public class HeaderEnricher implements Transformer { for (Map.Entry> entry : this.headersToAdd.entrySet()) { String key = entry.getKey(); HeaderValueMessageProcessor valueProcessor = entry.getValue(); + Boolean shouldOverwrite = valueProcessor.isOverwrite(); if (shouldOverwrite == null) { shouldOverwrite = this.defaultOverwrite; } + + boolean headerDoesNotExist = headerMap.get(key) == null; + /** - * Only evaluate value if necessary + * Only evaluate value expression if necessary */ - Object value = null; - if (headerMap.get(key) == null || shouldOverwrite || !this.shouldSkipNulls){ - value = valueProcessor.processMessage(message); - } - - if ((value != null && shouldOverwrite) || headerMap.get(key) == null || (value == null && !this.shouldSkipNulls)) { - headerMap.put(key, value); + if (headerDoesNotExist || shouldOverwrite) { + Object value = valueProcessor.processMessage(message); + if (value != null || !this.shouldSkipNulls) { + headerMap.put(key, value); + } } } - return MessageBuilder.withPayload(message.getPayload()).copyHeaders(headerMap).build(); - } + return MessageBuilder.withPayload(message.getPayload()).copyHeaders(headerMap).build(); + } catch (Exception e) { - throw new MessagingException(message, "failed to transform message headers", e); - } + throw new MessagingException(message, "failed to transform message headers", e); + } } @SuppressWarnings("rawtypes") @@ -138,17 +145,16 @@ public class HeaderEnricher implements Transformer { } } - public static interface HeaderValueMessageProcessor extends MessageProcessor { Boolean isOverwrite(); } - static abstract class AbstractHeaderValueMessageProcessor implements HeaderValueMessageProcessor { - // null indicates no explicit setting; use header-enricher's 'default-overwrite' value + // null indicates no explicit setting; use header-enricher's + // 'default-overwrite' value private volatile Boolean overwrite = null; public void setOverwrite(Boolean overwrite) { @@ -161,7 +167,6 @@ public class HeaderEnricher implements Transformer { } - static class StaticHeaderValueMessageProcessor extends AbstractHeaderValueMessageProcessor { private final T value; @@ -175,24 +180,27 @@ public class HeaderEnricher implements Transformer { } } + static class ExpressionEvaluatingHeaderValueMessageProcessor extends AbstractHeaderValueMessageProcessor + implements BeanFactoryAware { - static class ExpressionEvaluatingHeaderValueMessageProcessor extends AbstractHeaderValueMessageProcessor implements BeanFactoryAware { - - private static final ExpressionParser expressionParser = new SpelExpressionParser(new SpelParserConfiguration(true, true)); + private static final ExpressionParser expressionParser = new SpelExpressionParser(new SpelParserConfiguration( + true, true)); private final ExpressionEvaluatingMessageProcessor targetProcessor; /** - * Create a header value processor for the given Expression and the expected type - * of the expression evaluation result. The expectedType may be null if unknown. + * Create a header value processor for the given Expression and the + * expected type of the expression evaluation result. The expectedType + * may be null if unknown. */ public ExpressionEvaluatingHeaderValueMessageProcessor(Expression expression, Class expectedType) { this.targetProcessor = new ExpressionEvaluatingMessageProcessor(expression, expectedType); } /** - * 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. + * 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 ExpressionEvaluatingHeaderValueMessageProcessor(String expressionString, Class expectedType) { Expression expression = expressionParser.parseExpression(expressionString); @@ -209,6 +217,37 @@ public class HeaderEnricher implements Transformer { } + /* + * (non-Javadoc) + * + * @see + * org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang + * .String) + */ + public void setBeanName(String beanName) { + this.beanName = beanName; + + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + public void afterPropertiesSet() throws Exception { + boolean shouldOverwrite = this.defaultOverwrite; + for (HeaderValueMessageProcessor processor : this.headersToAdd.values()) { + Boolean processerOverwrite = processor.isOverwrite(); + if (processerOverwrite != null) { + shouldOverwrite |= processerOverwrite.booleanValue(); + } + } + if (!shouldOverwrite && !this.shouldSkipNulls) { + logger.warn(this.beanName + + " is configured to not overwrite existing headers. 'shouldSkipNulls = false' will have no effect"); + } + } static class MethodInvokingHeaderValueMessageProcessor extends AbstractHeaderValueMessageProcessor { diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/SpelHeaderEnricherIntegrationTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/transformer/SpelHeaderEnricherIntegrationTests-context.xml index 7cd275534d..2bd1480629 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/SpelHeaderEnricherIntegrationTests-context.xml +++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/SpelHeaderEnricherIntegrationTests-context.xml @@ -2,10 +2,8 @@ + xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> @@ -22,6 +20,15 @@
+ + +
+ + + +
+ diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/SpelHeaderEnricherIntegrationTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/SpelHeaderEnricherIntegrationTests.java index 9f0327de10..47fa83b455 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/SpelHeaderEnricherIntegrationTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/SpelHeaderEnricherIntegrationTests.java @@ -17,6 +17,7 @@ package org.springframework.integration.transformer; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,6 +33,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Mark Fisher + * @author David Turanski */ @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) @@ -42,13 +44,19 @@ public class SpelHeaderEnricherIntegrationTests { @Autowired private MessageChannel beanResolvingInput; - + @Autowired private MessageChannel expressionNotExecutedInput; - @Autowired @Qualifier("output") - private PollableChannel output; + @Autowired + private MessageChannel headerNotRemovedInput; + @Autowired + private MessageChannel headerRemovedInput; + + @Autowired + @Qualifier("output") + private PollableChannel output; @Test public void simple() { @@ -65,15 +73,30 @@ public class SpelHeaderEnricherIntegrationTests { Message result = output.receive(0); assertEquals(243, result.getHeaders().get("num")); } - + @Test - public void suppressBeanExecution(){ + public void suppressBeanExecution() { Message message = MessageBuilder.withPayload("test").setHeader("num", 3).build(); this.expressionNotExecutedInput.send(message); Message result = output.receive(0); assertEquals(3, result.getHeaders().get("num")); } + @Test + public void headerNotRemoved() { + Message message = MessageBuilder.withPayload("test").setHeader("num", 3).build(); + this.headerNotRemovedInput.send(message); + Message result = output.receive(0); + assertEquals(3, result.getHeaders().get("num")); + } + + @Test + public void headerRemoved() { + Message message = MessageBuilder.withPayload("test").setHeader("num", 3).build(); + this.headerRemovedInput.send(message); + Message result = output.receive(0); + assertNull(result.getHeaders().get("num")); + } static class TestBean { diff --git a/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XPathHeaderEnricherTests.java b/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XPathHeaderEnricherTests.java index ad16c7d2d3..41a3418548 100644 --- a/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XPathHeaderEnricherTests.java +++ b/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XPathHeaderEnricherTests.java @@ -34,6 +34,7 @@ import org.springframework.integration.xml.xpath.XPathEvaluationType; /** * @author Jonas Partner + * @author David Turanski * @since 2.0 */ public class XPathHeaderEnricherTests { @@ -72,6 +73,7 @@ public class XPathHeaderEnricherTests { String docAsString = "1"; XPathHeaderEnricher enricher = new XPathHeaderEnricher(expressionMap); enricher.setShouldSkipNulls(false); + enricher.setDefaultOverwrite(true); Message result = enricher.transform(MessageBuilder.withPayload(docAsString).setHeader("two", "x").build()); MessageHeaders headers = result.getHeaders(); assertNull(headers.get("two"));