From 72aaf0b03f013c85b4b2c6261f5377ca92c86b23 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Tue, 29 Jan 2019 12:03:34 -0500 Subject: [PATCH] GH-2723: Handle unsupported XML properties Fixes spring-projects/spring-integration#2723 Not all XML components support all the configuration properties. For example Saxon HE doesn't support `XMLConstants.ACCESS_EXTERNAL_DTD` and end up with an exception like: `IllegalArgumentException: Unknown configuration property http://javax.xml.XMLConstants/property/accessExternalDTD` * Change `XsltPayloadTransformer` to re-use `TransformerFactoryUtils` from spring-ws as a centralized source of `TransformerFactory` configuration. * Wrap `XMLConstants.ACCESS_EXTERNAL_STYLESHEET` to the `try..catch` and log INFO about not supported property **Cherry-pick to 5.0.x & 4.3.x** --- .../transformer/XsltPayloadTransformer.java | 37 ++++++++++++++----- .../XsltPayloadTransformerTests.java | 4 +- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java index 741858fc74..bf49898320 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java @@ -240,19 +240,13 @@ public class XsltPayloadTransformer extends AbstractXmlTransformer implements Be super.onInit(); this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory()); if (this.templates == null) { - TransformerFactory transformerFactory; - if (this.transformerFactoryClassName != null) { - transformerFactory = TransformerFactory.newInstance(this.transformerFactoryClassName, - this.classLoader); - } - else { - transformerFactory = TransformerFactoryUtils.newInstance(); - } - transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "file,jar:file"); try { + TransformerFactory transformerFactory = createTransformerFactory(); this.templates = transformerFactory.newTemplates(createStreamSourceOnResource(this.xslResource)); } + catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } catch (TransformerConfigurationException e) { throw new IllegalStateException(e); } @@ -262,6 +256,29 @@ public class XsltPayloadTransformer extends AbstractXmlTransformer implements Be } } + private TransformerFactory createTransformerFactory() throws ClassNotFoundException { + TransformerFactory transformerFactory; + if (this.transformerFactoryClassName != null) { + @SuppressWarnings("unchecked") + Class transformerFactoryClass = + (Class) ClassUtils.forName(this.transformerFactoryClassName, this.classLoader); + transformerFactory = TransformerFactoryUtils.newInstance(transformerFactoryClass); + } + else { + transformerFactory = TransformerFactoryUtils.newInstance(); + } + try { + transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "file,jar:file"); + } + catch (IllegalArgumentException ex) { + if (logger.isInfoEnabled()) { + logger.info("The '" + XMLConstants.ACCESS_EXTERNAL_STYLESHEET + "' property is not supported by " + + transformerFactory.getClass().getCanonicalName()); + } + } + return transformerFactory; + } + @Override protected Object doTransform(Message message) throws Exception { Transformer transformer = buildTransformer(message); diff --git a/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTests.java b/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTests.java index 704f554f75..1d644e8204 100644 --- a/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTests.java +++ b/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTests.java @@ -27,7 +27,6 @@ import javax.xml.transform.Result; import javax.xml.transform.Templates; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMResult; import org.junit.Before; @@ -148,7 +147,7 @@ public class XsltPayloadTransformerTests { transformed); } - @Test(expected = TransformerFactoryConfigurationError.class) + @Test(expected = IllegalStateException.class) public void testXsltPayloadWithBadTransformerFactoryClassname() throws Exception { transformer = new XsltPayloadTransformer(getXslResourceThatOutputsText(), "foo.bar.Baz"); transformer.setBeanFactory(Mockito.mock(BeanFactory.class)); @@ -249,6 +248,7 @@ public class XsltPayloadTransformerTests { this.objectToReturn = objectToReturn; } + @Override public Object transformResult(Result result) { return objectToReturn; }