[Practicalxml-commits] SF.net SVN: practicalxml:[28] trunk/src
Brought to you by:
kdgregory
From: Auto-Generated S. C. M. <pra...@li...> - 2008-10-08 00:08:43
|
Revision: 28 http://practicalxml.svn.sourceforge.net/practicalxml/?rev=28&view=rev Author: kdgregory Date: 2008-10-08 00:08:37 +0000 (Wed, 08 Oct 2008) Log Message: ----------- SchemaUtil: initial revision Added Paths: ----------- trunk/src/main/java/net/sf/practicalxml/SchemaUtil.java trunk/src/test/java/net/sf/practicalxml/TestSchemaUtil.java Added: trunk/src/main/java/net/sf/practicalxml/SchemaUtil.java =================================================================== --- trunk/src/main/java/net/sf/practicalxml/SchemaUtil.java (rev 0) +++ trunk/src/main/java/net/sf/practicalxml/SchemaUtil.java 2008-10-08 00:08:37 UTC (rev 28) @@ -0,0 +1,109 @@ +package net.sf.practicalxml; + +import javax.xml.XMLConstants; +import javax.xml.transform.dom.DOMSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + + +/** + * A collection of static utility methods for working with XML Schema + * documents. Since <code>javax.xml.validation.Schema</code> is an + * opaque object, most of these actually work with DOM documents that + * contain an XSD. + */ +public class SchemaUtil +{ + private final static String SCHEMA_NS = XMLConstants.W3C_XML_SCHEMA_NS_URI; + private final static String SCHEMA_PREFIX = "xsd"; + private final static String SCHEMA_ROOT = "schema"; + + + /** + * Creates a new <code>javax.xml.validation.SchemaFactory</code> instance + * for validation with XML Schema, which reports errors via the specified + * error handler. + */ + public synchronized static SchemaFactory newFactory(ErrorHandler errHandler) + { + SchemaFactory fact = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + fact.setErrorHandler(errHandler); + return fact; + } + + + /** + * A workaround for Sun bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6198705"> + * 6198705</code>, also known as Xerces bug <a href="http://issues.apache.org/jira/browse/XERCESJ-1130"> + * XERCESJ-1130</code>, which prevents the <code>SchemaFactory.ewSchema</code> + * method from combining multiple sources that have the same namespace. + * <p> + * This method works by parsing the children of the passed sources, + * verifying that their root element is <code><xsd:schema></code>, + * combining the children of this root into a new document, and calling + * <code>newSchema()</code> on the result. + * + * @param factory Used to create the schema object. This factory's + * <code>ErrorHandler</code> is also used to report + * errors when parsing the source documents. + * @param sources The source schema documents. + * + * @throws XmlException on any failure that is not handled by the + * factory's <code>ErrorHandler</code>. This includes parse + * errors and local validation of the source root element. + */ + public static Schema newSchema(SchemaFactory factory, InputSource... sources) + { + Element combined = DomUtil.newDocument(SCHEMA_NS, SCHEMA_PREFIX + ":" + SCHEMA_ROOT); + for (InputSource source : sources) + { + combineSchema(combined, source); + } + + System.out.println(OutputUtil.indentedString(combined.getOwnerDocument(), 4)); + + try + { + synchronized (factory) + { + return factory.newSchema(new DOMSource(combined.getOwnerDocument())); + } + } + catch (SAXException e) + { + throw new XmlException("unable to generate schema", e); + } + } + + +//---------------------------------------------------------------------------- +// Internals +//---------------------------------------------------------------------------- + + /** + * Parses, verifies, and combines a source document. + */ + private static void combineSchema(Element newRoot, InputSource source) + { + Document doc = ParseUtil.parse(source); + Element root = doc.getDocumentElement(); + if (!DomUtil.isNamed(root, SCHEMA_NS, SCHEMA_ROOT)) + { + throw new XmlException("invalid root element name: {" + + root.getNamespaceURI() + "}" + + DomUtil.getLocalName(root)); + } + for (Element child : DomUtil.getChildren(root)) + { + Node tmp = newRoot.getOwnerDocument().importNode(child, true); + newRoot.appendChild(tmp); + } + } +} Added: trunk/src/test/java/net/sf/practicalxml/TestSchemaUtil.java =================================================================== --- trunk/src/test/java/net/sf/practicalxml/TestSchemaUtil.java (rev 0) +++ trunk/src/test/java/net/sf/practicalxml/TestSchemaUtil.java 2008-10-08 00:08:37 UTC (rev 28) @@ -0,0 +1,91 @@ +package net.sf.practicalxml; + +import java.io.Reader; +import java.io.StringReader; + +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import net.sf.practicalxml.misc.ExceptionErrorHandler; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; + +import junit.framework.TestCase; + + +public class TestSchemaUtil extends TestCase +{ +//---------------------------------------------------------------------------- +// Definitions for newSchema() testing +//---------------------------------------------------------------------------- + + public final static String NEW_SCHEMA_START + = "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"; + + public final static String NEW_SCHEMA_DEF_1 + = "<xsd:element name=\"foo\" type=\"FooType\"/>"; + + public final static String NEW_SCHEMA_DEF_2 + = "<xsd:complexType name=\"FooType\">" + + "<xsd:sequence>" + + "<xsd:element name=\"argle\" type=\"xsd:integer\"/>" + + "<xsd:element name=\"bargle\" type=\"BarType\"/>" + + "</xsd:sequence>" + + "</xsd:complexType>"; + + public final static String NEW_SCHEMA_DEF_3 + = "<xsd:simpleType name=\"BarType\">" + + "<xsd:restriction base=\"xsd:string\">" + + "</xsd:restriction>" + + "</xsd:simpleType>"; + + public final static String NEW_SCHEMA_FINISH + = "</xsd:schema>"; + + +//---------------------------------------------------------------------------- +// Test Cases +//---------------------------------------------------------------------------- + + public void testNewFactory() throws Exception + { + ErrorHandler errHandler = new ExceptionErrorHandler(); + SchemaFactory fact = SchemaUtil.newFactory(errHandler); + + assertNotNull(fact); + assertSame(errHandler, fact.getErrorHandler()); + } + + + public void testNewSchemaWithSingleSource() throws Exception + { + Reader xsd = new StringReader( + NEW_SCHEMA_START + + NEW_SCHEMA_DEF_1 + NEW_SCHEMA_DEF_2 + NEW_SCHEMA_DEF_3 + + NEW_SCHEMA_FINISH); + + Schema schema = SchemaUtil.newSchema( + SchemaUtil.newFactory(new ExceptionErrorHandler()), + new InputSource(xsd)); + assertNotNull(schema); + } + + + public void testNewSchemaWithMultipleSources() throws Exception + { + Reader xsd1 = new StringReader( + NEW_SCHEMA_START + NEW_SCHEMA_DEF_1 + NEW_SCHEMA_FINISH); + Reader xsd2 = new StringReader( + NEW_SCHEMA_START + NEW_SCHEMA_DEF_2 + NEW_SCHEMA_FINISH); + Reader xsd3 = new StringReader( + NEW_SCHEMA_START + NEW_SCHEMA_DEF_3 + NEW_SCHEMA_FINISH); + + Schema schema = SchemaUtil.newSchema( + SchemaUtil.newFactory(new ExceptionErrorHandler()), + new InputSource(xsd1), + new InputSource(xsd2), + new InputSource(xsd3)); + assertNotNull(schema); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |