Return-Path: Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: (qmail 72438 invoked from network); 21 Mar 2009 02:17:41 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 21 Mar 2009 02:17:41 -0000 Received: (qmail 59312 invoked by uid 500); 21 Mar 2009 02:17:40 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 59254 invoked by uid 500); 21 Mar 2009 02:17:40 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 59243 invoked by uid 99); 21 Mar 2009 02:17:40 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Mar 2009 19:17:40 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 21 Mar 2009 02:17:30 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 4358323888D5; Sat, 21 Mar 2009 02:17:09 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r756862 - in /cxf/trunk/common/common: ./ src/main/java/org/apache/cxf/common/xmlschema/ src/test/java/org/apache/cxf/common/xmlschema/ Date: Sat, 21 Mar 2009 02:17:08 -0000 To: commits@cxf.apache.org From: bimargulies@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090321021709.4358323888D5@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: bimargulies Date: Sat Mar 21 02:17:08 2009 New Revision: 756862 URL: http://svn.apache.org/viewvc?rev=756862&view=rev Log: Getting ready to fix CXF-2123. Add utility, to be migrated to XML schema, that finds all the possible reasons to add an to a schema, and adds them. I will make Aegis if not everything else call this. Note that this adds a test dependency on Xerces to get a known-behavior DOM3 validator of xml schemas. We may want to employ this for other kinds of tests to make sure that we produce only valid schemata. Added: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/ cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMErrorException.java (with props) cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMLSInput.java (with props) cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/ImportRepairTest.java (with props) Modified: cxf/trunk/common/common/pom.xml cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/XmlSchemaUtils.java Modified: cxf/trunk/common/common/pom.xml URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/pom.xml?rev=756862&r1=756861&r2=756862&view=diff ============================================================================== --- cxf/trunk/common/common/pom.xml (original) +++ cxf/trunk/common/common/pom.xml Sat Mar 21 02:17:08 2009 @@ -153,7 +153,13 @@ geronimo-ws-metadata_2.0_spec test - + + + xerces + xercesImpl + test + Modified: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java?rev=756862&r1=756861&r2=756862&view=diff ============================================================================== --- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java (original) +++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java Sat Mar 21 02:17:08 2009 @@ -33,8 +33,19 @@ import org.apache.ws.commons.schema.XmlSchema; import org.apache.ws.commons.schema.XmlSchemaAttribute; import org.apache.ws.commons.schema.XmlSchemaCollection; +import org.apache.ws.commons.schema.XmlSchemaComplexContentExtension; +import org.apache.ws.commons.schema.XmlSchemaComplexContentRestriction; +import org.apache.ws.commons.schema.XmlSchemaComplexType; +import org.apache.ws.commons.schema.XmlSchemaContent; +import org.apache.ws.commons.schema.XmlSchemaContentModel; import org.apache.ws.commons.schema.XmlSchemaElement; +import org.apache.ws.commons.schema.XmlSchemaObject; +import org.apache.ws.commons.schema.XmlSchemaObjectCollection; import org.apache.ws.commons.schema.XmlSchemaObjectTable; +import org.apache.ws.commons.schema.XmlSchemaParticle; +import org.apache.ws.commons.schema.XmlSchemaSequence; +import org.apache.ws.commons.schema.XmlSchemaSimpleContentExtension; +import org.apache.ws.commons.schema.XmlSchemaSimpleContentRestriction; import org.apache.ws.commons.schema.XmlSchemaSimpleType; import org.apache.ws.commons.schema.XmlSchemaType; import org.apache.ws.commons.schema.extensions.ExtensionRegistry; @@ -44,33 +55,33 @@ import org.apache.ws.commons.schema.utils.TargetNamespaceValidator; /** - * Wrapper class for XmlSchemaCollection that deals with various quirks and bugs. - * One bug is WSCOMMONS-272. + * Wrapper class for XmlSchemaCollection that deals with various quirks and bugs. One bug is WSCOMMONS-272. */ public class SchemaCollection { private static final Method GET_ELEMENT_BY_NAME_METHOD; static { Method m = null; try { - m = XmlSchema.class.getMethod("getElementByName", - new Class[] {String.class}); + m = XmlSchema.class.getMethod("getElementByName", new Class[] { + String.class + }); } catch (Exception ex) { - //ignore + // ignore } GET_ELEMENT_BY_NAME_METHOD = m; } - + private XmlSchemaCollection schemaCollection; - + public SchemaCollection() { this(new XmlSchemaCollection()); } - + public SchemaCollection(XmlSchemaCollection col) { schemaCollection = col; col.getExtReg().setDefaultExtensionDeserializer(new FixedExtensionDeserializer()); if (schemaCollection.getNamespaceContext() == null) { - // an empty prefix map avoids extra checks for null. + // an empty prefix map avoids extra checks for null. schemaCollection.setNamespaceContext(new NamespaceMap()); } } @@ -78,7 +89,7 @@ public XmlSchemaCollection getXmlSchemaCollection() { return schemaCollection; } - + public boolean equals(Object obj) { return schemaCollection.equals(obj); } @@ -86,7 +97,7 @@ public XmlSchemaElement getElementByQName(QName qname) { return schemaCollection.getElementByQName(qname); } - + public XmlSchemaAttribute getAttributeByQName(QName qname) { String uri = qname.getNamespaceURI(); for (XmlSchema schema : schemaCollection.getXmlSchemas()) { @@ -111,12 +122,11 @@ public XmlSchemaType getTypeByQName(QName schemaTypeName) { XmlSchemaType xst = schemaCollection.getTypeByQName(schemaTypeName); - - //HACKY workaround for WSCOMMONS-355 - if (xst == null - && "http://www.w3.org/2001/XMLSchema".equals(schemaTypeName.getNamespaceURI())) { + + // HACKY workaround for WSCOMMONS-355 + if (xst == null && "http://www.w3.org/2001/XMLSchema".equals(schemaTypeName.getNamespaceURI())) { XmlSchema sch = getSchemaByTargetNamespace(schemaTypeName.getNamespaceURI()); - + if ("anySimpleType".equals(schemaTypeName.getLocalPart())) { XmlSchemaSimpleType type = new XmlSchemaSimpleType(sch); type.setName(schemaTypeName.getLocalPart()); @@ -129,7 +139,7 @@ xst = type; } } - + return xst; } @@ -197,9 +207,10 @@ public void setSchemaResolver(URIResolver schemaResolver) { schemaCollection.setSchemaResolver(schemaResolver); } - + /** * This function is not part of the XmlSchema API. Who knows why? + * * @param namespaceURI targetNamespace * @return schema, or null. */ @@ -216,13 +227,14 @@ for (XmlSchema schema : schemaCollection.getXmlSchemas()) { if (name.getNamespaceURI().equals(schema.getTargetNamespace())) { - //for XmlSchema 1.4, we should use: - //schema.getElementByName(name.getLocalPart()) != null - //but that doesn't exist in 1.3 so for now, use reflection + // for XmlSchema 1.4, we should use: + // schema.getElementByName(name.getLocalPart()) != null + // but that doesn't exist in 1.3 so for now, use reflection try { if (GET_ELEMENT_BY_NAME_METHOD != null) { - if (GET_ELEMENT_BY_NAME_METHOD.invoke(schema, - new Object[] {name.getLocalPart()}) != null) { + if (GET_ELEMENT_BY_NAME_METHOD.invoke(schema, new Object[] { + name.getLocalPart() + }) != null) { return schema; } } else if (schema.getElementByName(name) != null) { @@ -230,9 +242,9 @@ } } catch (java.lang.reflect.InvocationTargetException ex) { - //ignore + // ignore } catch (IllegalAccessException ex) { - //ignore + // ignore } } } @@ -242,6 +254,7 @@ /** * Once upon a time, XmlSchema had a bug in the constructor used in this function. So this wrapper was * created to hold a workaround. + * * @param namespaceURI TNS for new schema. * @return new schema */ @@ -249,15 +262,16 @@ public XmlSchema newXmlSchemaInCollection(String namespaceURI) { return new XmlSchema(namespaceURI, schemaCollection); } - + /** * Validate that a qualified name points to some namespace in the schema. + * * @param qname */ public void validateQNameNamespace(QName qname) { // astonishingly, xmlSchemaCollection has no accessor by target URL. if ("".equals(qname.getNamespaceURI())) { - return; // references to the 'unqualified' namespace are OK even if there is no schema for it. + return; // references to the 'unqualified' namespace are OK even if there is no schema for it. } for (XmlSchema schema : schemaCollection.getXmlSchemas()) { if (schema.getTargetNamespace().equals(qname.getNamespaceURI())) { @@ -270,8 +284,7 @@ public void validateElementName(QName referrer, QName elementQName) { XmlSchemaElement element = schemaCollection.getElementByQName(elementQName); if (element == null) { - throw new InvalidXmlSchemaReferenceException(referrer - + " references non-existent element " + throw new InvalidXmlSchemaReferenceException(referrer + " references non-existent element " + elementQName); } } @@ -279,12 +292,11 @@ public void validateTypeName(QName referrer, QName typeQName) { XmlSchemaType type = schemaCollection.getTypeByQName(typeQName); if (type == null) { - throw new InvalidXmlSchemaReferenceException(referrer - + " references non-existent type " + throw new InvalidXmlSchemaReferenceException(referrer + " references non-existent type " + typeQName); } } - + public void addGlobalElementToSchema(XmlSchemaElement element) { synchronized (this) { XmlSchema schema = getSchemaByTargetNamespace(element.getQName().getNamespaceURI()); @@ -292,11 +304,114 @@ schema = newXmlSchemaInCollection(element.getQName().getNamespaceURI()); } schema.getItems().add(element); - // believe it or not, it is up to us to do both of these adds! + // believe it or not, it is up to us to do both of these adds! schema.getElements().add(element.getQName(), element); } } - + + public void addCrossImports() { + /* + * We need to inventory all the cross-imports to see if any are missing. + */ + for (XmlSchema schema : schemaCollection.getXmlSchemas()) { + addOneSchemaCrossImports(schema); + } + } + + private void addOneSchemaCrossImports(XmlSchema schema) { + /* + * We need to visit all the top-level items. + */ + for (int x = 0; x < schema.getItems().getCount(); x++) { + XmlSchemaObject item = schema.getItems().getItem(x); + if (item instanceof XmlSchemaElement) { + addElementCrossImportsElement(schema, item); + } else if (item instanceof XmlSchemaAttribute) { + XmlSchemaAttribute attr = (XmlSchemaAttribute)item; + XmlSchemaUtils.addImportIfNeeded(schema, attr.getRefName()); + XmlSchemaUtils.addImportIfNeeded(schema, attr.getSchemaTypeName()); + if (attr.getSchemaType() != null) { + XmlSchemaUtils.addImportIfNeeded(schema, attr.getSchemaType().getBaseSchemaTypeName()); + } + } else if (item instanceof XmlSchemaType) { + XmlSchemaType type = (XmlSchemaType)item; + addCrossImportsType(schema, type); + } + } + } + + private void addElementCrossImportsElement(XmlSchema schema, XmlSchemaObject item) { + XmlSchemaElement element = (XmlSchemaElement)item; + XmlSchemaUtils.addImportIfNeeded(schema, element.getRefName()); + XmlSchemaUtils.addImportIfNeeded(schema, element.getSchemaTypeName()); + // if there's an anonymous type, it might have element refs in it. + XmlSchemaType schemaType = element.getSchemaType(); + addCrossImportsType(schema, schemaType); + } + + private void addCrossImportsType(XmlSchema schema, XmlSchemaType schemaType) { + if (schemaType != null) { + // the base type might cross schemas. + XmlSchemaUtils.addImportIfNeeded(schema, schemaType.getBaseSchemaTypeName()); + if (schemaType instanceof XmlSchemaComplexType) { + XmlSchemaComplexType complexType = (XmlSchemaComplexType)schemaType; + addCrossImports(schema, complexType.getContentModel()); + addCrossImportsAttributeList(schema, complexType.getAttributes()); + // could it be a choice or something else? + XmlSchemaSequence sequence = XmlSchemaUtils.getSequence(complexType); + addCrossImportsSequence(schema, sequence); + } + } + } + + private void addCrossImportsSequence(XmlSchema schema, XmlSchemaSequence sequence) { + XmlSchemaObjectCollection items = sequence.getItems(); + for (int x = 0; x < items.getCount(); x++) { + XmlSchemaObject seqItem = items.getItem(x); + if (seqItem instanceof XmlSchemaElement) { + addElementCrossImportsElement(schema, seqItem); + } + } + } + + private void addCrossImportsAttributeList(XmlSchema schema, XmlSchemaObjectCollection attributes) { + for (int x = 0; x < attributes.getCount(); x++) { + XmlSchemaAttribute attr = (XmlSchemaAttribute)attributes.getItem(x); + XmlSchemaUtils.addImportIfNeeded(schema, attr.getRefName()); + } + } + + private void addCrossImports(XmlSchema schema, XmlSchemaContentModel contentModel) { + if (contentModel == null) { + return; + } + XmlSchemaContent content = contentModel.getContent(); + if (content == null) { + return; + } + if (content instanceof XmlSchemaComplexContentExtension) { + XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension) content; + XmlSchemaUtils.addImportIfNeeded(schema, extension.getBaseTypeName()); + addCrossImportsAttributeList(schema, extension.getAttributes()); + XmlSchemaParticle particle = extension.getParticle(); + if (particle instanceof XmlSchemaSequence) { + addCrossImportsSequence(schema, (XmlSchemaSequence)particle); + } + } else if (content instanceof XmlSchemaComplexContentRestriction) { + XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction) content; + XmlSchemaUtils.addImportIfNeeded(schema, restriction.getBaseTypeName()); + addCrossImportsAttributeList(schema, restriction.getAttributes()); + } else if (content instanceof XmlSchemaSimpleContentExtension) { + XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension) content; + XmlSchemaUtils.addImportIfNeeded(schema, extension.getBaseTypeName()); + addCrossImportsAttributeList(schema, extension.getAttributes()); + } else if (content instanceof XmlSchemaSimpleContentRestriction) { + XmlSchemaSimpleContentRestriction restriction = (XmlSchemaSimpleContentRestriction) content; + XmlSchemaUtils.addImportIfNeeded(schema, restriction.getBaseTypeName()); + addCrossImportsAttributeList(schema, restriction.getAttributes()); + } + } + public static void addGlobalElementToSchema(XmlSchema schema, XmlSchemaElement element) { synchronized (schema) { schema.getItems().add(element); @@ -304,7 +419,7 @@ schema.getElements().add(element.getQName(), element); } } - + public static void addGlobalTypeToSchema(XmlSchema schema, XmlSchemaType type) { synchronized (schema) { schema.getItems().add(type); Modified: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/XmlSchemaUtils.java URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/XmlSchemaUtils.java?rev=756862&r1=756861&r2=756862&view=diff ============================================================================== --- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/XmlSchemaUtils.java (original) +++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/XmlSchemaUtils.java Sat Mar 21 02:17:08 2009 @@ -224,6 +224,23 @@ inc.add(imp); schema.getItems().add(imp); } + + /** + * For convenience, start from a qname, and add the import if it is non-null + * and has a namespace. + * @see #addImportIfNeeded(XmlSchema, String) + * @param schema + * @param qname + */ + public static void addImportIfNeeded(XmlSchema schema, QName qname) { + if (qname == null) { + return; + } + if (qname.getNamespaceURI() == null) { + return; + } + addImportIfNeeded(schema, qname.getNamespaceURI()); + } /** * This copes with an observed phenomenon in the schema built by the @@ -636,7 +653,7 @@ throw new UnsupportedConstruct(message); } - + public static void unsupportedConstruct(String messageKey, XmlSchemaType subject) { Message message = new Message(messageKey, LOG, subject.getQName(), cleanedUpSchemaSource(subject)); Added: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMErrorException.java URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMErrorException.java?rev=756862&view=auto ============================================================================== --- cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMErrorException.java (added) +++ cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMErrorException.java Sat Mar 21 02:17:08 2009 @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.common.xmlschema; + +import org.w3c.dom.DOMError; + +/** + * + */ +public class DOMErrorException extends RuntimeException { + private DOMError error; + + public DOMErrorException(DOMError error) { + this.error = error; + } + + public DOMError getError() { + return error; + } + +} Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMErrorException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMErrorException.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMLSInput.java URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMLSInput.java?rev=756862&view=auto ============================================================================== --- cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMLSInput.java (added) +++ cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMLSInput.java Sat Mar 21 02:17:08 2009 @@ -0,0 +1,131 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.common.xmlschema; + +import java.io.InputStream; +import java.io.Reader; +import java.io.StringWriter; +import java.util.logging.Logger; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.w3c.dom.ls.LSInput; + +import org.apache.cxf.common.logging.LogUtils; + +/** + * + */ +class DOMLSInput implements LSInput { + private static final Logger LOG = LogUtils.getL7dLogger(DOMLSInput.class); + private String systemId; + private String data; + + DOMLSInput(Document doc, String systemId) throws TransformerException { + this.systemId = systemId; + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + DOMSource source = new DOMSource(doc); + source.setSystemId(systemId); + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + transformer.transform(source, result); + data = writer.toString(); + LOG.fine(systemId + ": " + data); + + } + + /** {@inheritDoc}*/ + public String getBaseURI() { + return null; + } + + /** {@inheritDoc}*/ + public InputStream getByteStream() { + return null; + } + + /** {@inheritDoc}*/ + public boolean getCertifiedText() { + return false; + } + + /** {@inheritDoc}*/ + public Reader getCharacterStream() { + return null; + } + + /** {@inheritDoc}*/ + public String getEncoding() { + return "utf-8"; + } + + /** {@inheritDoc}*/ + public String getPublicId() { + return null; + } + + /** {@inheritDoc}*/ + public String getStringData() { + return data; + } + + /** {@inheritDoc}*/ + public String getSystemId() { + return systemId; + } + + /** {@inheritDoc}*/ + public void setBaseURI(String baseURI) { + } + + /** {@inheritDoc}*/ + public void setByteStream(InputStream byteStream) { + } + + /** {@inheritDoc}*/ + public void setCertifiedText(boolean certifiedText) { + } + + /** {@inheritDoc}*/ + public void setCharacterStream(Reader characterStream) { + } + + /** {@inheritDoc}*/ + public void setEncoding(String encoding) { + } + + /** {@inheritDoc}*/ + public void setPublicId(String publicId) { + } + + /** {@inheritDoc}*/ + public void setStringData(String stringData) { + } + + /** {@inheritDoc}*/ + public void setSystemId(String systemId) { + } +} Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMLSInput.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/DOMLSInput.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/ImportRepairTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/ImportRepairTest.java?rev=756862&view=auto ============================================================================== --- cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/ImportRepairTest.java (added) +++ cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/ImportRepairTest.java Sat Mar 21 02:17:08 2009 @@ -0,0 +1,297 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.common.xmlschema; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.transform.TransformerException; + +import org.w3c.dom.DOMError; +import org.w3c.dom.DOMErrorHandler; +import org.w3c.dom.Document; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSResourceResolver; + +import org.apache.cxf.common.logging.LogUtils; +import org.apache.ws.commons.schema.XmlSchema; +import org.apache.ws.commons.schema.XmlSchemaAttribute; +import org.apache.ws.commons.schema.XmlSchemaComplexContent; +import org.apache.ws.commons.schema.XmlSchemaComplexContentExtension; +import org.apache.ws.commons.schema.XmlSchemaComplexContentRestriction; +import org.apache.ws.commons.schema.XmlSchemaComplexType; +import org.apache.ws.commons.schema.XmlSchemaElement; +import org.apache.ws.commons.schema.XmlSchemaSequence; +import org.apache.ws.commons.schema.XmlSchemaSerializer; +import org.apache.ws.commons.schema.XmlSchemaSerializer.XmlSchemaSerializerException; +import org.apache.ws.commons.schema.XmlSchemaSimpleType; +import org.apache.ws.commons.schema.XmlSchemaSimpleTypeRestriction; +import org.apache.ws.commons.schema.utils.NamespaceMap; +import org.apache.xerces.xs.LSInputList; +import org.apache.xerces.xs.XSImplementation; +import org.apache.xerces.xs.XSLoader; + +import org.junit.Assert; +import org.junit.Test; + +/** + * + */ +public class ImportRepairTest extends Assert { + private static final class ListLSInput implements LSInputList { + private final List inputs; + + private ListLSInput(List inputs) { + this.inputs = inputs; + } + + public int getLength() { + return inputs.size(); + } + + public LSInput item(int index) { + return inputs.get(index); + } + } + + private static final Logger LOG = LogUtils.getL7dLogger(ImportRepairTest.class); + + private static final String IMPORTING_SCHEMA = "urn:importing"; + private static final String BASE_TYPE_SCHEMA1 = "urn:baseType1"; + private static final String BASE_TYPE_SCHEMA2 = "urn:baseType2"; + private static final String ELEMENT_TYPE_SCHEMA = "urn:elementType"; + private static final String ELEMENT_SCHEMA = "urn:element"; + private static final String ATTRIBUTE_SCHEMA = "urn:attribute"; + private static final String ATTRIBUTE_TYPE_SCHEMA = "urn:attributeType"; + + private SchemaCollection collection; + + @Test + public void testImportRepairs() throws Exception { + collection = new SchemaCollection(); + XmlSchema importingSchema = newSchema(IMPORTING_SCHEMA); + XmlSchema baseTypeSchema1 = newSchema(BASE_TYPE_SCHEMA1); + XmlSchema baseTypeSchema2 = newSchema(BASE_TYPE_SCHEMA2); + XmlSchema elementTypeSchema = newSchema(ELEMENT_TYPE_SCHEMA); + XmlSchema elementSchema = newSchema(ELEMENT_SCHEMA); + XmlSchema attributeSchema = newSchema(ATTRIBUTE_SCHEMA); + XmlSchema attributeTypeSchema = newSchema(ATTRIBUTE_TYPE_SCHEMA); + + createBaseType1(baseTypeSchema1); + + createBaseType2(baseTypeSchema2); + XmlSchemaComplexContentExtension derivedType1Extension = createDerivedType1(importingSchema); + createDerivedType2(importingSchema); + + createImportedElement(elementSchema); + + createTypeImportingElement(importingSchema); + + createTypeImportedByElement(elementTypeSchema); + + createElementWithImportedType(importingSchema); + + createImportedAttribute(attributeSchema); + + XmlSchemaAttribute importingAttribute = new XmlSchemaAttribute(); + importingAttribute.setRefName(new QName(ATTRIBUTE_SCHEMA, "imported")); + // borrow derivedType1 to make the reference. + derivedType1Extension.getAttributes().add(importingAttribute); + + createImportedAttributeType(attributeTypeSchema); + + createAttributeImportingType(importingSchema); + + /* + * Notice that no imports have been added. In an ideal world, XmlSchema would do this for us. + */ + boolean threw = false; + try { + tryToParseSchemas(); + } catch (DOMErrorException e) { + threw = true; + } + assertTrue(threw); + LOG.info("adding imports"); + collection.addCrossImports(); + tryToParseSchemas(); + } + + private void tryToParseSchemas() throws ClassNotFoundException, InstantiationException, + IllegalAccessException, XmlSchemaSerializerException, TransformerException { + // Get DOM Implementation using DOM Registry + final List inputs = new ArrayList(); + final Map resolverMap = new HashMap(); + + for (XmlSchema schema : collection.getXmlSchemas()) { + if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(schema.getTargetNamespace())) { + continue; + } + Document document = new XmlSchemaSerializer().serializeSchema(schema, false)[0]; + DOMLSInput input = new DOMLSInput(document, schema.getTargetNamespace()); + resolverMap.put(schema.getTargetNamespace(), input); + inputs.add(input); + } + + System.setProperty(DOMImplementationRegistry.PROPERTY, + "org.apache.xerces.dom.DOMXSImplementationSourceImpl"); + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + + XSImplementation impl = (XSImplementation)registry.getDOMImplementation("XS-Loader"); + + XSLoader schemaLoader = impl.createXSLoader(null); + schemaLoader.getConfig().setParameter("validate", Boolean.TRUE); + schemaLoader.getConfig().setParameter("error-handler", new DOMErrorHandler() { + + public boolean handleError(DOMError error) { + LOG.info("Schema parsing error: " + error.getMessage()); + throw new DOMErrorException(error); + } + }); + schemaLoader.getConfig().setParameter("resource-resolver", new LSResourceResolver() { + + public LSInput resolveResource(String type, String namespaceURI, String publicId, + String systemId, String baseURI) { + return resolverMap.get(namespaceURI); + } + }); + + schemaLoader.loadInputList(new ListLSInput(inputs)); + } + + private void createTypeImportedByElement(XmlSchema elementTypeSchema) { + XmlSchemaComplexType elementImportedType = new XmlSchemaComplexType(elementTypeSchema); + elementImportedType.setName("importedElementType"); + elementTypeSchema.addType(elementImportedType); + elementTypeSchema.getItems().add(elementImportedType); + elementImportedType.setParticle(new XmlSchemaSequence()); + } + + private XmlSchema newSchema(String uri) { + XmlSchema schema = collection.newXmlSchemaInCollection(uri); + schema.setNamespaceContext(new NamespaceMap()); + return schema; + } + + private void createAttributeImportingType(XmlSchema importingSchema) { + XmlSchemaAttribute attributeImportingType = new XmlSchemaAttribute(); + attributeImportingType.setName("importingType"); + importingSchema.getAttributes().add(new QName(ELEMENT_SCHEMA, "importingTypeAttribute"), + attributeImportingType); + importingSchema.getItems().add(attributeImportingType); + attributeImportingType.setSchemaTypeName(new QName(ATTRIBUTE_TYPE_SCHEMA, "importedAttributeType")); + } + + private void createImportedAttributeType(XmlSchema attributeTypeSchema) { + XmlSchemaSimpleType attributeImportedType = new XmlSchemaSimpleType(attributeTypeSchema); + attributeImportedType.setName("importedAttributeType"); + attributeTypeSchema.addType(attributeImportedType); + attributeTypeSchema.getItems().add(attributeImportedType); + XmlSchemaSimpleTypeRestriction simpleContent = new XmlSchemaSimpleTypeRestriction(); + attributeImportedType.setContent(simpleContent); + simpleContent.setBaseTypeName(new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "string")); + } + + private void createImportedAttribute(XmlSchema attributeSchema) { + XmlSchemaAttribute importedAttribute = new XmlSchemaAttribute(); + importedAttribute.setName("imported"); + importedAttribute.setSchemaTypeName(new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "string")); + attributeSchema.getAttributes().add(new QName(ATTRIBUTE_SCHEMA, "imported"), importedAttribute); + attributeSchema.getItems().add(importedAttribute); + } + + private void createElementWithImportedType(XmlSchema importingSchema) { + XmlSchemaElement elementWithImportedType = new XmlSchemaElement(); + elementWithImportedType.setName("elementWithImportedType"); + elementWithImportedType.setSchemaTypeName(new QName(ELEMENT_TYPE_SCHEMA, "importedElementType")); + importingSchema.getItems().add(elementWithImportedType); + importingSchema.getElements().add(elementWithImportedType.getQName(), elementWithImportedType); + } + + private void createTypeImportingElement(XmlSchema importingSchema) { + XmlSchemaComplexType typeWithElementRef = new XmlSchemaComplexType(importingSchema); + typeWithElementRef.setName("typeWithRef"); + importingSchema.addType(typeWithElementRef); + importingSchema.getItems().add(typeWithElementRef); + XmlSchemaSequence sequence = new XmlSchemaSequence(); + typeWithElementRef.setParticle(sequence); + XmlSchemaElement refElement = new XmlSchemaElement(); + sequence.getItems().add(refElement); + refElement.setRefName(new QName(ELEMENT_SCHEMA, "importedElement")); + } + + private void createImportedElement(XmlSchema elementSchema) { + XmlSchemaElement importedElement = new XmlSchemaElement(); + importedElement.setName("importedElement"); + importedElement.setSchemaTypeName(new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "string")); + elementSchema.getElements().add(new QName(ELEMENT_SCHEMA, "importedElement"), importedElement); + elementSchema.getItems().add(importedElement); + } + + private void createDerivedType2(XmlSchema importingSchema) { + XmlSchemaComplexContent complexContent; + XmlSchemaComplexType derivedType2 = new XmlSchemaComplexType(importingSchema); + derivedType2.setName("derivedRestriction"); + XmlSchemaComplexContentRestriction restriction = new XmlSchemaComplexContentRestriction(); + restriction.setBaseTypeName(new QName(BASE_TYPE_SCHEMA2, "baseType2")); + complexContent = new XmlSchemaComplexContent(); + complexContent.setContent(restriction); + derivedType2.setContentModel(complexContent); + importingSchema.addType(derivedType2); + importingSchema.getItems().add(derivedType2); + } + + private XmlSchemaComplexContentExtension createDerivedType1(XmlSchema importingSchema) { + XmlSchemaComplexType derivedType1 = new XmlSchemaComplexType(importingSchema); + derivedType1.setName("derivedExtension"); + XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension(); + extension.setBaseTypeName(new QName(BASE_TYPE_SCHEMA1, "baseType1")); + XmlSchemaComplexContent complexContent = new XmlSchemaComplexContent(); + complexContent.setContent(extension); + derivedType1.setContentModel(complexContent); + importingSchema.addType(derivedType1); + importingSchema.getItems().add(derivedType1); + return extension; + } + + private XmlSchemaComplexType createBaseType2(XmlSchema baseTypeSchema2) { + XmlSchemaComplexType baseType2 = new XmlSchemaComplexType(baseTypeSchema2); + baseType2.setName("baseType2"); + baseTypeSchema2.addType(baseType2); + baseTypeSchema2.getItems().add(baseType2); + baseType2.setParticle(new XmlSchemaSequence()); + return baseType2; + } + + private void createBaseType1(XmlSchema baseTypeSchema1) { + XmlSchemaComplexType baseType1 = new XmlSchemaComplexType(baseTypeSchema1); + baseType1.setName("baseType1"); + baseTypeSchema1.addType(baseType1); + baseTypeSchema1.getItems().add(baseType1); + baseType1.setParticle(new XmlSchemaSequence()); + } + +} Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/ImportRepairTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/xmlschema/ImportRepairTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date