INT-1659 exposed 'evaluate-as-node' attribute via the namespace, added tests

This commit is contained in:
Oleg Zhurakousky
2010-12-03 11:36:49 -05:00
parent 317d2cad7f
commit 928f38f315
4 changed files with 30 additions and 1 deletions

View File

@@ -23,6 +23,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractRouterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -46,6 +47,7 @@ public class XPathRouterParser extends AbstractRouterParser {
element.getNamespaceURI(), "xpath-expression");
Assert.isTrue(xPathExpressionNodes.getLength() <= 1, "At most one xpath-expression child may be specified.");
String xPathExpressionRef = element.getAttribute("xpath-expression-ref");
IntegrationNamespaceUtils.setValueIfAttributeDefined(xpathRouterBuilder, element, "evaluate-as-node");
boolean xPathExpressionChildPresent = (xPathExpressionNodes.getLength() == 1);
boolean xPathReferencePresent = StringUtils.hasText(xPathExpressionRef);
Assert.isTrue(xPathExpressionChildPresent ^ xPathReferencePresent,

View File

@@ -369,6 +369,18 @@
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="evaluate-as-node" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
By default XPath expressions are evaluated as NODESET type and then converted
to a List<String> of channel names, thus handling single channel scenarios as well as multiple.
However certain XPath expressions may evaluate as String type from the very
beginning (e.g., 'name(./node())' - which will return the name of the root node) thus resulting in
the exception if default evaluation type (NODESET) is used. This flag will allow you to manage the
evaluation type. It is TRUE by default, however if set to FALSE, the String evaluation type will be used.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="input-channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>

View File

@@ -265,5 +265,16 @@ public class XPathRouterParserTests {
assertNotNull(channelA.receive(10));
assertNotNull(channelB.receive(10));
}
@Test
public void testWithStringEvaluationType() throws Exception {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("XPathRouterTests-context.xml", this.getClass());
MessageChannel inputChannel = ac.getBean("xpathStringChannel", MessageChannel.class);
PollableChannel channelA = ac.getBean("channelA", PollableChannel.class);
Document doc = XmlTestUtil.getDocumentForString("<channelA/>");
GenericMessage<Document> docMessage = new GenericMessage<Document>(doc);
inputChannel.send(docMessage);
assertNotNull(channelA.receive(10));
}
}

View File

@@ -12,13 +12,17 @@
<int-xml:xpath-expression expression="/name"/>
</int-xml:xpath-router>
<int-xml:xpath-router id="xpathRouterAsString" input-channel="xpathStringChannel" evaluate-as-node="false">
<int-xml:xpath-expression expression="name(./node())"/>
</int-xml:xpath-router>
<int-xml:xpath-router id="xpathRouterWithMapping" input-channel="xpathRouterWithMappingChannel">
<int-xml:xpath-expression expression="/name"/>
<int-xml:mapping value="channelA" channel="channelB"/>
</int-xml:xpath-router>
<int-xml:xpath-router id="xpathRouterWithMappingMultiChannel" input-channel="multiChannelRouterChannel">
<int-xml:xpath-expression expression="/root/name"/>
<int-xml:xpath-expression expression="/root/name" />
<int-xml:mapping value="channelA" channel="channelA"/>
<int-xml:mapping value="channelB" channel="channelA"/>
</int-xml:xpath-router>