From a283ad60fb8f6983f2545c7d7b53091b93fe54d3 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 | 36 +++++++++++++------ .../XsltPayloadTransformerTests.java | 7 ++-- 2 files changed, 30 insertions(+), 13 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 24e9cb033c..1e2d1f5865 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 @@ -49,6 +49,7 @@ import org.springframework.integration.xml.source.SourceFactory; import org.springframework.messaging.Message; import org.springframework.messaging.MessagingException; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.PatternMatchUtils; import org.springframework.util.StringUtils; @@ -225,24 +226,39 @@ 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 (TransformerConfigurationException | IOException e) { + catch (ClassNotFoundException | TransformerConfigurationException | IOException e) { throw new IllegalStateException(e); } } } + 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 8983f89378..4802e5ee59 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 @@ -26,7 +26,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; @@ -161,10 +160,12 @@ public class XsltPayloadTransformerTests { @Test public void testXsltPayloadWithBadTransformerFactoryClassName() throws IOException { - XsltPayloadTransformer transformer = new XsltPayloadTransformer(getXslResourceThatOutputsText(), "foo.bar.Baz"); + XsltPayloadTransformer transformer = + new XsltPayloadTransformer(getXslResourceThatOutputsText(), "foo.bar.Baz"); transformer.setBeanFactory(Mockito.mock(BeanFactory.class)); assertThatThrownBy(transformer::afterPropertiesSet) - .isExactlyInstanceOf(TransformerFactoryConfigurationError.class); + .isExactlyInstanceOf(IllegalStateException.class) + .hasCauseExactlyInstanceOf(ClassNotFoundException.class); } @Test