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 34ec33df53..f6307097af 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,7 @@ import org.springframework.util.xml.DomUtils; * @author Jonas Partner * @author Mark Fisher * @author Oleg Zhurakousky + * @author Mike Bazos */ public class XsltPayloadTransformerParser extends AbstractTransformerParser { @@ -51,6 +52,7 @@ public class XsltPayloadTransformerParser extends AbstractTransformerParser { String resultTransformer = element.getAttribute("result-transformer"); String resultFactory = element.getAttribute("result-factory"); String resultType = element.getAttribute("result-type"); + String transformerFactoryClass = element.getAttribute("transformer-factory-class"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "xslt-param-headers"); Assert.isTrue(StringUtils.hasText(xslResource) ^ StringUtils.hasText(xslTemplates), "Exactly one of 'xsl-resource' or 'xsl-templates' is required."); @@ -60,6 +62,9 @@ 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){ 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 d586c858a6..149911bbed 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 @@ -47,6 +47,7 @@ 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; @@ -76,10 +77,11 @@ import org.springframework.xml.transform.StringSource; * @author Mark Fisher * @author Oleg Zhurakousky * @author Artem Bilan + * @author Mike Bazos */ public class XsltPayloadTransformer extends AbstractTransformer { - private final Log logger = LogFactory.getLog(this.getClass()); + private static final Log logger = LogFactory.getLog(XsltPayloadTransformer.class); private final Templates templates; @@ -107,21 +109,26 @@ public class XsltPayloadTransformer extends AbstractTransformer { } public XsltPayloadTransformer(Resource xslResource) throws Exception { - this(TransformerFactory.newInstance().newTemplates( - createStreamSourceOnResource(xslResource)), null); + this(xslResource, null, null); } public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer) throws Exception { - this(TransformerFactory.newInstance().newTemplates( - createStreamSourceOnResource(xslResource)), 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 transformerFactoryClass) throws Exception { + this(getTransformerFactory(transformerFactoryClass).newTemplates(createStreamSourceOnResource(xslResource)), null); + } public XsltPayloadTransformer(Templates templates, ResultTransformer resultTransformer) throws ParserConfigurationException { this.templates = templates; this.resultTransformer = resultTransformer; } - /** * Sets the SourceFactory. */ @@ -317,5 +324,21 @@ 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 58c6ebff3a..61f37d1a3f 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,6 +237,19 @@ + + + + + + + + + + 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 937b1564fe..20c93aedd9 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,6 +16,10 @@ 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 javax.xml.transform.Result; import javax.xml.transform.TransformerException; import javax.xml.transform.dom.DOMResult; @@ -34,15 +38,12 @@ import org.springframework.xml.transform.StringResult; import org.springframework.xml.transform.StringSource; import org.w3c.dom.Document; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; - /** * @author Jonas Partner * @author Oleg Zhurakousky * @author Gunnar Hillert + * @author Mike Bazos */ public class XsltPayloadTransformerTests { @@ -112,6 +113,28 @@ public class XsltPayloadTransformerTests { 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"); + Object transformed = transformer + .doTransform(buildMessage(new StringSource(docAsString))); + assertEquals("Wrong value from result conversion", returnValue, + transformed); + } + + @Test + 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); + } @Test(expected = TransformerException.class) public void testNonXmlString() throws Exception { diff --git a/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XsltTransformerTests-context.xml b/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XsltTransformerTests-context.xml index e9b189370d..c76f7e5aea 100644 --- a/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XsltTransformerTests-context.xml +++ b/spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/XsltTransformerTests-context.xml @@ -17,7 +17,8 @@ input-channel="paramHeadersWithStartWildCharacterChannel" output-channel="output" xsl-resource="classpath:org/springframework/integration/xml/transformer/transformer.xslt" - xslt-param-headers="*Param, foo"> + xslt-param-headers="*Param, foo" + transformer-factory-class="com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl">