INT-812: patch that catches IOException when determining wether the Resource can resolve to a systemId

This commit is contained in:
Iwein Fuld
2009-09-30 19:23:13 +00:00
parent d8bda324fb
commit a65d9c3ed2
4 changed files with 136 additions and 102 deletions

View File

@@ -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
*
* <p/>
* {@link String} payload in results in {@link String} payload out
*
* <p/>
* {@link Document} payload in {@link Document} payload out
*
* <p/>
* {@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.
*
* <p/>
* 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<Object, Object> {
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 <i>may</i> 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();
}
}

View File

@@ -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 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:template match=\"order\"><bob>test</bob></xsl:template></xsl:stylesheet>";

View File

@@ -0,0 +1,5 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="transform.xsl"/>
</xsl:stylesheet>

View File

@@ -0,0 +1,7 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="order">
<bob>test</bob>
</xsl:template>
</xsl:stylesheet>