Refactor/Standardize Router XSD Schema Attributes

- Add more documentation for schema elements in spring-integration-xml-2.1.xsd
  - Simplify Handling of Channel Resolution (Failures) for Routers
  - Fix PayloadTypeRouterTests
  - Update reference docs, XSD Schemas
  - Rename 'channel-resolution-required' to 'resolution-required'
  - Updated all tests accordingly
This commit is contained in:
Gunnar Hillert
2011-09-06 14:39:38 -04:00
committed by Mark Fisher
parent b55520369d
commit 2c023f6fd1
16 changed files with 1399 additions and 614 deletions

View File

@@ -342,98 +342,109 @@
</xsd:attribute>
</xsd:complexType>
<xsd:element name="xpath-router">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Defines an XPath router.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
<xsd:element name="mapping" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="value" type="xsd:string" />
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type
type="org.springframework.integration.core.MessageChannel" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="evaluate-as-string" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
By default XPath expressions are evaluated as NODESET type and then converted
to a List 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>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="xpath-expression-ref" type="xsd:string" use="optional">
<xsd:annotation>
<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="channel-resolver" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.ChannelResolver"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="resolution-required" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Specify whether this router should always be required to return at least one channel or name.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ignore-channel-name-resolution-failures" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Specify whether a failure to resolve a channel name returned by this router should be ignored.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="default-output-channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type
type="org.springframework.integration.core.MessageChannel" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<!-- XPath Router definition -->
<xsd:complexType name="commonXPathRouterType" abstract="true">
<xsd:complexContent>
<xsd:extension base="integration:abstractRouterType">
<xsd:attribute name="evaluate-as-string" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
By default XPath expressions are evaluated as NODESET type and then converted
to a List 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 'false' by default, however if
set to 'true', then String evaluation type will be used.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="xsd:boolean xsd:string" />
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="xpath-expression-ref" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
Reference to the XPathExpression instance to be
evaluated against the input Message's payload. Either
this or 'xpath-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:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="XPathRouterType">
<xsd:complexContent>
<xsd:extension base="commonXPathRouterType">
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
<xsd:element name="mapping" type="integration:mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
If the values returned by the Xpaxth Expression
do not represent the channel names itself, additional
mappings can be specified using the mapping sub-element.
For example if the '/request/responders' expression
results in two values 'responderA' and 'responderB'
but you don't want to couple the responder names
to channel names you may provide additional mappings
such as:
<int-xml:mapping value="responderA" channel="channelA"/>
<int-xml:mapping value="responderB" channel="channelB"/>
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attributeGroup ref="integration:topLevelRouterAttributeGroup"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="XPathRouterTypeChain">
<xsd:complexContent>
<xsd:extension base="commonXPathRouterType">
<xsd:sequence>
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
<xsd:element name="mapping" type="integration:mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
If the values returned by the Xpaxth Expression
do not represent the channel names itself, additional
mappings can be specified using the mapping sub-element.
For example if the '/request/responders' expression
results in two values 'responderA' and 'responderB'
but you don't want to couple the responder names
to channel names you may provide additional mappings
such as:
<int-xml:mapping value="responderA" channel="channelA"/>
<int-xml:mapping value="responderB" channel="channelB"/>
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="xpath-router" type="XPathRouterType"/>
<xsd:element name="xpath-selector">
<xsd:complexType>
@@ -468,12 +479,26 @@
</xsd:element>
<xsd:element name="xpath-expression">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines an XPath expression.
Internally XPath expressions will be evaluated as
NODESET type and converted to a List<String>
representing channel names. Typically such list
will contain a single channel name. However, based
on the result of an XPath Expression the XPath router
can also take on the characteristics of the
Recipient List Router if the XPath Expression
returns more then one value, thus resulting in
the List<String> containing more then one channel
name.
In that case Message will be sent to all channels
in the list.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Defines an XPath expression.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="beans:map" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>

View File

@@ -125,19 +125,6 @@ public class XPathRouterParserTests {
inputChannel.send(docMessage);
assertEquals("Wrong number of messages", 1, outputChannel.getQueueSize());
}
@Test
public void testSetChannelResolver() throws Exception {
StringBuffer contextBuffer = new StringBuffer("<si-xml:xpath-router id='router' channel-resolver='stubResolver' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
contextBuffer.append("<bean id='stubResolver' class='").append(StubChannelResolver.class.getName()).append("'/>");
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object resolver = accessor.getPropertyValue("channelResolver");
assertEquals("Wrong channel resolver ",StubChannelResolver.class, resolver.getClass());
}
@Test
public void testSetResolutionRequiredFalse() throws Exception {
@@ -163,32 +150,6 @@ public class XPathRouterParserTests {
assertEquals("Resolution required not set to true ", true, resolutionRequired);
}
@Test
public void testIgnoreChannelNameResolutionFailuresFalse() throws Exception {
StringBuffer contextBuffer = new StringBuffer(
"<si-xml:xpath-router id='router' ignore-channel-name-resolution-failures='false' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object ignoreChannelNameResolutionFailures = accessor.getPropertyValue("ignoreChannelNameResolutionFailures");
assertEquals("ignoreChannelNameResolutionFailures not set to false", false, ignoreChannelNameResolutionFailures);
}
@Test
public void testIgnoreChannelNameResolutionFailuresTrue() throws Exception {
StringBuffer contextBuffer = new StringBuffer(
"<si-xml:xpath-router id='router' ignore-channel-name-resolution-failures='true' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object ignoreChannelNameResolutionFailures = accessor.getPropertyValue("ignoreChannelNameResolutionFailures");
assertEquals("ignoreChannelNameResolutionFailures not set to true ", true, ignoreChannelNameResolutionFailures);
}
@Test
public void testSetDefaultOutputChannel() throws Exception {
StringBuffer contextBuffer = new StringBuffer("<si-xml:xpath-router id='router' default-output-channel='defaultOutput' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");