INT-1130 Added support for 'ref' and 'method' (for Map-returning methods) on the top level <header-enricher/> element.
This commit is contained in:
@@ -66,6 +66,7 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
|
||||
this.processHeaders(element, headers, parserContext);
|
||||
builder.addConstructorArgValue(headers);
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "default-overwrite");
|
||||
this.postProcessHeaderEnricher(builder, element, parserContext);
|
||||
}
|
||||
|
||||
protected void processHeaders(Element element, ManagedMap<String, Object> headers, ParserContext parserContext) {
|
||||
@@ -168,4 +169,10 @@ public abstract class HeaderEnricherParserSupport extends AbstractTransformerPar
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide any additional processing.
|
||||
*/
|
||||
protected void postProcessHeaderEnricher(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
@@ -16,8 +16,13 @@
|
||||
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.core.MessageHeaders;
|
||||
import org.springframework.integration.core.MessagePriority;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <header-enricher> element within the core integration
|
||||
@@ -38,4 +43,23 @@ public class StandardHeaderEnricherParser extends HeaderEnricherParserSupport {
|
||||
this.addElementToHeaderMapping("priority", MessageHeaders.PRIORITY, MessagePriority.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcessHeaderEnricher(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
|
||||
String ref = element.getAttribute("ref");
|
||||
String method = element.getAttribute("method");
|
||||
if (StringUtils.hasText(ref) || StringUtils.hasText(method)) {
|
||||
if (!StringUtils.hasText(ref) || !StringUtils.hasText(method)) {
|
||||
parserContext.getReaderContext().error(
|
||||
"If either 'ref' or 'method' is provided, then they are both required.",
|
||||
parserContext.extractSource(element));
|
||||
return;
|
||||
}
|
||||
BeanDefinitionBuilder processorBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
IntegrationNamespaceUtils.BASE_PACKAGE + ".handler.MethodInvokingMessageProcessor");
|
||||
processorBuilder.addConstructorArgReference(ref);
|
||||
processorBuilder.addConstructorArgValue(method);
|
||||
builder.addPropertyValue("messageProcessor", processorBuilder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ package org.springframework.integration.transformer;
|
||||
import java.util.HashMap;
|
||||
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;
|
||||
@@ -29,9 +32,9 @@ 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.MessageProcessor;
|
||||
import org.springframework.integration.handler.MethodInvokingMessageProcessor;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A Transformer that adds statically configured header values to a Message.
|
||||
@@ -43,20 +46,32 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class HeaderEnricher implements Transformer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(HeaderEnricher.class);
|
||||
|
||||
|
||||
private final Map<String, ValueHolder> headersToAdd;
|
||||
|
||||
private volatile MessageProcessor messageProcessor;
|
||||
|
||||
private volatile boolean defaultOverwrite = false;
|
||||
|
||||
|
||||
public HeaderEnricher() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HeaderEnricher with the given map of headers.
|
||||
*/
|
||||
public HeaderEnricher(Map<String, ValueHolder> headersToAdd) {
|
||||
Assert.notNull(headersToAdd, "headersToAdd must not be null");
|
||||
this.headersToAdd = headersToAdd;
|
||||
this.headersToAdd = (headersToAdd != null) ? headersToAdd : new HashMap<String, ValueHolder>();
|
||||
}
|
||||
|
||||
|
||||
public void setMessageProcessor(MessageProcessor messageProcessor) {
|
||||
this.messageProcessor = messageProcessor;
|
||||
}
|
||||
|
||||
public void setDefaultOverwrite(boolean defaultOverwrite) {
|
||||
this.defaultOverwrite = defaultOverwrite;
|
||||
}
|
||||
@@ -64,6 +79,7 @@ public class HeaderEnricher implements Transformer {
|
||||
public Message<?> transform(Message<?> message) {
|
||||
try {
|
||||
Map<String, Object> headerMap = new HashMap<String, Object>(message.getHeaders());
|
||||
this.addHeadersFromMessageProcessor(message, headerMap);
|
||||
for (Map.Entry<String, ValueHolder> entry : this.headersToAdd.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
ValueHolder valueHolder = entry.getValue();
|
||||
@@ -82,6 +98,28 @@ public class HeaderEnricher implements Transformer {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addHeadersFromMessageProcessor(Message<?> message, Map<String, Object> headerMap) {
|
||||
if (this.messageProcessor != null) {
|
||||
Object result = this.messageProcessor.processMessage(message);
|
||||
if (result instanceof Map) {
|
||||
Map resultMap = (Map) result;
|
||||
for (Object key : resultMap.keySet()) {
|
||||
if (key instanceof String) {
|
||||
if (this.defaultOverwrite || headerMap.get(key) == null) {
|
||||
headerMap.put((String) key, resultMap.get(key));
|
||||
}
|
||||
}
|
||||
else if (logger.isDebugEnabled()) {
|
||||
logger.debug("ignoring value for non-String key: " + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (logger.isDebugEnabled()) {
|
||||
logger.debug("expected a Map result from processor, but received: " + result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static interface ValueHolder {
|
||||
|
||||
|
||||
@@ -1261,6 +1261,28 @@
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string" />
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ref" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Reference to an Object to be invoked for header values.
|
||||
The 'method' attribute is required along with this.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="method" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Method to be invoked on the referenced Object as specified by the
|
||||
'ref' attribute. The method should return a Map with String-typed keys.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
Reference in New Issue
Block a user