diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java
index ba16447f90..a156c975d9 100644
--- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java
+++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java
@@ -39,146 +39,158 @@ import org.springframework.util.Assert;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
+import java.io.IOException;
+
/**
* Thread safe XSLT transformer implementation which returns a transformed {@link Source},
* {@link Document}, or {@link String}. If alwaysUseSourceResultFactories is
* false (default) the following logic occurs
- *
+ *
* {@link String} payload in results in {@link String} payload out
- *
+ *
* {@link Document} payload in {@link Document} payload out
- *
+ *
* {@link Source} payload in {@link Result} payload out, type will be determined
* by the {@link ResultFactory}, {@link DomResultFactory} by default. If an
* instance of {@link ResultTransformer} is registered this will be used to
* convert the result.
- *
+ *
* If alwaysUseSourceResultFactories is true then the ResultFactory and
* {@link SourceFactory} will be used to create the {@link Source} from the
* payload and the {@link Result} to pass into the transformer. An instance of
* {@link ResultTransformer} can also be provided to convert the Result prior to
* returning
- *
- *
+ *
* @author Jonas Partner
* @author Mark Fisher
*/
public class XsltPayloadTransformer extends AbstractPayloadTransformer {
- private final Templates templates;
+ private final Templates templates;
- private final ResultTransformer resultTransformer;
+ private final ResultTransformer resultTransformer;
- private volatile SourceFactory sourceFactory = new DomSourceFactory();
+ private volatile SourceFactory sourceFactory = new DomSourceFactory();
- private volatile ResultFactory resultFactory = new DomResultFactory();
+ private volatile ResultFactory resultFactory = new DomResultFactory();
- private volatile boolean alwaysUseSourceResultFactories = false;
+ private volatile boolean alwaysUseSourceResultFactories = false;
- public XsltPayloadTransformer(Templates templates) throws ParserConfigurationException {
- this(templates, null);
- }
+ public XsltPayloadTransformer(Templates templates) throws ParserConfigurationException {
+ this(templates, null);
+ }
- public XsltPayloadTransformer(Templates templates,
- ResultTransformer resultTransformer)
- throws ParserConfigurationException {
- this.templates = templates;
- this.resultTransformer = resultTransformer;
- }
+ public XsltPayloadTransformer(Templates templates,
+ ResultTransformer resultTransformer)
+ throws ParserConfigurationException {
+ this.templates = templates;
+ this.resultTransformer = resultTransformer;
+ }
- public XsltPayloadTransformer(Resource xslResource) throws Exception {
- this(TransformerFactory.newInstance().newTemplates(
- new StreamSource(xslResource.getInputStream())),null);
- }
+ public XsltPayloadTransformer(Resource xslResource) throws Exception {
+ this(TransformerFactory.newInstance().newTemplates(
+ createStreamSourceOnResource(xslResource)), null);
+ }
- public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer) throws Exception {
- this(TransformerFactory.newInstance().newTemplates(
- new StreamSource(xslResource.getInputStream())),resultTransformer);
- }
+ public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer) throws Exception {
+ this(TransformerFactory.newInstance().newTemplates(
+ createStreamSourceOnResource(xslResource)), resultTransformer);
+ }
+
+ /**
+ * Compensate for the fact that a Resource may not be a File or even addressable through a URI.
+ * If it is, we want the created StreamSource to read other resources relative to the provided one, if it
+ * isn't, it loads from the default path.
+ */
+ private static StreamSource createStreamSourceOnResource(Resource xslResource) throws IOException {
+ try {
+ String systemId = xslResource.getURI().toString();
+ return new StreamSource(xslResource.getInputStream(), systemId);
+ } catch (IOException e) {
+ return new StreamSource(xslResource.getInputStream());
+ }
+ }
- /**
- * @param sourceFactory
- */
- public void setSourceFactory(SourceFactory sourceFactory) {
- Assert.notNull(sourceFactory, "SourceFactory can not be null");
- this.sourceFactory = sourceFactory;
- }
+ /**
+ * @param sourceFactory
+ */
+ public void setSourceFactory(SourceFactory sourceFactory) {
+ Assert.notNull(sourceFactory, "SourceFactory can not be null");
+ this.sourceFactory = sourceFactory;
+ }
- /**
- * @param resultFactory
- */
- public void setResultFactory(ResultFactory resultFactory) {
- Assert.notNull(sourceFactory, "ResultFactory can not be null");
- this.resultFactory = resultFactory;
- }
+ /**
+ * @param resultFactory
+ */
+ public void setResultFactory(ResultFactory resultFactory) {
+ Assert.notNull(sourceFactory, "ResultFactory can not be null");
+ this.resultFactory = resultFactory;
+ }
- /**
- * Forces use of {@link ResultFactory} and {@link SourceFactory} even for
- * directly supported payloads such as {@link String} and {@link Document}
- *
- * @param alwaysUserSourceResultFactories
- */
- public void setAlwaysUseSourceResultFactories(
- boolean alwaysUserSourceResultFactories) {
- this.alwaysUseSourceResultFactories = alwaysUserSourceResultFactories;
- }
+ /**
+ * Forces use of {@link ResultFactory} and {@link SourceFactory} even for
+ * directly supported payloads such as {@link String} and {@link Document}
+ *
+ * @param alwaysUserSourceResultFactories
+ *
+ */
+ public void setAlwaysUseSourceResultFactories(
+ boolean alwaysUserSourceResultFactories) {
+ this.alwaysUseSourceResultFactories = alwaysUserSourceResultFactories;
+ }
- @Override
- public Object transformPayload(Object payload) throws TransformerException {
- Object transformedPayload = null;
- if (this.alwaysUseSourceResultFactories) {
- transformedPayload = transformUsingFactories(payload);
- }
- else if (payload instanceof String) {
- transformedPayload = transformString((String) payload);
- }
- else if (payload instanceof Document) {
- transformedPayload = transformDocument((Document) payload);
- }
- else if (payload instanceof Source) {
- transformedPayload = transformSource((Source) payload, payload);
- }
- else {
- // fall back to trying factories
- transformedPayload = transformUsingFactories(payload);
- }
- return transformedPayload;
- }
+ @Override
+ public Object transformPayload(Object payload) throws TransformerException {
+ Object transformedPayload = null;
+ if (this.alwaysUseSourceResultFactories) {
+ transformedPayload = transformUsingFactories(payload);
+ } else if (payload instanceof String) {
+ transformedPayload = transformString((String) payload);
+ } else if (payload instanceof Document) {
+ transformedPayload = transformDocument((Document) payload);
+ } else if (payload instanceof Source) {
+ transformedPayload = transformSource((Source) payload, payload);
+ } else {
+ // fall back to trying factories
+ transformedPayload = transformUsingFactories(payload);
+ }
+ return transformedPayload;
+ }
- protected Object transformUsingFactories(Object payload) throws TransformerException {
- Source source = sourceFactory.createSource(payload);
- return transformSource(source, payload);
- }
+ protected Object transformUsingFactories(Object payload) throws TransformerException {
+ Source source = sourceFactory.createSource(payload);
+ return transformSource(source, payload);
+ }
- protected Object transformSource(Source source, Object payload) throws TransformerException {
- Result result = resultFactory.createResult(payload);
- this.templates.newTransformer().transform(source, result);
+ protected Object transformSource(Source source, Object payload) throws TransformerException {
+ Result result = resultFactory.createResult(payload);
+ this.templates.newTransformer().transform(source, result);
- if (resultTransformer != null) {
- return resultTransformer.transformResult(result);
- }
- return result;
- }
+ if (resultTransformer != null) {
+ return resultTransformer.transformResult(result);
+ }
+ return result;
+ }
- protected String transformString(String stringPayload) throws TransformerException {
- StringResult result = new StringResult();
- this.templates.newTransformer().transform(
- new StringSource(stringPayload), result);
- return result.toString();
- }
+ protected String transformString(String stringPayload) throws TransformerException {
+ StringResult result = new StringResult();
+ this.templates.newTransformer().transform(
+ new StringSource(stringPayload), result);
+ return result.toString();
+ }
- protected Document transformDocument(Document documentPayload) throws TransformerException {
- DOMSource source = new DOMSource(documentPayload);
- Result result = resultFactory.createResult(documentPayload);
- if (!DOMResult.class.isAssignableFrom(result.getClass())) {
- throw new MessagingException(
- "Document to Document conversion requires a DOMResult-producing ResultFactory implementation");
- }
- DOMResult domResult = (DOMResult) result;
- this.templates.newTransformer().transform(source, domResult);
- return (Document) domResult.getNode();
- }
+ protected Document transformDocument(Document documentPayload) throws TransformerException {
+ DOMSource source = new DOMSource(documentPayload);
+ Result result = resultFactory.createResult(documentPayload);
+ if (!DOMResult.class.isAssignableFrom(result.getClass())) {
+ throw new MessagingException(
+ "Document to Document conversion requires a DOMResult-producing ResultFactory implementation");
+ }
+ DOMResult domResult = (DOMResult) result;
+ this.templates.newTransformer().transform(source, domResult);
+ return (Document) domResult.getNode();
+ }
}
diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTests.java
index 96407d09e9..7fe01c0977 100644
--- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTests.java
+++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTests.java
@@ -26,13 +26,16 @@ import javax.xml.transform.dom.DOMResult;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertThat;
import org.w3c.dom.Document;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
+import org.springframework.core.io.ClassPathResource;
import org.springframework.integration.core.MessagingException;
import org.springframework.integration.xml.util.XmlTestUtil;
import org.springframework.xml.transform.StringSource;
+import static org.hamcrest.CoreMatchers.is;
/**
* @author Jonas Partner
@@ -113,6 +116,13 @@ public class XsltPayloadTransformerTests {
transformer.transformPayload(new Long(12));
}
+ @Test
+ public void testXsltWithImports() throws Exception {
+ Resource resource = new ClassPathResource("transform-with-import.xsl", this.getClass());
+ transformer = new XsltPayloadTransformer(resource);
+ assertThat(transformer.transformString(docAsString), is(outputAsString));
+ }
+
private Resource getXslResource() throws Exception {
String xsl = "test ";
diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/transform-with-import.xsl b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/transform-with-import.xsl
new file mode 100644
index 0000000000..1500b7a419
--- /dev/null
+++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/transform-with-import.xsl
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/transform.xsl b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/transform.xsl
new file mode 100644
index 0000000000..c81165b217
--- /dev/null
+++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/transform.xsl
@@ -0,0 +1,7 @@
+
+
+
+ test
+
+
+