summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog49
-rw-r--r--gnu/xml/validation/relaxng/AnyNameNameClass.java58
-rw-r--r--gnu/xml/validation/relaxng/AttributePattern.java53
-rw-r--r--gnu/xml/validation/relaxng/ChoiceNameClass.java59
-rw-r--r--gnu/xml/validation/relaxng/ChoicePattern.java53
-rw-r--r--gnu/xml/validation/relaxng/DataPattern.java60
-rw-r--r--gnu/xml/validation/relaxng/Define.java52
-rw-r--r--gnu/xml/validation/relaxng/ElementPattern.java53
-rw-r--r--gnu/xml/validation/relaxng/EmptyPattern.java52
-rw-r--r--gnu/xml/validation/relaxng/FullSyntaxBuilder.java1651
-rw-r--r--gnu/xml/validation/relaxng/Grammar.java70
-rw-r--r--gnu/xml/validation/relaxng/GrammarException.java56
-rw-r--r--gnu/xml/validation/relaxng/GrammarValidator.java97
-rw-r--r--gnu/xml/validation/relaxng/GroupPattern.java53
-rw-r--r--gnu/xml/validation/relaxng/InterleavePattern.java53
-rw-r--r--gnu/xml/validation/relaxng/ListPattern.java52
-rw-r--r--gnu/xml/validation/relaxng/NSNameNameClass.java61
-rw-r--r--gnu/xml/validation/relaxng/NameClass.java50
-rw-r--r--gnu/xml/validation/relaxng/NameNameClass.java60
-rw-r--r--gnu/xml/validation/relaxng/NotAllowedPattern.java53
-rw-r--r--gnu/xml/validation/relaxng/OneOrMorePattern.java52
-rw-r--r--gnu/xml/validation/relaxng/Param.java52
-rw-r--r--gnu/xml/validation/relaxng/Pattern.java48
-rw-r--r--gnu/xml/validation/relaxng/RELAXNGSchemaFactory.java151
-rw-r--r--gnu/xml/validation/relaxng/RefPattern.java52
-rw-r--r--gnu/xml/validation/relaxng/TextPattern.java52
-rw-r--r--gnu/xml/validation/relaxng/ValuePattern.java58
-rw-r--r--gnu/xml/validation/xmlschema/AnyAttribute.java67
-rw-r--r--gnu/xml/validation/xmlschema/AttributeDeclaration.java99
-rw-r--r--gnu/xml/validation/xmlschema/AttributeUse.java79
-rw-r--r--gnu/xml/validation/xmlschema/ComplexType.java102
-rw-r--r--gnu/xml/validation/xmlschema/ElementDeclaration.java125
-rw-r--r--gnu/xml/validation/xmlschema/Particle.java61
-rw-r--r--gnu/xml/validation/xmlschema/ValidationException.java58
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchema.java134
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchemaAttributeTypeInfo.java100
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchemaBuilder.java844
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchemaElementTypeInfo.java93
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchemaSchemaFactory.java159
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchemaTypeInfo.java77
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchemaTypeInfoProvider.java82
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchemaValidator.java98
-rw-r--r--gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java394
-rw-r--r--javax/xml/validation/SchemaFactory.java8
44 files changed, 5788 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 3cb9ddae4..e56b6e12b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,52 @@
+2006-03-03 Chris Burdess <dog@gnu.org>
+
+ * gnu/xml/validation/relaxng/AnyNameNameClass.java,
+ gnu/xml/validation/relaxng/AttributePattern.java,
+ gnu/xml/validation/relaxng/ChoiceNameClass.java,
+ gnu/xml/validation/relaxng/ChoicePattern.java,
+ gnu/xml/validation/relaxng/DataPattern.java,
+ gnu/xml/validation/relaxng/Define.java,
+ gnu/xml/validation/relaxng/ElementPattern.java,
+ gnu/xml/validation/relaxng/EmptyPattern.java,
+ gnu/xml/validation/relaxng/FullSyntaxBuilder.java,
+ gnu/xml/validation/relaxng/Grammar.java,
+ gnu/xml/validation/relaxng/GrammarException.java,
+ gnu/xml/validation/relaxng/GrammarValidator.java,
+ gnu/xml/validation/relaxng/GroupPattern.java,
+ gnu/xml/validation/relaxng/InterleavePattern.java,
+ gnu/xml/validation/relaxng/ListPattern.java,
+ gnu/xml/validation/relaxng/NSNameNameClass.java,
+ gnu/xml/validation/relaxng/NameClass.java,
+ gnu/xml/validation/relaxng/NameNameClass.java,
+ gnu/xml/validation/relaxng/NotAllowedPattern.java,
+ gnu/xml/validation/relaxng/OneOrMorePattern.java,
+ gnu/xml/validation/relaxng/Param.java,
+ gnu/xml/validation/relaxng/Pattern.java,
+ gnu/xml/validation/relaxng/RELAXNGSchemaFactory.java,
+ gnu/xml/validation/relaxng/RefPattern.java,
+ gnu/xml/validation/relaxng/TextPattern.java,
+ gnu/xml/validation/relaxng/ValuePattern.java: New RELAX NG grammar
+ builder and data model.
+ * gnu/xml/validation/xmlschema/AnyAttribute.java,
+ gnu/xml/validation/xmlschema/AttributeDeclaration.java,
+ gnu/xml/validation/xmlschema/AttributeUse.java,
+ gnu/xml/validation/xmlschema/ComplexType.java,
+ gnu/xml/validation/xmlschema/ElementDeclaration.java,
+ gnu/xml/validation/xmlschema/Particle.java,
+ gnu/xml/validation/xmlschema/ValidationException.java,
+ gnu/xml/validation/xmlschema/XMLSchema.java,
+ gnu/xml/validation/xmlschema/XMLSchemaAttributeTypeInfo.java,
+ gnu/xml/validation/xmlschema/XMLSchemaBuilder.java,
+ gnu/xml/validation/xmlschema/XMLSchemaElementTypeInfo.java,
+ gnu/xml/validation/xmlschema/XMLSchemaSchemaFactory.java,
+ gnu/xml/validation/xmlschema/XMLSchemaTypeInfo.java,
+ gnu/xml/validation/xmlschema/XMLSchemaTypeInfoProvider.java,
+ gnu/xml/validation/xmlschema/XMLSchemaValidator.java,
+ gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java: New
+ W3C XML Schema builder and schema components.
+ * javax/xml/validation/SchemaFactory.java: Recognise RELAX NG and W3C
+ XML Schema namespace URIs.
+
2006-03-03 Thomas Fitzsimmons <fitzsim@redhat.com>
* NEWS: Add entry for --enable-collections.
diff --git a/gnu/xml/validation/relaxng/AnyNameNameClass.java b/gnu/xml/validation/relaxng/AnyNameNameClass.java
new file mode 100644
index 000000000..ecc016d4b
--- /dev/null
+++ b/gnu/xml/validation/relaxng/AnyNameNameClass.java
@@ -0,0 +1,58 @@
+/* AnyNameNameClass.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG anyName element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class AnyNameNameClass
+ extends NameClass
+{
+
+ NameClass exceptNameClass;
+
+ boolean matchesName(String uri, String localName)
+ {
+ return (exceptNameClass == null) ? true :
+ !exceptNameClass.matchesName(uri, localName);
+ }
+
+}
+
diff --git a/gnu/xml/validation/relaxng/AttributePattern.java b/gnu/xml/validation/relaxng/AttributePattern.java
new file mode 100644
index 000000000..48443d61b
--- /dev/null
+++ b/gnu/xml/validation/relaxng/AttributePattern.java
@@ -0,0 +1,53 @@
+/* AttributePattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG attribute element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class AttributePattern
+ extends Pattern
+{
+
+ NameClass nameClass;
+ Pattern pattern;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/ChoiceNameClass.java b/gnu/xml/validation/relaxng/ChoiceNameClass.java
new file mode 100644
index 000000000..e196cd4ee
--- /dev/null
+++ b/gnu/xml/validation/relaxng/ChoiceNameClass.java
@@ -0,0 +1,59 @@
+/* ChoiceNameClass.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG choice element (in the context of a name class).
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class ChoiceNameClass
+ extends NameClass
+{
+
+ NameClass name1;
+ NameClass name2;
+
+ boolean matchesName(String uri, String localName)
+ {
+ return name1.matchesName(uri, localName) ||
+ name2.matchesName(uri, localName);
+ }
+
+}
+
diff --git a/gnu/xml/validation/relaxng/ChoicePattern.java b/gnu/xml/validation/relaxng/ChoicePattern.java
new file mode 100644
index 000000000..54739b270
--- /dev/null
+++ b/gnu/xml/validation/relaxng/ChoicePattern.java
@@ -0,0 +1,53 @@
+/* ChoicePattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG choice element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class ChoicePattern
+ extends Pattern
+{
+
+ Pattern pattern1;
+ Pattern pattern2;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/DataPattern.java b/gnu/xml/validation/relaxng/DataPattern.java
new file mode 100644
index 000000000..2315b2ce6
--- /dev/null
+++ b/gnu/xml/validation/relaxng/DataPattern.java
@@ -0,0 +1,60 @@
+/* DataPattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+import java.util.LinkedList;
+import java.util.List;
+import org.relaxng.datatype.Datatype;
+import org.relaxng.datatype.DatatypeLibrary;
+
+/**
+ * A RELAX NG data element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class DataPattern
+ extends Pattern
+{
+
+ Datatype type;
+ DatatypeLibrary datatypeLibrary;
+ List params = new LinkedList();
+ Pattern exceptPattern;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/Define.java b/gnu/xml/validation/relaxng/Define.java
new file mode 100644
index 000000000..8801d581e
--- /dev/null
+++ b/gnu/xml/validation/relaxng/Define.java
@@ -0,0 +1,52 @@
+/* Define.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG define.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class Define
+{
+
+ String name;
+ ElementPattern element;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/ElementPattern.java b/gnu/xml/validation/relaxng/ElementPattern.java
new file mode 100644
index 000000000..9ff357075
--- /dev/null
+++ b/gnu/xml/validation/relaxng/ElementPattern.java
@@ -0,0 +1,53 @@
+/* ElementPattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class ElementPattern
+ extends Pattern
+{
+
+ NameClass nameClass;
+ Pattern pattern;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/EmptyPattern.java b/gnu/xml/validation/relaxng/EmptyPattern.java
new file mode 100644
index 000000000..ce568f84b
--- /dev/null
+++ b/gnu/xml/validation/relaxng/EmptyPattern.java
@@ -0,0 +1,52 @@
+/* EmptyPattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG empty element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class EmptyPattern
+ extends Pattern
+{
+
+ static final EmptyPattern INSTANCE = new EmptyPattern();
+
+}
+
diff --git a/gnu/xml/validation/relaxng/FullSyntaxBuilder.java b/gnu/xml/validation/relaxng/FullSyntaxBuilder.java
new file mode 100644
index 000000000..2a6833737
--- /dev/null
+++ b/gnu/xml/validation/relaxng/FullSyntaxBuilder.java
@@ -0,0 +1,1651 @@
+/* FullSyntaxBuilder.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.relaxng.datatype.DatatypeException;
+import org.relaxng.datatype.DatatypeLibrary;
+import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import gnu.xml.stream.XMLParser;
+
+/**
+ * Parses a RELAX NG XML DOM tree, constructing a compiled internal
+ * representation.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class FullSyntaxBuilder
+{
+
+ /**
+ * Complete vocabulary (elements and attributes) of the full syntax.
+ */
+ static final Map VOCABULARY = new HashMap();
+ static final Set STRIPPED_ATTRIBUTES = new HashSet();
+ static final Set PATTERN_ELEMENTS = new HashSet();
+ static
+ {
+ Set elementAttrs = Collections.singleton("name");
+ Set dataAttrs = new HashSet();
+ dataAttrs.add("type");
+ dataAttrs.add("datatypeLibrary");
+ Set valueAttrs = new HashSet();
+ valueAttrs.add("type");
+ valueAttrs.add("datatypeLibrary");
+ valueAttrs.add("ns");
+ Set externalAttrs = Collections.singleton("href");
+ Set startAttrs = Collections.singleton("combine");
+ Set defineAttrs = new HashSet();
+ defineAttrs.add("name");
+ defineAttrs.add("combine");
+ Set nsAttrs = Collections.singleton("ns");
+
+ VOCABULARY.put("element", elementAttrs);
+ VOCABULARY.put("attribute", elementAttrs);
+ VOCABULARY.put("group", Collections.EMPTY_SET);
+ VOCABULARY.put("interleave", Collections.EMPTY_SET);
+ VOCABULARY.put("choice", Collections.EMPTY_SET);
+ VOCABULARY.put("optional", Collections.EMPTY_SET);
+ VOCABULARY.put("zeroOrMore", Collections.EMPTY_SET);
+ VOCABULARY.put("oneOrMore", Collections.EMPTY_SET);
+ VOCABULARY.put("list", Collections.EMPTY_SET);
+ VOCABULARY.put("mixed", Collections.EMPTY_SET);
+ VOCABULARY.put("ref", elementAttrs);
+ VOCABULARY.put("parentRef", elementAttrs);
+ VOCABULARY.put("empty", Collections.EMPTY_SET);
+ VOCABULARY.put("text", Collections.EMPTY_SET);
+ VOCABULARY.put("value", valueAttrs);
+ VOCABULARY.put("data", dataAttrs);
+ VOCABULARY.put("notAllowed", Collections.EMPTY_SET);
+ VOCABULARY.put("externalRef", externalAttrs);
+ VOCABULARY.put("grammar", Collections.EMPTY_SET);
+ VOCABULARY.put("param", elementAttrs);
+ VOCABULARY.put("except", Collections.EMPTY_SET);
+ VOCABULARY.put("div", Collections.EMPTY_SET);
+ VOCABULARY.put("include", externalAttrs);
+ VOCABULARY.put("start", startAttrs);
+ VOCABULARY.put("define", defineAttrs);
+ VOCABULARY.put("name", nsAttrs);
+ VOCABULARY.put("anyName", Collections.EMPTY_SET);
+ VOCABULARY.put("nsName", nsAttrs);
+
+ STRIPPED_ATTRIBUTES.add("name");
+ STRIPPED_ATTRIBUTES.add("type");
+ STRIPPED_ATTRIBUTES.add("combine");
+
+ PATTERN_ELEMENTS.add("element");
+ PATTERN_ELEMENTS.add("attribute");
+ PATTERN_ELEMENTS.add("group");
+ PATTERN_ELEMENTS.add("interleave");
+ PATTERN_ELEMENTS.add("choice");
+ PATTERN_ELEMENTS.add("optional");
+ PATTERN_ELEMENTS.add("zeroOrMore");
+ PATTERN_ELEMENTS.add("oneOrMore");
+ PATTERN_ELEMENTS.add("list");
+ PATTERN_ELEMENTS.add("mixed");
+ PATTERN_ELEMENTS.add("ref");
+ PATTERN_ELEMENTS.add("parentRef");
+ PATTERN_ELEMENTS.add("empty");
+ PATTERN_ELEMENTS.add("text");
+ PATTERN_ELEMENTS.add("value");
+ PATTERN_ELEMENTS.add("data");
+ PATTERN_ELEMENTS.add("notAllowed");
+ PATTERN_ELEMENTS.add("externalRef");
+ PATTERN_ELEMENTS.add("grammar");
+ }
+
+ private Set urls; // recursion checking
+ private int refCount; // creation of ref names
+ private Map datatypeLibraries;
+
+ /**
+ * Parse the specified document into a grammar.
+ */
+ synchronized Grammar parse(Document doc)
+ throws IOException
+ {
+ urls = new HashSet();
+ refCount = 1;
+
+ doc.normalizeDocument(); // Normalize XML document
+ transform(doc); // Apply transformation rules to provide simple syntax
+
+ // 4.18. grammar element
+ Element p = doc.getDocumentElement();
+ Element grammar =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "grammar");
+ Element start =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "start");
+ doc.removeChild(p);
+ doc.appendChild(grammar);
+ grammar.appendChild(start);
+ start.appendChild(p);
+ transformGrammar(grammar, p);
+ Element define = getNextSiblingElement(start);
+ while (define != null)
+ {
+ Element next = getNextSiblingElement(define);
+ String name = define.getAttribute("new-name");
+ if (name != null)
+ {
+ define.setAttribute("name", name);
+ define.removeAttribute("new-name");
+ }
+ else
+ grammar.removeChild(define); // unreferenced
+ define = next;
+ }
+
+ // 4.19. define and ref elements
+ Set allDefines = new HashSet(), reachableDefines = new HashSet();
+ getDefines(allDefines, grammar, grammar, false);
+ getDefines(reachableDefines, grammar, start, true);
+ allDefines.removeAll(reachableDefines);
+ for (Iterator i = allDefines.iterator(); i.hasNext(); )
+ {
+ // remove unreachable defines
+ Element d = (Element) i.next();
+ Node parent = d.getParentNode();
+ parent.removeChild(d);
+ }
+ // replace all elements that are not children of defines by refs to new
+ // defines
+ Set elements = new HashSet();
+ getElements(elements, grammar, grammar);
+ for (Iterator i = elements.iterator(); i.hasNext(); )
+ {
+ Element element = (Element) i.next();
+ Node parent = element.getParentNode();
+ if (!reachableDefines.contains(parent))
+ {
+ define =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "define");
+ Element ref =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "ref");
+ String name = createRefName();
+ define.setAttribute("name", name);
+ ref.setAttribute("name", name);
+ parent.insertBefore(ref, element);
+ define.appendChild(element);
+ grammar.appendChild(define);
+ reachableDefines.add(define);
+ }
+ }
+ // Get defines that don't have element children
+ for (Iterator i = reachableDefines.iterator(); i.hasNext(); )
+ {
+ Element d = (Element) i.next();
+ Element child = getFirstChildElement(d);
+ if (child != null && "element".equals(child.getLocalName()))
+ i.remove();
+ }
+ // Expand refs that refer to these defines
+ expandRefs(reachableDefines, grammar);
+ // Remove any defines that don't have element children
+ for (Iterator i = reachableDefines.iterator(); i.hasNext(); )
+ {
+ Element d = (Element) i.next();
+ Node parent = d.getParentNode();
+ parent.removeChild(d);
+ }
+
+ transform2(p); // Apply second stage transformation rules
+
+ Grammar ret = parseGrammar(grammar);
+ datatypeLibraries = null; // free datatype libraries cache
+ return ret;
+ }
+
+ private void getDefines(Set defines, Element grammar, Element node,
+ boolean followRefs)
+ {
+ String elementName = node.getLocalName();
+ if ("define".equals(elementName))
+ defines.add(node);
+ else if ("ref".equals(elementName) && followRefs)
+ {
+ String rname = node.getAttribute("name");
+ Element define = getFirstChildElement(grammar);
+ define = getNextSiblingElement(define);
+ while (define != null)
+ {
+ String dname = define.getAttribute("name");
+ if (rname.equals(dname))
+ {
+ getDefines(defines, grammar, node, followRefs);
+ break;
+ }
+ define = getNextSiblingElement(define);
+ }
+ }
+ for (Element child = getFirstChildElement(node); child != null;
+ child = getNextSiblingElement(child))
+ getDefines(defines, grammar, child, followRefs);
+ }
+
+ private void getElements(Set elements, Element grammar, Element node)
+ {
+ String elementName = node.getLocalName();
+ if ("element".equals(elementName))
+ elements.add(node);
+ for (Element child = getFirstChildElement(node); child != null;
+ child = getNextSiblingElement(child))
+ getElements(elements, grammar, child);
+ }
+
+ private void expandRefs(Set defines, Element node)
+ throws GrammarException
+ {
+ String elementName = node.getLocalName();
+ if ("ref".equals(elementName))
+ {
+ String rname = node.getAttribute("name");
+ for (Iterator i = defines.iterator(); i.hasNext(); )
+ {
+ Element define = (Element) i.next();
+ String dname = define.getAttribute("name");
+ if (rname.equals(dname))
+ {
+ Element child = getFirstChildElement(define);
+ forbidRefs(child, rname);
+ Element refChild = (Element) child.cloneNode(true);
+ Node parent = node.getParentNode();
+ parent.insertBefore(refChild, node);
+ parent.removeChild(node);
+ node = refChild;
+ break;
+ }
+ }
+ }
+ for (Element child = getFirstChildElement(node); child != null;
+ child = getNextSiblingElement(child))
+ expandRefs(defines, child);
+ }
+
+ private void forbidRefs(Element node, String name)
+ throws GrammarException
+ {
+ String elementName = node.getLocalName();
+ if ("ref".equals(elementName))
+ {
+ String rname = node.getAttribute("name");
+ if (name.equals(rname))
+ throw new GrammarException("cannot expand ref with name '" + name +
+ "' due to circularity");
+ }
+ for (Element child = getFirstChildElement(node); child != null;
+ child = getNextSiblingElement(child))
+ forbidRefs(child, name);
+ }
+
+ private void transform(Node node)
+ throws IOException
+ {
+ Node parent = node.getParentNode();
+ switch (node.getNodeType())
+ {
+ case Node.ELEMENT_NODE:
+ // 4.1 Annotations
+ String elementNs = node.getNamespaceURI();
+ String elementName = node.getLocalName();
+ if (!XMLConstants.RELAXNG_NS_URI.equals(elementNs) ||
+ !VOCABULARY.containsKey(elementName))
+ parent.removeChild(node);
+ else
+ {
+ Set allowedAttrs = (Set) VOCABULARY.get(elementName);
+ NamedNodeMap attrs = node.getAttributes();
+ int len = attrs.getLength();
+ for (int i = len - 1; i >= 0; i--)
+ {
+ Node attr = attrs.item(i);
+ String attrNs = attr.getNamespaceURI();
+ String attrName = attr.getLocalName();
+ if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attrNs))
+ continue; // ignore namespace nodes
+ if (!(XMLConstants.RELAXNG_NS_URI.equals(attrNs) ||
+ attrNs == null) ||
+ !allowedAttrs.contains(attrName))
+ attrs.removeNamedItemNS(attrNs, attrName);
+ else
+ {
+ // 4.2 Whitespace
+ if (STRIPPED_ATTRIBUTES.contains(attrName))
+ attr.setNodeValue(attr.getNodeValue().trim());
+ // 4.3 datatypeLibrary attribute
+ else if ("datatypeLibrary".equals(attrName))
+ {
+ String dl = attr.getNodeValue();
+ attr.setNodeValue(escapeURL(dl));
+ }
+ // 4.5. href attribute
+ else if ("href".equals(attrName))
+ {
+ String href = attr.getNodeValue();
+ href = XMLParser.absolutize(node.getBaseURI(),
+ escapeURL(href));
+ attr.setNodeValue(href);
+ }
+ }
+ }
+ // 4.3 datatypeLibrary attribute
+ if ("data".equals(elementName) || "value".equals(elementName))
+ {
+ Element element = (Element) node;
+ String dl = element.getAttribute("datatypeLibrary");
+ if (dl == null)
+ {
+ Node p = parent;
+ while (dl == null && p != null &&
+ p.getNodeType() == Node.ELEMENT_NODE)
+ {
+ dl = ((Element) p)
+ .getAttribute("datatypeLibrary");
+ p = p.getParentNode();
+ }
+ if (dl == null)
+ dl = "";
+ element.setAttribute("datatypeLibrary", dl);
+ }
+ // 4.4. type attribute of value element
+ if ("value".equals(elementName))
+ {
+ String type = element.getAttribute("type");
+ if (type == null)
+ {
+ element.setAttribute("type", "token");
+ element.setAttribute("datatypeLibrary", "");
+ }
+ }
+ // 4.16. Constraints
+ // TODO validate type
+ }
+ // 4.6. externalRef element
+ else if ("externalRef".equals(elementName))
+ {
+ Element externalRef = (Element) node;
+ String href = externalRef.getAttribute("href");
+ // check for recursion
+ if (urls.contains(href))
+ throw new GrammarException("recursive href");
+ urls.add(href);
+ Element element = resolve(href);
+ String eNs = element.getNamespaceURI();
+ String eName = element.getLocalName();
+ if (!(XMLConstants.RELAXNG_NS_URI.equals(eNs) ||
+ eNs == null) ||
+ !PATTERN_ELEMENTS.contains(eName))
+ throw new GrammarException("externally referenced element " +
+ "is not a pattern");
+ transform(element);
+ urls.remove(href);
+ String ns = element.getAttribute("ns");
+ if (ns != null)
+ element.setAttribute("ns",
+ externalRef.getAttribute("ns"));
+ element = (Element) externalRef.getOwnerDocument()
+ .importNode(element, true);
+ parent.replaceChild(element, externalRef);
+ return;
+ }
+ // 4.7 include element
+ else if ("include".equals(elementName))
+ {
+ Element include = (Element) node;
+ String href = include.getAttribute("href");
+ // check for recursion
+ if (urls.contains(href))
+ throw new GrammarException("recursive href");
+ urls.add(href);
+ Element element = resolve(href);
+ String eNs = element.getNamespaceURI();
+ String eName = element.getLocalName();
+ if (!(XMLConstants.RELAXNG_NS_URI.equals(eNs) ||
+ eNs == null) ||
+ !"grammar".equals(eName))
+ throw new GrammarException("included element is not " +
+ "a grammar");
+
+ transform(element);
+ urls.remove(href);
+ // handle components
+ List includeComponents = getComponents(include);
+ List grammarComponents = getComponents(element);
+ for (Iterator i = includeComponents.iterator(); i.hasNext(); )
+ {
+ Element comp = (Element) i.next();
+ String compName = comp.getLocalName();
+ if ("start".equals(compName))
+ {
+ boolean found = false;
+ for (Iterator j = grammarComponents.iterator();
+ j.hasNext(); )
+ {
+ Element c2 = (Element) j.next();
+ if ("start".equals(c2.getLocalName()))
+ {
+ c2.getParentNode().removeChild(c2);
+ found = true;
+ }
+ }
+ if (!found)
+ throw new GrammarException("no start component in " +
+ "included grammar");
+ }
+ else if ("define".equals(compName))
+ {
+ String name = comp.getAttribute("name");
+ boolean found = false;
+ for (Iterator j = grammarComponents.iterator();
+ j.hasNext(); )
+ {
+ Element c2 = (Element) j.next();
+ if ("define".equals(c2.getLocalName()) &&
+ name.equals(c2.getAttribute("name")))
+ {
+ c2.getParentNode().removeChild(c2);
+ found = true;
+ }
+ }
+ if (!found)
+ throw new GrammarException("no define component " +
+ "with name '" + name +
+ "' in included grammar");
+ }
+ }
+ // transform to div element
+ Document doc = include.getOwnerDocument();
+ Element includeDiv =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "div");
+ Element grammarDiv =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "div");
+ // XXX copy include non-href attributes (none defined?)
+ element = (Element) doc.importNode(element, true);
+ Node ctx = element.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ grammarDiv.appendChild(ctx);
+ ctx = next;
+ }
+ includeDiv.appendChild(grammarDiv);
+ ctx = include.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ includeDiv.appendChild(ctx);
+ ctx = next;
+ }
+ parent.replaceChild(includeDiv, include);
+ transform(includeDiv);
+ return;
+ }
+ // 4.8. name attribute of element and attribute elements
+ else if ("attribute".equals(elementName) ||
+ "element".equals(elementName))
+ {
+ Element element = (Element) node;
+ String name = element.getAttribute("name");
+ if (name != null)
+ {
+ Document doc = element.getOwnerDocument();
+ Element n =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "name");
+ n.appendChild(doc.createTextNode(name));
+ Node first = element.getFirstChild();
+ if (first != null)
+ element.insertBefore(n, first);
+ else
+ element.appendChild(n);
+ if ("attribute".equals(elementName))
+ {
+ String ns = element.getAttribute("ns");
+ if (ns != null)
+ {
+ n.setAttribute("ns", ns);
+ element.removeAttribute("ns");
+ }
+ }
+ element.removeAttribute("name");
+ }
+ // 4.12. Number of child elements
+ if ("attribute".equals(elementName))
+ {
+ if (getComponents(node).size() == 1)
+ {
+ Document doc = node.getOwnerDocument();
+ Element text =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "text");
+ node.appendChild(text);
+ }
+ }
+ else // element
+ {
+ if (node.getChildNodes().getLength() > 2)
+ {
+ // transform to 2 child elements
+ Document doc = node.getOwnerDocument();
+ Element child =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "group");
+ Node ctx = getFirstChildElement(node);
+ ctx = getNextSiblingElement(ctx); // skip 1
+ while (ctx != null)
+ {
+ Node next = getNextSiblingElement(ctx);
+ child.appendChild(ctx);
+ ctx = next;
+ }
+ node.appendChild(child);
+ }
+ }
+ }
+ // 4.11. div element
+ else if ("div".equals(elementName))
+ {
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ parent.insertBefore(ctx, node);
+ transform(ctx);
+ ctx = next;
+ }
+ parent.removeChild(node);
+ return;
+ }
+ else if ("mixed".equals(elementName))
+ {
+ // 4.12. Number of child elements
+ transformToOneChildElement(node, "group");
+ // 4.13. mixed element
+ Document doc = node.getOwnerDocument();
+ Node interleave =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "interleave");
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ interleave.appendChild(ctx);
+ ctx = next;
+ }
+ Node text =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "text");
+ interleave.appendChild(text);
+ parent.insertBefore(interleave, node);
+ parent.removeChild(node);
+ node = interleave;
+ }
+ else if ("optional".equals(elementName))
+ {
+ // 4.12. Number of child elements
+ transformToOneChildElement(node, "group");
+ // 4.14. optional element
+ Document doc = node.getOwnerDocument();
+ Node choice =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "choice");
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ choice.appendChild(ctx);
+ ctx = next;
+ }
+ Node empty =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "empty");
+ choice.appendChild(empty);
+ parent.insertBefore(choice, node);
+ parent.removeChild(node);
+ node = choice;
+ }
+ else if ("zeroOrMore".equals(elementName))
+ {
+ // 4.12. Number of child elements
+ transformToOneChildElement(node, "group");
+ // 4.15. zeroOrMore element
+ Document doc = node.getOwnerDocument();
+ Node choice =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "choice");
+ Node oneOrMore =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "oneOrMore");
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ oneOrMore.appendChild(ctx);
+ ctx = next;
+ }
+ Node empty =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "empty");
+ choice.appendChild(oneOrMore);
+ choice.appendChild(empty);
+ parent.insertBefore(choice, node);
+ parent.removeChild(node);
+ node = choice;
+ }
+ else if ("list".equals(elementName) ||
+ "oneOrMore".equals(elementName) ||
+ "define".equals(elementName))
+ {
+ // 4.12. Number of child elements
+ transformToOneChildElement(node, "group");
+ }
+ else if ("except".equals(elementName))
+ {
+ // 4.12. Number of child elements
+ transformToOneChildElement(node, "choice");
+ // 4.16. Constraints
+ String parentName = parent.getLocalName();
+ if ("anyName".equals(parentName))
+ forbidDescendants(node, Collections.singleton("anyName"));
+ else if ("nsName".equals(parentName))
+ {
+ Set names = new HashSet();
+ names.add("nsName");
+ names.add("anyName");
+ forbidDescendants(node, names);
+ }
+ }
+ else if ("choice".equals(elementName) ||
+ "group".equals(elementName) ||
+ "interleave".equals(elementName))
+ {
+ // 4.12. Number of child elements
+ Node ctx = getFirstChildElement(node);
+ Node next = getNextSiblingElement(ctx);
+ if (next == null)
+ {
+ // replace
+ parent.insertBefore(ctx, node);
+ parent.removeChild(node);
+ transform(ctx);
+ return;
+ }
+ else
+ {
+ // transform to 2 child elements
+ Node next2 = getNextSiblingElement(next);
+ if (next2 != null)
+ {
+ Document doc = node.getOwnerDocument();
+ Node child =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ elementName);
+ child.appendChild(ctx);
+ child.appendChild(next);
+ node.insertBefore(next2, child);
+ transform(node); // recurse
+ }
+ }
+ }
+ // 4.17. combine attribute
+ else if ("grammar".equals(elementName))
+ {
+ String combine = null;
+ List nodes = new LinkedList();
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ if ("start".equals(ctx.getLocalName()))
+ {
+ String c = ((Element) ctx).getAttribute("combine");
+ if (combine != null && !combine.equals(c))
+ throw new GrammarException("multiple start elements "+
+ "but no combine attribute");
+ combine = c;
+ nodes.add(ctx);
+ }
+ ctx = next;
+ }
+ if (!nodes.isEmpty())
+ combineNodes(node, combine, "start", nodes);
+ // defines
+ Map defines = new HashMap();
+ Map defineCombines = new HashMap();
+ ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ if ("define".equals(ctx.getLocalName()))
+ {
+ String name = ((Element) ctx).getAttribute("name");
+ combine = (String) defineCombines.get(name);
+ String c = ((Element) ctx).getAttribute("combine");
+ if (combine != null && !combine.equals(c))
+ throw new GrammarException("multiple define " +
+ "elements with name '"+
+ name + "' but no " +
+ "combine attribute");
+ defineCombines.put(name, c);
+ nodes = (List) defines.get(name);
+ if (nodes == null)
+ {
+ nodes = new LinkedList();
+ defines.put(name, nodes);
+ }
+ nodes.add(ctx);
+ }
+ ctx = next;
+ }
+ for (Iterator i = defines.keySet().iterator(); i.hasNext(); )
+ {
+ String name = (String) i.next();
+ combine = (String) defineCombines.get(name);
+ nodes = (List) defines.get(name);
+ if (!nodes.isEmpty())
+ combineNodes(node, combine, "define", nodes);
+ }
+ }
+ // 4.9. ns attribute
+ if ("name".equals(elementName) ||
+ "nsName".equals(elementName) ||
+ "value".equals(elementName))
+ {
+ Element element = (Element) node;
+ String ns = element.getAttribute("ns");
+ if (ns == null)
+ {
+ Node ctx = parent;
+ while (ns == null && ctx != null &&
+ ctx.getNodeType() == Node.ELEMENT_NODE)
+ {
+ ns = ((Element) ctx).getAttribute("ns");
+ ctx = ctx.getParentNode();
+ }
+ element.setAttribute("ns", (ns == null) ? "" : ns);
+ }
+ if ("name".equals(elementName))
+ {
+ // 4.10. QNames
+ String name = element.getTextContent();
+ int ci = name.indexOf(':');
+ if (ci != -1)
+ {
+ String prefix = name.substring(0, ci);
+ element.setTextContent(name.substring(ci + 1));
+ ns = element.lookupNamespaceURI(prefix);
+ element.setAttribute("ns", (ns == null) ? "" : ns);
+ }
+ // 4.16. Constraints
+ if (isDescendantOfFirstChildOfAttribute(element) &&
+ "".equals(element.getAttribute("ns")) &&
+ "xmlns".equals(element.getTextContent()))
+ throw new GrammarException("name cannot be xmlns");
+ }
+ else if ("nsName".equals(elementName))
+ {
+ // 4.16. Constraints
+ if (isDescendantOfFirstChildOfAttribute(element) &&
+ "http://www.w3.org/2000/xmlns"
+ .equals(element.getAttribute("ns")))
+ throw new GrammarException("nsName cannot be XMLNS URI");
+ }
+ }
+ }
+
+ break;
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ // 4.2 Whitespace
+ String parentName = parent.getLocalName();
+ if ("name".equals(parentName))
+ node.setNodeValue(node.getNodeValue().trim());
+ if (!"param".equals(parentName) &&
+ !"value".equals(parentName) &&
+ isWhitespace(node.getNodeValue()))
+ parent.removeChild(node);
+ break;
+ case Node.DOCUMENT_NODE:
+ break;
+ default:
+ parent.removeChild(node);
+ }
+ // Transform children
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ transform(ctx);
+ ctx = next;
+ }
+ }
+
+ /**
+ * Transforms the schema to place all defines under the top-level grammar
+ * element and replace all other grammar elements by their start child.
+ */
+ private void transformGrammar(Node grammar, Node node)
+ throws GrammarException
+ {
+ if (node.getNodeType() == Node.ELEMENT_NODE)
+ {
+ String elementName = node.getLocalName();
+ if ("grammar".equals(elementName))
+ {
+ handleRefs(grammar, node, node);
+ Node start = null;
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ String childName = ctx.getLocalName();
+ if ("define".equals(childName))
+ grammar.appendChild(ctx);
+ else if ("start".equals(childName))
+ start = ctx;
+ ctx = next;
+ }
+ if (start == null)
+ throw new GrammarException("no start element for grammar");
+ Node p = getFirstChildElement(start);
+ Node parent = node.getParentNode();
+ parent.insertBefore(p, node);
+ parent.removeChild(node);
+ node = p;
+ }
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ transformGrammar(grammar, ctx);
+ ctx = next;
+ }
+ }
+ }
+
+ /**
+ * Checks that all references in the specified grammar match a define in
+ * the grammar.
+ */
+ private void handleRefs(Node grammar1, Node grammar2, Node node)
+ throws GrammarException
+ {
+ if (node.getNodeType() == Node.ELEMENT_NODE)
+ {
+ String elementName = node.getLocalName();
+ if ("ref".equals(elementName) || "parentRef".equals(elementName))
+ {
+ Node grammar = grammar2;
+ if ("parentRef".equals(elementName))
+ grammar = grammar1;
+
+ String name = ((Element) node).getAttribute("name");
+ if (name != null)
+ throw new GrammarException("no name attribute on " +
+ elementName);
+ Node define = null;
+ for (Node ctx = grammar.getFirstChild();
+ define == null && ctx != null;
+ ctx = ctx.getNextSibling())
+ {
+ if ("define".equals(ctx.getLocalName()))
+ {
+ String dname = ((Element) ctx).getAttribute("name");
+ if (name.equals(dname))
+ define = ctx;
+ }
+ }
+ if (define == null)
+ throw new GrammarException("no define for '" + name + "'");
+ name = ((Element) define).getAttribute("new-name");
+ if (name == null)
+ {
+ name = createRefName();
+ ((Element) define).setAttribute("new-name", name);
+ }
+ if ("parentRef".equals(elementName))
+ {
+ Document doc = node.getOwnerDocument();
+ Node ref = doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
+ "ref");
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ ref.appendChild(ctx);
+ ctx = next;
+ }
+ Node parent = node.getParentNode();
+ parent.insertBefore(ref, node);
+ parent.removeChild(node);
+ node = ref;
+ }
+ ((Element) node).setAttribute("name", name);
+ }
+ else if ("grammar".equals(elementName))
+ {
+ grammar1 = grammar2;
+ grammar2 = node;
+ }
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ handleRefs(grammar1, grammar2, ctx);
+ ctx = next;
+ }
+ }
+ }
+
+ private String createRefName()
+ {
+ return "ref" + Integer.toString(refCount++);
+ }
+
+ private void transform2(Node node)
+ throws GrammarException
+ {
+ Node parent = node.getParentNode();
+ if (node.getNodeType() == Node.ELEMENT_NODE)
+ {
+ String elementName = node.getLocalName();
+ // 4.20. notAllowed element
+ if ("notAllowed".equals(elementName))
+ {
+ String parentName = parent.getLocalName();
+ if ("attribute".equals(parentName) ||
+ "list".equals(parentName) ||
+ "group".equals(parentName) ||
+ "interleave".equals(parentName) ||
+ "oneOrMore".equals(parentName))
+ {
+ Node pp = parent.getParentNode();
+ pp.insertBefore(node, parent);
+ pp.removeChild(parent);
+ transform2(node); // apply recursively
+ return;
+ }
+ else if ("choice".equals(parentName))
+ {
+ Node p1 = getFirstChildElement(parent);
+ Node p2 = getNextSiblingElement(p1);
+ if (p1 == null || p2 == null)
+ throw new GrammarException("choice does not have two " +
+ "children");
+ String p1Name = p1.getLocalName();
+ String p2Name = p2.getLocalName();
+ Node pp = parent.getParentNode();
+ if ("notAllowed".equals(p1Name) &&
+ "notAllowed".equals(p2Name))
+ {
+ pp.insertBefore(p1, parent);
+ pp.removeChild(parent);
+ transform2(p1); //apply recursively
+ return;
+ }
+ else if ("notAllowed".equals(p1Name))
+ {
+ pp.insertBefore(p2, parent);
+ pp.removeChild(parent);
+ transform2(p2);
+ return;
+ }
+ else
+ {
+ pp.insertBefore(p1, parent);
+ pp.removeChild(parent);
+ transform2(p1);
+ return;
+ }
+ }
+ else if ("except".equals(parentName))
+ {
+ Node pp = parent.getParentNode();
+ pp.removeChild(parent);
+ return;
+ }
+ }
+ // 4.21. empty element
+ else if ("empty".equals(elementName))
+ {
+ String parentName = parent.getLocalName();
+ if ("group".equals(parentName) ||
+ "interleave".equals(parentName))
+ {
+ Node p1 = getFirstChildElement(parent);
+ Node p2 = getNextSiblingElement(p1);
+ if (p1 == null || p2 == null)
+ throw new GrammarException(parentName + " does not have " +
+ "two children");
+ String p1Name = p1.getLocalName();
+ String p2Name = p2.getLocalName();
+ Node pp = parent.getParentNode();
+ if ("empty".equals(p1Name) &&
+ "empty".equals(p2Name))
+ {
+ pp.insertBefore(p1, parent);
+ pp.removeChild(parent);
+ transform2(p1);
+ return;
+ }
+ else if ("empty".equals(p1Name))
+ {
+ pp.insertBefore(p2, parent);
+ pp.removeChild(parent);
+ transform2(p2);
+ return;
+ }
+ else
+ {
+ pp.insertBefore(p1, parent);
+ pp.removeChild(parent);
+ transform2(p1);
+ return;
+ }
+ }
+ else if ("choice".equals(parentName))
+ {
+ Node p1 = getFirstChildElement(parent);
+ Node p2 = getNextSiblingElement(p1);
+ if (p1 == null || p2 == null)
+ throw new GrammarException(parentName + " does not have " +
+ "two children");
+ String p1Name = p1.getLocalName();
+ String p2Name = p2.getLocalName();
+ Node pp = parent.getParentNode();
+ if ("empty".equals(p1Name) &&
+ "empty".equals(p2Name))
+ {
+ pp.insertBefore(p1, parent);
+ pp.removeChild(parent);
+ transform2(p1);
+ return;
+ }
+ }
+ else if ("oneOrMore".equals(parentName))
+ {
+ Node pp = parent.getParentNode();
+ pp.insertBefore(node, parent);
+ pp.removeChild(parent);
+ transform2(node);
+ return;
+ }
+ }
+ Node ctx = node.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ transform2(ctx);
+ ctx = next;
+ }
+ }
+ }
+
+ private static boolean isWhitespace(String text)
+ {
+ int len = text.length();
+ for (int i = 0; i < len; i++)
+ {
+ char c = text.charAt(i);
+ if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
+ return false;
+ }
+ return true;
+ }
+
+ private static String escapeURL(String url)
+ {
+ try
+ {
+ return URLEncoder.encode(url, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ RuntimeException e2 = new RuntimeException("UTF-8 is unsupported");
+ e2.initCause(e);
+ throw e2;
+ }
+ }
+
+ /**
+ * Resolve a URL to an element, as described in section 4.5.
+ */
+ private static Element resolve(String url)
+ throws IOException
+ {
+ try
+ {
+ URL u = new URL(url);
+ InputStream in = u.openStream();
+ DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
+ f.setNamespaceAware(true);
+ f.setCoalescing(true);
+ f.setExpandEntityReferences(true);
+ f.setIgnoringComments(true);
+ f.setIgnoringElementContentWhitespace(true);
+ DocumentBuilder b = f.newDocumentBuilder();
+ Document doc = b.parse(in, url);
+ in.close();
+ String fragment = u.getRef();
+ if (fragment != null)
+ return doc.getElementById(fragment);
+ return doc.getDocumentElement();
+ }
+ catch (SAXException e)
+ {
+ IOException e2 = new IOException("error parsing included element");
+ e2.initCause(e);
+ throw e2;
+ }
+ catch (ParserConfigurationException e)
+ {
+ IOException e2 = new IOException("error parsing included element");
+ e2.initCause(e);
+ throw e2;
+ }
+ }
+
+ /**
+ * Returns the "components" of an element, as described in section 4.7.
+ */
+ private List getComponents(Node node)
+ {
+ List ret = new LinkedList();
+ for (Node ctx = node.getFirstChild(); ctx != null;
+ ctx = ctx.getNextSibling())
+ {
+ if (ctx.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+ String ns = ctx.getNamespaceURI();
+ if (ns != null && !ns.equals(XMLConstants.RELAXNG_NS_URI))
+ continue;
+ String name = ctx.getLocalName();
+ if ("div".equals(name))
+ ret.addAll(getComponents(ctx));
+ else if (VOCABULARY.containsKey(name))
+ ret.add(ctx);
+ }
+ return ret;
+ }
+
+ private static void transformToOneChildElement(Node node, String name)
+ {
+ if (node.getChildNodes().getLength() < 2)
+ return;
+ Document doc = node.getOwnerDocument();
+ Element child = doc.createElementNS(XMLConstants.RELAXNG_NS_URI, name);
+ Node ctx = getFirstChildElement(node);
+ while (ctx != null)
+ {
+ Node next = getNextSiblingElement(ctx);
+ child.appendChild(ctx);
+ ctx = next;
+ }
+ node.appendChild(child);
+ }
+
+ private static Element getFirstChildElement(Node node)
+ {
+ Node ctx = node.getFirstChild();
+ while (ctx != null && ctx.getNodeType() != Node.ELEMENT_NODE)
+ ctx = ctx.getNextSibling();
+ return (Element) ctx;
+ }
+
+ private static Element getNextSiblingElement(Node node)
+ {
+ Node ctx = node.getNextSibling();
+ while (ctx != null && ctx.getNodeType() != Node.ELEMENT_NODE)
+ ctx = ctx.getNextSibling();
+ return (Element) ctx;
+ }
+
+ private static void forbidDescendants(Node node, Set names)
+ throws GrammarException
+ {
+ for (Node ctx = node.getFirstChild(); ctx != null;
+ ctx = ctx.getNextSibling())
+ {
+ String ns = ctx.getNamespaceURI();
+ if (!XMLConstants.RELAXNG_NS_URI.equals(ns))
+ continue;
+ String name = ctx.getLocalName();
+ if (names.contains(name))
+ throw new GrammarException("name not allowed: " + name);
+ forbidDescendants(ctx, names);
+ }
+ }
+
+ private static boolean isDescendantOfFirstChildOfAttribute(Node node)
+ {
+ Node child = node;
+ Node parent = node.getParentNode();
+ while (parent != null && !"attribute".equals(parent.getLocalName()))
+ {
+ child = parent;
+ parent = child.getParentNode();
+ }
+ if (parent == null)
+ return false;
+ Node firstChild = getFirstChildElement(parent);
+ return firstChild == child;
+ }
+
+ private static void combineNodes(Node node, String combine, String name,
+ List nodes)
+ {
+ Document doc = node.getOwnerDocument();
+ Node child =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, name);
+ Node combineNode =
+ doc.createElementNS(XMLConstants.RELAXNG_NS_URI, combine);
+ child.appendChild(combineNode);
+ boolean inserted = false;
+ for (Iterator i = nodes.iterator(); i.hasNext(); )
+ {
+ Node startNode = (Node) i.next();
+ if (!inserted)
+ {
+ node.insertBefore(child, startNode);
+ inserted = true;
+ }
+ Node ctx = startNode.getFirstChild();
+ while (ctx != null)
+ {
+ Node next = ctx.getNextSibling();
+ combineNode.appendChild(ctx);
+ ctx = next;
+ }
+ node.removeChild(startNode);
+ }
+ }
+
+ Grammar parseGrammar(Element node)
+ throws GrammarException
+ {
+ checkName(node, "grammar");
+ Grammar grammar = new Grammar();
+ Element start = getFirstChildElement(node);
+ grammar.start = parsePattern(getFirstChildElement(start));
+ for (Element define = getNextSiblingElement(start); define != null;
+ define = getNextSiblingElement(define))
+ grammar.defines.add(parseDefine(define));
+ return grammar;
+ }
+
+ Define parseDefine(Element node)
+ throws GrammarException
+ {
+ checkName(node, "define");
+ Define define = new Define();
+ define.name = node.getAttribute("name");
+ define.element = parseElement(getFirstChildElement(node));
+ return define;
+ }
+
+ Pattern parseTop(Element node)
+ throws GrammarException
+ {
+ String name = node.getLocalName();
+ if ("notAllowed".equals(name))
+ return parseNotAllowed(node);
+ return parsePattern(node);
+ }
+
+ Pattern parsePattern(Element node)
+ throws GrammarException
+ {
+ String name = node.getLocalName();
+ if ("empty".equals(name))
+ return parseEmpty(node);
+ return parseNonEmptyPattern(node);
+ }
+
+ Pattern parseNonEmptyPattern(Element node)
+ throws GrammarException
+ {
+ String name = node.getLocalName();
+ if ("text".equals(name))
+ return parseText(node);
+ else if ("data".equals(name))
+ return parseData(node);
+ else if ("value".equals(name))
+ return parseValue(node);
+ else if ("list".equals(name))
+ return parseList(node);
+ else if ("attribute".equals(name))
+ return parseAttribute(node);
+ else if ("ref".equals(name))
+ return parseRef(node);
+ else if ("oneOrMore".equals(name))
+ return parseOneOrMore(node);
+ else if ("choice".equals(name))
+ return parseChoice(node);
+ else if ("group".equals(name))
+ return parseGroup(node);
+ else if ("interleave".equals(name))
+ return parseInterleave(node);
+ throw new GrammarException("invalid pattern: " + name);
+ }
+
+ ElementPattern parseElement(Element node)
+ throws GrammarException
+ {
+ checkName(node, "element");
+ ElementPattern element = new ElementPattern();
+ Element nameClass = getFirstChildElement(node);
+ element.nameClass = parseNameClass(nameClass);
+ element.pattern = parseTop(getNextSiblingElement(nameClass));
+ return element;
+ }
+
+ NotAllowedPattern parseNotAllowed(Element node)
+ throws GrammarException
+ {
+ checkName(node, "notAllowed");
+ return NotAllowedPattern.INSTANCE;
+ }
+
+ EmptyPattern parseEmpty(Element node)
+ throws GrammarException
+ {
+ checkName(node, "empty");
+ return EmptyPattern.INSTANCE;
+ }
+
+ TextPattern parseText(Element node)
+ throws GrammarException
+ {
+ checkName(node, "text");
+ return TextPattern.INSTANCE;
+ }
+
+ DataPattern parseData(Element node)
+ throws GrammarException
+ {
+ checkName(node, "data");
+ DataPattern data = new DataPattern();
+ DatatypeLibrary dl =
+ getDatatypeLibrary(node.getAttribute("datatypeLibrary"));
+ String type = node.getAttribute("type");
+ try
+ {
+ data.type = dl.createDatatype(type);
+ data.datatypeLibrary = dl;
+ }
+ catch (DatatypeException e)
+ {
+ GrammarException e2 = new GrammarException(type);
+ e2.initCause(e);
+ throw e2;
+ }
+ Element ctx = getFirstChildElement(node);
+ while (ctx != null)
+ {
+ Element next = getNextSiblingElement(ctx);
+ String name = ctx.getLocalName();
+ if ("param".equals(name))
+ data.params.add(parseParam(ctx));
+ else if ("except".equals(name) && next == null)
+ data.exceptPattern = parsePattern(getFirstChildElement(ctx));
+ else
+ throw new GrammarException("invalid element: " + name);
+ ctx = next;
+ }
+ return data;
+ }
+
+ Param parseParam(Element node)
+ throws GrammarException
+ {
+ checkName(node, "param");
+ Param param = new Param();
+ param.name = node.getAttribute("name");
+ param.value = node.getTextContent();
+ return param;
+ }
+
+ ValuePattern parseValue(Element node)
+ throws GrammarException
+ {
+ checkName(node, "value");
+ ValuePattern value = new ValuePattern();
+ DatatypeLibrary dl =
+ getDatatypeLibrary(node.getAttribute("datatypeLibrary"));
+ String type = node.getAttribute("type");
+ try
+ {
+ value.type = dl.createDatatype(type);
+ value.datatypeLibrary = dl;
+ }
+ catch (DatatypeException e)
+ {
+ GrammarException e2 = new GrammarException(type);
+ e2.initCause(e);
+ throw e2;
+ }
+ value.ns = node.getAttribute("ns");
+ value.value = node.getTextContent();
+ return value;
+ }
+
+ ListPattern parseList(Element node)
+ throws GrammarException
+ {
+ checkName(node, "list");
+ ListPattern list = new ListPattern();
+ list.pattern = parsePattern(getFirstChildElement(node));
+ return list;
+ }
+
+ AttributePattern parseAttribute(Element node)
+ throws GrammarException
+ {
+ checkName(node, "attribute");
+ AttributePattern attribute = new AttributePattern();
+ Element nameClass = getFirstChildElement(node);
+ attribute.nameClass = parseNameClass(nameClass);
+ attribute.pattern = parsePattern(getNextSiblingElement(nameClass));
+ return attribute;
+ }
+
+ RefPattern parseRef(Element node)
+ throws GrammarException
+ {
+ checkName(node, "ref");
+ RefPattern ref = new RefPattern();
+ ref.name = node.getAttribute("name");
+ return ref;
+ }
+
+ OneOrMorePattern parseOneOrMore(Element node)
+ throws GrammarException
+ {
+ checkName(node, "oneOrMore");
+ OneOrMorePattern oneOrMore = new OneOrMorePattern();
+ oneOrMore.pattern = parseNonEmptyPattern(getFirstChildElement(node));
+ return oneOrMore;
+ }
+
+ ChoicePattern parseChoice(Element node)
+ throws GrammarException
+ {
+ checkName(node, "choice");
+ ChoicePattern choice = new ChoicePattern();
+ Element p1 = getFirstChildElement(node);
+ Element p2 = getNextSiblingElement(p1);
+ choice.pattern1 = parsePattern(p1);
+ choice.pattern2 = parseNonEmptyPattern(p2);
+ return choice;
+ }
+
+ GroupPattern parseGroup(Element node)
+ throws GrammarException
+ {
+ checkName(node, "group");
+ GroupPattern group = new GroupPattern();
+ Element p1 = getFirstChildElement(node);
+ Element p2 = getNextSiblingElement(p1);
+ group.pattern1 = parseNonEmptyPattern(p1);
+ group.pattern2 = parseNonEmptyPattern(p2);
+ return group;
+ }
+
+ InterleavePattern parseInterleave(Element node)
+ throws GrammarException
+ {
+ checkName(node, "interleave");
+ InterleavePattern interleave = new InterleavePattern();
+ Element p1 = getFirstChildElement(node);
+ Element p2 = getNextSiblingElement(p1);
+ interleave.pattern1 = parseNonEmptyPattern(p1);
+ interleave.pattern2 = parseNonEmptyPattern(p2);
+ return interleave;
+ }
+
+ NameClass parseNameClass(Element node)
+ throws GrammarException
+ {
+ String name = node.getLocalName();
+ if ("anyName".equals(name))
+ return parseAnyName(node);
+ else if ("name".equals(name))
+ return parseName(node);
+ else if ("nsName".equals(name))
+ return parseNsName(node);
+ else if ("choice".equals(name))
+ return parseChoiceNameClass(node);
+ throw new GrammarException("invalid name class: " + name);
+ }
+
+ AnyNameNameClass parseAnyName(Element node)
+ throws GrammarException
+ {
+ checkName(node, "anyName");
+ AnyNameNameClass anyName = new AnyNameNameClass();
+ Element except = getFirstChildElement(node);
+ if (except != null) {
+ checkName(except, "except");
+ anyName.exceptNameClass = parseNameClass(getFirstChildElement(except));
+ }
+ return anyName;
+ }
+
+ NameNameClass parseName(Element node)
+ throws GrammarException
+ {
+ checkName(node, "name");
+ NameNameClass name = new NameNameClass();
+ name.ns = node.getAttribute("ns");
+ name.name = node.getTextContent();
+ return name;
+ }
+
+ NSNameNameClass parseNsName(Element node)
+ throws GrammarException
+ {
+ checkName(node, "nsName");
+ NSNameNameClass nsName = new NSNameNameClass();
+ nsName.ns = node.getAttribute("ns");
+ Element except = getFirstChildElement(node);
+ if (except != null) {
+ checkName(except, "except");
+ nsName.exceptNameClass = parseNameClass(getFirstChildElement(except));
+ }
+ return nsName;
+ }
+
+ ChoiceNameClass parseChoiceNameClass(Element node)
+ throws GrammarException
+ {
+ checkName(node, "choice");
+ ChoiceNameClass choice = new ChoiceNameClass();
+ Element c1 = getFirstChildElement(node);
+ Element c2 = getNextSiblingElement(c1);
+ choice.name1 = parseNameClass(c1);
+ choice.name2 = parseNameClass(c2);
+ return choice;
+ }
+
+ void checkName(Element node, String name)
+ throws GrammarException
+ {
+ if (!name.equals(node.getLocalName()))
+ throw new GrammarException("expecting " + name);
+ }
+
+ DatatypeLibrary getDatatypeLibrary(String uri)
+ throws GrammarException
+ {
+ if (datatypeLibraries == null)
+ datatypeLibraries = new HashMap();
+ DatatypeLibrary library = (DatatypeLibrary) datatypeLibraries.get(uri);
+ if (library == null)
+ {
+ library = new DatatypeLibraryLoader().createDatatypeLibrary(uri);
+ if (library == null)
+ throw new GrammarException("Datatype library not supported: " + uri);
+ datatypeLibraries.put(uri, library);
+ }
+ return library;
+ }
+
+}
diff --git a/gnu/xml/validation/relaxng/Grammar.java b/gnu/xml/validation/relaxng/Grammar.java
new file mode 100644
index 000000000..76eff4f3a
--- /dev/null
+++ b/gnu/xml/validation/relaxng/Grammar.java
@@ -0,0 +1,70 @@
+/* Grammar.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+import java.util.LinkedList;
+import java.util.List;
+import javax.xml.validation.Schema;
+import javax.xml.validation.Validator;
+import javax.xml.validation.ValidatorHandler;
+
+/**
+ * A RELAX NG grammar.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class Grammar
+ extends Schema
+{
+
+ Pattern start;
+ List defines = new LinkedList();
+
+ public Validator newValidator()
+ {
+ return new GrammarValidator(this);
+ }
+
+ public ValidatorHandler newValidatorHandler()
+ {
+ // TODO
+ return null;
+ }
+
+}
+
diff --git a/gnu/xml/validation/relaxng/GrammarException.java b/gnu/xml/validation/relaxng/GrammarException.java
new file mode 100644
index 000000000..71d03de97
--- /dev/null
+++ b/gnu/xml/validation/relaxng/GrammarException.java
@@ -0,0 +1,56 @@
+/* GrammarException.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+import java.io.IOException;
+
+/**
+ * Exception parsing a grammar.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class GrammarException
+ extends IOException
+{
+
+ GrammarException(String message)
+ {
+ super(message);
+ }
+
+}
diff --git a/gnu/xml/validation/relaxng/GrammarValidator.java b/gnu/xml/validation/relaxng/GrammarValidator.java
new file mode 100644
index 000000000..d811aeec9
--- /dev/null
+++ b/gnu/xml/validation/relaxng/GrammarValidator.java
@@ -0,0 +1,97 @@
+/* GrammarValidator.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+import java.io.IOException;
+import javax.xml.transform.Source;
+import javax.xml.transform.Result;
+import javax.xml.validation.Validator;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * RELAX NG validator.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class GrammarValidator
+ extends Validator
+{
+
+ final Grammar grammar;
+ ErrorHandler errorHandler;
+ LSResourceResolver resourceResolver;
+
+ GrammarValidator(Grammar grammar)
+ {
+ this.grammar = grammar;
+ }
+
+ public ErrorHandler getErrorHandler()
+ {
+ return errorHandler;
+ }
+
+ public void setErrorHandler(ErrorHandler errorHandler)
+ {
+ this.errorHandler = errorHandler;
+ }
+
+ public LSResourceResolver getResourceResolver()
+ {
+ return resourceResolver;
+ }
+
+ public void setResourceResolver(LSResourceResolver resourceResolver)
+ {
+ this.resourceResolver = resourceResolver;
+ }
+
+ public void reset()
+ {
+ // TODO
+ }
+
+ public void validate(Source source, Result result)
+ throws SAXException, IOException
+ {
+ // TODO
+ }
+
+}
diff --git a/gnu/xml/validation/relaxng/GroupPattern.java b/gnu/xml/validation/relaxng/GroupPattern.java
new file mode 100644
index 000000000..b01090efa
--- /dev/null
+++ b/gnu/xml/validation/relaxng/GroupPattern.java
@@ -0,0 +1,53 @@
+/* GroupPattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG group element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class GroupPattern
+ extends Pattern
+{
+
+ Pattern pattern1;
+ Pattern pattern2;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/InterleavePattern.java b/gnu/xml/validation/relaxng/InterleavePattern.java
new file mode 100644
index 000000000..aa7c28e5e
--- /dev/null
+++ b/gnu/xml/validation/relaxng/InterleavePattern.java
@@ -0,0 +1,53 @@
+/* InterleavePattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG interleave element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class InterleavePattern
+ extends Pattern
+{
+
+ Pattern pattern1;
+ Pattern pattern2;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/ListPattern.java b/gnu/xml/validation/relaxng/ListPattern.java
new file mode 100644
index 000000000..4c0393ae5
--- /dev/null
+++ b/gnu/xml/validation/relaxng/ListPattern.java
@@ -0,0 +1,52 @@
+/* ListPattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG list element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class ListPattern
+ extends Pattern
+{
+
+ Pattern pattern;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/NSNameNameClass.java b/gnu/xml/validation/relaxng/NSNameNameClass.java
new file mode 100644
index 000000000..f485e9970
--- /dev/null
+++ b/gnu/xml/validation/relaxng/NSNameNameClass.java
@@ -0,0 +1,61 @@
+/* NSNameNameClass.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG nsName element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class NSNameNameClass
+ extends NameClass
+{
+
+ String ns;
+ NameClass exceptNameClass;
+
+ boolean matchesName(String uri, String localName)
+ {
+ if (!ns.equals(uri))
+ return false;
+ return (exceptNameClass == null) ? true :
+ !exceptNameClass.matchesName(uri, localName);
+ }
+
+}
+
diff --git a/gnu/xml/validation/relaxng/NameClass.java b/gnu/xml/validation/relaxng/NameClass.java
new file mode 100644
index 000000000..2a3dc83e5
--- /dev/null
+++ b/gnu/xml/validation/relaxng/NameClass.java
@@ -0,0 +1,50 @@
+/* NameClass.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG name class.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+abstract class NameClass
+{
+
+ abstract boolean matchesName(String uri, String localName);
+
+}
diff --git a/gnu/xml/validation/relaxng/NameNameClass.java b/gnu/xml/validation/relaxng/NameNameClass.java
new file mode 100644
index 000000000..d5a0c5f04
--- /dev/null
+++ b/gnu/xml/validation/relaxng/NameNameClass.java
@@ -0,0 +1,60 @@
+/* NameNameClass.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG name element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class NameNameClass
+ extends NameClass
+{
+
+ String ns;
+ String name;
+
+ boolean matchesName(String uri, String localName)
+ {
+ if (!ns.equals(uri))
+ return false;
+ return name.equals(localName);
+ }
+
+}
+
diff --git a/gnu/xml/validation/relaxng/NotAllowedPattern.java b/gnu/xml/validation/relaxng/NotAllowedPattern.java
new file mode 100644
index 000000000..8263a4573
--- /dev/null
+++ b/gnu/xml/validation/relaxng/NotAllowedPattern.java
@@ -0,0 +1,53 @@
+/* NotAllowedPattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG notAllowed element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class NotAllowedPattern
+ extends Pattern
+{
+
+ static final NotAllowedPattern INSTANCE = new NotAllowedPattern();
+
+}
+
+
diff --git a/gnu/xml/validation/relaxng/OneOrMorePattern.java b/gnu/xml/validation/relaxng/OneOrMorePattern.java
new file mode 100644
index 000000000..99864d72a
--- /dev/null
+++ b/gnu/xml/validation/relaxng/OneOrMorePattern.java
@@ -0,0 +1,52 @@
+/* OneOrMorePattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG oneOrMore element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class OneOrMorePattern
+ extends Pattern
+{
+
+ Pattern pattern;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/Param.java b/gnu/xml/validation/relaxng/Param.java
new file mode 100644
index 000000000..246ad20b7
--- /dev/null
+++ b/gnu/xml/validation/relaxng/Param.java
@@ -0,0 +1,52 @@
+/* Param.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG param element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class Param
+{
+
+ String name;
+ String value;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/Pattern.java b/gnu/xml/validation/relaxng/Pattern.java
new file mode 100644
index 000000000..3bf9a9919
--- /dev/null
+++ b/gnu/xml/validation/relaxng/Pattern.java
@@ -0,0 +1,48 @@
+/* Pattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG pattern.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+abstract class Pattern
+{
+}
+
diff --git a/gnu/xml/validation/relaxng/RELAXNGSchemaFactory.java b/gnu/xml/validation/relaxng/RELAXNGSchemaFactory.java
new file mode 100644
index 000000000..e1eb758ea
--- /dev/null
+++ b/gnu/xml/validation/relaxng/RELAXNGSchemaFactory.java
@@ -0,0 +1,151 @@
+/* RelaxNGSchemaFactory.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+import java.io.IOException;
+import java.net.URL;
+import javax.xml.XMLConstants;
+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 javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Schema factory for RELAX NG grammars.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+public class RELAXNGSchemaFactory
+ extends SchemaFactory
+{
+
+ LSResourceResolver resourceResolver;
+
+ public LSResourceResolver getResourceResolver()
+ {
+ return resourceResolver;
+ }
+
+ public void setResourceResolver(LSResourceResolver resourceResolver)
+ {
+ this.resourceResolver = resourceResolver;
+ }
+
+ public boolean isSchemaLanguageSupported(String schemaLanguage)
+ {
+ return XMLConstants.RELAXNG_NS_URI.equals(schemaLanguage);
+ }
+
+ public Schema newSchema()
+ throws SAXException
+ {
+ // TODO
+ throw new UnsupportedOperationException();
+ }
+
+ public Schema newSchema(Source[] schemata)
+ throws SAXException
+ {
+ if (schemata == null || schemata.length != 1)
+ throw new IllegalArgumentException("must specify one source");
+ // TODO multiple schemata
+ // TODO compact syntax
+ try
+ {
+ Document doc = getDocument(schemata[0]);
+ FullSyntaxBuilder builder = new FullSyntaxBuilder();
+ return builder.parse(doc);
+ }
+ catch (IOException e)
+ {
+ SAXException e2 = new SAXException(e.getMessage());
+ e2.initCause(e);
+ throw e2;
+ }
+ }
+
+ private static Document getDocument(Source source)
+ throws SAXException, IOException
+ {
+ if (source instanceof DOMSource)
+ {
+ Node node = ((DOMSource) source).getNode();
+ if (node != null && node instanceof Document)
+ return (Document) node;
+ }
+ String url = source.getSystemId();
+ try
+ {
+ InputSource input = new InputSource(url);
+ if (source instanceof StreamSource)
+ {
+ StreamSource streamSource = (StreamSource) source;
+ input.setByteStream(streamSource.getInputStream());
+ input.setCharacterStream(streamSource.getReader());
+ }
+ if (input.getByteStream() == null &&
+ input.getCharacterStream() == null &&
+ url != null)
+ input.setByteStream(new URL(url).openStream());
+ DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
+ f.setNamespaceAware(true);
+ f.setCoalescing(true);
+ f.setExpandEntityReferences(true);
+ f.setIgnoringComments(true);
+ f.setIgnoringElementContentWhitespace(true);
+ DocumentBuilder b = f.newDocumentBuilder();
+ return b.parse(input);
+ }
+ catch (ParserConfigurationException e)
+ {
+ SAXException e2 = new SAXException(e.getMessage());
+ e2.initCause(e);
+ throw e2;
+ }
+ }
+
+}
diff --git a/gnu/xml/validation/relaxng/RefPattern.java b/gnu/xml/validation/relaxng/RefPattern.java
new file mode 100644
index 000000000..d7de09542
--- /dev/null
+++ b/gnu/xml/validation/relaxng/RefPattern.java
@@ -0,0 +1,52 @@
+/* RefPattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG ref element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class RefPattern
+ extends Pattern
+{
+
+ String name;
+
+}
+
diff --git a/gnu/xml/validation/relaxng/TextPattern.java b/gnu/xml/validation/relaxng/TextPattern.java
new file mode 100644
index 000000000..06af3c34a
--- /dev/null
+++ b/gnu/xml/validation/relaxng/TextPattern.java
@@ -0,0 +1,52 @@
+/* TextPattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+/**
+ * A RELAX NG text element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class TextPattern
+ extends Pattern
+{
+
+ static final TextPattern INSTANCE = new TextPattern();
+
+}
+
diff --git a/gnu/xml/validation/relaxng/ValuePattern.java b/gnu/xml/validation/relaxng/ValuePattern.java
new file mode 100644
index 000000000..81260b0ca
--- /dev/null
+++ b/gnu/xml/validation/relaxng/ValuePattern.java
@@ -0,0 +1,58 @@
+/* ValuePattern.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.relaxng;
+
+import org.relaxng.datatype.Datatype;
+import org.relaxng.datatype.DatatypeLibrary;
+
+/**
+ * A RELAX NG value element.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class ValuePattern
+ extends Pattern
+{
+
+ DatatypeLibrary datatypeLibrary;
+ Datatype type;
+ String ns;
+ String value;
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/AnyAttribute.java b/gnu/xml/validation/xmlschema/AnyAttribute.java
new file mode 100644
index 000000000..df90dc626
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/AnyAttribute.java
@@ -0,0 +1,67 @@
+/* AnyAttribute.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import gnu.xml.validation.datatype.Annotation;
+
+/**
+ * An attribute wildcard.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+final class AnyAttribute
+{
+
+ static final int STRICT = 0;
+ static final int LAX = 1;
+ static final int SKIP = 2;
+
+ final String namespace;
+
+ final int processContents;
+
+ Annotation annotation;
+
+ AnyAttribute(String namespace, int processContents)
+ {
+ this.namespace = namespace;
+ this.processContents = processContents;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/AttributeDeclaration.java b/gnu/xml/validation/xmlschema/AttributeDeclaration.java
new file mode 100644
index 000000000..98b322bee
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/AttributeDeclaration.java
@@ -0,0 +1,99 @@
+/* AttributeDeclaration.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import gnu.xml.validation.datatype.Annotation;
+import gnu.xml.validation.datatype.SimpleType;
+import javax.xml.namespace.QName;
+
+/**
+ * An XML Schema attribute declaration schema component.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class AttributeDeclaration
+{
+
+ static final int NONE = 0;
+ static final int DEFAULT = 1;
+ static final int FIXED = 2;
+
+ /**
+ * The scope of this attribute declaration (global or local).
+ */
+ final boolean scope;
+
+ /**
+ * The constraint type.
+ * One of NONE, DEFAULT, FIXED.
+ */
+ final int type;
+
+ /**
+ * The value constraint.
+ */
+ final String value;
+
+ /**
+ * The name of the attribute to which this declaration refers.
+ */
+ final QName name;
+
+ /**
+ * The type definition corresponding to this attribute.
+ */
+ final SimpleType datatype;
+
+ /**
+ * The annotation associated with this attribute declaration, if any.
+ */
+ final Annotation annotation;
+
+ AttributeDeclaration(boolean scope, int type, String value, QName name,
+ SimpleType datatype, Annotation annotation)
+ {
+ this.scope = scope;
+ this.type = type;
+ this.value = value;
+ this.name = name;
+ this.datatype = datatype;
+ this.annotation = annotation;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/AttributeUse.java b/gnu/xml/validation/xmlschema/AttributeUse.java
new file mode 100644
index 000000000..f8bb11b91
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/AttributeUse.java
@@ -0,0 +1,79 @@
+/* AttributeUse.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+/**
+ * An XML Schema attribute use schema component.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class AttributeUse
+{
+
+ /**
+ * Whether the attribute is required.
+ */
+ final boolean required;
+
+ /**
+ * The constraint type.
+ * One of NONE, DEFAULT, FIXED.
+ */
+ final int type;
+
+ /**
+ * The value constraint.
+ */
+ final String value;
+
+ /**
+ * The name of the attribute to which this declaration refers.
+ */
+ final AttributeDeclaration declaration;
+
+ AttributeUse(boolean required, int type, String value,
+ AttributeDeclaration declaration)
+ {
+ this.required = required;
+ this.type = type;
+ this.value = value;
+ this.declaration = declaration;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/ComplexType.java b/gnu/xml/validation/xmlschema/ComplexType.java
new file mode 100644
index 000000000..2c7acb10a
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/ComplexType.java
@@ -0,0 +1,102 @@
+/* ComplexType.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.xml.namespace.QName;
+import gnu.xml.validation.datatype.Type;
+
+/**
+ * A complex type definition.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class ComplexType
+ extends Type
+{
+
+ /**
+ * Either a simple type definition or a complex type definition.
+ */
+ QName baseType;
+
+ /**
+ * Either EXTENSION or RESTRICTION.
+ */
+ int derivationMethod;
+
+ /**
+ * A subset of {EXTENSION, RESTRICTION}.
+ */
+ final int finality;
+
+ final boolean isAbstract;
+
+ Set attributeUses;
+
+ AnyAttribute attributeWildcard;
+
+ /**
+ * One of EMPTY, SIMPLE, MIXED, or ELEMENT_ONLY.
+ */
+ int contentType;
+
+ /**
+ * A simple type definition or a Particle.
+ */
+ Object contentModel;
+
+ final int prohibitedSubstitutions;
+
+ Set annotations;
+
+ ComplexType(QName name,
+ boolean isAbstract,
+ int prohibitedSubstitutions,
+ int finality)
+ {
+ super(name);
+ this.isAbstract = isAbstract;
+ this.prohibitedSubstitutions = prohibitedSubstitutions;
+ this.finality = finality;
+ attributeUses = new LinkedHashSet();
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/ElementDeclaration.java b/gnu/xml/validation/xmlschema/ElementDeclaration.java
new file mode 100644
index 000000000..d41f5e536
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/ElementDeclaration.java
@@ -0,0 +1,125 @@
+/* ElementDeclaration.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import gnu.xml.validation.datatype.Annotation;
+import gnu.xml.validation.datatype.Type;
+import javax.xml.namespace.QName;
+
+/**
+ * An XML Schema element declaration schema component.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class ElementDeclaration
+{
+
+ /**
+ * The name of the element to which this declaration refers.
+ */
+ final QName name;
+
+ /**
+ * The type definition corresponding to this element.
+ */
+ Type datatype;
+
+ /**
+ * The scope of this schema component.
+ * One of GLOBAL, LOCAL, or ABSENT.
+ */
+ final int scope;
+
+ /**
+ * If scope is LOCAL, the parent element definition.
+ */
+ final ElementDeclaration parent;
+
+ /**
+ * The constraint type.
+ * One of NONE, DEFAULT, FIXED.
+ */
+ final int type;
+
+ /**
+ * The value constraint.
+ */
+ final String value;
+
+ final boolean nillable;
+
+ // TODO identity-constraint definitions
+
+ final QName substitutionGroup;
+
+ final int substitutionGroupExclusions;
+
+ final int disallowedSubstitutions;
+
+ final boolean isAbstract;
+
+ /**
+ * The annotation associated with this attribute declaration, if any.
+ */
+ Annotation annotation;
+
+ ElementDeclaration(QName name,
+ Type datatype,
+ int scope, ElementDeclaration parent,
+ int type, String value,
+ boolean nillable,
+ QName substitutionGroup,
+ int substitutionGroupExclusions,
+ int disallowedSubstitutions,
+ boolean isAbstract)
+ {
+ this.name = name;
+ this.datatype = datatype;
+ this.scope = scope;
+ this.parent = parent;
+ this.type = type;
+ this.value = value;
+ this.nillable = nillable;
+ this.substitutionGroup = substitutionGroup;
+ this.substitutionGroupExclusions = substitutionGroupExclusions;
+ this.disallowedSubstitutions = disallowedSubstitutions;
+ this.isAbstract = isAbstract;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/Particle.java b/gnu/xml/validation/xmlschema/Particle.java
new file mode 100644
index 000000000..995c4ff09
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/Particle.java
@@ -0,0 +1,61 @@
+/* Particle.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+/**
+ * Container for element content.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class Particle
+{
+
+ final Integer minOccurs;
+ final Integer maxOccurs;
+
+ final Object term;
+
+ Particle(Integer minOccurs, Integer maxOccurs, Object term)
+ {
+ this.minOccurs = minOccurs;
+ this.maxOccurs = maxOccurs;
+ this.term = term;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/ValidationException.java b/gnu/xml/validation/xmlschema/ValidationException.java
new file mode 100644
index 000000000..f2d684309
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/ValidationException.java
@@ -0,0 +1,58 @@
+/* ValidationException.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+
+/**
+ * An XML Schema validation rule violation.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class ValidationException
+ extends SAXParseException
+{
+
+ ValidationException(String message, Locator locator)
+ {
+ super(message, locator);
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchema.java b/gnu/xml/validation/xmlschema/XMLSchema.java
new file mode 100644
index 000000000..647cbdeff
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchema.java
@@ -0,0 +1,134 @@
+/* XMLSchema.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.xml.validation.Schema;
+import javax.xml.validation.Validator;
+import javax.xml.validation.ValidatorHandler;
+
+/**
+ * An XML Schema schema.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+final class XMLSchema
+ extends Schema
+{
+
+ static final int FINAL_NONE = 0x00;
+ static final int FINAL_EXTENSION = 0x01;
+ static final int FINAL_RESTRICTION = 0x02;
+ static final int FINAL_LIST = 0x04;
+ static final int FINAL_UNION = 0x08;
+ static final int FINAL_ALL = 0x0f;
+
+ static final int BLOCK_NONE = 0x00;
+ static final int BLOCK_EXTENSION = 0x01;
+ static final int BLOCK_RESTRICTION = 0x02;
+ static final int BLOCK_SUBSTITUTION = 0x04;
+ static final int BLOCK_ALL = 0x07;
+
+ static final int GLOBAL = 0x00;
+ static final int LOCAL = 0x01;
+ static final int ABSENT = 0x02;
+
+ static final int CONSTRAINT_NONE = 0x00;
+ static final int CONSTRAINT_DEFAULT = 0x01;
+ static final int CONSTRAINT_FIXED = 0x02;
+
+ static final int CONTENT_EMPTY = 0x00;
+ static final int CONTENT_SIMPLE = 0x01;
+ static final int CONTENT_MIXED = 0x02;
+ static final int CONTENT_ELEMENT_ONLY = 0x03;
+
+ final String targetNamespace;
+ final String version;
+ final int finalDefault;
+ final int blockDefault;
+ final boolean attributeFormQualified;
+ final boolean elementFormQualified;
+
+ /**
+ * The element declarations in this schema.
+ */
+ final Map elementDeclarations;
+
+ /**
+ * The attribute declarations in this schema.
+ */
+ final Map attributeDeclarations;
+
+ /**
+ * The type declarations in this schema.
+ */
+ final Map types;
+
+ XMLSchema(String targetNamespace, String version,
+ int finalDefault, int blockDefault,
+ boolean attributeFormQualified,
+ boolean elementFormQualified)
+ {
+ this.targetNamespace = targetNamespace;
+ this.version = version;
+ this.finalDefault = finalDefault;
+ this.blockDefault = blockDefault;
+ this.attributeFormQualified = attributeFormQualified;
+ this.elementFormQualified = elementFormQualified;
+ elementDeclarations = new LinkedHashMap();
+ attributeDeclarations = new LinkedHashMap();
+ types = new LinkedHashMap();
+ }
+
+ public Validator newValidator()
+ {
+ // TODO
+ //return new XMLSchemaValidator(this);
+ return null;
+ }
+
+ public ValidatorHandler newValidatorHandler()
+ {
+ // TODO
+ //return new XMLSchemaValidatorHandler(this);
+ return null;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaAttributeTypeInfo.java b/gnu/xml/validation/xmlschema/XMLSchemaAttributeTypeInfo.java
new file mode 100644
index 000000000..758bc94cd
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchemaAttributeTypeInfo.java
@@ -0,0 +1,100 @@
+/* XMLSchemaAttributeTypeInfo.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import org.w3c.dom.TypeInfo;
+import gnu.xml.validation.datatype.SimpleType;
+
+/**
+ * Attribute type information provided by validation against an XML Schema.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+final class XMLSchemaAttributeTypeInfo
+ extends XMLSchemaTypeInfo
+{
+
+ final XMLSchema schema;
+ final AttributeDeclaration decl;
+ final SimpleType type;
+ boolean id;
+ final boolean specified;
+
+ XMLSchemaAttributeTypeInfo(XMLSchema schema, AttributeDeclaration decl,
+ boolean specified)
+ {
+ this.schema = schema;
+ this.decl = decl;
+ this.specified = specified;
+ type = (decl == null) ? null : decl.datatype;
+ }
+
+ public String getTypeName()
+ {
+ if (type == null)
+ {
+ return "CDATA";
+ }
+ return type.name.getLocalPart();
+ }
+
+ public String getTypeNamespace()
+ {
+ if (type == null)
+ {
+ return "";
+ }
+ return type.name.getNamespaceURI();
+ }
+
+ public boolean isDerivedFrom(String typeNamespace, String typeName,
+ int derivationMethod)
+ {
+ if (type == null)
+ {
+ return false;
+ }
+ else
+ {
+ return simpleTypeIsDerivedFrom(type, typeNamespace, typeName,
+ derivationMethod);
+ }
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaBuilder.java b/gnu/xml/validation/xmlschema/XMLSchemaBuilder.java
new file mode 100644
index 000000000..ddf91409d
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchemaBuilder.java
@@ -0,0 +1,844 @@
+/* XMLSchemaBuilder.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import org.relaxng.datatype.DatatypeException;
+import org.relaxng.datatype.DatatypeLibrary;
+import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import gnu.xml.validation.datatype.Annotation;
+import gnu.xml.validation.datatype.AtomicSimpleType;
+import gnu.xml.validation.datatype.ListSimpleType;
+import gnu.xml.validation.datatype.SimpleType;
+import gnu.xml.validation.datatype.Type;
+import gnu.xml.validation.datatype.UnionSimpleType;
+
+/**
+ * Parses an XML Schema DOM tree, constructing a compiled internal
+ * representation.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class XMLSchemaBuilder
+{
+
+ XMLSchema schema;
+ final DatatypeLibrary typeLibrary;
+
+ XMLSchemaBuilder()
+ {
+ final String ns = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ typeLibrary = new DatatypeLibraryLoader().createDatatypeLibrary(ns);
+ }
+
+ void parseSchema(Node node)
+ throws DatatypeException
+ {
+ String uri = node.getNamespaceURI();
+ String name = node.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ node.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("schema".equals(name))
+ {
+ NamedNodeMap attrs = node.getAttributes();
+ String targetNamespace = getAttribute(attrs, "targetNamespace");
+ String version = getAttribute(attrs, "version");
+ String fd = getAttribute(attrs, "finalDefault");
+ int finalDefault = parseFullDerivationSet(fd);
+ String bd = getAttribute(attrs, "blockDefault");
+ int blockDefault = parseBlockSet(bd);
+ String afd = getAttribute(attrs, "attributeFormDefault");
+ boolean attributeFormQualified = "qualified".equals(afd);
+ String efd = getAttribute(attrs, "elementFormDefault");
+ boolean elementFormQualified = "qualified".equals(efd);
+ schema = new XMLSchema(targetNamespace, version,
+ finalDefault, blockDefault,
+ attributeFormQualified,
+ elementFormQualified);
+ for (Node child = node.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ parseTopLevelElement(child);
+ }
+ return;
+ }
+ }
+ // TODO throw schema exception
+ }
+
+ void parseTopLevelElement(Node node)
+ throws DatatypeException
+ {
+ String uri = node.getNamespaceURI();
+ String name = node.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ node.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("element".equals(name))
+ {
+ ElementDeclaration ed =
+ (ElementDeclaration) parseElement(node, null);
+ schema.elementDeclarations.put(ed.name, ed);
+ // TODO
+ }
+ else if ("attribute".equals(name))
+ {
+ AttributeDeclaration ad =
+ (AttributeDeclaration) parseAttribute(node, true);
+ schema.attributeDeclarations.put(ad.name, ad);
+ // TODO
+ }
+ else if ("type".equals(name))
+ {
+ // TODO
+ }
+ else if ("group".equals(name))
+ {
+ // TODO
+ }
+ else if ("attributeGroup".equals(name))
+ {
+ // TODO
+ }
+ else if ("notation".equals(name))
+ {
+ // TODO
+ }
+ else if ("identityConstraint".equals(name))
+ {
+ // TODO
+ }
+ }
+ // TODO throw schema exception
+ }
+
+ Object parseAttribute(Node node, boolean scope)
+ throws DatatypeException
+ {
+ NamedNodeMap attrs = node.getAttributes();
+ String def = getAttribute(attrs, "default");
+ String fixed = getAttribute(attrs, "fixed");
+ int constraintType = AttributeDeclaration.NONE;
+ String constraintValue = null;
+ if (def != null)
+ {
+ constraintType = AttributeDeclaration.DEFAULT;
+ constraintValue = def;
+ }
+ else if (fixed != null)
+ {
+ constraintType = AttributeDeclaration.FIXED;
+ constraintValue = fixed;
+ }
+ // TODO form = (qualified | unqualified)
+ String attrName = getAttribute(attrs, "name");
+ String attrNamespace = getAttribute(attrs, "targetNamespace");
+ String ref = getAttribute(attrs, "ref");
+ String use = getAttribute(attrs, "use");
+ String type = getAttribute(attrs, "type");
+ SimpleType datatype = (type == null) ? null :
+ parseSimpleType(asQName(type, node));
+ Annotation annotation = null;
+ for (Node child = node.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ String uri = child.getNamespaceURI();
+ String name = child.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ child.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("annotation".equals(name))
+ {
+ annotation = parseAnnotation(child);
+ }
+ else if ("simpleType".equals(name))
+ {
+ datatype = parseSimpleType(child);
+ }
+ else
+ {
+ // TODO throw schema exception
+ }
+ }
+ }
+ if (scope)
+ {
+ return new AttributeDeclaration(scope,
+ constraintType,
+ constraintValue,
+ new QName(attrNamespace, attrName),
+ datatype,
+ annotation);
+ }
+ else
+ {
+ boolean required = "required".equals(use);
+ // TODO ref
+ AttributeDeclaration decl = (ref == null) ?
+ new AttributeDeclaration(scope,
+ AttributeDeclaration.NONE,
+ null,
+ new QName(attrNamespace, attrName),
+ datatype,
+ annotation) :
+ /*schema.getAttributeDeclaration(ref)*/ null;
+ return new AttributeUse(required,
+ constraintType,
+ constraintValue,
+ decl);
+ }
+ }
+
+ int parseFullDerivationSet(String value)
+ {
+ int ret = XMLSchema.FINAL_NONE;
+ if ("#all".equals(value))
+ {
+ ret = XMLSchema.FINAL_ALL;
+ }
+ else
+ {
+ StringTokenizer st = new StringTokenizer(value, " ");
+ while (st.hasMoreTokens())
+ {
+ String token = st.nextToken();
+ if ("extension".equals(token))
+ {
+ ret |= XMLSchema.FINAL_EXTENSION;
+ }
+ else if ("restriction".equals(token))
+ {
+ ret |= XMLSchema.FINAL_RESTRICTION;
+ }
+ else if ("list".equals(token))
+ {
+ ret |= XMLSchema.FINAL_LIST;
+ }
+ else if ("union".equals(token))
+ {
+ ret |= XMLSchema.FINAL_UNION;
+ }
+ }
+ }
+ return ret;
+ }
+
+ int parseSimpleTypeDerivationSet(String value)
+ {
+ int ret = XMLSchema.FINAL_NONE;
+ if ("#all".equals(value))
+ {
+ ret = XMLSchema.FINAL_LIST |
+ XMLSchema.FINAL_UNION |
+ XMLSchema.FINAL_RESTRICTION;
+ }
+ else
+ {
+ StringTokenizer st = new StringTokenizer(value, " ");
+ while (st.hasMoreTokens())
+ {
+ String token = st.nextToken();
+ if ("list".equals(token))
+ {
+ ret |= XMLSchema.FINAL_LIST;
+ }
+ else if ("union".equals(token))
+ {
+ ret |= XMLSchema.FINAL_UNION;
+ }
+ else if ("restriction".equals(token))
+ {
+ ret |= XMLSchema.FINAL_RESTRICTION;
+ }
+ }
+ }
+ return ret;
+ }
+
+ int parseComplexTypeDerivationSet(String value)
+ {
+ int ret = XMLSchema.FINAL_NONE;
+ if ("#all".equals(value))
+ {
+ ret = XMLSchema.FINAL_EXTENSION | XMLSchema.FINAL_RESTRICTION;
+ }
+ else
+ {
+ StringTokenizer st = new StringTokenizer(value, " ");
+ while (st.hasMoreTokens())
+ {
+ String token = st.nextToken();
+ if ("extension".equals(token))
+ {
+ ret |= XMLSchema.FINAL_EXTENSION;
+ }
+ else if ("restriction".equals(token))
+ {
+ ret |= XMLSchema.FINAL_RESTRICTION;
+ }
+ }
+ }
+ return ret;
+ }
+
+ int parseBlockSet(String value)
+ {
+ int ret = XMLSchema.BLOCK_NONE;
+ if ("#all".equals(value))
+ {
+ ret = XMLSchema.BLOCK_ALL;
+ }
+ else
+ {
+ StringTokenizer st = new StringTokenizer(value, " ");
+ while (st.hasMoreTokens())
+ {
+ String token = st.nextToken();
+ if ("extension".equals(token))
+ {
+ ret |= XMLSchema.BLOCK_EXTENSION;
+ }
+ else if ("restriction".equals(token))
+ {
+ ret |= XMLSchema.BLOCK_RESTRICTION;
+ }
+ else if ("substitution".equals(token))
+ {
+ ret |= XMLSchema.BLOCK_SUBSTITUTION;
+ }
+ }
+ }
+ return ret;
+ }
+
+ int parseComplexTypeBlockSet(String value)
+ {
+ int ret = XMLSchema.BLOCK_NONE;
+ if ("#all".equals(value))
+ {
+ ret = XMLSchema.BLOCK_EXTENSION | XMLSchema.BLOCK_RESTRICTION;
+ }
+ else
+ {
+ StringTokenizer st = new StringTokenizer(value, " ");
+ while (st.hasMoreTokens())
+ {
+ String token = st.nextToken();
+ if ("extension".equals(token))
+ {
+ ret |= XMLSchema.BLOCK_EXTENSION;
+ }
+ else if ("restriction".equals(token))
+ {
+ ret |= XMLSchema.BLOCK_RESTRICTION;
+ }
+ }
+ }
+ return ret;
+ }
+
+ Object parseElement(Node node, ElementDeclaration parent)
+ throws DatatypeException
+ {
+ NamedNodeMap attrs = node.getAttributes();
+ Integer minOccurs = null;
+ Integer maxOccurs = null;
+ Node parentNode = node.getParentNode();
+ boolean notTopLevel = !"schema".equals(parentNode.getLocalName());
+ if (notTopLevel)
+ {
+ String ref = getAttribute(attrs, "ref");
+ if (ref != null)
+ {
+ minOccurs = getOccurrence(getAttribute(attrs, "minOccurs"));
+ maxOccurs = getOccurrence(getAttribute(attrs, "maxOccurs"));
+ // TODO resolve top-level element declaration
+ ElementDeclaration ad = null;
+ return new Particle(minOccurs, maxOccurs, ad);
+ }
+ }
+ String elementName = getAttribute(attrs, "name");
+ String elementNamespace = getAttribute(attrs, "targetNamespace");
+ String type = getAttribute(attrs, "type");
+ Type datatype = (type != null) ?
+ parseSimpleType(asQName(type, node)) : null;
+ int scope = (parent == null) ?
+ XMLSchema.GLOBAL :
+ XMLSchema.LOCAL;
+ String def = getAttribute(attrs, "default");
+ String fixed = getAttribute(attrs, "fixed");
+ int constraintType = AttributeDeclaration.NONE;
+ String constraintValue = null;
+ if (def != null)
+ {
+ constraintType = AttributeDeclaration.DEFAULT;
+ constraintValue = def;
+ }
+ else if (fixed != null)
+ {
+ constraintType = AttributeDeclaration.FIXED;
+ constraintValue = fixed;
+ }
+ String sg = getAttribute(attrs, "substitutionGroup");
+ QName substitutionGroup = QName.valueOf(sg);
+ String sgPrefix = substitutionGroup.getPrefix();
+ if (sgPrefix != null && !"".equals(sgPrefix))
+ {
+ String sgName = substitutionGroup.getLocalPart();
+ String sgNamespace = node.lookupNamespaceURI(sgPrefix);
+ substitutionGroup = new QName(sgNamespace, sgName);
+ }
+
+ String block = getAttribute(attrs, "block");
+ int substitutionGroupExclusions = (block == null) ?
+ schema.blockDefault :
+ parseBlockSet(block);
+ String final_ = getAttribute(attrs, "final");
+ int disallowedSubstitutions = (final_ == null) ?
+ schema.finalDefault :
+ parseFullDerivationSet(final_);
+
+ boolean nillable = "true".equals(getAttribute(attrs, "nillable"));
+ boolean isAbstract = "true".equals(getAttribute(attrs, "abstract"));
+
+ if (notTopLevel)
+ {
+ minOccurs = getOccurrence(getAttribute(attrs, "minOccurs"));
+ maxOccurs = getOccurrence(getAttribute(attrs, "maxOccurs"));
+ String form = getAttribute(attrs, "form");
+ if (form != null)
+ {
+ if ("qualified".equals(form))
+ {
+ elementNamespace = schema.targetNamespace;
+ }
+ }
+ else if (schema.elementFormQualified)
+ {
+ elementNamespace = schema.targetNamespace;
+ }
+ }
+ ElementDeclaration ed =
+ new ElementDeclaration(new QName(elementNamespace, elementName),
+ datatype,
+ scope, parent,
+ constraintType, constraintValue,
+ nillable,
+ substitutionGroup,
+ substitutionGroupExclusions,
+ disallowedSubstitutions,
+ isAbstract);
+
+ for (Node child = node.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ String uri = child.getNamespaceURI();
+ String name = child.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ child.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("annotation".equals(name))
+ {
+ ed.annotation = parseAnnotation(child);
+ }
+ else if ("simpleType".equals(name) && datatype == null)
+ {
+ ed.datatype = parseSimpleType(child);
+ }
+ else if ("complexType".equals(name) && datatype == null)
+ {
+ ed.datatype = parseComplexType(child, ed);
+ }
+ else
+ {
+ // throw schema exception
+ }
+ }
+ }
+
+ if (notTopLevel)
+ {
+ return new Particle(minOccurs, maxOccurs, ed);
+ }
+ else
+ {
+ return ed;
+ }
+ }
+
+ Integer getOccurrence(String value)
+ {
+ if (value == null)
+ {
+ return new Integer(1);
+ }
+ else if ("unbounded".equals(value))
+ {
+ return null;
+ }
+ else
+ {
+ return new Integer(value);
+ }
+ }
+
+ SimpleType parseSimpleType(QName typeName)
+ throws DatatypeException
+ {
+ SimpleType type = (SimpleType) schema.types.get(typeName);
+ if (!XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(typeName.getNamespaceURI()))
+ return null;
+ String localName = typeName.getLocalPart();
+ return (SimpleType) typeLibrary.createDatatype(localName);
+ }
+
+ SimpleType parseSimpleType(Node simpleType)
+ throws DatatypeException
+ {
+ NamedNodeMap attrs = simpleType.getAttributes();
+ String typeFinal = getAttribute(attrs, "final");
+ if (typeFinal == null)
+ {
+ Node schema = simpleType.getParentNode();
+ while (schema != null && !"schema".equals(schema.getLocalName()))
+ {
+ schema = schema.getParentNode();
+ }
+ if (schema != null)
+ {
+ NamedNodeMap schemaAttrs = schema.getAttributes();
+ typeFinal = getAttribute(schemaAttrs, "finalDefault");
+ }
+ }
+ int typeFinality = parseSimpleTypeDerivationSet(typeFinal);
+ QName typeName = asQName(getAttribute(attrs, "name"), simpleType);
+ int variety = 0;
+ Set facets = new LinkedHashSet();
+ int fundamentalFacets = 0; // TODO
+ SimpleType baseType = null; // TODO
+ Annotation annotation = null;
+ // TODO use DatatypeBuilder
+ for (Node child = simpleType.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ String uri = child.getNamespaceURI();
+ String name = child.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ child.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("annotation".equals(name))
+ {
+ annotation = parseAnnotation(child);
+ }
+ else if ("restriction".equals(name))
+ {
+ // TODO
+ }
+ else if ("list".equals(name))
+ {
+ variety = SimpleType.LIST;
+ // TODO
+ }
+ else if ("union".equals(name))
+ {
+ variety = SimpleType.UNION;
+ // TODO
+ }
+ }
+ }
+ return new SimpleType(typeName, variety, facets, fundamentalFacets,
+ baseType, annotation);
+ }
+
+ Type parseComplexType(Node complexType, ElementDeclaration parent)
+ throws DatatypeException
+ {
+ NamedNodeMap attrs = complexType.getAttributes();
+ QName typeName = asQName(getAttribute(attrs, "name"), complexType);
+ boolean isAbstract = "true".equals(getAttribute(attrs, "abstract"));
+ String block = getAttribute(attrs, "block");
+ int prohibitedSubstitutions = (block == null) ?
+ schema.blockDefault :
+ parseComplexTypeBlockSet(block);
+ String final_ = getAttribute(attrs, "final");
+ int finality = (final_ == null) ?
+ schema.finalDefault :
+ parseComplexTypeDerivationSet(final_);
+ ComplexType type = new ComplexType(typeName, isAbstract,
+ prohibitedSubstitutions, finality);
+ boolean mixed = "true".equals(getAttribute(attrs, "mixed"));
+ for (Node child = complexType.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ String uri = child.getNamespaceURI();
+ String name = child.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ child.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("simpleContent".equals(name))
+ {
+ parseSimpleContent(child, type);
+ }
+ }
+ }
+ if (mixed)
+ {
+ type.contentType = XMLSchema.CONTENT_MIXED;
+ }
+ return type;
+ }
+
+ void parseSimpleContent(Node simpleContent, ComplexType type)
+ throws DatatypeException
+ {
+ for (Node child = simpleContent.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ String uri = child.getNamespaceURI();
+ String name = child.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ child.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("annotation".equals(name))
+ {
+ type.annotations.add(parseAnnotation(child));
+ }
+ else if ("restriction".equals(name))
+ {
+ type.derivationMethod = XMLSchema.FINAL_RESTRICTION;
+ parseRestriction(child, type);
+ }
+ else if ("extension".equals(name))
+ {
+ type.derivationMethod = XMLSchema.FINAL_EXTENSION;
+ parseExtension(child, type);
+ }
+ }
+ }
+ }
+
+ void parseRestriction(Node restriction, ComplexType type)
+ throws DatatypeException
+ {
+ NamedNodeMap attrs = restriction.getAttributes();
+ String base = getAttribute(attrs, "base");
+ QName baseType = asQName(base, restriction);
+ SimpleType simpleType = null;
+ for (Node child = restriction.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ String uri = child.getNamespaceURI();
+ String name = child.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ child.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("annotation".equals(name))
+ {
+ type.annotations.add(parseAnnotation(child));
+ }
+ else if ("simpleType".equals(name))
+ {
+ type.contentType = XMLSchema.CONTENT_SIMPLE;
+ simpleType = parseSimpleType(child);
+ }
+ else if ("minExclusive".equals(name))
+ {
+ }
+ else if ("minInclusive".equals(name))
+ {
+ }
+ else if ("maxExclusive".equals(name))
+ {
+ }
+ else if ("maxInclusive".equals(name))
+ {
+ }
+ else if ("totalDigits".equals(name))
+ {
+ }
+ else if ("fractionDigits".equals(name))
+ {
+ }
+ else if ("length".equals(name))
+ {
+ }
+ else if ("minLength".equals(name))
+ {
+ }
+ else if ("maxLength".equals(name))
+ {
+ }
+ else if ("enumeration".equals(name))
+ {
+ }
+ else if ("whiteSpace".equals(name))
+ {
+ }
+ else if ("pattern".equals(name))
+ {
+ }
+ else if ("attribute".equals(name))
+ {
+ AttributeUse use =
+ (AttributeUse) parseAttribute(child, false);
+ schema.attributeDeclarations.put(use.declaration.name,
+ use.declaration);
+ type.attributeUses.add(use);
+ }
+ else if ("attributeGroup".equals(name))
+ {
+ NamedNodeMap agAttrs = child.getAttributes();
+ String ref = getAttribute(agAttrs, "ref");
+ QName ag = asQName(ref, child);
+ type.attributeUses.add(ag);
+ }
+ else if ("anyAttribute".equals(name))
+ {
+ type.attributeWildcard = parseAnyAttribute(child);
+ }
+ }
+ }
+ }
+
+ void parseExtension(Node extension, ComplexType type)
+ throws DatatypeException
+ {
+ NamedNodeMap attrs = extension.getAttributes();
+ String base = getAttribute(attrs, "base");
+ QName baseType = asQName(base, extension);
+ for (Node child = extension.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ String uri = child.getNamespaceURI();
+ String name = child.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ child.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("annotation".equals(name))
+ {
+ type.annotations.add(parseAnnotation(child));
+ }
+ else if ("attribute".equals(name))
+ {
+ AttributeUse use =
+ (AttributeUse) parseAttribute(child, false);
+ schema.attributeDeclarations.put(use.declaration.name,
+ use.declaration);
+ type.attributeUses.add(use);
+ }
+ else if ("attributeGroup".equals(name))
+ {
+ NamedNodeMap agAttrs = child.getAttributes();
+ String ref = getAttribute(agAttrs, "ref");
+ QName ag = asQName(ref, child);
+ type.attributeUses.add(ag);
+ }
+ else if ("anyAttribute".equals(name))
+ {
+ type.attributeWildcard = parseAnyAttribute(child);
+ }
+ }
+ }
+ }
+
+ AnyAttribute parseAnyAttribute(Node node)
+ {
+ NamedNodeMap attrs = node.getAttributes();
+ String namespace = getAttribute(attrs, "namespace");
+ String pc = getAttribute(attrs, "processContents");
+ int processContents = AnyAttribute.STRICT;
+ if ("lax".equals(pc))
+ {
+ processContents = AnyAttribute.LAX;
+ }
+ else if ("skip".equals(pc))
+ {
+ processContents = AnyAttribute.SKIP;
+ }
+ AnyAttribute ret = new AnyAttribute(namespace, processContents);
+ for (Node child = node.getFirstChild(); child != null;
+ child = child.getNextSibling())
+ {
+ String uri = child.getNamespaceURI();
+ String name = child.getLocalName();
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri) &&
+ child.getNodeType() == Node.ELEMENT_NODE)
+ {
+ if ("annotation".equals(name))
+ {
+ ret.annotation = parseAnnotation(child);
+ }
+ }
+ }
+ return ret;
+ }
+
+ Annotation parseAnnotation(Node node)
+ {
+ // TODO
+ return null;
+ }
+
+ private static String getAttribute(NamedNodeMap attrs, String name)
+ {
+ Node attr = attrs.getNamedItem(name);
+ return (attr == null) ? null : attr.getNodeValue();
+ }
+
+ private static QName asQName(String text, Node resolver)
+ {
+ QName name = QName.valueOf(text);
+ String prefix = name.getPrefix();
+ if (prefix != null && prefix.length() > 0)
+ {
+ String uri = resolver.lookupNamespaceURI(prefix);
+ name = new QName(uri, name.getLocalPart());
+ }
+ return name;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaElementTypeInfo.java b/gnu/xml/validation/xmlschema/XMLSchemaElementTypeInfo.java
new file mode 100644
index 000000000..98a5fb759
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchemaElementTypeInfo.java
@@ -0,0 +1,93 @@
+/* XMLSchemaElementTypeInfo.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import org.w3c.dom.TypeInfo;
+import gnu.xml.validation.datatype.SimpleType;
+import gnu.xml.validation.datatype.Type;
+
+/**
+ * Element type information provided by validation against an XML Schema.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+final class XMLSchemaElementTypeInfo
+ extends XMLSchemaTypeInfo
+{
+
+ final XMLSchema schema;
+ final ElementDeclaration decl;
+ final Type type;
+ boolean nil;
+
+ XMLSchemaElementTypeInfo(XMLSchema schema, ElementDeclaration decl,
+ Type type)
+ {
+ this.schema = schema;
+ this.decl = decl;
+ this.type = type;
+ }
+
+ public String getTypeName()
+ {
+ return type.name.getLocalPart();
+ }
+
+ public String getTypeNamespace()
+ {
+ return type.name.getNamespaceURI();
+ }
+
+ public boolean isDerivedFrom(String typeNamespace, String typeName,
+ int derivationMethod)
+ {
+ if (type instanceof SimpleType)
+ {
+ SimpleType simpleType = (SimpleType) type;
+ return simpleTypeIsDerivedFrom(simpleType, typeNamespace, typeName,
+ derivationMethod);
+ }
+ else
+ {
+ // TODO
+ return false;
+ }
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaSchemaFactory.java b/gnu/xml/validation/xmlschema/XMLSchemaSchemaFactory.java
new file mode 100644
index 000000000..b37ae5431
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchemaSchemaFactory.java
@@ -0,0 +1,159 @@
+/* XMLSchemaSchemaFactory.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import java.io.IOException;
+import java.net.URL;
+import javax.xml.XMLConstants;
+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 javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.relaxng.datatype.DatatypeException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Schema factory for W3C XML Schema schemata.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+public class XMLSchemaSchemaFactory
+ extends SchemaFactory
+{
+
+ LSResourceResolver resourceResolver;
+
+ public LSResourceResolver getResourceResolver()
+ {
+ return resourceResolver;
+ }
+
+ public void setResourceResolver(LSResourceResolver resourceResolver)
+ {
+ this.resourceResolver = resourceResolver;
+ }
+
+ public boolean isSchemaLanguageSupported(String schemaLanguage)
+ {
+ return XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(schemaLanguage);
+ }
+
+ public Schema newSchema()
+ throws SAXException
+ {
+ // TODO
+ throw new UnsupportedOperationException();
+ }
+
+ public Schema newSchema(Source[] schemata)
+ throws SAXException
+ {
+ if (schemata == null || schemata.length != 1)
+ throw new IllegalArgumentException("must specify one source");
+ // TODO multiple sources
+ try
+ {
+ Document doc = getDocument(schemata[0]);
+ XMLSchemaBuilder builder = new XMLSchemaBuilder();
+ builder.parseSchema(doc);
+ return builder.schema;
+ }
+ catch (IOException e)
+ {
+ SAXException e2 = new SAXException(e.getMessage());
+ e2.initCause(e);
+ throw e2;
+ }
+ catch (DatatypeException e)
+ {
+ SAXException e2 = new SAXException(e.getMessage());
+ e2.initCause(e);
+ throw e2;
+ }
+ }
+
+ private static Document getDocument(Source source)
+ throws SAXException, IOException
+ {
+ if (source instanceof DOMSource)
+ {
+ Node node = ((DOMSource) source).getNode();
+ if (node != null && node instanceof Document)
+ return (Document) node;
+ }
+ String url = source.getSystemId();
+ try
+ {
+ InputSource input = new InputSource(url);
+ if (source instanceof StreamSource)
+ {
+ StreamSource streamSource = (StreamSource) source;
+ input.setByteStream(streamSource.getInputStream());
+ input.setCharacterStream(streamSource.getReader());
+ }
+ if (input.getByteStream() == null &&
+ input.getCharacterStream() == null &&
+ url != null)
+ input.setByteStream(new URL(url).openStream());
+ DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
+ f.setNamespaceAware(true);
+ f.setCoalescing(true);
+ f.setExpandEntityReferences(true);
+ f.setIgnoringComments(true);
+ f.setIgnoringElementContentWhitespace(true);
+ DocumentBuilder b = f.newDocumentBuilder();
+ return b.parse(input);
+ }
+ catch (ParserConfigurationException e)
+ {
+ SAXException e2 = new SAXException(e.getMessage());
+ e2.initCause(e);
+ throw e2;
+ }
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaTypeInfo.java b/gnu/xml/validation/xmlschema/XMLSchemaTypeInfo.java
new file mode 100644
index 000000000..60cc25fc4
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchemaTypeInfo.java
@@ -0,0 +1,77 @@
+/* XMLSchemaTypeInfo.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import org.w3c.dom.TypeInfo;
+import gnu.xml.validation.datatype.SimpleType;
+
+/**
+ * Abstract superclass providing simple type derivation.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+abstract class XMLSchemaTypeInfo
+ implements TypeInfo
+{
+
+ protected boolean simpleTypeIsDerivedFrom(SimpleType simpleType,
+ String typeNamespace,
+ String typeName,
+ int derivationMethod)
+ {
+ switch (derivationMethod)
+ {
+ case TypeInfo.DERIVATION_RESTRICTION:
+ SimpleType baseType = simpleType.baseType;
+ while (baseType != null)
+ {
+ if (baseType.name.getNamespaceURI().equals(typeNamespace) &&
+ baseType.name.getLocalPart().equals(typeName))
+ {
+ return true;
+ }
+ baseType = baseType.baseType;
+ }
+ break;
+ // TODO other methods
+ }
+ return false;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaTypeInfoProvider.java b/gnu/xml/validation/xmlschema/XMLSchemaTypeInfoProvider.java
new file mode 100644
index 000000000..9b20c0c8d
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchemaTypeInfoProvider.java
@@ -0,0 +1,82 @@
+/* XMLSchemaTypeInfoProvider.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import javax.xml.validation.TypeInfoProvider;
+import org.w3c.dom.TypeInfo;
+
+/**
+ * TypeInfo provider for XML Schema validator handler.
+ * This simply delegates to the handler. It wouldn't be required if
+ * TypeInfoProvider were an interface instead of an abstract class.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+final class XMLSchemaTypeInfoProvider
+ extends TypeInfoProvider
+{
+
+ final XMLSchemaValidatorHandler handler;
+
+ XMLSchemaTypeInfoProvider(XMLSchemaValidatorHandler handler)
+ {
+ this.handler = handler;
+ }
+
+ public TypeInfo getElementTypeInfo()
+ {
+ return handler.getElementTypeInfo();
+ }
+
+ public TypeInfo getAttributeTypeInfo(int index)
+ {
+ return handler.getAttributeTypeInfo(index);
+ }
+
+ public boolean isIdAttribute(int index)
+ {
+ return handler.isIdAttribute(index);
+ }
+
+ public boolean isSpecified(int index)
+ {
+ return handler.isSpecified(index);
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaValidator.java b/gnu/xml/validation/xmlschema/XMLSchemaValidator.java
new file mode 100644
index 000000000..056babf64
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchemaValidator.java
@@ -0,0 +1,98 @@
+/* XMLSchemaValidator.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import java.io.IOException;
+import javax.xml.validation.Validator;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * JAXP validator for an XML Schema.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+final class XMLSchemaValidator
+ extends Validator
+{
+
+ final XMLSchema schema;
+
+ ErrorHandler errorHandler;
+ LSResourceResolver resourceResolver;
+
+ XMLSchemaValidator(XMLSchema schema)
+ {
+ this.schema = schema;
+ }
+
+ public void reset()
+ {
+ }
+
+ public void validate(Source source, Result result)
+ throws SAXException, IOException
+ {
+ // TODO
+ }
+
+ public ErrorHandler getErrorHandler()
+ {
+ return errorHandler;
+ }
+
+ public void setErrorHandler(ErrorHandler errorHandler)
+ {
+ this.errorHandler = errorHandler;
+ }
+
+ public LSResourceResolver getResourceResolver()
+ {
+ return resourceResolver;
+ }
+
+ public void setResourceResolver(LSResourceResolver resourceResolver)
+ {
+ this.resourceResolver = resourceResolver;
+ }
+
+}
+
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java b/gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java
new file mode 100644
index 000000000..9e6d8e9a9
--- /dev/null
+++ b/gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java
@@ -0,0 +1,394 @@
+/* XMLSchemaValidatorHandler.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.validation.xmlschema;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.validation.TypeInfoProvider;
+import javax.xml.validation.ValidatorHandler;
+import org.relaxng.datatype.DatatypeException;
+import org.relaxng.datatype.DatatypeLibrary;
+import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
+import org.w3c.dom.TypeInfo;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.Attributes2Impl;
+import org.xml.sax.helpers.NamespaceSupport;
+import gnu.xml.validation.datatype.SimpleType;
+import gnu.xml.validation.datatype.Type;
+
+/**
+ * Streaming validator.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+final class XMLSchemaValidatorHandler
+ extends ValidatorHandler
+{
+
+ final XMLSchema schema;
+ final TypeInfoProvider typeInfoProvider;
+ final NamespaceSupport namespaceSupport;
+ final DatatypeLibrary typeLibrary;
+ Locator loc;
+ ContentHandler contentHandler;
+ ErrorHandler errorHandler;
+ LSResourceResolver resourceResolver;
+ final LinkedList context; // element context
+ final ArrayList attributes; // attribute context;
+
+ XMLSchemaValidatorHandler(XMLSchema schema)
+ {
+ this.schema = schema;
+ typeInfoProvider = new XMLSchemaTypeInfoProvider(this);
+ namespaceSupport = new NamespaceSupport();
+ context = new LinkedList();
+ attributes = new ArrayList();
+ final String ns = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ typeLibrary = new DatatypeLibraryLoader().createDatatypeLibrary(ns);
+ }
+
+ public ContentHandler getContentHandler()
+ {
+ return contentHandler;
+ }
+
+ public void setContentHandler(ContentHandler contentHandler)
+ {
+ this.contentHandler = contentHandler;
+ }
+
+ public ErrorHandler getErrorHandler()
+ {
+ return errorHandler;
+ }
+
+ public void setErrorHandler(ErrorHandler errorHandler)
+ {
+ this.errorHandler = errorHandler;
+ }
+
+ public LSResourceResolver getResourceResolver()
+ {
+ return resourceResolver;
+ }
+
+ public void setResourceResolver(LSResourceResolver resourceResolver)
+ {
+ this.resourceResolver = resourceResolver;
+ }
+
+ public TypeInfoProvider getTypeInfoProvider()
+ {
+ return typeInfoProvider;
+ }
+
+ TypeInfo getElementTypeInfo()
+ {
+ return (XMLSchemaElementTypeInfo) context.getFirst();
+ }
+
+ TypeInfo getAttributeTypeInfo(int index)
+ {
+ return (XMLSchemaAttributeTypeInfo) attributes.get(index);
+ }
+
+ boolean isIdAttribute(int index)
+ {
+ XMLSchemaAttributeTypeInfo typeInfo =
+ (XMLSchemaAttributeTypeInfo) attributes.get(index);
+ return typeInfo.id;
+ }
+
+ boolean isSpecified(int index)
+ {
+ XMLSchemaAttributeTypeInfo typeInfo =
+ (XMLSchemaAttributeTypeInfo) attributes.get(index);
+ return typeInfo.specified;
+ }
+
+ public void setDocumentLocator(Locator locator)
+ {
+ loc = locator;
+ if (contentHandler != null)
+ {
+ contentHandler.setDocumentLocator(locator);
+ }
+ }
+
+ public void startDocument()
+ throws SAXException
+ {
+ namespaceSupport.reset();
+ context.clear();
+ attributes.clear();
+ if (contentHandler != null)
+ {
+ contentHandler.startDocument();
+ }
+ }
+
+ public void endDocument()
+ throws SAXException
+ {
+ if (contentHandler != null)
+ {
+ contentHandler.endDocument();
+ }
+ }
+
+ public void startPrefixMapping(String prefix, String uri)
+ throws SAXException
+ {
+ namespaceSupport.declarePrefix(prefix, uri);
+ if (contentHandler != null)
+ {
+ contentHandler.startPrefixMapping(prefix, uri);
+ }
+ }
+
+ public void endPrefixMapping(String prefix)
+ throws SAXException
+ {
+ if (contentHandler != null)
+ {
+ contentHandler.endPrefixMapping(prefix);
+ }
+ }
+
+ public void startElement(String uri, String localName, String qName,
+ Attributes atts)
+ throws SAXException
+ {
+ namespaceSupport.pushContext();
+ QName name = new QName(uri, localName);
+ ElementDeclaration decl =
+ (ElementDeclaration) schema.elementDeclarations.get(name);
+ // Validation Rule: Element Locally Valid (Element)
+ String xsiType =
+ atts.getValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ xsiType = xsiType.trim(); // normalise
+ String xsiNil =
+ atts.getValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ Type type = decl.datatype;
+ if (xsiType.length() > 0)
+ {
+ try
+ {
+ Type specifiedType = resolveType(xsiType);
+ // TODO 4.3
+ type = specifiedType;
+ }
+ catch (DatatypeException e) // 4.1, 4.2
+ {
+ ValidationException e2 =
+ new ValidationException("Can't resolve type " + xsiType,
+ loc);
+ e2.initCause(e);
+ throw e2;
+ }
+ }
+ XMLSchemaElementTypeInfo typeInfo =
+ new XMLSchemaElementTypeInfo(schema, decl, type);
+ if (decl == null) // 1
+ {
+ throw new ValidationException("No declaration for " + name, loc);
+ }
+ if (decl.isAbstract) // 2
+ {
+ throw new ValidationException("Declaration for " + name +
+ " is abstract", loc);
+ }
+ if (xsiNil.length() > 0)
+ {
+ if (!decl.nillable) // 3.1
+ {
+ throw new ValidationException("Declaration for " + name +
+ " is nillable but xsi:nil present",
+ loc);
+ }
+ else if ("true".equals(xsiNil)) // 3.2
+ {
+ typeInfo.nil = true;
+ if (decl.type == XMLSchema.CONSTRAINT_FIXED) // 3.2.2
+ {
+ throw new ValidationException("Declaration for " + name +
+ " is fixed but xsi:nil is true",
+ loc);
+ }
+ }
+ }
+ // TODO 5, 6, 7
+
+ // parent
+ if (!context.isEmpty())
+ {
+ XMLSchemaElementTypeInfo parent =
+ (XMLSchemaElementTypeInfo) context.getFirst();
+ if (parent.nil) // Element Locally Valid (Element) 3.2.1
+ {
+ throw new ValidationException("Parent of " + qName +
+ " is declared xsi:nil", loc);
+ }
+ // TODO
+ }
+ context.addFirst(typeInfo);
+ // attributes
+ int len = atts.getLength();
+ Attributes2Impl atts2 = new Attributes2Impl();
+ int count = 0;
+ for (int i = 0; i < len; i++)
+ {
+ String attUri = atts.getURI(i);
+ String attLocalName = atts.getLocalName(i);
+ String attQName = atts.getQName(i);
+ String attValue = atts.getValue(i);
+
+ if (XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(attUri))
+ {
+ continue; // ?
+ }
+
+ QName attName = new QName(attUri, attLocalName);
+ AttributeDeclaration attDecl =
+ (AttributeDeclaration) schema.attributeDeclarations.get(attName);
+ boolean declared = (attDecl != null);
+
+ String attType = (attDecl != null) ?
+ attDecl.datatype.toString() : "CDATA";
+ XMLSchemaAttributeTypeInfo attTypeInfo =
+ new XMLSchemaAttributeTypeInfo(schema, attDecl, true);
+ attributes.add(attTypeInfo);
+
+ atts2.addAttribute(attUri, attLocalName, attQName, attType, attValue);
+ atts2.setDeclared(count, declared);
+ atts2.setSpecified(count, true);
+ count++;
+ }
+ // add defaulted attributes to atts2
+ // TODO
+ // atts2.setSpecified(count, false);
+ if (contentHandler != null)
+ {
+ contentHandler.startElement(uri, localName, qName, atts2);
+ }
+ }
+
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException
+ {
+ // TODO check all required have been seen
+ context.removeFirst();
+ attributes.clear();
+ namespaceSupport.popContext();
+ if (contentHandler != null)
+ {
+ contentHandler.endElement(uri, localName, qName);
+ }
+ }
+
+ public void characters(char[] ch, int start, int length)
+ throws SAXException
+ {
+ XMLSchemaElementTypeInfo parent =
+ (XMLSchemaElementTypeInfo) context.getFirst();
+ if (parent.nil) // Element Locally Valid (Element) 3.2.1
+ {
+ throw new ValidationException(parent.decl.name.toString() +
+ " is declared xsi:nil",
+ loc);
+ }
+ // TODO
+ if (contentHandler != null)
+ {
+ contentHandler.characters(ch, start, length);
+ }
+ }
+
+ public void ignorableWhitespace(char[] ch, int start, int length)
+ throws SAXException
+ {
+ if (contentHandler != null)
+ {
+ contentHandler.ignorableWhitespace(ch, start, length);
+ }
+ }
+
+ public void processingInstruction(String target, String data)
+ throws SAXException
+ {
+ if (contentHandler != null)
+ {
+ contentHandler.processingInstruction(target, data);
+ }
+ }
+
+ public void skippedEntity(String name)
+ throws SAXException
+ {
+ if (contentHandler != null)
+ {
+ contentHandler.skippedEntity(name);
+ }
+ }
+
+ Type resolveType(String value)
+ throws DatatypeException
+ {
+ QName name = QName.valueOf(value);
+ String prefix = name.getPrefix();
+ String localName = name.getLocalPart();
+ if (prefix != null && prefix.length() > 0)
+ {
+ String uri = namespaceSupport.getURI(prefix);
+ if (!XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri))
+ return null;
+ }
+ if ("anyType".equals(localName))
+ return Type.ANY_TYPE;
+ return (SimpleType) typeLibrary.createDatatype(localName);
+ }
+
+}
+
diff --git a/javax/xml/validation/SchemaFactory.java b/javax/xml/validation/SchemaFactory.java
index 35bf20564..f33c1c629 100644
--- a/javax/xml/validation/SchemaFactory.java
+++ b/javax/xml/validation/SchemaFactory.java
@@ -39,6 +39,7 @@ package javax.xml.validation;
import java.io.File;
import java.net.URL;
+import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.ls.LSResourceResolver;
@@ -50,7 +51,7 @@ import org.xml.sax.SAXNotSupportedException;
/**
* Factory for obtaining schemata.
*
- * @author (a href='mailto:dog@gnu.org'>Chris Burdess</a)
+ * @author Chris Burdess (dog@gnu.org)
* @since 1.3
*/
public abstract class SchemaFactory
@@ -70,7 +71,10 @@ public abstract class SchemaFactory
*/
public static final SchemaFactory newInstance(String schemaLanguage)
{
- // TODO
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(schemaLanguage))
+ return new gnu.xml.validation.xmlschema.XMLSchemaSchemaFactory();
+ if (XMLConstants.RELAXNG_NS_URI.equals(schemaLanguage))
+ return new gnu.xml.validation.relaxng.RELAXNGSchemaFactory();
throw new IllegalArgumentException(schemaLanguage);
}