diff --git a/xml/pom.xml b/xml/pom.xml
index 23ecf9e9..406ce7e4 100644
--- a/xml/pom.xml
+++ b/xml/pom.xml
@@ -66,6 +66,10 @@
wstx-asl
test
+
+ org.apache.ws.commons.schema
+ XmlSchema
+
easymock
diff --git a/xml/src/main/java/org/springframework/xml/xsd/InlineableXsdSchema.java b/xml/src/main/java/org/springframework/xml/xsd/InlineableXsdSchema.java
new file mode 100644
index 00000000..d44b7321
--- /dev/null
+++ b/xml/src/main/java/org/springframework/xml/xsd/InlineableXsdSchema.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 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.xml.xsd;
+
+/**
+ * Represents an abstraction for XSD schemas.
+
+ * @author Arjen Poutsma
+ * @since 1.5.0
+ */
+public interface InlineableXsdSchema extends XsdSchema {
+
+ /**
+ * Inlines this schema into a set of self-contained schema's.
+ * */
+ XsdSchema[] inline();
+}
diff --git a/xml/src/main/java/org/springframework/xml/xsd/SimpleXsdSchema.java b/xml/src/main/java/org/springframework/xml/xsd/SimpleXsdSchema.java
new file mode 100644
index 00000000..d8cc648c
--- /dev/null
+++ b/xml/src/main/java/org/springframework/xml/xsd/SimpleXsdSchema.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2008 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.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;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
+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;
+
+/**
+ * The default {@link XsdSchema} implementation.
+ *
+ * Allows a XSD to be set by the {@link #setXsd(Resource)}, or directly in the {@link #SimpleXsdSchema(Resource)
+ * constructor}.
+ *
+ * @author Mark LaFond
+ * @author Arjen Poutsma
+ * @since 1.5.0
+ */
+public class SimpleXsdSchema implements XsdSchema, InitializingBean {
+
+ private static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+ private static final String SCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema";
+
+ 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;
+
+ static {
+ documentBuilderFactory.setNamespaceAware(true);
+ }
+
+ /**
+ * Create a new instance of the {@link SimpleXsdSchema} class.
+ *
+ * A subsequent call to the {@link #setXsd(Resource)} method is required.
+ */
+ public SimpleXsdSchema() {
+ }
+
+ /**
+ * Create a new instance of the {@link SimpleXsdSchema} class with the specified resource.
+ *
+ * @param xsdResource the XSD resource; must not be null
+ * @throws IllegalArgumentException if the supplied xsdResource is null
+ */
+ public SimpleXsdSchema(Resource xsdResource) {
+ Assert.notNull(xsdResource, "xsdResource must not be null");
+ this.xsdResource = xsdResource;
+ }
+
+ /**
+ * Set the XSD resource to be exposed by calls to this instances' {@link #getSource()} method.
+ *
+ * @param xsdResource the XSD resource
+ */
+ public void setXsd(Resource xsdResource) {
+ this.xsdResource = xsdResource;
+ }
+
+ public String getTargetNamespace() {
+ return schemaElement.getAttribute("targetNamespace");
+ }
+
+ public Source getSource() {
+ 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 void afterPropertiesSet() throws ParserConfigurationException, IOException, SAXException {
+ Assert.notNull(xsdResource, "'xsd' is required");
+ Assert.isTrue(this.xsdResource.exists(), "xsd '" + this.xsdResource + "' does not exit");
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ loadSchema(documentBuilder);
+ }
+
+ private void loadSchema(DocumentBuilder documentBuilder) throws SAXException, IOException {
+ Document schemaDocument = documentBuilder.parse(SaxUtils.createInputSource(xsdResource));
+ schemaElement = schemaDocument.getDocumentElement();
+ Assert.isTrue(SCHEMA_NAME.getLocalPart().equals(schemaElement.getLocalName()),
+ xsdResource + " has invalid root element : [" + schemaElement.getLocalName() + "] instead of [schema]");
+ Assert.isTrue(SCHEMA_NAME.getNamespaceURI().equals(schemaElement.getNamespaceURI()), xsdResource +
+ " has invalid root element: [" + schemaElement.getNamespaceURI() + "] instead of [" +
+ SCHEMA_NAME.getNamespaceURI() + "]");
+ Assert.hasText(getTargetNamespace(), xsdResource + " has no targetNamespace");
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer("SimpleXsdSchema");
+ buffer.append('{');
+ buffer.append(getTargetNamespace());
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/xml/src/main/java/org/springframework/xml/xsd/XsdSchema.java b/xml/src/main/java/org/springframework/xml/xsd/XsdSchema.java
new file mode 100644
index 00000000..30a8d02a
--- /dev/null
+++ b/xml/src/main/java/org/springframework/xml/xsd/XsdSchema.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 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.xml.xsd;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+
+/**
+ * Represents an abstraction for XSD schemas.
+ *
+ * @author Mark LaFond
+ * @author Arjen Poutsma
+ * @since 1.5.0
+ */
+public interface XsdSchema {
+
+ /**
+ * Returns the target namespace of theis schema.
+ *
+ * @return the target namespace
+ */
+ String getTargetNamespace();
+
+ /**
+ * Returns the qualified names of all top-level elements declared in the schema. This excludes elements declared as child of
+ * another element, simplyType, or complexType.
+ *
+ * @return the top-level element names
+ */
+ QName[] getElementNames();
+
+ /**
+ * Returns the Source of the schema.
+ *
+ * @return the Source of this XSD schema
+ */
+ Source getSource();
+}
diff --git a/xml/src/main/java/org/springframework/xml/xsd/XsdSchemaException.java b/xml/src/main/java/org/springframework/xml/xsd/XsdSchemaException.java
new file mode 100644
index 00000000..af74c2e2
--- /dev/null
+++ b/xml/src/main/java/org/springframework/xml/xsd/XsdSchemaException.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2008 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.xml.xsd;
+
+import org.springframework.xml.XmlException;
+
+/**
+ * Base class for all WSDL definition exceptions.
+ *
+ * @author Mark LaFond
+ * @author Arjen Poutsma
+ * @since 1.5.0
+ */
+public class XsdSchemaException extends XmlException {
+
+ public XsdSchemaException(String message) {
+ super(message);
+ }
+
+ public XsdSchemaException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+}
diff --git a/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchema.java b/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchema.java
new file mode 100644
index 00000000..09e01209
--- /dev/null
+++ b/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchema.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2008 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.xml.xsd.commons;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaInclude;
+import org.apache.ws.commons.schema.XmlSchemaObject;
+import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
+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.xml.sax.SaxUtils;
+import org.springframework.xml.xsd.InlineableXsdSchema;
+import org.springframework.xml.xsd.XsdSchema;
+
+/**
+ * Implementation of the {@link XsdSchema} interface that uses Apache WS-Commons XML Schema.
+ *
+ * @author Arjen Poutsma
+ * @see Commons XML Schema
+ * @since 1.5.0
+ */
+public class CommonsXsdSchema implements InlineableXsdSchema, InitializingBean {
+
+ private XmlSchema schema;
+
+ private Resource xsdResource;
+
+ /**
+ * Create a new, empty instance of the {@link CommonsXsdSchema} class.
+ *
+ * A subsequent call to the {@link #setXsd(Resource)} method is required.
+ */
+ public CommonsXsdSchema() {
+ }
+
+ /**
+ * Create a new instance of the {@link CommonsXsdSchema} class with the specified resource.
+ *
+ * @param xsdResource the XSD resource; must not be null
+ * @throws IllegalArgumentException if the supplied xsdResource is null
+ */
+ public CommonsXsdSchema(Resource xsdResource) {
+ Assert.notNull(xsdResource, "xsdResource must not be null");
+ this.xsdResource = xsdResource;
+ }
+
+ /**
+ * Create a new instance of the {@link CommonsXsdSchema} class with the specified {@link XmlSchema} reference.
+ *
+ * @param schema the Commons XmlSchema object; must not be null
+ * @throws IllegalArgumentException if the supplied schema is null
+ */
+ private CommonsXsdSchema(XmlSchema schema) {
+ Assert.notNull(schema, "'schema' must not be null");
+ this.schema = schema;
+ }
+
+ /**
+ * Set the XSD resource to be exposed by calls to this instances' {@link #getSource()} method.
+ *
+ * @param xsdResource the XSD resource
+ */
+ public void setXsd(Resource xsdResource) {
+ this.xsdResource = xsdResource;
+ }
+
+ public String getTargetNamespace() {
+ return schema.getTargetNamespace();
+ }
+
+ public QName[] getElementNames() {
+ List result = new ArrayList();
+ Iterator iterator = schema.getElements().getNames();
+ while (iterator.hasNext()) {
+ QName name = (QName) iterator.next();
+ result.add(name);
+ }
+ return (QName[]) result.toArray(new QName[result.size()]);
+ }
+
+ public void merge(XsdSchema o) {
+ Assert.isInstanceOf(CommonsXsdSchema.class, o);
+ XmlSchema otherSchema = ((CommonsXsdSchema) o).schema;
+ Assert.isTrue(this.schema.getTargetNamespace().equals(otherSchema.getTargetNamespace()),
+ "Schema does not have same namespace");
+ XmlSchemaObjectCollection otherItems = otherSchema.getItems();
+ for (int i = 0; i < otherItems.getCount(); i++) {
+ schema.getItems().add(otherItems.getItem(i));
+ }
+ }
+
+ public Source getSource() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ schema.write(bos);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ return new StreamSource(bis);
+ }
+
+ /** Returns the wrapped Commons XmlSchema object. */
+ public XmlSchema getSchema() {
+ return schema;
+ }
+
+ public void afterPropertiesSet() throws IOException, SAXException {
+ Assert.notNull(xsdResource, "'xsd' is required");
+ Assert.isTrue(this.xsdResource.exists(), "xsd '" + this.xsdResource + "' does not exit");
+ loadSchema();
+ }
+
+ private void loadSchema() throws SAXException, IOException {
+ XmlSchemaCollection schemaCollection = new XmlSchemaCollection();
+ this.schema = schemaCollection.read(SaxUtils.createInputSource(xsdResource), null);
+ }
+
+ public XsdSchema[] inline() {
+ XmlSchema clone = cloneSchema(schema);
+ inlineIncludes(clone, new ArrayList());
+ return new XsdSchema[]{new CommonsXsdSchema(clone)};
+ }
+
+ private static XmlSchema cloneSchema(XmlSchema schema) {
+ XmlSchemaCollection schemaCollection = new XmlSchemaCollection();
+ XmlSchema clone = new XmlSchema(schemaCollection);
+ XmlSchemaObjectCollection originalItems = schema.getItems();
+ XmlSchemaObjectCollection cloneItems = clone.getItems();
+ for (int i = 0; i < originalItems.getCount(); i++) {
+ cloneItems.add(originalItems.getItem(i));
+ }
+ return clone;
+ }
+
+ private static void inlineIncludes(XmlSchema schema, List processedSchemas) {
+ processedSchemas.add(schema);
+ XmlSchemaObjectCollection includes = schema.getIncludes();
+ for (int i = 0; i < includes.getCount(); i++) {
+ if (includes.getItem(i) instanceof XmlSchemaInclude) {
+ XmlSchemaInclude include = (XmlSchemaInclude) includes.getItem(i);
+ XmlSchema includedSchema = include.getSchema();
+ XmlSchemaObjectCollection items = schema.getItems();
+ if (!processedSchemas.contains(includedSchema)) {
+ inlineIncludes(includedSchema, processedSchemas);
+ XmlSchemaObjectCollection includesItems = includedSchema.getItems();
+ for (int j = 0; j < includesItems.getCount(); j++) {
+ XmlSchemaObject includedItem = includesItems.getItem(j);
+ items.add(includedItem);
+ }
+ }
+ // remove the
+ items.remove(include);
+ }
+ }
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer("CommonsXsdSchema");
+ buffer.append('{');
+ buffer.append(getTargetNamespace());
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+}
diff --git a/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaException.java b/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaException.java
new file mode 100644
index 00000000..dcf6797c
--- /dev/null
+++ b/xml/src/main/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008 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.xml.xsd.commons;
+
+import org.apache.ws.commons.schema.XmlSchemaException;
+
+import org.springframework.xml.xsd.XsdSchemaException;
+
+/**
+ * Commons XmlSchema version of the {@link XsdSchemaException}.
+ *
+ * @author Arjen Poutsma
+ * @since 1.5.0
+ */
+public class CommonsXsdSchemaException extends XsdSchemaException {
+
+ public CommonsXsdSchemaException(String message) {
+ super(message);
+ }
+
+ public CommonsXsdSchemaException(String message, XmlSchemaException exception) {
+ super(message, exception);
+ }
+}
diff --git a/xml/src/main/java/org/springframework/xml/xsd/commons/package.html b/xml/src/main/java/org/springframework/xml/xsd/commons/package.html
new file mode 100644
index 00000000..55ffa82d
--- /dev/null
+++ b/xml/src/main/java/org/springframework/xml/xsd/commons/package.html
@@ -0,0 +1,5 @@
+
+
+Contains a implementation of the XsdSchema interfaces that uses Apache WS-Commons XML Schema.
+
+
diff --git a/xml/src/main/java/org/springframework/xml/xsd/package.html b/xml/src/main/java/org/springframework/xml/xsd/package.html
new file mode 100644
index 00000000..7f65b3a7
--- /dev/null
+++ b/xml/src/main/java/org/springframework/xml/xsd/package.html
@@ -0,0 +1,5 @@
+
+
+Provides an abstraction over XSD XML schemas. Contains the XsdSchema and related interfaces.
+
+
diff --git a/xml/src/test/java/org/springframework/xml/xsd/SimpleXsdSchemaTest.java b/xml/src/test/java/org/springframework/xml/xsd/SimpleXsdSchemaTest.java
new file mode 100644
index 00000000..26e24e8c
--- /dev/null
+++ b/xml/src/test/java/org/springframework/xml/xsd/SimpleXsdSchemaTest.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright ${YEAR} 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.xml.xsd;
+
+import org.springframework.core.io.Resource;
+
+public class SimpleXsdSchemaTest extends AbstractXsdSchemaTestCase {
+
+ protected XsdSchema createSchema(Resource resource) throws Exception {
+ SimpleXsdSchema schema = new SimpleXsdSchema(resource);
+ schema.afterPropertiesSet();
+ return schema;
+ }
+
+}
\ No newline at end of file
diff --git a/xml/src/test/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaTest.java b/xml/src/test/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaTest.java
new file mode 100644
index 00000000..52d47832
--- /dev/null
+++ b/xml/src/test/java/org/springframework/xml/xsd/commons/CommonsXsdSchemaTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright ${YEAR} 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.xml.xsd.commons;
+
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.Source;
+
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.xml.xsd.AbstractXsdSchemaTestCase;
+import org.springframework.xml.xsd.XsdSchema;
+import org.springframework.xml.transform.ResourceSource;
+
+public class CommonsXsdSchemaTest extends AbstractXsdSchemaTestCase {
+
+ protected XsdSchema createSchema(Resource resource) throws Exception {
+ CommonsXsdSchema schema = new CommonsXsdSchema(resource);
+ schema.afterPropertiesSet();
+ return schema;
+ }
+
+ public void testInline() throws Exception {
+ Resource resource = new ClassPathResource("A.xsd", AbstractXsdSchemaTestCase.class);
+ CommonsXsdSchema schema = new CommonsXsdSchema(resource);
+ schema.afterPropertiesSet();
+ XsdSchema[] inlined = schema.inline();
+ for (int i = 0; i < inlined.length; i++) {
+ transformer.transform(inlined[i].getSource(), new StreamResult(System.out));
+ System.out.println();
+ }
+ }
+
+ public void testCircular() throws Exception {
+ Resource resource = new ClassPathResource("circular-1.xsd", AbstractXsdSchemaTestCase.class);
+ CommonsXsdSchema schema = new CommonsXsdSchema(resource);
+ schema.afterPropertiesSet();
+ XsdSchema[] inlined = schema.inline();
+ for (int i = 0; i < inlined.length; i++) {
+ transformer.transform(inlined[i].getSource(), new StreamResult(System.out));
+ System.out.println();
+ }
+ }
+}
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/A.xsd b/xml/src/test/resources/org/springframework/xml/xsd/A.xsd
new file mode 100644
index 00000000..dd680b01
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/A.xsd
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/AbstractXsdSchemaTestCase.java b/xml/src/test/resources/org/springframework/xml/xsd/AbstractXsdSchemaTestCase.java
new file mode 100644
index 00000000..dacc087d
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/AbstractXsdSchemaTestCase.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 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.xml.xsd;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+
+import org.custommonkey.xmlunit.XMLTestCase;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.w3c.dom.Document;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.xml.sax.SaxUtils;
+
+public abstract class AbstractXsdSchemaTestCase extends XMLTestCase {
+
+ private DocumentBuilder documentBuilder;
+
+ protected Transformer transformer;
+
+ protected final void setUp() throws Exception {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ transformer = transformerFactory.newTransformer();
+ XMLUnit.setIgnoreWhitespace(true);
+ }
+
+ public void testSingle() throws Exception {
+ Resource resource = new ClassPathResource("single.xsd", AbstractXsdSchemaTestCase.class);
+ XsdSchema single = createSchema(resource);
+ String namespace = "http://www.springframework.org/spring-ws/single/schema";
+ assertEquals("Invalid target namespace", namespace, single.getTargetNamespace());
+ QName[] elementNames = single.getElementNames();
+ assertQNamesEqual(new QName[]{new QName(namespace, "GetOrderRequest"), new QName(namespace, "GetOrderResponse"),
+ new QName(namespace, "GetOrderFault")}, elementNames);
+ resource = new ClassPathResource("single.xsd", AbstractXsdSchemaTestCase.class);
+ Document expected = documentBuilder.parse(SaxUtils.createInputSource(resource));
+ DOMResult domResult = new DOMResult();
+ transformer.transform(single.getSource(), domResult);
+ Document result = (Document) domResult.getNode();
+ assertXMLEqual("Invalid Source returned", expected, result);
+ }
+
+ public void testIncludes() throws Exception {
+ Resource resource = new ClassPathResource("including.xsd", AbstractXsdSchemaTestCase.class);
+ XsdSchema including = createSchema(resource);
+ String namespace = "http://www.springframework.org/spring-ws/include/schema";
+ assertEquals("Invalid target namespace", namespace, including.getTargetNamespace());
+ QName[] elementNames = including.getElementNames();
+ assertQNamesEqual(new QName[]{new QName(namespace, "GetOrderRequest")}, elementNames);
+ resource = new ClassPathResource("including.xsd", AbstractXsdSchemaTestCase.class);
+ Document expected = documentBuilder.parse(SaxUtils.createInputSource(resource));
+ DOMResult domResult = new DOMResult();
+ transformer.transform(including.getSource(), domResult);
+ Document result = (Document) domResult.getNode();
+ assertXMLEqual("Invalid Source returned", expected, result);
+ }
+
+ public void testImports() throws Exception {
+ Resource resource = new ClassPathResource("importing.xsd", AbstractXsdSchemaTestCase.class);
+ XsdSchema importing = createSchema(resource);
+ String namespace = "http://www.springframework.org/spring-ws/importing/schema";
+ assertEquals("Invalid target namespace", namespace, importing.getTargetNamespace());
+ QName[] elementNames = importing.getElementNames();
+ assertQNamesEqual(new QName[]{new QName(namespace, "GetOrderRequest")}, elementNames);
+ resource = new ClassPathResource("importing.xsd", AbstractXsdSchemaTestCase.class);
+ Document expected = documentBuilder.parse(SaxUtils.createInputSource(resource));
+ DOMResult domResult = new DOMResult();
+ transformer.transform(importing.getSource(), domResult);
+ Document result = (Document) domResult.getNode();
+ assertXMLEqual("Invalid Source returned", expected, result);
+ }
+
+ private void assertQNamesEqual(QName[] expected, QName[] result) {
+ Set expectedSet = new HashSet(Arrays.asList(expected));
+ Set resultSet = new HashSet(Arrays.asList(result));
+ assertEquals("Invalid QNames", expectedSet, resultSet);
+ }
+
+ protected abstract XsdSchema createSchema(Resource resource) throws Exception;
+}
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/B.xsd b/xml/src/test/resources/org/springframework/xml/xsd/B.xsd
new file mode 100644
index 00000000..cb797af5
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/B.xsd
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/C.xsd b/xml/src/test/resources/org/springframework/xml/xsd/C.xsd
new file mode 100644
index 00000000..932c8dcc
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/C.xsd
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/D.xsd b/xml/src/test/resources/org/springframework/xml/xsd/D.xsd
new file mode 100644
index 00000000..0f15daf5
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/D.xsd
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/circular-1.xsd b/xml/src/test/resources/org/springframework/xml/xsd/circular-1.xsd
new file mode 100644
index 00000000..673bce49
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/circular-1.xsd
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/circular-2.xsd b/xml/src/test/resources/org/springframework/xml/xsd/circular-2.xsd
new file mode 100644
index 00000000..00015897
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/circular-2.xsd
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/circular-3.xsd b/xml/src/test/resources/org/springframework/xml/xsd/circular-3.xsd
new file mode 100644
index 00000000..df7a3991
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/circular-3.xsd
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/imported.xsd b/xml/src/test/resources/org/springframework/xml/xsd/imported.xsd
new file mode 100644
index 00000000..22dcb834
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/imported.xsd
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/importing.xsd b/xml/src/test/resources/org/springframework/xml/xsd/importing.xsd
new file mode 100644
index 00000000..421f6aa7
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/importing.xsd
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/included.xsd b/xml/src/test/resources/org/springframework/xml/xsd/included.xsd
new file mode 100644
index 00000000..fc508ca7
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/included.xsd
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/including.xsd b/xml/src/test/resources/org/springframework/xml/xsd/including.xsd
new file mode 100644
index 00000000..78dd1daf
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/including.xsd
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/src/test/resources/org/springframework/xml/xsd/single.xsd b/xml/src/test/resources/org/springframework/xml/xsd/single.xsd
new file mode 100644
index 00000000..df338465
--- /dev/null
+++ b/xml/src/test/resources/org/springframework/xml/xsd/single.xsd
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file