Added the 'header-enricher' element to the core namespace (INT-489).

This commit is contained in:
Mark Fisher
2008-11-22 15:43:39 +00:00
parent d943af0e87
commit abb370b257
7 changed files with 179 additions and 29 deletions

View File

@@ -105,6 +105,7 @@ public class IntegrationNamespaceHandler implements NamespaceHandler {
registerBeanDefinitionParser("splitter", new SplitterParser());
registerBeanDefinitionParser("aggregator", new AggregatorParser());
registerBeanDefinitionParser("resequencer", new ResequencerParser());
registerBeanDefinitionParser("header-enricher", new StandardHeaderEnricherParser());
registerBeanDefinitionParser("inbound-channel-adapter", new MethodInvokingInboundChannelAdapterParser());
registerBeanDefinitionParser("outbound-channel-adapter", new MethodInvokingOutboundChannelAdapterParser());
registerBeanDefinitionParser("gateway", new GatewayParser());

View File

@@ -84,20 +84,18 @@ public class SimpleHeaderEnricherParser extends AbstractTransformerParser {
Node node = attributes.item(i);
String name = node.getNodeName();
if (this.isEligibleHeaderName(name)) {
if (this.referenceAttributes.contains(name)) {
headers.put(name, new RuntimeBeanReference(node.getNodeValue()));
}
else {
headers.put(name, node.getNodeValue());
Object value = (this.referenceAttributes.contains(name))
? new RuntimeBeanReference(node.getNodeValue())
: node.getNodeValue();
if (this.prefix != null) {
name = this.prefix + name;
}
headers.put(name, value);
}
}
this.postProcessHeaders(element, headers);
builder.addConstructorArgValue(headers);
builder.addPropertyValue("overwrite", this.shouldOverwrite(element));
if (this.prefix != null) {
builder.addPropertyValue("prefix", this.prefix);
}
}
/**

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2002-2008 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.config.xml;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.integration.core.MessageHeaders;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Parser for the <header-enricher> element within the core integration
* namespace. This is used for setting the <em>standard</em>, out-of-the-box
* configurable {@link MessageHeaders}, such as 'reply-channel', 'priority',
* and 'correlation-id'. It will also accept custom header values (or bean
* references) if provided as 'header' sub-elements.
*
* @author Mark Fisher
*/
public class StandardHeaderEnricherParser extends SimpleHeaderEnricherParser {
private static final String[] REFERENCE_ATTRIBUTES = new String[] {
"reply-channel", "error-channel"
};
public StandardHeaderEnricherParser() {
super(MessageHeaders.PREFIX, REFERENCE_ATTRIBUTES);
}
@Override
@SuppressWarnings("unchecked")
protected void postProcessHeaders(Element element, ManagedMap headers) {
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE && node.getLocalName().equals("header")) {
Element headerElement = (Element) node;
String name = headerElement.getAttribute("name");
String value = headerElement.getAttribute("value");
String ref = headerElement.getAttribute("ref");
boolean isValue = StringUtils.hasText(value);
boolean isRef = StringUtils.hasText(ref);
Assert.isTrue(isValue ^ isRef, "Exactly one of the 'value' or 'ref' attributes is required.");
if (isValue) {
headers.put(name, value);
}
else {
headers.put(name, new RuntimeBeanReference(ref));
}
}
}
}
}

View File

@@ -266,6 +266,14 @@
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="header-enricher">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="header" type="headerElementType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="headerEnricherAttributes"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="transformer" type="handlerType"/>
<xsd:element name="service-activator" type="handlerType"/>
<xsd:element name="splitter" type="handlerType"/>
@@ -387,6 +395,48 @@
</xsd:complexType>
</xsd:element>
<xsd:element name="header-enricher">
<xsd:annotation>
<xsd:documentation>
Defines a HeaderEnricher endpoint for values defined in the MessageHeaders.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="inputOutputEndpointType">
<xsd:sequence>
<xsd:element name="header" type="headerElementType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="headerEnricherAttributes"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="headerElementType">
<xsd:annotation>
<xsd:documentation>
Defines a Message Header value or ref.
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="ref" type="xsd:string"/>
<xsd:attribute name="value" type="xsd:string"/>
</xsd:complexType>
<xsd:attributeGroup name="headerEnricherAttributes">
<xsd:annotation>
<xsd:documentation>
Provides the names of the standard configurable MessageHeaders.
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="reply-channel" type="xsd:string"/>
<xsd:attribute name="error-channel" type="xsd:string"/>
<xsd:attribute name="correlation-id" type="xsd:string"/>
<xsd:attribute name="expiration-date" type="xsd:string"/>
<xsd:attribute name="priority" type="xsd:string"/>
</xsd:attributeGroup>
<xsd:element name="thread-pool-task-executor">
<xsd:complexType>
<xsd:annotation>

View File

@@ -22,8 +22,8 @@ import org.springframework.util.Assert;
/**
* A Transformer that adds statically configured header values to a Message.
* Accepts an optional 'prefix' String and a boolean that specifies whether
* values should be overwritten. By default, any existing header values for
* Accepts the boolean 'overwrite' property that specifies whether values
* should be overwritten. By default, any existing header values for
* a given key, will <em>not</em> be replaced.
*
* @author Mark Fisher
@@ -34,8 +34,6 @@ public class HeaderEnricher extends AbstractHeaderTransformer {
private volatile boolean overwrite;
private volatile String prefix;
/**
* Create a HeaderEnricher with the given map of headers.
@@ -50,17 +48,10 @@ public class HeaderEnricher extends AbstractHeaderTransformer {
this.overwrite = overwrite;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
@Override
protected final void transformHeaders(Map<String, Object> headers) {
for (Map.Entry<String, Object> entry : this.headersToAdd.entrySet()) {
String key = entry.getKey();
if (this.prefix != null) {
key = this.prefix + key;
}
if (this.overwrite || headers.get(key) == null) {
headers.put(key, entry.getValue());
}