This commit is contained in:
Arjen Poutsma
2008-03-05 16:06:55 +00:00
parent 2d974e7264
commit 917f939ac7
8 changed files with 154 additions and 205 deletions

View File

@@ -662,6 +662,7 @@
<link>http://jakarta.apache.org/commons/httpclient/apidocs/</link>
<link>http://ws.apache.org/wss4j/apidocs/</link>
<link>http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/</link>
<link>http://ws.apache.org/commons/XmlSchema/apidocs/</link>
</links>
</configuration>
</plugin>

View File

@@ -1,101 +0,0 @@
/*
* 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.ws.wsdl.wsdl11;
import java.util.Iterator;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.namespace.QName;
import junit.framework.TestCase;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaObjectTable;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaSimpleType;
import org.apache.ws.commons.schema.XmlSchemaSimpleTypeRestriction;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaExternal;
import org.apache.ws.commons.schema.XmlSchemaInclude;
import org.apache.ws.commons.schema.XmlSchemaImport;
import org.w3c.dom.Document;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.xml.sax.SaxUtils;
/**
* @author Arjen Poutsma
* @since 1.5.0
*/
public class CommonXsdTest extends TestCase {
public void testIt() throws Exception {
XmlSchemaCollection collection = new XmlSchemaCollection();
Resource r = new ClassPathResource("A.xsd", getClass());
XmlSchema schema = collection.read(SaxUtils.createInputSource(r), null);
handleSchema(schema);
schema.write(System.out);
r = new ClassPathResource("D.xsd", getClass());
schema = collection.read(SaxUtils.createInputSource(r), null);
handleSchema(schema);
schema.write(System.out);
}
private void handleSchema(XmlSchema schema) {
if ("http://www.w3.org/2001/XMLSchema".equals(schema.getTargetNamespace())) {
return;
}
XmlSchemaObjectCollection includes = schema.getIncludes();
for (int i = 0; i < includes.getCount(); i++) {
XmlSchemaExternal external = (XmlSchemaExternal) includes.getItem(i);
if (external instanceof XmlSchemaInclude) {
XmlSchema includedSchema = external.getSchema();
handleSchema(includedSchema);
XmlSchemaObjectCollection includesItems = includedSchema.getItems();
for (int j = 0; j < includesItems.getCount(); j++) {
schema.getItems().add(includesItems.getItem(j));
}
// includes.remove(external);
schema.getItems().remove(external);
}
}
}
private void dumpSchemaObject(XmlSchemaObject obj) {
System.out.println(obj);
if (obj instanceof XmlSchemaSimpleType) {
XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType) obj;
XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction) simpleType.getContent();
System.out.println("simple type with base name " + restriction.getBaseTypeName());
} else if (obj instanceof XmlSchemaComplexType) {
XmlSchemaComplexType complexType = (XmlSchemaComplexType) obj;
XmlSchemaSequence seq = (XmlSchemaSequence) complexType.getParticle();
System.out.println("complex type containing sequence");
XmlSchemaObjectCollection seqCol = seq.getItems();
for (int j = 0; j < seqCol.getCount(); j++) {
XmlSchemaElement element = (XmlSchemaElement) seqCol.getItem(j);
dumpSchemaObject(element.getSchemaType());
}
}
}
}

View File

@@ -29,15 +29,15 @@ import javax.xml.transform.Source;
public interface XsdSchema {
/**
* Returns the target namespace of theis schema.
* Returns the target namespace of this 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 <code>element</code>, <code>simplyType</code>, or <code>complexType</code>.
* Returns the qualified names of all top-level elements declared in the schema. This excludes elements declared as
* child of another <code>element</code>, <code>simplyType</code>, or <code>complexType</code>.
*
* @return the top-level element names
*/

View File

@@ -18,7 +18,6 @@ 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;
@@ -27,9 +26,6 @@ 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.XmlSchemaObjectCollection;
import org.xml.sax.SAXException;
import org.springframework.util.Assert;
import org.springframework.xml.xsd.XsdSchema;
@@ -43,7 +39,7 @@ import org.springframework.xml.xsd.XsdSchema;
*/
public class CommonsXsdSchema implements XsdSchema {
private XmlSchema schema;
private final XmlSchema schema;
/**
* Create a new instance of the {@link CommonsXsdSchema} class with the specified {@link XmlSchema} reference.
@@ -70,17 +66,6 @@ public class CommonsXsdSchema implements XsdSchema {
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);
@@ -93,51 +78,6 @@ public class CommonsXsdSchema implements XsdSchema {
return schema;
}
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 <include/>
items.remove(include);
}
}
}*/
public String toString() {
StringBuffer buffer = new StringBuffer("CommonsXsdSchema");
buffer.append('{');

View File

@@ -16,14 +16,18 @@
package org.springframework.xml.xsd.commons;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.commons.schema.ValidationEventHandler;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.constants.Constants;
import org.apache.ws.commons.schema.XmlSchemaExternal;
import org.apache.ws.commons.schema.XmlSchemaImport;
import org.apache.ws.commons.schema.XmlSchemaInclude;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
@@ -34,6 +38,10 @@ import org.springframework.xml.xsd.XsdSchemaCollection;
/**
* Implementation of the {@link XsdSchemaCollection} that uses Apache WS-Commons XML Schema.
* <p/>
* Setting the {@link #setInline(boolean) inline} flag to <code>true</code> will result in all referenced schemas
* (included and imported) being merged into the referred schema. When including the schemas into a WSDL, this greatly
* simplifies the deloyment of the schemas.
*
* @author Arjen Poutsma
* @see <a href="http://ws.apache.org/commons/XmlSchema/">Commons XML Schema</a>
@@ -41,15 +49,15 @@ import org.springframework.xml.xsd.XsdSchemaCollection;
*/
public class CommonsXsdSchemaCollection implements XsdSchemaCollection, InitializingBean {
private static final Log logger = LogFactory.getLog(CommonsXsdSchemaCollection.class);
private final XmlSchemaCollection schemaCollection = new XmlSchemaCollection();
private final List xmlSchemas = new ArrayList();
private Resource[] xsdResources;
private boolean inlineIncludes = false;
private boolean inline = false;
private ValidationEventHandler validationEventHandler;
/**
* Constructs a new, empty instance of the <code>CommonsXsdSchemaCollection</code>.
@@ -82,15 +90,26 @@ public class CommonsXsdSchemaCollection implements XsdSchemaCollection, Initiali
* <p/>
* Defaults to <code>false</code>.
*/
public void setInlineIncludes(boolean inlineIncludes) {
this.inlineIncludes = inlineIncludes;
public void setInline(boolean inline) {
this.inline = inline;
}
public void afterPropertiesSet() throws Exception {
/** Sets the WS-Commons validation event handler to use while parsing schemas. */
public void setValidationEventHandler(ValidationEventHandler validationEventHandler) {
this.validationEventHandler = validationEventHandler;
}
public void afterPropertiesSet() throws IOException {
Assert.notEmpty(xsdResources, "'xsds' must not be empty");
for (int i = 0; i < xsdResources.length; i++) {
Assert.isTrue(xsdResources[i].exists(), xsdResources[i] + " does not exit");
xmlSchemas.add(schemaCollection.read(SaxUtils.createInputSource(xsdResources[i]), null));
XmlSchema xmlSchema =
schemaCollection.read(SaxUtils.createInputSource(xsdResources[i]), validationEventHandler);
xmlSchemas.add(xmlSchema);
if (inline) {
inlineIncludes(xmlSchema, new ArrayList());
findImports(xmlSchema, new ArrayList());
}
}
}
@@ -103,16 +122,55 @@ public class CommonsXsdSchemaCollection implements XsdSchemaCollection, Initiali
return result;
}
private void inlineIncludes(XmlSchema schema, List processedSchemas) {
processedSchemas.add(schema);
XmlSchemaObjectCollection includes = schema.getIncludes();
for (int i = 0; i < includes.getCount(); i++) {
XmlSchemaExternal external = (XmlSchemaExternal) includes.getItem(i);
if (external instanceof XmlSchemaInclude) {
XmlSchema includedSchema = external.getSchema();
XmlSchemaObjectCollection items = schema.getItems();
if (!processedSchemas.contains(includedSchema)) {
inlineIncludes(includedSchema, processedSchemas);
findImports(includedSchema, new ArrayList());
XmlSchemaObjectCollection includeItems = includedSchema.getItems();
for (int j = 0; j < includeItems.getCount(); j++) {
XmlSchemaObject includedItem = includeItems.getItem(j);
items.add(includedItem);
}
}
// remove the <include/>
items.remove(external);
}
}
}
private void findImports(XmlSchema schema, List processedSchemas) {
processedSchemas.add(schema);
XmlSchemaObjectCollection includes = schema.getIncludes();
for (int i = 0; i < includes.getCount(); i++) {
XmlSchemaExternal external = (XmlSchemaExternal) includes.getItem(i);
if (external instanceof XmlSchemaImport) {
XmlSchema importedSchema = external.getSchema();
if (!processedSchemas.contains(importedSchema)) {
inlineIncludes(importedSchema, processedSchemas);
findImports(importedSchema, processedSchemas);
xmlSchemas.add(importedSchema);
}
// remove the schemaLocation
external.setSchemaLocation(null);
}
}
}
public String toString() {
StringBuffer buffer = new StringBuffer("CommonsXsdSchemaCollection");
buffer.append('{');
XmlSchema[] schemas = schemaCollection.getXmlSchemas();
for (int i = 0; i < schemas.length; i++) {
if (!Constants.URI_2001_SCHEMA_XSD.equals(schemas[i].getTargetNamespace())) {
buffer.append(schemas[i].getTargetNamespace());
if (i < schemas.length - 1) {
buffer.append(',');
}
for (int i = 0; i < xmlSchemas.size(); i++) {
XmlSchema schema = (XmlSchema) xmlSchemas.get(i);
buffer.append(schema.getTargetNamespace());
if (i < xmlSchemas.size() - 1) {
buffer.append(',');
}
}
buffer.append('}');

View File

@@ -16,18 +16,38 @@
package org.springframework.xml.xsd.commons;
import junit.framework.TestCase;
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;
import org.springframework.xml.xsd.AbstractXsdSchemaTestCase;
import org.springframework.xml.xsd.XsdSchema;
public class CommonsXsdSchemaCollectionTest extends TestCase {
public class CommonsXsdSchemaCollectionTest extends XMLTestCase {
private CommonsXsdSchemaCollection collection;
private Transformer transformer;
private DocumentBuilder documentBuilder;
protected void setUp() throws Exception {
collection = new CommonsXsdSchemaCollection();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformer = transformerFactory.newTransformer();
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
documentBuilder = documentBuilderFactory.newDocumentBuilder();
XMLUnit.setIgnoreWhitespace(true);
}
public void testSingle() throws Exception {
@@ -37,32 +57,36 @@ public class CommonsXsdSchemaCollectionTest extends TestCase {
assertEquals("Invalid amount of XSDs loaded", 1, collection.getXsdSchemas().length);
}
public void testIncludes() throws Exception {
Resource resource = new ClassPathResource("including.xsd", AbstractXsdSchemaTestCase.class);
collection.setXsds(new Resource[]{resource});
public void testInlineComplex() throws Exception {
Resource a = new ClassPathResource("A.xsd", AbstractXsdSchemaTestCase.class);
collection.setXsds(new Resource[]{a});
collection.setInline(true);
collection.afterPropertiesSet();
assertEquals("Invalid amount of XSDs loaded", 2, collection.getXsdSchemas().length);
XsdSchema[] schemas = collection.getXsdSchemas();
assertEquals("Invalid amount of XSDs loaded", 2, schemas.length);
assertEquals("Invalid target namespace", "urn:1", schemas[0].getTargetNamespace());
Resource abc = new ClassPathResource("ABC.xsd", AbstractXsdSchemaTestCase.class);
Document expected = documentBuilder.parse(SaxUtils.createInputSource(abc));
DOMResult domResult = new DOMResult();
transformer.transform(schemas[0].getSource(), domResult);
assertXMLEqual("Invalid XSD generated", expected, (Document) domResult.getNode());
assertEquals("Invalid target namespace", "urn:2", schemas[1].getTargetNamespace());
Resource cd = new ClassPathResource("CD.xsd", AbstractXsdSchemaTestCase.class);
expected = documentBuilder.parse(SaxUtils.createInputSource(cd));
domResult = new DOMResult();
transformer.transform(schemas[1].getSource(), domResult);
assertXMLEqual("Invalid XSD generated", expected, (Document) domResult.getNode());
}
public void testImports() throws Exception {
Resource resource = new ClassPathResource("importing.xsd", AbstractXsdSchemaTestCase.class);
public void testCircular() throws Exception {
Resource resource = new ClassPathResource("circular-1.xsd", AbstractXsdSchemaTestCase.class);
collection.setXsds(new Resource[]{resource});
collection.setInline(true);
collection.afterPropertiesSet();
assertEquals("Invalid amount of XSDs loaded", 2, collection.getXsdSchemas().length);
}
public void testDuplicates() throws Exception {
Resource resource = new ClassPathResource("single.xsd", AbstractXsdSchemaTestCase.class);
collection.setXsds(new Resource[]{resource, resource});
collection.afterPropertiesSet();
assertEquals("Invalid amount of XSDs loaded", 1, collection.getXsdSchemas().length);
}
public void testComplex() throws Exception {
Resource resource = new ClassPathResource("A.xsd", AbstractXsdSchemaTestCase.class);
collection.setXsds(new Resource[]{resource});
collection.afterPropertiesSet();
assertEquals("Invalid amount of XSDs loaded", 5, collection.getXsdSchemas().length);
XsdSchema[] schemas = collection.getXsdSchemas();
assertEquals("Invalid amount of XSDs loaded", 1, schemas.length);
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<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="B">
<xsd:sequence>
<xsd:element name="c" type="tns:C"/>
<xsd:element name="d" type="ns0:D"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="C">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
</xsd:schema>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:2" attributeFormDefault="unqualified"
elementFormDefault="qualified" targetNamespace="urn:2">
<xsd:simpleType name="D">
<xsd:restriction base="C"/>
</xsd:simpleType>
<xsd:simpleType name="C">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
</xsd:schema>