diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/AbstractXPathMessageSelector.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/AbstractXPathMessageSelector.java index 24c963e51d..af5d217642 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/AbstractXPathMessageSelector.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/AbstractXPathMessageSelector.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. @@ -34,20 +34,20 @@ public abstract class AbstractXPathMessageSelector implements MessageSelector { private final XPathExpression xPathExpresion; - private XmlPayloadConverter converter = new DefaultXmlPayloadConverter(); + private volatile XmlPayloadConverter converter = new DefaultXmlPayloadConverter(); /** - * @param xPathExpression simple String expression + * @param xPathExpression XPath expression as a String */ public AbstractXPathMessageSelector(String xPathExpression) { this.xPathExpresion = XPathExpressionFactory.createXPathExpression(xPathExpression); } /** - * @param xPathExpression - * @param prefix - * @param namespace + * @param xPathExpression XPath expression as a String + * @param prefix namespace prefix + * @param namespace namespace URI */ public AbstractXPathMessageSelector(String xPathExpression, String prefix, String namespace) { Map namespaces = new HashMap(); @@ -56,15 +56,15 @@ public abstract class AbstractXPathMessageSelector implements MessageSelector { } /** - * @param xPathExpression - * @param namespaces + * @param xPathExpression XPath expression as a String + * @param namespaces Map of namespaces with prefixes as the Map keys */ - public AbstractXPathMessageSelector(String xPathExpression, Map namespaces) { + public AbstractXPathMessageSelector(String xPathExpression, Map namespaces) { this.xPathExpresion = XPathExpressionFactory.createXPathExpression(xPathExpression, namespaces); } /** - * @param xPathExpression + * @param xPathExpression XPath expression */ public AbstractXPathMessageSelector(XPathExpression xPathExpression) { this.xPathExpresion = xPathExpression; diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/BooleanTestXPathMessageSelector.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/BooleanTestXPathMessageSelector.java index 638721aa20..adfc32132f 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/BooleanTestXPathMessageSelector.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/BooleanTestXPathMessageSelector.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. @@ -36,32 +36,30 @@ public class BooleanTestXPathMessageSelector extends AbstractXPathMessageSelecto /** * Create a boolean testing XPath {@link MessageSelector} supporting - * mutliple namespaces. + * multiple namespaces. * - * @param expression - * @param namespaces + * @param expression XPath expression as a String + * @param namespaces Map of namespaces where the keys are namespace prefixes */ public BooleanTestXPathMessageSelector(String expression, Map namespaces) { super(expression, namespaces); } /** - * Create a boolean testing XPath {@link MessageSelector} supporting a - * single namespace. + * Create a boolean testing XPath {@link MessageSelector} supporting a single namespace. * - * @param expression - * @param prefix - * @param namespace + * @param expression XPath expression as a String + * @param prefix namespace prefix + * @param namespace namespace URI */ public BooleanTestXPathMessageSelector(String expression, String prefix, String namespace) { super(expression, prefix, namespace); } /** - * Create a boolean testing XPath {@link MessageSelector} with no namespace - * support. + * Create a boolean testing XPath {@link MessageSelector} with no namespace support. * - * @param expression + * @param expression XPath expression as a String */ public BooleanTestXPathMessageSelector(String expression) { super(expression); @@ -71,7 +69,7 @@ public class BooleanTestXPathMessageSelector extends AbstractXPathMessageSelecto * Create a boolean testing XPath {@link MessageSelector} using the * provided {@link XPathExpression}. * - * @param expression + * @param expression XPath expression */ public BooleanTestXPathMessageSelector(XPathExpression expression) { super(expression); diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/StringValueTestXPathMessageSelector.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/StringValueTestXPathMessageSelector.java index bb4bb6a566..5972032d3f 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/StringValueTestXPathMessageSelector.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/StringValueTestXPathMessageSelector.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. @@ -39,12 +39,11 @@ public class StringValueTestXPathMessageSelector extends AbstractXPathMessageSel /** - * Create a selector which tests for the given value and supports multiple - * namespaces. + * Create a selector which tests for the given value and supports multiple namespaces. * - * @param expression - * @param namespaces - * @param valueToTestFor + * @param expression XPath expression as a String + * @param namespaces Map of namespaces where the keys are namespace prefixes + * @param valueToTestFor value to test for */ public StringValueTestXPathMessageSelector(String expression, Map namespaces, String valueToTestFor) { super(expression, namespaces); @@ -54,10 +53,10 @@ public class StringValueTestXPathMessageSelector extends AbstractXPathMessageSel /** * Creates a single namespace Xpath selector. * - * @param expression - * @param prefix - * @param namespace - * @param valueToTestFor + * @param expression XPath expression as a String + * @param prefix namespace prefix + * @param namespace namespace URI + * @param valueToTestFor value to test for */ public StringValueTestXPathMessageSelector(String expression, String prefix, String namespace, String valueToTestFor) { super(expression, prefix, namespace); @@ -65,10 +64,10 @@ public class StringValueTestXPathMessageSelector extends AbstractXPathMessageSel } /** - * Creates non-namespaced testing selector. + * Creates a non-namespaced testing selector. * - * @param expression - * @param valueToTestFor + * @param expression XPath expression as a String + * @param valueToTestFor value to test for */ public StringValueTestXPathMessageSelector(String expression, String valueToTestFor) { super(expression); @@ -78,8 +77,8 @@ public class StringValueTestXPathMessageSelector extends AbstractXPathMessageSel /** * Creates a selector with the provided {@link XPathExpression}. * - * @param expression - * @param valueToTestFor + * @param expression XPath expression + * @param valueToTestFor value to test for */ public StringValueTestXPathMessageSelector(XPathExpression expression, String valueToTestFor) { super(expression); diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/XmlValidatingMessageSelector.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/XmlValidatingMessageSelector.java index 471f021c25..5639dc9641 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/XmlValidatingMessageSelector.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/XmlValidatingMessageSelector.java @@ -18,6 +18,10 @@ package org.springframework.integration.xml.selector; import java.io.IOException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.xml.sax.SAXParseException; + import org.springframework.core.io.Resource; import org.springframework.integration.Message; import org.springframework.integration.MessageHandlingException; @@ -32,70 +36,76 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.xml.validation.XmlValidator; import org.springframework.xml.validation.XmlValidatorFactory; -import org.xml.sax.SAXParseException; + /** - * * @author Oleg Zhurakousky * @since 2.0 - * */ public class XmlValidatingMessageSelector implements MessageSelector { - + + private final Log logger = LogFactory.getLog(this.getClass()); + private final XmlValidator xmlValidator; - + private volatile boolean throwExceptionOnRejection; private volatile XmlPayloadConverter converter = new DefaultXmlPayloadConverter(); - - public XmlValidatingMessageSelector(XmlValidator xmlValidator) throws Exception{ - Assert.notNull(xmlValidator, "XmlValidator can not be 'null'"); + + + public XmlValidatingMessageSelector(XmlValidator xmlValidator) { + Assert.notNull(xmlValidator, "XmlValidator must not be null"); this.xmlValidator = xmlValidator; } + /** - * Will create this selector with default {@link XmlValidator} which - * will be initialized with 'schema' location as {@link Resource} and 'schemaType' as - * either {@link XmlValidatorFactory#SCHEMA_W3C_XML} or {@link XmlValidatorFactory#SCHEMA_RELAX_NG}. + * Creates a selector with a default {@link XmlValidator}. The validator will be initialized with + * the provided 'schema' location {@link Resource} and 'schemaType'. The valid options for schema + * type are {@link XmlValidatorFactory#SCHEMA_W3C_XML} or {@link XmlValidatorFactory#SCHEMA_RELAX_NG}. * If no 'schemaType' is provided it will default to {@link XmlValidatorFactory#SCHEMA_W3C_XML}; * - * @param schema - * @param schemaType - * @throws IOException + * @throws IOException if the XmlValidatorFactory fails to create a validator */ public XmlValidatingMessageSelector(Resource schema, String schemaType) throws IOException { Assert.notNull(schema, "You must provide XML schema location to perform validation"); - if (!StringUtils.hasText(schemaType)){ + if (!StringUtils.hasText(schemaType)) { schemaType = XmlValidatorFactory.SCHEMA_W3C_XML; } this.xmlValidator = XmlValidatorFactory.createValidator(schema, schemaType); } - + + public void setThrowExceptionOnRejection(boolean throwExceptionOnRejection) { this.throwExceptionOnRejection = throwExceptionOnRejection; } - + /** - * Converter used to convert payloads prior to validation - * - * @param converter + * Specify the Converter to use when converting payloads prior to validation. */ public void setConverter(XmlPayloadConverter converter) { Assert.notNull(converter, "'converter' must not be null"); this.converter = converter; } - + @SuppressWarnings("unchecked") public boolean accept(Message message) { SAXParseException[] validationExceptions = null; try { - validationExceptions = xmlValidator.validate(converter.convertToSource(message.getPayload())); - } catch (Exception e) { + validationExceptions = this.xmlValidator.validate(this.converter.convertToSource(message.getPayload())); + } + catch (Exception e) { throw new MessageHandlingException(message, e); } boolean validationSuccess = ObjectUtils.isEmpty(validationExceptions); - if (!validationSuccess && throwExceptionOnRejection){ - throw new MessageRejectedException(message, "Message was rejected due to XML Validation errors", - new AggregatedXmlMessageValidationException(CollectionUtils.arrayToList(validationExceptions))); + if (!validationSuccess) { + if (this.throwExceptionOnRejection) { + throw new MessageRejectedException(message, "Message was rejected due to XML Validation errors", + new AggregatedXmlMessageValidationException(CollectionUtils.arrayToList(validationExceptions))); + } + if (logger.isDebugEnabled()) { + logger.debug("Message was rejected due to XML Validation errors"); + } } return validationSuccess; } + } diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.java index 811826c7a4..979e7ad674 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.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. @@ -16,6 +16,7 @@ package org.springframework.integration.xml.source; +import java.io.File; import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; @@ -24,31 +25,34 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; -import org.springframework.integration.MessagingException; - import org.w3c.dom.Document; import org.xml.sax.InputSource; +import org.springframework.integration.MessagingException; + /** - * {@link SourceFactory} implementation which supports creation of a - * {@link DOMSource} from a {@link Document} or {@link String} payload. + * {@link SourceFactory} implementation which supports creation of a {@link DOMSource} + * from a {@link Document}, {@link File} or {@link String} payload. * * @author Jonas Partner * @author Mark Fisher */ public class DomSourceFactory implements SourceFactory { - private final DocumentBuilderFactory docBuilderFactory; + private final DocumentBuilderFactory documentBuilderFactory; + public DomSourceFactory() { - this.docBuilderFactory = DocumentBuilderFactory.newInstance(); - this.docBuilderFactory.setNamespaceAware(true); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + this.documentBuilderFactory = factory; } - public DomSourceFactory(DocumentBuilderFactory docBuilderFactory) { - this.docBuilderFactory = docBuilderFactory; + public DomSourceFactory(DocumentBuilderFactory documentBuilderFactory) { + this.documentBuilderFactory = documentBuilderFactory; } + public Source createSource(Object payload) { Source source = null; if (payload instanceof Document) { @@ -57,34 +61,44 @@ public class DomSourceFactory implements SourceFactory { else if (payload instanceof String) { source = createDomSourceForString((String) payload); } - + else if (payload instanceof File) { + source = createDomSourceForFile((File) payload); + } if (source == null) { - throw new MessagingException("Failed to create Source for payload type [" + payload.getClass().getName() - + "]"); + throw new MessagingException("failed to create Source for payload type [" + + payload.getClass().getName() + "]"); } return source; } - protected DOMSource createDomSourceForDocument(Document document) { - DOMSource source = new DOMSource(document.getDocumentElement()); - return source; + private DOMSource createDomSourceForDocument(Document document) { + return new DOMSource(document.getDocumentElement()); } - protected DOMSource createDomSourceForString(String s) { + private DOMSource createDomSourceForString(String s) { try { - Document doc = getNewDocumentBuilder().parse(new InputSource(new StringReader(s))); - DOMSource source = new DOMSource(doc.getDocumentElement()); - return source; + Document document = getNewDocumentBuilder().parse(new InputSource(new StringReader(s))); + return new DOMSource(document.getDocumentElement()); } catch (Exception e) { - throw new MessagingException("Exception creating DOMSource", e); + throw new MessagingException("failed to create DOMSource for String payload", e); + } + } + + private DOMSource createDomSourceForFile(File file) { + try { + Document document = this.getNewDocumentBuilder().parse(file); + return new DOMSource(document.getDocumentElement()); + } + catch (Exception e) { + throw new MessagingException("failed to create DOMSource for File payload", e); } } protected DocumentBuilder getNewDocumentBuilder() throws ParserConfigurationException { - synchronized (docBuilderFactory) { - return docBuilderFactory.newDocumentBuilder(); + synchronized (this.documentBuilderFactory) { + return documentBuilderFactory.newDocumentBuilder(); } - } + }