Merge pull request #80 from markfisher/INT-2124
add support for 'converter' on <xpath-router>
This commit is contained in:
@@ -295,8 +295,14 @@
|
||||
</int-xml:xpath-router>
|
||||
]]></programlisting>
|
||||
</para>
|
||||
|
||||
|
||||
|
||||
<para>The XPath Router does support custom implementations of the XmlPayloadConverter strategy, and when configuring
|
||||
an 'xpath-router' element in XML, a reference to such an implementation may be provided via the 'converter' attribute.
|
||||
However, the DefaultXmlPayloadConverter is used if this reference is not provided, and it
|
||||
should be sufficient in most cases since it can convert from Node, Document, Source,
|
||||
File, and String typed payloads. If you need to extend beyond the capabilities of
|
||||
that default implementation, then an upstream Transformer is probably a better option
|
||||
than providing a reference to a custom implementation of this strategy here.</para>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -395,7 +401,7 @@
|
||||
<emphasis>XML Payload Converter</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
You can also use implementation of the <classname>org.springframework.integration.xml.XmlPayloadConverter</classname> to
|
||||
You can also use an implementation of the <classname>org.springframework.integration.xml.XmlPayloadConverter</classname> to
|
||||
provide more granular transformation:
|
||||
<programlisting language="xml"><![CDATA[<int-xml:xpath-transformer input-channel="customConverterInput" xpath-expression="/test/@type"
|
||||
converter="testXmlPayloadConverter" output-channel="output"/>
|
||||
@@ -421,6 +427,12 @@
|
||||
}
|
||||
}]]></programlisting>
|
||||
</para>
|
||||
<para>The DefaultXmlPayloadConverter is used if this reference is not provided, and it
|
||||
should be sufficient in most cases since it can convert from Node, Document, Source,
|
||||
File, and String typed payloads. If you need to extend beyond the capabilities of
|
||||
that default implementation, then an upstream Transformer is probably a better option
|
||||
than providing a reference to a custom implementation of this strategy here.</para>
|
||||
|
||||
<para>
|
||||
<emphasis>Combination of SpEL and XPath expressions</emphasis>
|
||||
</para>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -60,6 +60,7 @@ public class XPathRouterParser extends AbstractRouterParser {
|
||||
else {
|
||||
xpathRouterBuilder.addConstructorArgReference(xPathExpressionRef);
|
||||
}
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(xpathRouterBuilder, element, "converter");
|
||||
return xpathRouterBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -225,6 +225,11 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify the XmlPayloadConverter to use when converting a Message payload prior to XPath evaluation.
|
||||
The DefaultXmlPayloadConverter is used if this reference is not provided, and it
|
||||
should be sufficient in most cases since it can convert from Node, Document, Source,
|
||||
File, and String typed payloads. If you need to extend beyond the capabilities of
|
||||
that default implementation, then an upstream Transformer is probably a better option
|
||||
than providing a reference to a custom implementation of this strategy here.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
@@ -399,6 +404,23 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="converter" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify the Converter to use when converting payloads prior to XPath evaluation.
|
||||
The DefaultXmlPayloadConverter is used if this reference is not provided, and it
|
||||
should be sufficient in most cases since it can convert from Node, Document, Source,
|
||||
File, and String typed payloads. If you need to extend beyond the capabilities of
|
||||
that default implementation, then an upstream Transformer is probably a better option
|
||||
than providing a reference to a custom implementation of this strategy here.
|
||||
</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:attribute name="channel-resolver" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
|
||||
@@ -225,6 +225,11 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify the XmlPayloadConverter to use when converting a Message payload prior to XPath evaluation.
|
||||
The DefaultXmlPayloadConverter is used if this reference is not provided, and it
|
||||
should be sufficient in most cases since it can convert from Node, Document, Source,
|
||||
File, and String typed payloads. If you need to extend beyond the capabilities of
|
||||
that default implementation, then an upstream Transformer is probably a better option
|
||||
than providing a reference to a custom implementation of this strategy here.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
@@ -411,6 +416,23 @@
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="integration:topLevelRouterAttributeGroup"/>
|
||||
<xsd:attribute name="converter" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify the Converter to use when converting payloads prior to XPath evaluation.
|
||||
The DefaultXmlPayloadConverter is used if this reference is not provided, and it
|
||||
should be sufficient in most cases since it can convert from Node, Document, Source,
|
||||
File, and String typed payloads. If you need to extend beyond the capabilities of
|
||||
that default implementation, then an upstream Transformer is probably a better option
|
||||
than providing a reference to a custom implementation of this strategy here.
|
||||
</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>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -20,14 +20,18 @@ import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
@@ -36,9 +40,9 @@ import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.router.AbstractMessageRouter;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.xml.DefaultXmlPayloadConverter;
|
||||
import org.springframework.integration.xml.util.XmlTestUtil;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
* @author Jonas Partner
|
||||
@@ -235,7 +239,31 @@ public class XPathRouterParserTests {
|
||||
GenericMessage<Document> docMessage = new GenericMessage<Document>(doc);
|
||||
inputChannel.send(docMessage);
|
||||
assertNotNull(channelA.receive(10));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithCustomXmlPayloadConverter() throws Exception {
|
||||
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("XPathRouterTests-context.xml", this.getClass());
|
||||
MessageChannel inputChannel = ac.getBean("customConverterChannel", MessageChannel.class);
|
||||
PollableChannel channelZ = ac.getBean("channelZ", PollableChannel.class);
|
||||
GenericMessage<String> message = new GenericMessage<String>("<name>channelA</name>");
|
||||
inputChannel.send(message);
|
||||
Message<?> result = channelZ.receive(0);
|
||||
assertNotNull(result);
|
||||
assertEquals("<name>channelA</name>", result.getPayload());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class TestXmlPayloadConverter extends DefaultXmlPayloadConverter {
|
||||
|
||||
@Override
|
||||
public Document convertToDocument(Object object) {
|
||||
if (object instanceof String) {
|
||||
object = ((String) object).replace("A", "Z");
|
||||
}
|
||||
return super.convertToDocument(object);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-xml="http://www.springframework.org/schema/integration/xml"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
|
||||
http://www.springframework.org/schema/integration/xml http://www.springframework.org/schema/integration/xml/spring-integration-xml-2.0.xsd">
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
|
||||
http://www.springframework.org/schema/integration/xml http://www.springframework.org/schema/integration/xml/spring-integration-xml-2.1.xsd">
|
||||
|
||||
|
||||
<int-xml:xpath-router id="xpathRouterEmpty" input-channel="xpathRouterEmptyChannel">
|
||||
@@ -26,6 +26,10 @@
|
||||
<int-xml:mapping value="channelA" channel="channelA"/>
|
||||
<int-xml:mapping value="channelB" channel="channelA"/>
|
||||
</int-xml:xpath-router>
|
||||
|
||||
<int-xml:xpath-router id="xpathRouterWithCustomConverter" input-channel="customConverterChannel" evaluate-as-string="true" converter="testConverter">
|
||||
<int-xml:xpath-expression expression="/name"/>
|
||||
</int-xml:xpath-router>
|
||||
|
||||
<int:channel id="channelA">
|
||||
<int:queue/>
|
||||
@@ -35,4 +39,10 @@
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="channelZ">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<bean id="testConverter" class="org.springframework.integration.xml.config.XPathRouterParserTests$TestXmlPayloadConverter"/>
|
||||
|
||||
</beans>
|
||||
|
||||
Reference in New Issue
Block a user