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:
committed by
Gary Russell
parent
4c6ffec6fe
commit
a283ad60fb
@@ -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<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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user