This commit is contained in:
Arjen Poutsma
2008-03-17 12:23:53 +00:00
parent ee63e0494e
commit a4f3017816
13 changed files with 165 additions and 59 deletions

View File

@@ -20,6 +20,9 @@ import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
@@ -33,8 +36,8 @@ import org.springframework.ws.soap.SoapMessage;
import org.springframework.xml.transform.TransformerObjectSupport;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.springframework.xml.xsd.XsdSchema;
import org.springframework.xml.xsd.XsdSchemaCollection;
/**
* Abstract base class for <code>EndpointInterceptor</code> implementations that validate part of the message using a
@@ -81,6 +84,14 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
return schemas;
}
/**
* Sets the schema resource to use for validation. Setting either this property or <code>schemas</code> is
* required.
*/
public void setSchema(Resource schema) {
setSchemas(new Resource[]{schema});
}
/**
* Sets the schema resources to use for validation. Setting either this property or <code>schema</code> is
* required.
@@ -95,11 +106,27 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
}
/**
* Sets the schema resource to use for validation. Setting either this property or <code>schemas</code> is
* required.
* Sets the {@link XsdSchema} to use for validation. Setting this property, {@link
* #setXsdSchemaCollection(XsdSchemaCollection) xsdSchemaCollection}, {@link #setSchema(Resource) schema}, or {@link
* #setSchemas(Resource[]) schemas} is required.
*
* @param schema the xsd schema to use
* @throws IOException in case of I/O errors
*/
public void setSchema(Resource schema) {
setSchemas(new Resource[]{schema});
public void setXsdSchema(XsdSchema schema) throws IOException {
this.validator = schema.createValidator();
}
/**
* Sets the {@link XsdSchemaCollection} to use for validation. Setting this property, {@link
* #setXsdSchema(XsdSchema) xsdSchema}, {@link #setSchema(Resource) schema}, or {@link #setSchemas(Resource[])
* schemas} is required.
*
* @param schemaCollection the xsd schema collection to use
* @throws IOException in case of I/O errors
*/
public void setXsdSchemaCollection(XsdSchemaCollection schemaCollection) throws IOException {
this.validator = schemaCollection.createValidator();
}
/** Indicates whether the request should be validated against the schema. Default is <code>true</code>. */
@@ -113,15 +140,17 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
}
public void afterPropertiesSet() throws Exception {
Assert.notEmpty(schemas, "setting either the schema or schemas property is required");
Assert.hasLength(schemaLanguage, "schemaLanguage is required");
for (int i = 0; i < schemas.length; i++) {
Assert.isTrue(schemas[i].exists(), "schema [" + schemas[i] + "] does not exist");
if (validator == null && !ObjectUtils.isEmpty(schemas)) {
Assert.hasLength(schemaLanguage, "schemaLanguage is required");
for (int i = 0; i < schemas.length; i++) {
Assert.isTrue(schemas[i].exists(), "schema [" + schemas[i] + "] does not exist");
}
if (logger.isInfoEnabled()) {
logger.info("Validating using " + StringUtils.arrayToCommaDelimitedString(schemas));
}
validator = XmlValidatorFactory.createValidator(schemas, schemaLanguage);
}
if (logger.isInfoEnabled()) {
logger.info("Validating using " + StringUtils.arrayToCommaDelimitedString(schemas));
}
validator = XmlValidatorFactory.createValidator(schemas, schemaLanguage);
Assert.notNull(validator, "Setting 'schema', 'schemas', 'xsdSchema', or 'xsdSchemaCollection' is required");
}
/**

View File

@@ -16,6 +16,7 @@
package org.springframework.ws.wsdl.wsdl11.provider;
import java.io.IOException;
import javax.wsdl.Definition;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
@@ -32,6 +33,7 @@ import org.w3c.dom.Element;
import org.springframework.util.Assert;
import org.springframework.ws.wsdl.WsdlDefinitionException;
import org.springframework.xml.transform.TransformerObjectSupport;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.xsd.XsdSchema;
import org.springframework.xml.xsd.XsdSchemaCollection;
@@ -61,6 +63,10 @@ public class InliningXsdSchemaTypesProvider extends TransformerObjectSupport imp
public XsdSchema[] getXsdSchemas() {
return new XsdSchema[]{schema};
}
public XmlValidator createValidator() throws IOException {
throw new UnsupportedOperationException();
}
};
}

View File

@@ -28,6 +28,9 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import org.custommonkey.xmlunit.XMLTestCase;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.LocatorImpl;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.ws.MockWebServiceMessage;
@@ -42,8 +45,7 @@ import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import org.springframework.ws.soap.saaj.support.SaajUtils;
import org.springframework.ws.soap.soap11.Soap11Fault;
import org.springframework.ws.soap.soap12.Soap12Fault;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.LocatorImpl;
import org.springframework.xml.xsd.SimpleXsdSchema;
public class PayloadValidatingInterceptorTest extends XMLTestCase {
@@ -189,6 +191,7 @@ public class PayloadValidatingInterceptorTest extends XMLTestCase {
System.setProperty("javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI,
"org.apache.xerces.jaxp.validation.XMLSchemaFactory");
try {
PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
interceptor.setSchema(new ClassPathResource(SCHEMA2, PayloadValidatingInterceptorTest.class));
interceptor.afterPropertiesSet();
MessageFactory messageFactory = MessageFactory.newInstance();
@@ -284,4 +287,21 @@ public class PayloadValidatingInterceptorTest extends XMLTestCase {
}
public void testXsdSchema() throws Exception {
PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
SimpleXsdSchema schema = new SimpleXsdSchema(new ClassPathResource(SCHEMA, getClass()));
schema.afterPropertiesSet();
interceptor.setXsdSchema(schema);
interceptor.setValidateRequest(true);
interceptor.setValidateResponse(true);
interceptor.afterPropertiesSet();
MockWebServiceMessage request = new MockWebServiceMessage();
request.setPayload(new ClassPathResource(VALID_MESSAGE, getClass()));
context = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
boolean result = interceptor.handleRequest(context, null);
assertTrue("Invalid response from interceptor", result);
assertFalse("Response set", context.hasResponse());
}
}

20
pom.xml
View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws</artifactId>
@@ -491,6 +492,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-1</version>
<inherited>false</inherited>
<executions>
<execution>
@@ -515,6 +517,7 @@
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-1</version>
<inherited>false</inherited>
<executions>
<execution>
@@ -590,19 +593,20 @@
<postProcess>
<copy todir="target/site/reference">
<fileset dir="target/docbkx">
<include name="**/*.html" />
<include name="**/*.pdf" />
<include name="**/*.html"/>
<include name="**/*.pdf"/>
</fileset>
</copy>
<copy todir="target/site/reference/html">
<fileset dir="src/docbkx/resources">
<include name="**/*.css" />
<include name="**/*.png" />
<include name="**/*.gif" />
<include name="**/*.jpg" />
<include name="**/*.css"/>
<include name="**/*.png"/>
<include name="**/*.gif"/>
<include name="**/*.jpg"/>
</fileset>
</copy>
<move file="target/site/reference/pdf/index.pdf" tofile="target/site/reference/pdf/spring-ws-reference.pdf" failonerror="false" />
<move file="target/site/reference/pdf/index.pdf"
tofile="target/site/reference/pdf/spring-ws-reference.pdf" failonerror="false"/>
</postProcess>
</configuration>
</plugin>

View File

@@ -17,8 +17,6 @@
package org.springframework.xml.xsd;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -28,16 +26,15 @@ import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.xml.namespace.QNameUtils;
import org.springframework.xml.sax.SaxUtils;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
/**
* The default {@link XsdSchema} implementation.
@@ -57,8 +54,6 @@ public class SimpleXsdSchema implements XsdSchema, InitializingBean {
private static final QName SCHEMA_NAME = QNameUtils.createQName(SCHEMA_NAMESPACE, "schema", "xsd");
private static final QName ELEMENT_NAME = QNameUtils.createQName(SCHEMA_NAMESPACE, "element", "xsd");
private Resource xsdResource;
private Element schemaElement;
@@ -103,24 +98,8 @@ public class SimpleXsdSchema implements XsdSchema, InitializingBean {
return new DOMSource(schemaElement);
}
public QName[] getElementNames() {
NodeList children = schemaElement.getChildNodes();
List result = new ArrayList(children.getLength());
for (int i = 0; i < children.getLength(); i++) {
if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element) children.item(i);
QName childName = QNameUtils.getQNameForNode(childElement);
if (ELEMENT_NAME.equals(childName)) {
result.add(getElementName(childElement));
}
}
}
return (QName[]) result.toArray(new QName[result.size()]);
}
private QName getElementName(Element element) {
String attributeValue = element.getAttribute("name");
return StringUtils.hasLength(attributeValue) ? new QName(getTargetNamespace(), attributeValue) : null;
public XmlValidator createValidator() throws IOException {
return XmlValidatorFactory.createValidator(xsdResource, XmlValidatorFactory.SCHEMA_W3C_XML);
}
public void afterPropertiesSet() throws ParserConfigurationException, IOException, SAXException {

View File

@@ -16,8 +16,11 @@
package org.springframework.xml.xsd;
import java.io.IOException;
import javax.xml.transform.Source;
import org.springframework.xml.validation.XmlValidator;
/**
* Represents an abstraction for XSD schemas.
*
@@ -35,9 +38,17 @@ public interface XsdSchema {
String getTargetNamespace();
/**
* Returns the <code>Source</code> of the schema.
* Returns the {@link Source} of the schema.
*
* @return the <code>Source</code> of this XSD schema
* @return the source of this XSD schema
*/
Source getSource();
/**
* Creates a {@link XmlValidator} based on the schema.
*
* @return a validator for this schema
* @throws IOException in case of I/O errors
*/
XmlValidator createValidator() throws IOException;
}

View File

@@ -16,6 +16,10 @@
package org.springframework.xml.xsd;
import java.io.IOException;
import org.springframework.xml.validation.XmlValidator;
/**
* Represents an abstraction for a collection of XSD schemas.
*
@@ -25,9 +29,18 @@ package org.springframework.xml.xsd;
public interface XsdSchemaCollection {
/**
* Returns all schema's contained in this collection.
* Returns all schemas contained in this collection.
*
* @return the schema's contained in this collection
* @return the schemas contained in this collection
*/
XsdSchema[] getXsdSchemas();
/**
* Creates a {@link XmlValidator} based on the schemas contained in this collection.
*
* @return a validator for this collection
* @throws IOException in case of I/O errors
*/
XmlValidator createValidator() throws IOException;
}

View File

@@ -18,6 +18,7 @@ package org.springframework.xml.xsd.commons;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -32,7 +33,11 @@ import org.w3c.dom.Document;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.util.Assert;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
import org.springframework.xml.xsd.XsdSchema;
/**
@@ -91,6 +96,11 @@ public class CommonsXsdSchema implements XsdSchema {
return new StreamSource(bis);
}
public XmlValidator createValidator() throws IOException {
Resource resource = new UrlResource(schema.getSourceURI());
return XmlValidatorFactory.createValidator(resource, XmlValidatorFactory.SCHEMA_W3C_XML);
}
/** Returns the wrapped Commons <code>XmlSchema</code> object. */
public XmlSchema getSchema() {
return schema;

View File

@@ -31,8 +31,11 @@ import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.util.Assert;
import org.springframework.xml.sax.SaxUtils;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
import org.springframework.xml.xsd.XsdSchema;
import org.springframework.xml.xsd.XsdSchemaCollection;
@@ -122,6 +125,15 @@ public class CommonsXsdSchemaCollection implements XsdSchemaCollection, Initiali
return result;
}
public XmlValidator createValidator() throws IOException {
Resource[] resources = new Resource[xmlSchemas.size()];
for (int i = xmlSchemas.size() - 1; i >= 0; i--) {
XmlSchema xmlSchema = (XmlSchema) xmlSchemas.get(i);
resources[i] = new UrlResource(xmlSchema.getSourceURI());
}
return XmlValidatorFactory.createValidator(resources, XmlValidatorFactory.SCHEMA_W3C_XML);
}
private void inlineIncludes(XmlSchema schema, List processedSchemas) {
processedSchemas.add(schema);
XmlSchemaObjectCollection includes = schema.getIncludes();

View File

@@ -29,6 +29,7 @@ import org.w3c.dom.Document;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.xml.sax.SaxUtils;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.xsd.AbstractXsdSchemaTestCase;
import org.springframework.xml.xsd.XsdSchema;
@@ -89,4 +90,13 @@ public class CommonsXsdSchemaCollectionTest extends XMLTestCase {
assertEquals("Invalid amount of XSDs loaded", 1, schemas.length);
}
public void testCreateValidator() throws Exception {
Resource a = new ClassPathResource("A.xsd", AbstractXsdSchemaTestCase.class);
collection.setXsds(new Resource[]{a});
collection.setInline(true);
collection.afterPropertiesSet();
XmlValidator validator = collection.createValidator();
assertNotNull("No XmlValidator returned", validator);
}
}

View File

@@ -4,7 +4,9 @@
xmlns:tns="urn:1" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:include schemaLocation="B.xsd"/>
<xsd:simpleType name="A">
<xsd:restriction base="tns:B"/>
</xsd:simpleType>
<xsd:complexType name="A">
<xsd:complexContent>
<xsd:extension base="tns:B"/>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>

View File

@@ -2,9 +2,11 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns0="urn:2" xmlns:tns="urn:1"
attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:1">
<xsd:import namespace="urn:2"/>
<xsd:simpleType name="A">
<xsd:restriction base="tns:B"/>
</xsd:simpleType>
<xsd:complexType name="A">
<xsd:complexContent>
<xsd:extension base="tns:B"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="B">
<xsd:sequence>
<xsd:element name="c" type="tns:C"/>

View File

@@ -29,6 +29,7 @@ import org.w3c.dom.Document;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.xml.sax.SaxUtils;
import org.springframework.xml.validation.XmlValidator;
public abstract class AbstractXsdSchemaTestCase extends XMLTestCase {
@@ -84,5 +85,12 @@ public abstract class AbstractXsdSchemaTestCase extends XMLTestCase {
assertXMLEqual("Invalid Source returned", expected, result);
}
public void testCreateValidator() throws Exception {
Resource resource = new ClassPathResource("single.xsd", AbstractXsdSchemaTestCase.class);
XsdSchema single = createSchema(resource);
XmlValidator validator = single.createValidator();
assertNotNull("No XmlValidator returned", validator);
}
protected abstract XsdSchema createSchema(Resource resource) throws Exception;
}