diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XsltPayloadTransformerParser.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XsltPayloadTransformerParser.java index f6307097af..b5c3a87bfa 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XsltPayloadTransformerParser.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XsltPayloadTransformerParser.java @@ -62,9 +62,6 @@ public class XsltPayloadTransformerParser extends AbstractTransformerParser { else if (StringUtils.hasText(xslTemplates)) { builder.addConstructorArgReference(xslTemplates); } - if (StringUtils.hasText(transformerFactoryClass)) { - builder.addConstructorArgValue(transformerFactoryClass); - } XmlNamespaceUtils.configureResultFactory(builder, resultType, resultFactory); boolean resultFactorySpecified = StringUtils.hasText(resultFactory) || StringUtils.hasText(resultType); if(resultFactorySpecified){ @@ -73,6 +70,9 @@ public class XsltPayloadTransformerParser extends AbstractTransformerParser { if (StringUtils.hasText(resultTransformer)) { builder.addConstructorArgReference(resultTransformer); } + if (StringUtils.hasText(transformerFactoryClass)) { + builder.addConstructorArgValue(transformerFactoryClass); + } List xslParameterElements = DomUtils.getChildElementsByTagName(element, "xslt-param"); if (!CollectionUtils.isEmpty(xslParameterElements)) { Map xslParameterMappings = new ManagedMap(); 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 149911bbed..e79a01c2e2 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 @@ -19,7 +19,6 @@ package org.springframework.integration.xml.transformer; import java.io.IOException; import java.util.Map; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Templates; @@ -30,10 +29,9 @@ import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; +import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.core.io.Resource; import org.springframework.expression.Expression; import org.springframework.expression.spel.support.StandardEvaluationContext; @@ -47,7 +45,6 @@ import org.springframework.integration.xml.result.ResultFactory; import org.springframework.integration.xml.source.DomSourceFactory; import org.springframework.integration.xml.source.SourceFactory; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.PatternMatchUtils; import org.springframework.xml.transform.StringResult; @@ -78,19 +75,22 @@ import org.springframework.xml.transform.StringSource; * @author Oleg Zhurakousky * @author Artem Bilan * @author Mike Bazos + * @author Gary Russell */ -public class XsltPayloadTransformer extends AbstractTransformer { +public class XsltPayloadTransformer extends AbstractTransformer implements BeanClassLoaderAware { - private static final Log logger = LogFactory.getLog(XsltPayloadTransformer.class); + private final ResultTransformer resultTransformer; - private final Templates templates; + private volatile Resource xslResource; + + private volatile Templates templates; + + private String transformerFactoryClassName; private volatile StandardEvaluationContext evaluationContext; private Map xslParameterMappings; - private final ResultTransformer resultTransformer; - private volatile SourceFactory sourceFactory = new DomSourceFactory(); private volatile ResultFactory resultFactory = new DomResultFactory(); @@ -103,28 +103,38 @@ public class XsltPayloadTransformer extends AbstractTransformer { private volatile String[] xsltParamHeaders; + private ClassLoader classLoader; - public XsltPayloadTransformer(Templates templates) throws ParserConfigurationException { + + public XsltPayloadTransformer(Templates templates) { this(templates, null); } - public XsltPayloadTransformer(Resource xslResource) throws Exception { + public XsltPayloadTransformer(Resource xslResource) { this(xslResource, null, null); } - public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer) throws Exception { + public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer) { this(xslResource, resultTransformer, null); } - - public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer, String transformerFactoryClass) throws Exception { - this(getTransformerFactory(transformerFactoryClass).newTemplates(createStreamSourceOnResource(xslResource)), resultTransformer); + + public XsltPayloadTransformer(Resource xslResource, String transformerFactoryClassName) { + Assert.notNull(xslResource, "'xslResource' must not be null."); + Assert.hasText(transformerFactoryClassName, "'transformerFactoryClassName' must not be empty String."); + this.xslResource = xslResource; + this.transformerFactoryClassName = transformerFactoryClassName; + this.resultTransformer = null; } - public XsltPayloadTransformer(Resource xslResource, String transformerFactoryClass) throws Exception { - this(getTransformerFactory(transformerFactoryClass).newTemplates(createStreamSourceOnResource(xslResource)), null); - } + public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer, String transformerFactoryClassName) { + Assert.notNull(xslResource, "'xslResource' must not be null."); + this.xslResource = xslResource; + this.resultTransformer = resultTransformer; + this.transformerFactoryClassName = transformerFactoryClassName; + } - public XsltPayloadTransformer(Templates templates, ResultTransformer resultTransformer) throws ParserConfigurationException { + public XsltPayloadTransformer(Templates templates, ResultTransformer resultTransformer) { + Assert.notNull(templates, "'templates' must not be null."); this.templates = templates; this.resultTransformer = resultTransformer; } @@ -168,16 +178,32 @@ public class XsltPayloadTransformer extends AbstractTransformer { this.xsltParamHeaders = xsltParamHeaders; } + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + Assert.notNull(classLoader, "'beanClassLoader' must not be null."); + this.classLoader = classLoader; + } + + @Override public String getComponentType() { return "xml:xslt-transformer"; } - @Override protected void onInit() throws Exception { super.onInit(); this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory()); + if (this.templates == null) { + TransformerFactory transformerFactory; + if (this.transformerFactoryClassName != null) { + transformerFactory = TransformerFactory.newInstance(this.transformerFactoryClassName, this.classLoader); + } + else { + transformerFactory = TransformerFactory.newInstance(); + } + this.templates = transformerFactory.newTemplates(createStreamSourceOnResource(this.xslResource)); + } } @Override @@ -276,6 +302,7 @@ public class XsltPayloadTransformer extends AbstractTransformer { return (Document) domResult.getNode(); } + private Transformer buildTransformer(Message message) throws TransformerException { // process individual mappings Transformer transformer = this.templates.newTransformer(); @@ -308,7 +335,6 @@ public class XsltPayloadTransformer extends AbstractTransformer { return transformer; } - /** * Compensate for the fact that a Resource may not be a File or even * addressable through a URI. If it is, we want the created StreamSource to @@ -324,21 +350,5 @@ public class XsltPayloadTransformer extends AbstractTransformer { return new StreamSource(xslResource.getInputStream()); } } - - private static TransformerFactory getTransformerFactory(String transformerFactoryImplClass) { - TransformerFactory transformerFactory = null; - - if (transformerFactoryImplClass == null || transformerFactoryImplClass.length() <= 0) { - transformerFactory = TransformerFactory.newInstance(); - } else if(ClassUtils.isPresent(transformerFactoryImplClass, ClassLoader.getSystemClassLoader())) { - transformerFactory = TransformerFactory.newInstance(transformerFactoryImplClass, ClassLoader.getSystemClassLoader()); - } else { - if (logger.isWarnEnabled()) { - logger.warn(String.format("Class [%s] was not found will default to [%s], please ensure [%s] is located on your class path", transformerFactoryImplClass, TransformerFactory.class, transformerFactoryImplClass)); - } - transformerFactory = TransformerFactory.newInstance(); - } - - return transformerFactory; - } + } diff --git a/spring-integration-xml/src/main/resources/org/springframework/integration/xml/config/spring-integration-xml-2.2.xsd b/spring-integration-xml/src/main/resources/org/springframework/integration/xml/config/spring-integration-xml-2.2.xsd index 61f37d1a3f..58c6ebff3a 100644 --- a/spring-integration-xml/src/main/resources/org/springframework/integration/xml/config/spring-integration-xml-2.2.xsd +++ b/spring-integration-xml/src/main/resources/org/springframework/integration/xml/config/spring-integration-xml-2.2.xsd @@ -237,19 +237,6 @@ - - - - - - - - - - diff --git a/spring-integration-xml/src/main/resources/org/springframework/integration/xml/config/spring-integration-xml-3.0.xsd b/spring-integration-xml/src/main/resources/org/springframework/integration/xml/config/spring-integration-xml-3.0.xsd index ae605e70ca..3ccf9a8344 100644 --- a/spring-integration-xml/src/main/resources/org/springframework/integration/xml/config/spring-integration-xml-3.0.xsd +++ b/spring-integration-xml/src/main/resources/org/springframework/integration/xml/config/spring-integration-xml-3.0.xsd @@ -237,6 +237,21 @@ + + + + + + + + + + + + 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 20c93aedd9..460db25ea7 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 @@ -16,16 +16,19 @@ package org.springframework.integration.xml.transformer; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import javax.xml.transform.Result; import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMResult; import org.junit.Before; import org.junit.Test; +import org.w3c.dom.Document; + import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; @@ -36,7 +39,6 @@ import org.springframework.integration.xml.result.StringResultFactory; import org.springframework.integration.xml.util.XmlTestUtil; import org.springframework.xml.transform.StringResult; import org.springframework.xml.transform.StringSource; -import org.w3c.dom.Document; /** @@ -56,6 +58,7 @@ public class XsltPayloadTransformerTests { @Before public void setUp() throws Exception { transformer = new XsltPayloadTransformer(getXslResource()); + transformer.afterPropertiesSet(); } @Test @@ -108,32 +111,30 @@ public class XsltPayloadTransformerTests { Integer returnValue = new Integer(13); transformer = new XsltPayloadTransformer(getXslResource(), new StubResultTransformer(returnValue)); + transformer.afterPropertiesSet(); Object transformed = transformer .doTransform(buildMessage(new StringSource(docAsString))); assertEquals("Wrong value from result conversion", returnValue, transformed); } - + @Test public void testXsltPayloadWithTransformerFactoryClassname() throws Exception { Integer returnValue = new Integer(13); transformer = new XsltPayloadTransformer(getXslResource(), new StubResultTransformer(returnValue), "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); + transformer.afterPropertiesSet(); Object transformed = transformer .doTransform(buildMessage(new StringSource(docAsString))); assertEquals("Wrong value from result conversion", returnValue, transformed); } - - @Test + + @Test(expected = TransformerFactoryConfigurationError.class) public void testXsltPayloadWithBadTransformerFactoryClassname() throws Exception { - Integer returnValue = new Integer(13); - transformer = new XsltPayloadTransformer(getXslResource(), new StubResultTransformer(returnValue), - "foo.bar.Baz"); - Object transformed = transformer - .doTransform(buildMessage(new StringSource(docAsString))); - assertEquals("Wrong value from result conversion", returnValue, - transformed); + transformer = new XsltPayloadTransformer(getXslResource(), "foo.bar.Baz"); + transformer.afterPropertiesSet(); + transformer.doTransform(buildMessage(new StringSource(docAsString))); } @Test(expected = TransformerException.class) @@ -151,8 +152,9 @@ public class XsltPayloadTransformerTests { Resource resource = new ClassPathResource("transform-with-import.xsl", this.getClass()); transformer = new XsltPayloadTransformer(resource); + transformer.afterPropertiesSet(); assertEquals(transformer.doTransform(buildMessage(docAsString)), - outputAsString); + outputAsString); } @@ -163,6 +165,7 @@ public class XsltPayloadTransformerTests { transformer = new XsltPayloadTransformer(resource); transformer.setResultFactory(new StringResultFactory()); transformer.setAlwaysUseResultFactory(true); + transformer.afterPropertiesSet(); Object returned = transformer.doTransform(buildMessage(XmlTestUtil.getDocumentForString(docAsString))); assertEquals("Wrong type of return ", StringResult.class, returned.getClass()); } @@ -175,6 +178,7 @@ public class XsltPayloadTransformerTests { transformer = new XsltPayloadTransformer(resource); transformer.setResultFactory(new StringResultFactory()); transformer.setAlwaysUseResultFactory(true); + transformer.afterPropertiesSet(); Object returned = transformer.doTransform(buildMessage(XmlTestUtil.getDocumentForString(docAsString))); assertEquals("Wrong type of return ", StringResult.class, returned.getClass()); } @@ -184,6 +188,7 @@ public class XsltPayloadTransformerTests { transformer = new XsltPayloadTransformer(getXslResourceThatOutputsText()); transformer.setResultFactory(new StringResultFactory()); transformer.setAlwaysUseResultFactory(true); + transformer.afterPropertiesSet(); Object returned = transformer.doTransform(buildMessage(XmlTestUtil.getDocumentForString(docAsString))); assertEquals("Wrong type of return ", StringResult.class, returned.getClass()); assertEquals("Wrong content in string", "hello world", returned.toString());