diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/MarshallingTransformer.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/MarshallingTransformer.java index 0c4e2e497e..c5a24f461c 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/MarshallingTransformer.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/MarshallingTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -46,8 +46,7 @@ public class MarshallingTransformer extends AbstractTransformer { private volatile boolean extractPayload = true; - public MarshallingTransformer(Marshaller marshaller, ResultTransformer resultTransformer) - throws ParserConfigurationException { + public MarshallingTransformer(Marshaller marshaller, ResultTransformer resultTransformer) throws ParserConfigurationException { Assert.notNull(marshaller, "a marshaller is required"); this.marshaller = marshaller; this.resultTransformer = resultTransformer; @@ -89,9 +88,6 @@ public class MarshallingTransformer extends AbstractTransformer { catch (IOException e) { throw new MessagingException("Failed to marshal payload", e); } - if (transformedPayload == null) { - throw new MessagingException("Failed to transform payload"); - } if (this.resultTransformer != null) { transformedPayload = this.resultTransformer.transformResult(result); } diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToDocumentTransformer.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToDocumentTransformer.java index 1267116a07..5e13461a5a 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToDocumentTransformer.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToDocumentTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2010 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. @@ -24,11 +24,12 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Result; import javax.xml.transform.dom.DOMResult; -import org.springframework.integration.MessagingException; -import org.springframework.xml.transform.StringResult; import org.w3c.dom.Document; import org.xml.sax.InputSource; +import org.springframework.integration.MessagingException; +import org.springframework.xml.transform.StringResult; + /** * Creates a {@link Document} from a {@link Result} payload. Supports * {@link DOMResult} and {@link StringResult} implementations. @@ -40,6 +41,7 @@ public class ResultToDocumentTransformer implements ResultTransformer { // Not guaranteed to be thread safe private final DocumentBuilderFactory documentBuilderFactory; + public ResultToDocumentTransformer(DocumentBuilderFactory documentBuilderFactory) { this.documentBuilderFactory = documentBuilderFactory; } @@ -49,40 +51,41 @@ public class ResultToDocumentTransformer implements ResultTransformer { this.documentBuilderFactory.setNamespaceAware(true); } - public Object transformResult(Result res) { - Document doc = null; - if (DOMResult.class.isAssignableFrom(res.getClass())) { - doc = createDocumentFromDomResult((DOMResult) res); + + public Object transformResult(Result result) { + Document document = null; + if (DOMResult.class.isAssignableFrom(result.getClass())) { + document = createDocumentFromDomResult((DOMResult) result); } - else if (StringResult.class.isAssignableFrom(res.getClass())) { - doc = createDocumentFromStringResult((StringResult) res); + else if (StringResult.class.isAssignableFrom(result.getClass())) { + document = createDocumentFromStringResult((StringResult) result); } else { - throw new MessagingException("Failed to create document from payload type [" + res.getClass().getName() - + "]"); + throw new MessagingException("failed to create document from payload type [" + + result.getClass().getName() + "]"); } - return doc; + return document; } - protected Document createDocumentFromDomResult(DOMResult domResult) { + private Document createDocumentFromDomResult(DOMResult domResult) { return (Document) domResult.getNode(); } - protected Document createDocumentFromStringResult(StringResult stringResult) { + private Document createDocumentFromStringResult(StringResult stringResult) { try { return getDocumentBuilder().parse(new InputSource(new StringReader(stringResult.toString()))); } catch (Exception e) { - throw new MessagingException("Failed to create Document from StringResult payload", e); + throw new MessagingException("failed to create Document from StringResult payload", e); } } - protected synchronized DocumentBuilder getDocumentBuilder() { + private synchronized DocumentBuilder getDocumentBuilder() { try { return this.documentBuilderFactory.newDocumentBuilder(); } catch (ParserConfigurationException e) { - throw new MessagingException("Failed to create a new DocumentBuilder", e); + throw new MessagingException("failed to create a new DocumentBuilder", e); } } diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToStringTransformer.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToStringTransformer.java index 33d9249115..3382864806 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToStringTransformer.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultToStringTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2010 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. @@ -13,11 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.xml.transformer; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Result; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; @@ -30,62 +28,49 @@ import org.springframework.integration.MessagingException; import org.springframework.xml.transform.StringResult; /** - * Converts the passed {@link Result} to an instance of {@link String} - * + * Converts the passed {@link Result} to an instance of {@link String}. * Supports {@link StringResult} and {@link DOMResult} * * @author Jonas Partner - * + * @author Mark Fisher */ public class ResultToStringTransformer implements ResultTransformer { - private DocumentBuilderFactory docBuilderFactory; + private final TransformerFactory transformerFactory; - private TransformerFactory transformerFactory; public ResultToStringTransformer() { - this.docBuilderFactory = DocumentBuilderFactory.newInstance(); - this.docBuilderFactory.setNamespaceAware(true); this.transformerFactory = TransformerFactory.newInstance(); } - protected Transformer getNewTransformer() - throws TransformerConfigurationException { - synchronized (transformerFactory) { - return transformerFactory.newTransformer(); - } - } - public Object transformResult(Result res) { + public Object transformResult(Result result) { String returnString = null; - if (res instanceof StringResult) { - returnString = ((StringResult) res).toString(); - } else if (res instanceof DOMResult) { + if (result instanceof StringResult) { + returnString = ((StringResult) result).toString(); + } + else if (result instanceof DOMResult) { try { - StringResult strRes = new StringResult(); - getNewTransformer().transform( - new DOMSource(((DOMResult) res).getNode()), strRes); - returnString = strRes.toString(); - } catch (TransformerException transE) { - throw new MessagingException( - "Transformation from DOMSOurce failed", transE); + StringResult stringResult = new StringResult(); + this.getNewTransformer().transform( + new DOMSource(((DOMResult) result).getNode()), stringResult); + returnString = stringResult.toString(); + } + catch (TransformerException e) { + throw new MessagingException("failed to transform from DOMSource failed", e); } } - if (returnString == null) { - throw new MessagingException("Could not convert Result type " - + res.getClass().getName() + " to string"); + throw new MessagingException("failed to convert Result type [" + + result.getClass().getName() + "] to string"); } - return returnString; } - protected DocumentBuilder getNewDocumentBuilder() - throws ParserConfigurationException { - synchronized (docBuilderFactory) { - return docBuilderFactory.newDocumentBuilder(); + private Transformer getNewTransformer() throws TransformerConfigurationException { + synchronized (this.transformerFactory) { + return this.transformerFactory.newTransformer(); } - } } diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultTransformer.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultTransformer.java index c2769349e8..62c73b0a6b 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultTransformer.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/ResultTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2010 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. @@ -13,10 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.xml.transformer; +import javax.xml.transform.Result; + +/** + * @author Jonas Partner + */ public interface ResultTransformer { - Object transformResult(javax.xml.transform.Result res); + Object transformResult(Result result); } diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/SourceCreatingTransformer.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/SourceCreatingTransformer.java index b2fd320f7c..539cad4293 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/SourceCreatingTransformer.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/SourceCreatingTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2010 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. @@ -41,6 +41,7 @@ public class SourceCreatingTransformer extends AbstractPayloadTransformer { - private volatile boolean alwaysUseSourceFactory = false; - private final Unmarshaller unmarshaller; private volatile SourceFactory sourceFactory = new DomSourceFactory(); + private volatile boolean alwaysUseSourceFactory = false; + public UnmarshallingTransformer(Unmarshaller unmarshaller) { this.unmarshaller = unmarshaller; @@ -63,22 +63,21 @@ public class UnmarshallingTransformer extends AbstractPayloadTransformer { + static class XPathExpressionEvaluatingHeaderValueMessageProcessor implements HeaderValueMessageProcessor { private final XPathExpression expression; diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XsltHeaders.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XsltHeaders.java deleted file mode 100644 index 464ebd80ab..0000000000 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/XsltHeaders.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2010 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.integration.xml.transformer; - -import javax.xml.transform.Transformer; - -/** - * Message headers that can be used to configure the {@link Transformer} - * instance used for XSL transformation. - * - * @author Jonas Partner - */ -public abstract class XsltHeaders { - - public static final String PREFIX = "xslt_"; - - public static final String OUTPUT_PROPERTY = PREFIX + "output_property_"; - - public static final String PARAMETER = PREFIX + "parameter_"; - -} 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 48e6f87690..e6adbf96cc 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 @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.xml.transformer; import java.io.IOException; @@ -44,6 +45,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.ObjectUtils; import org.springframework.util.PatternMatchUtils; import org.springframework.xml.transform.StringResult; import org.springframework.xml.transform.StringSource; @@ -76,8 +78,11 @@ import org.w3c.dom.Document; public class XsltPayloadTransformer extends AbstractTransformer { private final Log logger = LogFactory.getLog(this.getClass()); + private final Templates templates; - private final StandardEvaluationContext context = new StandardEvaluationContext(); + + private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext(); + private Map xslParameterMappings; private final ResultTransformer resultTransformer; @@ -88,17 +93,13 @@ public class XsltPayloadTransformer extends AbstractTransformer { private volatile boolean alwaysUseSourceResultFactories = false; - private String[] xsltParamHeaders; + private volatile String[] xsltParamHeaders; + public XsltPayloadTransformer(Templates templates) throws ParserConfigurationException { this(templates, null); } - public XsltPayloadTransformer(Templates templates, ResultTransformer resultTransformer) throws ParserConfigurationException { - this.templates = templates; - this.resultTransformer = resultTransformer; - } - public XsltPayloadTransformer(Resource xslResource) throws Exception { this(TransformerFactory.newInstance().newTemplates(createStreamSourceOnResource(xslResource)), null); } @@ -107,28 +108,18 @@ public class XsltPayloadTransformer extends AbstractTransformer { this(TransformerFactory.newInstance().newTemplates(createStreamSourceOnResource(xslResource)), resultTransformer); } - - /** - * 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 - * read other resources relative to the provided one. If it isn't, it loads - * from the default path. - */ - private static StreamSource createStreamSourceOnResource(Resource xslResource) throws IOException { - try { - String systemId = xslResource.getURI().toString(); - return new StreamSource(xslResource.getInputStream(), systemId); - } - catch (IOException e) { - return new StreamSource(xslResource.getInputStream()); - } + public XsltPayloadTransformer(Templates templates, ResultTransformer resultTransformer) throws ParserConfigurationException { + this.templates = templates; + this.resultTransformer = resultTransformer; + this.evaluationContext.addPropertyAccessor(new MapAccessor()); } + /** * Sets the SourceFactory. */ public void setSourceFactory(SourceFactory sourceFactory) { - Assert.notNull(sourceFactory, "SourceFactory can not be null"); + Assert.notNull(sourceFactory, "SourceFactory must not be null"); this.sourceFactory = sourceFactory; } @@ -136,7 +127,7 @@ public class XsltPayloadTransformer extends AbstractTransformer { * Sets the ResultFactory */ public void setResultFactory(ResultFactory resultFactory) { - Assert.notNull(sourceFactory, "ResultFactory can not be null"); + Assert.notNull(sourceFactory, "ResultFactory must not be null"); this.resultFactory = resultFactory; } @@ -144,8 +135,20 @@ public class XsltPayloadTransformer extends AbstractTransformer { * Specifies whether {@link ResultFactory} and {@link SourceFactory} should always * be used, even for directly supported payloads such as {@link String} and {@link Document}. */ - public void setAlwaysUseSourceResultFactories(boolean alwaysUserSourceResultFactories) { - this.alwaysUseSourceResultFactories = alwaysUserSourceResultFactories; + public void setAlwaysUseSourceResultFactories(boolean alwaysUseSourceResultFactories) { + this.alwaysUseSourceResultFactories = alwaysUseSourceResultFactories; + } + + public void setXslParameterMappings(Map xslParameterMappings) { + this.xslParameterMappings = xslParameterMappings; + } + + public void setXsltParamHeaders(String[] xsltParamHeaders) { + this.xsltParamHeaders = xsltParamHeaders; + } + + public String getComponentType() { + return "xml:xslt-transformer"; } @Override @@ -172,29 +175,29 @@ public class XsltPayloadTransformer extends AbstractTransformer { return transformedPayload; } - protected Object transformUsingFactories(Object payload, Transformer transformer) throws TransformerException { - Source source = sourceFactory.createSource(payload); + private Object transformUsingFactories(Object payload, Transformer transformer) throws TransformerException { + Source source = this.sourceFactory.createSource(payload); return transformSource(source, payload, transformer); } - protected Object transformSource(Source source, Object payload, Transformer transformer) throws TransformerException { - Result result = resultFactory.createResult(payload); + private Object transformSource(Source source, Object payload, Transformer transformer) throws TransformerException { + Result result = this.resultFactory.createResult(payload); transformer.transform(source, result); - if (resultTransformer != null) { - return resultTransformer.transformResult(result); + if (this.resultTransformer != null) { + return this.resultTransformer.transformResult(result); } return result; } - protected String transformString(String stringPayload, Transformer transformer) throws TransformerException { + private String transformString(String stringPayload, Transformer transformer) throws TransformerException { StringResult result = new StringResult(); transformer.transform(new StringSource(stringPayload), result); return result.toString(); } - protected Document transformDocument(Document documentPayload, Transformer transformer) throws TransformerException { + private Document transformDocument(Document documentPayload, Transformer transformer) throws TransformerException { DOMSource source = new DOMSource(documentPayload); - Result result = resultFactory.createResult(documentPayload); + Result result = this.resultFactory.createResult(documentPayload); if (!DOMResult.class.isAssignableFrom(result.getClass())) { throw new MessagingException( "Document to Document conversion requires a DOMResult-producing ResultFactory implementation."); @@ -203,51 +206,52 @@ public class XsltPayloadTransformer extends AbstractTransformer { transformer.transform(source, domResult); return (Document) domResult.getNode(); } - - protected Transformer buildTransformer(Message message) throws TransformerException { + + private Transformer buildTransformer(Message message) throws TransformerException { //process individual mappings Transformer transformer = this.templates.newTransformer(); - context.setRootObject(message); - context.addPropertyAccessor(new MapAccessor()); - if (xslParameterMappings != null){ - for (String parameterName: xslParameterMappings.keySet()) { - Expression expression = xslParameterMappings.get(parameterName); - Object value = null; + if (this.xslParameterMappings != null){ + for (String parameterName: this.xslParameterMappings.keySet()) { + Expression expression = this.xslParameterMappings.get(parameterName); try { - value = expression.getValue(context); + Object value = expression.getValue(this.evaluationContext, message); transformer.setParameter(parameterName, value); - } catch (Exception e) { - logger.warn("Header expression '" + expression.getExpressionString() + "' can not resolve within current message and will not be mapped to XSLT parameter"); - } + } + catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn("Evaluation of header expression '" + expression.getExpressionString() + + "' failed. The XSLT parameter '" + parameterName + "' will be skipped."); + } + } } } // process xslt-parameter-headers MessageHeaders headers = message.getHeaders(); - if (xsltParamHeaders != null){ + if (!ObjectUtils.isEmpty(this.xsltParamHeaders)) { for (String headerName : headers.keySet()) { - if (PatternMatchUtils.simpleMatch(xsltParamHeaders, headerName)){ + if (PatternMatchUtils.simpleMatch(this.xsltParamHeaders, headerName)) { transformer.setParameter(headerName, headers.get(headerName)); - } + } } } return transformer; } - public Map getXslParameterMappings() { - return xslParameterMappings; + + /** + * 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 + * read other resources relative to the provided one. If it isn't, it loads + * from the default path. + */ + private static StreamSource createStreamSourceOnResource(Resource xslResource) throws IOException { + try { + String systemId = xslResource.getURI().toString(); + return new StreamSource(xslResource.getInputStream(), systemId); + } + catch (IOException e) { + return new StreamSource(xslResource.getInputStream()); + } } - public void setXslParameterMappings(Map xslParameterMappings) { - this.xslParameterMappings = xslParameterMappings; - } - public String[] getXsltParamHeaders() { - return xsltParamHeaders; - } - - public void setXsltParamHeaders(String[] xsltParamHeaders) { - this.xsltParamHeaders = xsltParamHeaders; - } - public String getComponentType(){ - return "xml:xslt-transformer"; - } } diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/xpath/XPathEvaluationType.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/xpath/XPathEvaluationType.java index ca3966e4d9..92ec5d655e 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/xpath/XPathEvaluationType.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/xpath/XPathEvaluationType.java @@ -1,33 +1,62 @@ +/* + * Copyright 2002-2010 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.integration.xml.xpath; -import org.springframework.xml.xpath.XPathExpression; import org.w3c.dom.Node; +import org.springframework.xml.xpath.XPathExpression; /** - * Enumeration of different types o XPath evaluation used to indicate the type of evaluation that should be carried out - * using a provided XPath expression + * Enumeration of different types of XPath evaluation used to indicate the type + * of evaluation that should be carried out using a provided XPath expression. */ public enum XPathEvaluationType { - BOOLEAN_RESULT {public Object evaluateXPath(XPathExpression expression, Node node) { - return expression.evaluateAsBoolean(node); - }}, + BOOLEAN_RESULT { + public Object evaluateXPath(XPathExpression expression, Node node) { + return expression.evaluateAsBoolean(node); + } + }, - STRING_RESULT {public Object evaluateXPath(XPathExpression expression, Node node) { - return expression.evaluateAsString(node); - }}, - NUMBER_RESULT {public Object evaluateXPath(XPathExpression expression, Node node) { - return expression.evaluateAsNumber(node); - }}, + STRING_RESULT { + public Object evaluateXPath(XPathExpression expression, Node node) { + return expression.evaluateAsString(node); + } + }, - NODE_RESULT {public Object evaluateXPath(XPathExpression expression, Node node) { - return expression.evaluateAsNode(node); - }}, - NODE_LIST_RESULT {public Object evaluateXPath(XPathExpression expression, Node node) { - return expression.evaluateAsNodeList(node); - }}; + NUMBER_RESULT { + public Object evaluateXPath(XPathExpression expression, Node node) { + return expression.evaluateAsNumber(node); + } + }, - public abstract Object evaluateXPath(XPathExpression expression, Node node); + NODE_RESULT { + public Object evaluateXPath(XPathExpression expression, Node node) { + return expression.evaluateAsNode(node); + } + }, + + NODE_LIST_RESULT { + public Object evaluateXPath(XPathExpression expression, Node node) { + return expression.evaluateAsNodeList(node); + } + }; + + + public abstract Object evaluateXPath(XPathExpression expression, Node node); }