INT-1156 completed namespace support for XPath Transformer

This commit is contained in:
Mark Fisher
2010-06-10 18:13:20 +00:00
parent ad8a45fec3
commit 070ae5ee96
6 changed files with 207 additions and 23 deletions

View File

@@ -41,9 +41,19 @@ public class XPathTransformerParser extends AbstractTransformerParser {
@Override
protected void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String expression = element.getAttribute("expression");
Assert.isTrue(StringUtils.hasText(expression), "The 'expression' attribute is required.");
builder.addConstructorArgValue(expression);
String expressionRef = element.getAttribute("expression-ref");
boolean hasRef = StringUtils.hasText(expressionRef);
Assert.isTrue(hasRef ^ StringUtils.hasText(expression),
"Exactly one of the 'expression' or 'expression-ref' attributes is required.");
if (hasRef) {
builder.addConstructorArgReference(expressionRef);
}
else {
builder.addConstructorArgValue(expression);
}
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "evaluation-type");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "node-mapper");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "converter");
}
}

View File

@@ -16,9 +16,6 @@
package org.springframework.integration.xml.transformer;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Node;
import org.springframework.integration.core.Message;
@@ -34,6 +31,13 @@ import org.springframework.xml.xpath.XPathExpressionFactory;
/**
* Transformer implementation that evaluates an XPath expression against the inbound
* Message payload and returns a Message whose payload is the result of that evaluation.
* Prior to evaluation, the payload may be converted by the configured {@link XmlPayloadConverter}
* instance. The default converter type is {@link DefaultXmlPayloadConverter}.
* <p>
* The evaluation result type will depend on either the enumeration value provided to
* {@link #setEvaluationType(XPathEvaluationType)} or the presence of a {@link NodeMapper},
* which takes precedence. If no {@link NodeMapper} or evaluation type is configured explicitly,
* the default evaluation type is {@link XPathEvaluationType#STRING_RESULT}.
*
* @author Mark Fisher
* @since 2.0
@@ -49,18 +53,21 @@ public class XPathTransformer extends AbstractTransformer {
private volatile NodeMapper nodeMapper;
/**
* Create an {@link XPathTransformer} that will create an XPath expression from the given String
* to be evaluated against converted inbound Message payloads.
*/
public XPathTransformer(String expression) {
this.xpathExpression = XPathExpressionFactory.createXPathExpression(expression);
}
public XPathTransformer(String expression, Map<String, String> namespaces) {
this.xpathExpression = XPathExpressionFactory.createXPathExpression(expression, namespaces);
}
public XPathTransformer(String expression, String prefix, String namespace) {
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put(prefix, namespace);
this.xpathExpression = XPathExpressionFactory.createXPathExpression(expression, namespaces);
/**
* Create an {@link XPathTransformer} that will evaluate the given {@link XPathExpression}
* against converted inbound Message payloads.
*/
public XPathTransformer(XPathExpression expression) {
Assert.notNull(expression, "expression must not be null");
this.xpathExpression = expression;
}
@@ -68,16 +75,16 @@ public class XPathTransformer extends AbstractTransformer {
* Specify the expected {@link XPathEvaluationType}. The default is {@link XPathEvaluationType#STRING_RESULT}.
*/
public void setEvaluationType(XPathEvaluationType evaluationType) {
Assert.notNull(evaluationType, "evaluationType must not be null.");
this.evaluationType = evaluationType;
}
/**
* Set a {@link NodeMapper} to use for generating the result object.
* This will also set the evaluationType to <code>null</code> since
* the actual type determination is a responsibility of the NodeMapper.
* Set a {@link NodeMapper} to use for generating the result object. By default the NodeMapper is null,
* but if explicitly set, type determination is the responsibility of the NodeMapper, taking precedence
* over any configured evaluationType.
*/
public void setNodeMapper(NodeMapper nodeMapper) {
this.evaluationType = null;
this.nodeMapper = nodeMapper;
}
@@ -93,8 +100,7 @@ public class XPathTransformer extends AbstractTransformer {
protected Object doTransform(Message<?> message) throws Exception {
Node node = this.converter.convertToNode(message.getPayload());
Object result = null;
if (evaluationType == null) {
Assert.notNull(this.nodeMapper, "NodeMapper required if evaluationType is null.");
if (this.nodeMapper != null) {
result = this.xpathExpression.evaluateAsObject(node, this.nodeMapper);
}
else {

View File

@@ -166,13 +166,27 @@
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="inputOutputEndpoint">
<xsd:attribute name="expression" type="xsd:string" use="required">
<xsd:attribute name="expression" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
The XPath expression to be evaluated against the input Message's payload.
The XPath expression string to be evaluated against the input Message's payload.
Either this or 'expression-ref' must be provided, but not both.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expression-ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Reference to the XPathExpression instance to be evaluated against the input Message's payload.
Either this or 'expression' must be provided, but not both.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.xml.xpath.XPathExpression"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="evaluation-type" default="STRING_RESULT">
<xsd:annotation>
<xsd:documentation>
@@ -182,13 +196,39 @@
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="BOOLEAN_RESULT"/>
<xsd:enumeration value="STRING_RESULT"/>
<xsd:enumeration value="NUMBER_RESULT"/>
<xsd:enumeration value="NODE_RESULT"/>
<xsd:enumeration value="NODE_LIST_RESULT"/>
<xsd:enumeration value="NUMBER_RESULT"/>
<xsd:enumeration value="STRING_RESULT"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="node-mapper">
<xsd:annotation>
<xsd:documentation>
Reference to a NodeMapper. If this is provided, the 'evaluation-type' will be ignored. Instead, the
org.springframework.xml.xpath.XPathExpression's evaluateAsObject(Node node, NodeMapper nodeMapper)
method will be invoked.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.xml.xpath.NodeMapper"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="converter">
<xsd:annotation>
<xsd:documentation>
Specify the XmlPayloadConverter to use when converting a Message payload prior to XPath evaluation.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.xml.XmlPayloadConverter"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>