polishing

This commit is contained in:
Mark Fisher
2010-11-02 17:03:40 -04:00
parent 012d9df8f4
commit 3490779396
5 changed files with 109 additions and 88 deletions

View File

@@ -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<String,String> namespaces = new HashMap<String, String>();
@@ -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<String,String> namespaces) {
public AbstractXPathMessageSelector(String xPathExpression, Map<String, String> namespaces) {
this.xPathExpresion = XPathExpressionFactory.createXPathExpression(xPathExpression, namespaces);
}
/**
* @param xPathExpression
* @param xPathExpression XPath expression
*/
public AbstractXPathMessageSelector(XPathExpression xPathExpression) {
this.xPathExpresion = xPathExpression;

View File

@@ -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<String, String> 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);

View File

@@ -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<String, String> 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);

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}