INT-3067 Xslt method=text StringResult coercion
Previously there was a need to add `result-type="StringResult"` to <int-xml:xslt-transformer> for xslt output `method='text'` in case payload was non-standard type (e.g. `File`), if we wanted to get result as text. * Add coercion to `StringResult` code, if `Transformer`'s property `method` is 'text' and there is no explicit `resultFactory` provided. * Add documentation to reference manual JIRA: https://jira.springsource.org/browse/INT-3067
This commit is contained in:
committed by
Gunnar Hillert
parent
d549734837
commit
41fe514469
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -25,9 +25,10 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility methods for the XML namespace.
|
||||
*
|
||||
*
|
||||
* @author Jonas Partner
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
abstract class XmlNamespaceUtils {
|
||||
|
||||
@@ -54,7 +55,7 @@ abstract class XmlNamespaceUtils {
|
||||
else if (resultType.equals(STRING_RESULT)) {
|
||||
builder.addPropertyValue("resultFactory", new StringResultFactory());
|
||||
}
|
||||
else {
|
||||
else if (resultType.equals(DOM_RESULT)) {
|
||||
builder.addPropertyValue("resultFactory", new DomResultFactory());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ import org.springframework.xml.transform.StringSource;
|
||||
* @author Jonas Partner
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class XsltPayloadTransformer extends AbstractTransformer {
|
||||
|
||||
@@ -93,6 +94,8 @@ public class XsltPayloadTransformer extends AbstractTransformer {
|
||||
|
||||
private volatile ResultFactory resultFactory = new DomResultFactory();
|
||||
|
||||
private volatile boolean resultFactoryExplicitlySet;
|
||||
|
||||
private volatile boolean alwaysUseSourceFactory = false;
|
||||
|
||||
private volatile boolean alwaysUseResultFactory = false;
|
||||
@@ -135,6 +138,7 @@ public class XsltPayloadTransformer extends AbstractTransformer {
|
||||
public void setResultFactory(ResultFactory resultFactory) {
|
||||
Assert.notNull(sourceFactory, "ResultFactory must not be null");
|
||||
this.resultFactory = resultFactory;
|
||||
this.resultFactoryExplicitlySet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,7 +218,13 @@ public class XsltPayloadTransformer extends AbstractTransformer {
|
||||
}
|
||||
|
||||
private Object transformSource(Source source, Object payload, Transformer transformer) throws TransformerException {
|
||||
Result result = this.resultFactory.createResult(payload);
|
||||
Result result;
|
||||
if (!this.resultFactoryExplicitlySet && "text".equals(transformer.getOutputProperties().getProperty("method"))) {
|
||||
result = new StringResult();
|
||||
}
|
||||
else {
|
||||
result = this.resultFactory.createResult(payload);
|
||||
}
|
||||
transformer.transform(source, result);
|
||||
if (this.resultTransformer != null) {
|
||||
return this.resultTransformer.transformResult(result);
|
||||
|
||||
@@ -53,6 +53,12 @@
|
||||
xsl-resource="classpath:org/springframework/integration/xml/transformer/transform-tostring.xsl">
|
||||
</int-xml:xslt-transformer>
|
||||
|
||||
<int-xml:xslt-transformer id="outputFileAsString"
|
||||
input-channel="outputFileAsStringChannel"
|
||||
output-channel="output" result-transformer="resultToStringTransformer"
|
||||
xsl-resource="classpath:org/springframework/integration/xml/transformer/transform-tostring.xsl">
|
||||
</int-xml:xslt-transformer>
|
||||
|
||||
<bean id="resultToStringTransformer" class="org.springframework.integration.xml.transformer.ResultToStringTransformer" />
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -28,6 +29,7 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
@@ -41,94 +43,103 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Jonas Partner
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class XsltTransformerTests {
|
||||
private String docAsString = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><order><orderItem>test</orderItem></order>";
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
@Autowired
|
||||
@Qualifier("output")
|
||||
private QueueChannel output;
|
||||
private String docAsString = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><order><orderItem>test</orderItem></order>";
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
@Autowired
|
||||
@Qualifier("output")
|
||||
private QueueChannel output;
|
||||
|
||||
@Test
|
||||
public void testParamHeadersWithStartWildCharacter() {
|
||||
MessageChannel input = applicationContext.getBean("paramHeadersWithStartWildCharacterChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
setHeader("testParam", "testParamValue").
|
||||
setHeader("testParam2", "FOO").
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
MessageHistory history = MessageHistory.read(resultMessage);
|
||||
assertNotNull(history);
|
||||
Properties componentHistoryRecord = TestUtils.locateComponentInHistory(history, "paramHeadersWithStartWildCharacter", 0);
|
||||
assertNotNull(componentHistoryRecord);
|
||||
assertEquals("xml:xslt-transformer", componentHistoryRecord.get("type"));
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("testParamValue"));
|
||||
assertFalse(((String) resultMessage.getPayload()).contains("FOO"));
|
||||
}
|
||||
@Test
|
||||
public void testParamHeadersWithStartWildCharacter() {
|
||||
MessageChannel input = applicationContext.getBean("paramHeadersWithStartWildCharacterChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
setHeader("testParam", "testParamValue").
|
||||
setHeader("testParam2", "FOO").
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
MessageHistory history = MessageHistory.read(resultMessage);
|
||||
assertNotNull(history);
|
||||
Properties componentHistoryRecord = TestUtils.locateComponentInHistory(history, "paramHeadersWithStartWildCharacter", 0);
|
||||
assertNotNull(componentHistoryRecord);
|
||||
assertEquals("xml:xslt-transformer", componentHistoryRecord.get("type"));
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("testParamValue"));
|
||||
assertFalse(((String) resultMessage.getPayload()).contains("FOO"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParamHeadersWithEndWildCharacter() {
|
||||
MessageChannel input = applicationContext.getBean("paramHeadersWithEndWildCharacterChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
setHeader("testParam", "testParamValue").
|
||||
setHeader("testParam2", "FOO").
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("testParamValue"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("FOO"));
|
||||
}
|
||||
@Test
|
||||
public void testParamHeadersWithEndWildCharacter() {
|
||||
MessageChannel input = applicationContext.getBean("paramHeadersWithEndWildCharacterChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
setHeader("testParam", "testParamValue").
|
||||
setHeader("testParam2", "FOO").
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("testParamValue"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("FOO"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParamHeadersWithIndividualParameters() {
|
||||
MessageChannel input = applicationContext.getBean("paramHeadersWithIndividualParametersChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
setHeader("testParam", "testParamValue").
|
||||
setHeader("testParam2", "FOO").
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("testParamValue"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("FOO"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("hello"));
|
||||
}
|
||||
@Test
|
||||
public void testParamHeadersWithIndividualParameters() {
|
||||
MessageChannel input = applicationContext.getBean("paramHeadersWithIndividualParametersChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
setHeader("testParam", "testParamValue").
|
||||
setHeader("testParam2", "FOO").
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("testParamValue"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("FOO"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParamHeadersCombo() {
|
||||
MessageChannel input = applicationContext.getBean("paramHeadersComboChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
setHeader("testParam", "testParamValue").
|
||||
setHeader("testParam2", "FOO").
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("testParamValue"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("FOO"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("hello"));
|
||||
}
|
||||
@Test
|
||||
public void testParamHeadersCombo() {
|
||||
MessageChannel input = applicationContext.getBean("paramHeadersComboChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
setHeader("testParam", "testParamValue").
|
||||
setHeader("testParam2", "FOO").
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("testParamValue"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("FOO"));
|
||||
assertTrue(((String) resultMessage.getPayload()).contains("hello"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void outputAsString() {
|
||||
MessageChannel input = applicationContext.getBean("outputAsStringChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
String stringPayload = (String)resultMessage.getPayload();
|
||||
assertEquals("Wrong content of payload", "hello world text",stringPayload.trim());
|
||||
}
|
||||
@Test
|
||||
public void outputAsString() {
|
||||
MessageChannel input = applicationContext.getBean("outputAsStringChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(this.docAsString).
|
||||
build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
String stringPayload = (String)resultMessage.getPayload();
|
||||
assertEquals("Wrong content of payload", "hello world text",stringPayload.trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt3067OutputFileAsString() throws IOException {
|
||||
MessageChannel input = applicationContext.getBean("outputFileAsStringChannel", MessageChannel.class);
|
||||
Message<?> message = MessageBuilder.withPayload(new ClassPathResource("org/springframework/integration/xml/transformer/xsl-text-file.xml").getFile()).build();
|
||||
input.send(message);
|
||||
Message<?> resultMessage = output.receive();
|
||||
assertEquals("Wrong payload type", String.class, resultMessage.getPayload().getClass());
|
||||
String stringPayload = (String) resultMessage.getPayload();
|
||||
assertEquals("Wrong content of payload", "hello world text", stringPayload.trim());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<order>
|
||||
<orderItem>test</orderItem>
|
||||
</order>
|
||||
@@ -727,6 +727,22 @@
|
||||
<classname>String</classname>, the resulting payload will be of type
|
||||
<classname><ulink url="http://docs.oracle.com/javase/6/docs/api/org/w3c/dom/Document.html">Document</ulink></classname>.
|
||||
</para>
|
||||
<para><emphasis>XsltPayloadTransformer and <xsl:output method="text"/></emphasis></para>
|
||||
<para><code><xsl:output method="text"/></code> tells the XSLT
|
||||
template to only produce text content from the input source.
|
||||
In this particuliar case there is no reason to have a
|
||||
<classname>DomResult</classname>. Therefore, the
|
||||
<classname><ulink url="http://static.springsource.org/spring-integration/api/org/springframework/integration/xml/transformer/XsltPayloadTransformer.html">XsltPayloadTransformer</ulink></classname>
|
||||
defaults to <classname>StringResult</classname> if the
|
||||
<ulink url="http://docs.oracle.com/javase/7/docs/api/javax/xml/transform/Transformer.html#getOutputProperties()">output property</ulink>
|
||||
called <code>method</code> of the underlying
|
||||
<classname>javax.xml.transform.Transformer</classname> returns <code>"text"</code>.
|
||||
This coercion is performed independent from the inbound payload type. Keep
|
||||
in mind that this <quote>smart</quote> behavior is only available, if the
|
||||
<code>result-type</code> or <code>result-factory</code> attributes
|
||||
aren't provided for the respective <code><int-xml:xslt-transformer></code>
|
||||
component.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section id="xml-xpath-transformer">
|
||||
|
||||
Reference in New Issue
Block a user