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**
This commit is contained in:
Artem Bilan
2019-01-29 12:03:34 -05:00
committed by Gary Russell
parent 5dc4b57bd8
commit 72aaf0b03f
2 changed files with 29 additions and 12 deletions

View File

@@ -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<TransformerFactory> transformerFactoryClass =
(Class<TransformerFactory>) 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);

View File

@@ -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;
}