src/share/jaxws_classes/com/sun/xml/internal/rngom/parse/xml/SchemaParser.java

Fri, 04 Oct 2013 16:21:34 +0100

author
mkos
date
Fri, 04 Oct 2013 16:21:34 +0100
changeset 408
b0610cd08440
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
permissions
-rw-r--r--

8025054: Update JAX-WS RI integration to 2.2.9-b130926.1035
Reviewed-by: chegar

     1 /*
     2  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 /*
    26  * Copyright (C) 2004-2012
    27  *
    28  * Permission is hereby granted, free of charge, to any person obtaining a copy
    29  * of this software and associated documentation files (the "Software"), to deal
    30  * in the Software without restriction, including without limitation the rights
    31  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    32  * copies of the Software, and to permit persons to whom the Software is
    33  * furnished to do so, subject to the following conditions:
    34  *
    35  * The above copyright notice and this permission notice shall be included in
    36  * all copies or substantial portions of the Software.
    37  *
    38  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    39  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    40  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    41  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    42  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    43  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    44  * THE SOFTWARE.
    45  */
    46 package com.sun.xml.internal.rngom.parse.xml;
    48 import java.util.Enumeration;
    49 import java.util.Hashtable;
    50 import java.util.Stack;
    51 import java.util.Vector;
    52 import java.util.List;
    53 import java.util.ArrayList;
    54 import java.util.Arrays;
    56 import com.sun.xml.internal.rngom.ast.builder.Annotations;
    57 import com.sun.xml.internal.rngom.ast.builder.CommentList;
    58 import com.sun.xml.internal.rngom.ast.builder.DataPatternBuilder;
    59 import com.sun.xml.internal.rngom.ast.builder.Div;
    60 import com.sun.xml.internal.rngom.ast.builder.ElementAnnotationBuilder;
    61 import com.sun.xml.internal.rngom.ast.builder.Grammar;
    62 import com.sun.xml.internal.rngom.ast.builder.GrammarSection;
    63 import com.sun.xml.internal.rngom.ast.builder.Include;
    64 import com.sun.xml.internal.rngom.ast.builder.IncludedGrammar;
    65 import com.sun.xml.internal.rngom.ast.builder.NameClassBuilder;
    66 import com.sun.xml.internal.rngom.ast.builder.SchemaBuilder;
    67 import com.sun.xml.internal.rngom.ast.builder.Scope;
    68 import com.sun.xml.internal.rngom.ast.om.Location;
    69 import com.sun.xml.internal.rngom.ast.om.ParsedElementAnnotation;
    70 import com.sun.xml.internal.rngom.ast.om.ParsedNameClass;
    71 import com.sun.xml.internal.rngom.ast.om.ParsedPattern;
    72 import com.sun.xml.internal.rngom.parse.Context;
    73 import com.sun.xml.internal.rngom.parse.IllegalSchemaException;
    74 import com.sun.xml.internal.rngom.parse.Parseable;
    75 import com.sun.xml.internal.rngom.util.Localizer;
    76 import com.sun.xml.internal.rngom.util.Uri;
    77 import com.sun.xml.internal.rngom.xml.sax.AbstractLexicalHandler;
    78 import com.sun.xml.internal.rngom.xml.sax.XmlBaseHandler;
    79 import com.sun.xml.internal.rngom.xml.util.Naming;
    80 import com.sun.xml.internal.rngom.xml.util.WellKnownNamespaces;
    81 import org.xml.sax.Attributes;
    82 import org.xml.sax.ContentHandler;
    83 import org.xml.sax.ErrorHandler;
    84 import org.xml.sax.Locator;
    85 import org.xml.sax.SAXException;
    86 import org.xml.sax.SAXNotRecognizedException;
    87 import org.xml.sax.SAXNotSupportedException;
    88 import org.xml.sax.SAXParseException;
    89 import org.xml.sax.XMLReader;
    90 import org.xml.sax.helpers.DefaultHandler;
    92 class SchemaParser {
    94     private static final String relaxngURIPrefix =
    95             WellKnownNamespaces.RELAX_NG.substring(0, WellKnownNamespaces.RELAX_NG.lastIndexOf('/') + 1);
    96     static final String relaxng10URI = WellKnownNamespaces.RELAX_NG;
    97     private static final Localizer localizer = new Localizer(new Localizer(Parseable.class), SchemaParser.class);
    98     private String relaxngURI;
    99     private final XMLReader xr;
   100     private final ErrorHandler eh;
   101     private final SchemaBuilder schemaBuilder;
   102     /**
   103      * The value of the {@link SchemaBuilder#getNameClassBuilder()} for the
   104      * {@link #schemaBuilder} object.
   105      */
   106     private final NameClassBuilder nameClassBuilder;
   107     private ParsedPattern startPattern;
   108     private Locator locator;
   109     private final XmlBaseHandler xmlBaseHandler = new XmlBaseHandler();
   110     private final ContextImpl context = new ContextImpl();
   111     private boolean hadError = false;
   112     private Hashtable patternTable;
   113     private Hashtable nameClassTable;
   115     static class PrefixMapping {
   117         final String prefix;
   118         final String uri;
   119         final PrefixMapping next;
   121         PrefixMapping(String prefix, String uri, PrefixMapping next) {
   122             this.prefix = prefix;
   123             this.uri = uri;
   124             this.next = next;
   125         }
   126     }
   128     static abstract class AbstractContext extends DtdContext implements Context {
   130         PrefixMapping prefixMapping;
   132         AbstractContext() {
   133             prefixMapping = new PrefixMapping("xml", WellKnownNamespaces.XML, null);
   134         }
   136         AbstractContext(AbstractContext context) {
   137             super(context);
   138             prefixMapping = context.prefixMapping;
   139         }
   141         public String resolveNamespacePrefix(String prefix) {
   142             for (PrefixMapping p = prefixMapping; p != null; p = p.next) {
   143                 if (p.prefix.equals(prefix)) {
   144                     return p.uri;
   145                 }
   146             }
   147             return null;
   148         }
   150         public Enumeration prefixes() {
   151             Vector v = new Vector();
   152             for (PrefixMapping p = prefixMapping; p != null; p = p.next) {
   153                 if (!v.contains(p.prefix)) {
   154                     v.addElement(p.prefix);
   155                 }
   156             }
   157             return v.elements();
   158         }
   160         public Context copy() {
   161             return new SavedContext(this);
   162         }
   163     }
   165     static class SavedContext extends AbstractContext {
   167         private final String baseUri;
   169         SavedContext(AbstractContext context) {
   170             super(context);
   171             this.baseUri = context.getBaseUri();
   172         }
   174         public String getBaseUri() {
   175             return baseUri;
   176         }
   177     }
   179     class ContextImpl extends AbstractContext {
   181         public String getBaseUri() {
   182             return xmlBaseHandler.getBaseUri();
   183         }
   184     }
   186     static interface CommentHandler {
   188         void comment(String value);
   189     }
   191     abstract class Handler implements ContentHandler, CommentHandler {
   193         CommentList comments;
   195         CommentList getComments() {
   196             CommentList tem = comments;
   197             comments = null;
   198             return tem;
   199         }
   201         public void comment(String value) {
   202             if (comments == null) {
   203                 comments = schemaBuilder.makeCommentList();
   204             }
   205             comments.addComment(value, makeLocation());
   206         }
   208         public void processingInstruction(String target, String date) {
   209         }
   211         public void skippedEntity(String name) {
   212         }
   214         public void ignorableWhitespace(char[] ch, int start, int len) {
   215         }
   217         public void startDocument() {
   218         }
   220         public void endDocument() {
   221         }
   223         public void startPrefixMapping(String prefix, String uri) {
   224             context.prefixMapping = new PrefixMapping(prefix, uri, context.prefixMapping);
   225         }
   227         public void endPrefixMapping(String prefix) {
   228             context.prefixMapping = context.prefixMapping.next;
   229         }
   231         public void setDocumentLocator(Locator loc) {
   232             locator = loc;
   233             xmlBaseHandler.setLocator(loc);
   234         }
   235     }
   237     abstract class State extends Handler {
   239         State parent;
   240         String nsInherit;
   241         String ns;
   242         String datatypeLibrary;
   243         /**
   244          * The current scope, or null if there's none.
   245          */
   246         Scope scope;
   247         Location startLocation;
   248         Annotations annotations;
   250         void set() {
   251             xr.setContentHandler(this);
   252         }
   254         abstract State create();
   256         abstract State createChildState(String localName) throws SAXException;
   258         void setParent(State parent) {
   259             this.parent = parent;
   260             this.nsInherit = parent.getNs();
   261             this.datatypeLibrary = parent.datatypeLibrary;
   262             this.scope = parent.scope;
   263             this.startLocation = makeLocation();
   264             if (parent.comments != null) {
   265                 annotations = schemaBuilder.makeAnnotations(parent.comments, getContext());
   266                 parent.comments = null;
   267             } else if (parent instanceof RootState) {
   268                 annotations = schemaBuilder.makeAnnotations(null, getContext());
   269             }
   270         }
   272         String getNs() {
   273             return ns == null ? nsInherit : ns;
   274         }
   276         boolean isRelaxNGElement(String uri) throws SAXException {
   277             return uri.equals(relaxngURI);
   278         }
   280         public void startElement(String namespaceURI,
   281                 String localName,
   282                 String qName,
   283                 Attributes atts) throws SAXException {
   284             xmlBaseHandler.startElement();
   285             if (isRelaxNGElement(namespaceURI)) {
   286                 State state = createChildState(localName);
   287                 if (state == null) {
   288                     xr.setContentHandler(new Skipper(this));
   289                     return;
   290                 }
   291                 state.setParent(this);
   292                 state.set();
   293                 state.attributes(atts);
   294             } else {
   295                 checkForeignElement();
   296                 ForeignElementHandler feh = new ForeignElementHandler(this, getComments());
   297                 feh.startElement(namespaceURI, localName, qName, atts);
   298                 xr.setContentHandler(feh);
   299             }
   300         }
   302         public void endElement(String namespaceURI,
   303                 String localName,
   304                 String qName) throws SAXException {
   305             xmlBaseHandler.endElement();
   306             parent.set();
   307             end();
   308         }
   310         void setName(String name) throws SAXException {
   311             error("illegal_name_attribute");
   312         }
   314         void setOtherAttribute(String name, String value) throws SAXException {
   315             error("illegal_attribute_ignored", name);
   316         }
   318         void endAttributes() throws SAXException {
   319         }
   321         void checkForeignElement() throws SAXException {
   322         }
   324         void attributes(Attributes atts) throws SAXException {
   325             int len = atts.getLength();
   326             for (int i = 0; i < len; i++) {
   327                 String uri = atts.getURI(i);
   328                 if (uri.length() == 0) {
   329                     String name = atts.getLocalName(i);
   330                     if (name.equals("name")) {
   331                         setName(atts.getValue(i).trim());
   332                     } else if (name.equals("ns")) {
   333                         ns = atts.getValue(i);
   334                     } else if (name.equals("datatypeLibrary")) {
   335                         datatypeLibrary = atts.getValue(i);
   336                         checkUri(datatypeLibrary);
   337                         if (!datatypeLibrary.equals("")
   338                                 && !Uri.isAbsolute(datatypeLibrary)) {
   339                             error("relative_datatype_library");
   340                         }
   341                         if (Uri.hasFragmentId(datatypeLibrary)) {
   342                             error("fragment_identifier_datatype_library");
   343                         }
   344                         datatypeLibrary = Uri.escapeDisallowedChars(datatypeLibrary);
   345                     } else {
   346                         setOtherAttribute(name, atts.getValue(i));
   347                     }
   348                 } else if (uri.equals(relaxngURI)) {
   349                     error("qualified_attribute", atts.getLocalName(i));
   350                 } else if (uri.equals(WellKnownNamespaces.XML)
   351                         && atts.getLocalName(i).equals("base")) {
   352                     xmlBaseHandler.xmlBaseAttribute(atts.getValue(i));
   353                 } else {
   354                     if (annotations == null) {
   355                         annotations = schemaBuilder.makeAnnotations(null, getContext());
   356                     }
   357                     annotations.addAttribute(uri, atts.getLocalName(i), findPrefix(atts.getQName(i), uri),
   358                             atts.getValue(i), startLocation);
   359                 }
   360             }
   361             endAttributes();
   362         }
   364         abstract void end() throws SAXException;
   366         void endChild(ParsedPattern pattern) {
   367             // XXX cannot happen; throw exception
   368         }
   370         void endChild(ParsedNameClass nc) {
   371             // XXX cannot happen; throw exception
   372         }
   374         @Override
   375         public void startDocument() {
   376         }
   378         @Override
   379         public void endDocument() {
   380             if (comments != null && startPattern != null) {
   381                 startPattern = schemaBuilder.commentAfter(startPattern, comments);
   382                 comments = null;
   383             }
   384         }
   386         public void characters(char[] ch, int start, int len) throws SAXException {
   387             for (int i = 0; i < len; i++) {
   388                 switch (ch[start + i]) {
   389                     case ' ':
   390                     case '\r':
   391                     case '\n':
   392                     case '\t':
   393                         break;
   394                     default:
   395                         error("illegal_characters_ignored");
   396                         break;
   397                 }
   398             }
   399         }
   401         boolean isPatternNamespaceURI(String s) {
   402             return s.equals(relaxngURI);
   403         }
   405         void endForeignChild(ParsedElementAnnotation ea) {
   406             if (annotations == null) {
   407                 annotations = schemaBuilder.makeAnnotations(null, getContext());
   408             }
   409             annotations.addElement(ea);
   410         }
   412         void mergeLeadingComments() {
   413             if (comments != null) {
   414                 if (annotations == null) {
   415                     annotations = schemaBuilder.makeAnnotations(comments, getContext());
   416                 } else {
   417                     annotations.addLeadingComment(comments);
   418                 }
   419                 comments = null;
   420             }
   421         }
   422     }
   424     class ForeignElementHandler extends Handler {
   426         final State nextState;
   427         ElementAnnotationBuilder builder;
   428         final Stack builderStack = new Stack();
   429         StringBuffer textBuf;
   430         Location textLoc;
   432         ForeignElementHandler(State nextState, CommentList comments) {
   433             this.nextState = nextState;
   434             this.comments = comments;
   435         }
   437         public void startElement(String namespaceURI, String localName,
   438                 String qName, Attributes atts) {
   439             flushText();
   440             if (builder != null) {
   441                 builderStack.push(builder);
   442             }
   443             Location loc = makeLocation();
   444             builder = schemaBuilder.makeElementAnnotationBuilder(namespaceURI,
   445                     localName,
   446                     findPrefix(qName, namespaceURI),
   447                     loc,
   448                     getComments(),
   449                     getContext());
   450             int len = atts.getLength();
   451             for (int i = 0; i < len; i++) {
   452                 String uri = atts.getURI(i);
   453                 builder.addAttribute(uri, atts.getLocalName(i), findPrefix(atts.getQName(i), uri),
   454                         atts.getValue(i), loc);
   455             }
   456         }
   458         public void endElement(String namespaceURI, String localName,
   459                 String qName) {
   460             flushText();
   461             if (comments != null) {
   462                 builder.addComment(getComments());
   463             }
   464             ParsedElementAnnotation ea = builder.makeElementAnnotation();
   465             if (builderStack.empty()) {
   466                 nextState.endForeignChild(ea);
   467                 nextState.set();
   468             } else {
   469                 builder = (ElementAnnotationBuilder) builderStack.pop();
   470                 builder.addElement(ea);
   471             }
   472         }
   474         public void characters(char ch[], int start, int length) {
   475             if (textBuf == null) {
   476                 textBuf = new StringBuffer();
   477             }
   478             textBuf.append(ch, start, length);
   479             if (textLoc == null) {
   480                 textLoc = makeLocation();
   481             }
   482         }
   484         @Override
   485         public void comment(String value) {
   486             flushText();
   487             super.comment(value);
   488         }
   490         void flushText() {
   491             if (textBuf != null && textBuf.length() != 0) {
   492                 builder.addText(textBuf.toString(), textLoc, getComments());
   493                 textBuf.setLength(0);
   494             }
   495             textLoc = null;
   496         }
   497     }
   499     static class Skipper extends DefaultHandler implements CommentHandler {
   501         int level = 1;
   502         final State nextState;
   504         Skipper(State nextState) {
   505             this.nextState = nextState;
   506         }
   508         @Override
   509         public void startElement(String namespaceURI,
   510                 String localName,
   511                 String qName,
   512                 Attributes atts) throws SAXException {
   513             ++level;
   514         }
   516         @Override
   517         public void endElement(String namespaceURI,
   518                 String localName,
   519                 String qName) throws SAXException {
   520             if (--level == 0) {
   521                 nextState.set();
   522             }
   523         }
   525         public void comment(String value) {
   526         }
   527     }
   529     abstract class EmptyContentState extends State {
   531         State createChildState(String localName) throws SAXException {
   532             error("expected_empty", localName);
   533             return null;
   534         }
   536         abstract ParsedPattern makePattern() throws SAXException;
   538         void end() throws SAXException {
   539             if (comments != null) {
   540                 if (annotations == null) {
   541                     annotations = schemaBuilder.makeAnnotations(null, getContext());
   542                 }
   543                 annotations.addComment(comments);
   544                 comments = null;
   545             }
   546             parent.endChild(makePattern());
   547         }
   548     }
   549     static private final int INIT_CHILD_ALLOC = 5;
   551     abstract class PatternContainerState extends State {
   553         List<ParsedPattern> childPatterns;
   555         State createChildState(String localName) throws SAXException {
   556             State state = (State) patternTable.get(localName);
   557             if (state == null) {
   558                 error("expected_pattern", localName);
   559                 return null;
   560             }
   561             return state.create();
   562         }
   564         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
   565             if (patterns.size() == 1 && anno == null) {
   566                 return patterns.get(0);
   567             }
   568             return schemaBuilder.makeGroup(patterns, loc, anno);
   569         }
   571         @Override
   572         void endChild(ParsedPattern pattern) {
   573             if (childPatterns == null) {
   574                 childPatterns = new ArrayList<ParsedPattern>(INIT_CHILD_ALLOC);
   575             }
   576             childPatterns.add(pattern);
   577         }
   579         @Override
   580         void endForeignChild(ParsedElementAnnotation ea) {
   581             // Harshit : Annotation handling should always be taken care of, irrespective of childPatterns being null or not.
   582             super.endForeignChild(ea);
   583             if (childPatterns != null) {
   584                 int idx = childPatterns.size() - 1;
   585                 childPatterns.set(idx, schemaBuilder.annotateAfter(childPatterns.get(idx), ea));
   586             }
   587         }
   589         void end() throws SAXException {
   590             if (childPatterns == null) {
   591                 error("missing_children");
   592                 endChild(schemaBuilder.makeErrorPattern());
   593             }
   594             if (comments != null) {
   595                 int idx = childPatterns.size() - 1;
   596                 childPatterns.set(idx, schemaBuilder.commentAfter(childPatterns.get(idx), comments));
   597                 comments = null;
   598             }
   599             sendPatternToParent(buildPattern(childPatterns, startLocation, annotations));
   600         }
   602         void sendPatternToParent(ParsedPattern p) {
   603             parent.endChild(p);
   604         }
   605     }
   607     class GroupState extends PatternContainerState {
   609         State create() {
   610             return new GroupState();
   611         }
   612     }
   614     class ZeroOrMoreState extends PatternContainerState {
   616         State create() {
   617             return new ZeroOrMoreState();
   618         }
   620         @Override
   621         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
   622             return schemaBuilder.makeZeroOrMore(super.buildPattern(patterns, loc, null), loc, anno);
   623         }
   624     }
   626     class OneOrMoreState extends PatternContainerState {
   628         State create() {
   629             return new OneOrMoreState();
   630         }
   632         @Override
   633         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
   634             return schemaBuilder.makeOneOrMore(super.buildPattern(patterns, loc, null), loc, anno);
   635         }
   636     }
   638     class OptionalState extends PatternContainerState {
   640         State create() {
   641             return new OptionalState();
   642         }
   644         @Override
   645         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
   646             return schemaBuilder.makeOptional(super.buildPattern(patterns, loc, null), loc, anno);
   647         }
   648     }
   650     class ListState extends PatternContainerState {
   652         State create() {
   653             return new ListState();
   654         }
   656         @Override
   657         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
   658             return schemaBuilder.makeList(super.buildPattern(patterns, loc, null), loc, anno);
   659         }
   660     }
   662     class ChoiceState extends PatternContainerState {
   664         State create() {
   665             return new ChoiceState();
   666         }
   668         @Override
   669         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
   670             return schemaBuilder.makeChoice(patterns, loc, anno);
   671         }
   672     }
   674     class InterleaveState extends PatternContainerState {
   676         State create() {
   677             return new InterleaveState();
   678         }
   680         @Override
   681         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) {
   682             return schemaBuilder.makeInterleave(patterns, loc, anno);
   683         }
   684     }
   686     class MixedState extends PatternContainerState {
   688         State create() {
   689             return new MixedState();
   690         }
   692         @Override
   693         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
   694             return schemaBuilder.makeMixed(super.buildPattern(patterns, loc, null), loc, anno);
   695         }
   696     }
   698     static interface NameClassRef {
   700         void setNameClass(ParsedNameClass nc);
   701     }
   703     class ElementState extends PatternContainerState implements NameClassRef {
   705         ParsedNameClass nameClass;
   706         boolean nameClassWasAttribute;
   707         String name;
   709         @Override
   710         void setName(String name) {
   711             this.name = name;
   712         }
   714         public void setNameClass(ParsedNameClass nc) {
   715             nameClass = nc;
   716         }
   718         @Override
   719         void endAttributes() throws SAXException {
   720             if (name != null) {
   721                 nameClass = expandName(name, getNs(), null);
   722                 nameClassWasAttribute = true;
   723             } else {
   724                 new NameClassChildState(this, this).set();
   725             }
   726         }
   728         State create() {
   729             return new ElementState();
   730         }
   732         @Override
   733         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
   734             return schemaBuilder.makeElement(nameClass, super.buildPattern(patterns, loc, null), loc, anno);
   735         }
   737         @Override
   738         void endForeignChild(ParsedElementAnnotation ea) {
   739             if (nameClassWasAttribute || childPatterns != null || nameClass == null) {
   740                 super.endForeignChild(ea);
   741             } else {
   742                 nameClass = nameClassBuilder.annotateAfter(nameClass, ea);
   743             }
   744         }
   745     }
   747     class RootState extends PatternContainerState {
   749         IncludedGrammar grammar;
   751         RootState() {
   752         }
   754         RootState(IncludedGrammar grammar, Scope scope, String ns) {
   755             this.grammar = grammar;
   756             this.scope = scope;
   757             this.nsInherit = ns;
   758             this.datatypeLibrary = "";
   759         }
   761         State create() {
   762             return new RootState();
   763         }
   765         @Override
   766         State createChildState(String localName) throws SAXException {
   767             if (grammar == null) {
   768                 return super.createChildState(localName);
   769             }
   770             if (localName.equals("grammar")) {
   771                 return new MergeGrammarState(grammar);
   772             }
   773             error("expected_grammar", localName);
   774             return null;
   775         }
   777         @Override
   778         void checkForeignElement() throws SAXException {
   779             error("root_bad_namespace_uri", WellKnownNamespaces.RELAX_NG);
   780         }
   782         @Override
   783         void endChild(ParsedPattern pattern) {
   784             startPattern = pattern;
   785         }
   787         @Override
   788         boolean isRelaxNGElement(String uri) throws SAXException {
   789             if (!uri.startsWith(relaxngURIPrefix)) {
   790                 return false;
   791             }
   792             if (!uri.equals(WellKnownNamespaces.RELAX_NG)) {
   793                 warning("wrong_uri_version",
   794                         WellKnownNamespaces.RELAX_NG.substring(relaxngURIPrefix.length()),
   795                         uri.substring(relaxngURIPrefix.length()));
   796             }
   797             relaxngURI = uri;
   798             return true;
   799         }
   800     }
   802     class NotAllowedState extends EmptyContentState {
   804         State create() {
   805             return new NotAllowedState();
   806         }
   808         ParsedPattern makePattern() {
   809             return schemaBuilder.makeNotAllowed(startLocation, annotations);
   810         }
   811     }
   813     class EmptyState extends EmptyContentState {
   815         State create() {
   816             return new EmptyState();
   817         }
   819         ParsedPattern makePattern() {
   820             return schemaBuilder.makeEmpty(startLocation, annotations);
   821         }
   822     }
   824     class TextState extends EmptyContentState {
   826         State create() {
   827             return new TextState();
   828         }
   830         ParsedPattern makePattern() {
   831             return schemaBuilder.makeText(startLocation, annotations);
   832         }
   833     }
   835     class ValueState extends EmptyContentState {
   837         final StringBuffer buf = new StringBuffer();
   838         String type;
   840         State create() {
   841             return new ValueState();
   842         }
   844         @Override
   845         void setOtherAttribute(String name, String value) throws SAXException {
   846             if (name.equals("type")) {
   847                 type = checkNCName(value.trim());
   848             } else {
   849                 super.setOtherAttribute(name, value);
   850             }
   851         }
   853         @Override
   854         public void characters(char[] ch, int start, int len) {
   855             buf.append(ch, start, len);
   856         }
   858         @Override
   859         void checkForeignElement() throws SAXException {
   860             error("value_contains_foreign_element");
   861         }
   863         ParsedPattern makePattern() throws SAXException {
   864             if (type == null) {
   865                 return makePattern("", "token");
   866             } else {
   867                 return makePattern(datatypeLibrary, type);
   868             }
   869         }
   871         @Override
   872         void end() throws SAXException {
   873             mergeLeadingComments();
   874             super.end();
   875         }
   877         ParsedPattern makePattern(String datatypeLibrary, String type) {
   878             return schemaBuilder.makeValue(datatypeLibrary,
   879                     type,
   880                     buf.toString(),
   881                     getContext(),
   882                     getNs(),
   883                     startLocation,
   884                     annotations);
   885         }
   886     }
   888     class DataState extends State {
   890         String type;
   891         ParsedPattern except = null;
   892         DataPatternBuilder dpb = null;
   894         State create() {
   895             return new DataState();
   896         }
   898         State createChildState(String localName) throws SAXException {
   899             if (localName.equals("param")) {
   900                 if (except != null) {
   901                     error("param_after_except");
   902                 }
   903                 return new ParamState(dpb);
   904             }
   905             if (localName.equals("except")) {
   906                 if (except != null) {
   907                     error("multiple_except");
   908                 }
   909                 return new ChoiceState();
   910             }
   911             error("expected_param_except", localName);
   912             return null;
   913         }
   915         @Override
   916         void setOtherAttribute(String name, String value) throws SAXException {
   917             if (name.equals("type")) {
   918                 type = checkNCName(value.trim());
   919             } else {
   920                 super.setOtherAttribute(name, value);
   921             }
   922         }
   924         @Override
   925         void endAttributes() throws SAXException {
   926             if (type == null) {
   927                 error("missing_type_attribute");
   928             } else {
   929                 dpb = schemaBuilder.makeDataPatternBuilder(datatypeLibrary, type, startLocation);
   930             }
   931         }
   933         void end() throws SAXException {
   934             ParsedPattern p;
   935             if (dpb != null) {
   936                 if (except != null) {
   937                     p = dpb.makePattern(except, startLocation, annotations);
   938                 } else {
   939                     p = dpb.makePattern(startLocation, annotations);
   940                 }
   941             } else {
   942                 p = schemaBuilder.makeErrorPattern();
   943             }
   944             // XXX need to capture comments
   945             parent.endChild(p);
   946         }
   948         @Override
   949         void endChild(ParsedPattern pattern) {
   950             except = pattern;
   951         }
   952     }
   954     class ParamState extends State {
   956         private final StringBuffer buf = new StringBuffer();
   957         private final DataPatternBuilder dpb;
   958         private String name;
   960         ParamState(DataPatternBuilder dpb) {
   961             this.dpb = dpb;
   962         }
   964         State create() {
   965             return new ParamState(null);
   966         }
   968         @Override
   969         void setName(String name) throws SAXException {
   970             this.name = checkNCName(name);
   971         }
   973         @Override
   974         void endAttributes() throws SAXException {
   975             if (name == null) {
   976                 error("missing_name_attribute");
   977             }
   978         }
   980         State createChildState(String localName) throws SAXException {
   981             error("expected_empty", localName);
   982             return null;
   983         }
   985         @Override
   986         public void characters(char[] ch, int start, int len) {
   987             buf.append(ch, start, len);
   988         }
   990         @Override
   991         void checkForeignElement() throws SAXException {
   992             error("param_contains_foreign_element");
   993         }
   995         void end() throws SAXException {
   996             if (name == null) {
   997                 return;
   998             }
   999             if (dpb == null) {
  1000                 return;
  1002             mergeLeadingComments();
  1003             dpb.addParam(name, buf.toString(), getContext(), getNs(), startLocation, annotations);
  1007     class AttributeState extends PatternContainerState implements NameClassRef {
  1009         ParsedNameClass nameClass;
  1010         boolean nameClassWasAttribute;
  1011         String name;
  1013         State create() {
  1014             return new AttributeState();
  1017         @Override
  1018         void setName(String name) {
  1019             this.name = name;
  1022         public void setNameClass(ParsedNameClass nc) {
  1023             nameClass = nc;
  1026         @Override
  1027         void endAttributes() throws SAXException {
  1028             if (name != null) {
  1029                 String nsUse;
  1030                 if (ns != null) {
  1031                     nsUse = ns;
  1032                 } else {
  1033                     nsUse = "";
  1035                 nameClass = expandName(name, nsUse, null);
  1036                 nameClassWasAttribute = true;
  1037             } else {
  1038                 new NameClassChildState(this, this).set();
  1042         @Override
  1043         void endForeignChild(ParsedElementAnnotation ea) {
  1044             if (nameClassWasAttribute || childPatterns != null || nameClass == null) {
  1045                 super.endForeignChild(ea);
  1046             } else {
  1047                 nameClass = nameClassBuilder.annotateAfter(nameClass, ea);
  1051         @Override
  1052         void end() throws SAXException {
  1053             if (childPatterns == null) {
  1054                 endChild(schemaBuilder.makeText(startLocation, null));
  1056             super.end();
  1059         @Override
  1060         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  1061             return schemaBuilder.makeAttribute(nameClass, super.buildPattern(patterns, loc, null), loc, anno);
  1064         @Override
  1065         State createChildState(String localName) throws SAXException {
  1066             State tem = super.createChildState(localName);
  1067             if (tem != null && childPatterns != null) {
  1068                 error("attribute_multi_pattern");
  1070             return tem;
  1074     abstract class SinglePatternContainerState extends PatternContainerState {
  1076         @Override
  1077         State createChildState(String localName) throws SAXException {
  1078             if (childPatterns == null) {
  1079                 return super.createChildState(localName);
  1081             error("too_many_children");
  1082             return null;
  1086     class GrammarSectionState extends State {
  1088         GrammarSection section;
  1090         GrammarSectionState() {
  1093         GrammarSectionState(GrammarSection section) {
  1094             this.section = section;
  1097         State create() {
  1098             return new GrammarSectionState(null);
  1101         State createChildState(String localName) throws SAXException {
  1102             if (localName.equals("define")) {
  1103                 return new DefineState(section);
  1105             if (localName.equals("start")) {
  1106                 return new StartState(section);
  1108             if (localName.equals("include")) {
  1109                 Include include = section.makeInclude();
  1110                 if (include != null) {
  1111                     return new IncludeState(include);
  1114             if (localName.equals("div")) {
  1115                 return new DivState(section.makeDiv());
  1117             error("expected_define", localName);
  1118             // XXX better errors
  1119             return null;
  1122         void end() throws SAXException {
  1123             if (comments != null) {
  1124                 section.topLevelComment(comments);
  1125                 comments = null;
  1129         @Override
  1130         void endForeignChild(ParsedElementAnnotation ea) {
  1131             section.topLevelAnnotation(ea);
  1135     class DivState extends GrammarSectionState {
  1137         final Div div;
  1139         DivState(Div div) {
  1140             super(div);
  1141             this.div = div;
  1144         @Override
  1145         void end() throws SAXException {
  1146             super.end();
  1147             div.endDiv(startLocation, annotations);
  1151     class IncludeState extends GrammarSectionState {
  1153         String href;
  1154         final Include include;
  1156         IncludeState(Include include) {
  1157             super(include);
  1158             this.include = include;
  1161         @Override
  1162         void setOtherAttribute(String name, String value) throws SAXException {
  1163             if (name.equals("href")) {
  1164                 href = value;
  1165                 checkUri(href);
  1166             } else {
  1167                 super.setOtherAttribute(name, value);
  1171         @Override
  1172         void endAttributes() throws SAXException {
  1173             if (href == null) {
  1174                 error("missing_href_attribute");
  1175             } else {
  1176                 href = resolve(href);
  1180         @Override
  1181         void end() throws SAXException {
  1182             super.end();
  1183             if (href != null) {
  1184                 try {
  1185                     include.endInclude(parseable, href, getNs(), startLocation, annotations);
  1186                 } catch (IllegalSchemaException e) {
  1192     class MergeGrammarState extends GrammarSectionState {
  1194         final IncludedGrammar grammar;
  1196         MergeGrammarState(IncludedGrammar grammar) {
  1197             super(grammar);
  1198             this.grammar = grammar;
  1201         @Override
  1202         void end() throws SAXException {
  1203             super.end();
  1204             parent.endChild(grammar.endIncludedGrammar(startLocation, annotations));
  1208     class GrammarState extends GrammarSectionState {
  1210         Grammar grammar;
  1212         @Override
  1213         void setParent(State parent) {
  1214             super.setParent(parent);
  1215             grammar = schemaBuilder.makeGrammar(scope);
  1216             section = grammar;
  1217             scope = grammar;
  1220         @Override
  1221         State create() {
  1222             return new GrammarState();
  1225         @Override
  1226         void end() throws SAXException {
  1227             super.end();
  1228             parent.endChild(grammar.endGrammar(startLocation, annotations));
  1232     class RefState extends EmptyContentState {
  1234         String name;
  1236         State create() {
  1237             return new RefState();
  1240         @Override
  1241         void endAttributes() throws SAXException {
  1242             if (name == null) {
  1243                 error("missing_name_attribute");
  1247         @Override
  1248         void setName(String name) throws SAXException {
  1249             this.name = checkNCName(name);
  1252         ParsedPattern makePattern() throws SAXException {
  1253             if (name == null) {
  1254                 return schemaBuilder.makeErrorPattern();
  1256             if (scope == null) {
  1257                 error("ref_outside_grammar", name);
  1258                 return schemaBuilder.makeErrorPattern();
  1259             } else {
  1260                 return scope.makeRef(name, startLocation, annotations);
  1265     class ParentRefState extends RefState {
  1267         @Override
  1268         State create() {
  1269             return new ParentRefState();
  1272         @Override
  1273         ParsedPattern makePattern() throws SAXException {
  1274             if (name == null) {
  1275                 return schemaBuilder.makeErrorPattern();
  1277             if (scope == null) {
  1278                 error("parent_ref_outside_grammar", name);
  1279                 return schemaBuilder.makeErrorPattern();
  1280             } else {
  1281                 return scope.makeParentRef(name, startLocation, annotations);
  1286     class ExternalRefState extends EmptyContentState {
  1288         String href;
  1290         State create() {
  1291             return new ExternalRefState();
  1294         @Override
  1295         void setOtherAttribute(String name, String value) throws SAXException {
  1296             if (name.equals("href")) {
  1297                 href = value;
  1298                 checkUri(href);
  1299             } else {
  1300                 super.setOtherAttribute(name, value);
  1304         @Override
  1305         void endAttributes() throws SAXException {
  1306             if (href == null) {
  1307                 error("missing_href_attribute");
  1308             } else {
  1309                 href = resolve(href);
  1313         ParsedPattern makePattern() {
  1314             if (href != null) {
  1315                 try {
  1316                     return schemaBuilder.makeExternalRef(parseable,
  1317                             href,
  1318                             getNs(),
  1319                             scope,
  1320                             startLocation,
  1321                             annotations);
  1322                 } catch (IllegalSchemaException e) {
  1325             return schemaBuilder.makeErrorPattern();
  1329     abstract class DefinitionState extends PatternContainerState {
  1331         GrammarSection.Combine combine = null;
  1332         final GrammarSection section;
  1334         DefinitionState(GrammarSection section) {
  1335             this.section = section;
  1338         @Override
  1339         void setOtherAttribute(String name, String value) throws SAXException {
  1340             if (name.equals("combine")) {
  1341                 value = value.trim();
  1342                 if (value.equals("choice")) {
  1343                     combine = GrammarSection.COMBINE_CHOICE;
  1344                 } else if (value.equals("interleave")) {
  1345                     combine = GrammarSection.COMBINE_INTERLEAVE;
  1346                 } else {
  1347                     error("combine_attribute_bad_value", value);
  1349             } else {
  1350                 super.setOtherAttribute(name, value);
  1354         @Override
  1355         ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  1356             return super.buildPattern(patterns, loc, null);
  1360     class DefineState extends DefinitionState {
  1362         String name;
  1364         DefineState(GrammarSection section) {
  1365             super(section);
  1368         State create() {
  1369             return new DefineState(null);
  1372         @Override
  1373         void setName(String name) throws SAXException {
  1374             this.name = checkNCName(name);
  1377         @Override
  1378         void endAttributes() throws SAXException {
  1379             if (name == null) {
  1380                 error("missing_name_attribute");
  1384         @Override
  1385         void sendPatternToParent(ParsedPattern p) {
  1386             if (name != null) {
  1387                 section.define(name, combine, p, startLocation, annotations);
  1392     class StartState extends DefinitionState {
  1394         StartState(GrammarSection section) {
  1395             super(section);
  1398         State create() {
  1399             return new StartState(null);
  1402         @Override
  1403         void sendPatternToParent(ParsedPattern p) {
  1404             section.define(GrammarSection.START, combine, p, startLocation, annotations);
  1407         @Override
  1408         State createChildState(String localName) throws SAXException {
  1409             State tem = super.createChildState(localName);
  1410             if (tem != null && childPatterns != null) {
  1411                 error("start_multi_pattern");
  1413             return tem;
  1417     abstract class NameClassContainerState extends State {
  1419         State createChildState(String localName) throws SAXException {
  1420             State state = (State) nameClassTable.get(localName);
  1421             if (state == null) {
  1422                 error("expected_name_class", localName);
  1423                 return null;
  1425             return state.create();
  1429     class NameClassChildState extends NameClassContainerState {
  1431         final State prevState;
  1432         final NameClassRef nameClassRef;
  1434         State create() {
  1435             return null;
  1438         NameClassChildState(State prevState, NameClassRef nameClassRef) {
  1439             this.prevState = prevState;
  1440             this.nameClassRef = nameClassRef;
  1441             setParent(prevState.parent);
  1442             this.ns = prevState.ns;
  1445         @Override
  1446         void endChild(ParsedNameClass nameClass) {
  1447             nameClassRef.setNameClass(nameClass);
  1448             prevState.set();
  1451         @Override
  1452         void endForeignChild(ParsedElementAnnotation ea) {
  1453             prevState.endForeignChild(ea);
  1456         void end() throws SAXException {
  1457             nameClassRef.setNameClass(nameClassBuilder.makeErrorNameClass());
  1458             error("missing_name_class");
  1459             prevState.set();
  1460             prevState.end();
  1464     abstract class NameClassBaseState extends State {
  1466         abstract ParsedNameClass makeNameClass() throws SAXException;
  1468         void end() throws SAXException {
  1469             parent.endChild(makeNameClass());
  1473     class NameState extends NameClassBaseState {
  1475         final StringBuffer buf = new StringBuffer();
  1477         State createChildState(String localName) throws SAXException {
  1478             error("expected_name", localName);
  1479             return null;
  1482         State create() {
  1483             return new NameState();
  1486         @Override
  1487         public void characters(char[] ch, int start, int len) {
  1488             buf.append(ch, start, len);
  1491         @Override
  1492         void checkForeignElement() throws SAXException {
  1493             error("name_contains_foreign_element");
  1496         ParsedNameClass makeNameClass() throws SAXException {
  1497             mergeLeadingComments();
  1498             return expandName(buf.toString().trim(), getNs(), annotations);
  1501     private static final int PATTERN_CONTEXT = 0;
  1502     private static final int ANY_NAME_CONTEXT = 1;
  1503     private static final int NS_NAME_CONTEXT = 2;
  1504     private SAXParseable parseable;
  1506     class AnyNameState extends NameClassBaseState {
  1508         ParsedNameClass except = null;
  1510         State create() {
  1511             return new AnyNameState();
  1514         State createChildState(String localName) throws SAXException {
  1515             if (localName.equals("except")) {
  1516                 if (except != null) {
  1517                     error("multiple_except");
  1519                 return new NameClassChoiceState(getContext());
  1521             error("expected_except", localName);
  1522             return null;
  1525         int getContext() {
  1526             return ANY_NAME_CONTEXT;
  1529         ParsedNameClass makeNameClass() {
  1530             if (except == null) {
  1531                 return makeNameClassNoExcept();
  1532             } else {
  1533                 return makeNameClassExcept(except);
  1537         ParsedNameClass makeNameClassNoExcept() {
  1538             return nameClassBuilder.makeAnyName(startLocation, annotations);
  1541         ParsedNameClass makeNameClassExcept(ParsedNameClass except) {
  1542             return nameClassBuilder.makeAnyName(except, startLocation, annotations);
  1545         @Override
  1546         void endChild(ParsedNameClass nameClass) {
  1547             except = nameClass;
  1551     class NsNameState extends AnyNameState {
  1553         @Override
  1554         State create() {
  1555             return new NsNameState();
  1558         @Override
  1559         ParsedNameClass makeNameClassNoExcept() {
  1560             return nameClassBuilder.makeNsName(getNs(), null, null);
  1563         @Override
  1564         ParsedNameClass makeNameClassExcept(ParsedNameClass except) {
  1565             return nameClassBuilder.makeNsName(getNs(), except, null, null);
  1568         @Override
  1569         int getContext() {
  1570             return NS_NAME_CONTEXT;
  1574     class NameClassChoiceState extends NameClassContainerState {
  1576         private ParsedNameClass[] nameClasses;
  1577         private int nNameClasses;
  1578         private int context;
  1580         NameClassChoiceState() {
  1581             this.context = PATTERN_CONTEXT;
  1584         NameClassChoiceState(int context) {
  1585             this.context = context;
  1588         @Override
  1589         void setParent(State parent) {
  1590             super.setParent(parent);
  1591             if (parent instanceof NameClassChoiceState) {
  1592                 this.context = ((NameClassChoiceState) parent).context;
  1596         State create() {
  1597             return new NameClassChoiceState();
  1600         @Override
  1601         State createChildState(String localName) throws SAXException {
  1602             if (localName.equals("anyName")) {
  1603                 if (context >= ANY_NAME_CONTEXT) {
  1604                     error(context == ANY_NAME_CONTEXT
  1605                             ? "any_name_except_contains_any_name"
  1606                             : "ns_name_except_contains_any_name");
  1607                     return null;
  1609             } else if (localName.equals("nsName")) {
  1610                 if (context == NS_NAME_CONTEXT) {
  1611                     error("ns_name_except_contains_ns_name");
  1612                     return null;
  1615             return super.createChildState(localName);
  1618         @Override
  1619         void endChild(ParsedNameClass nc) {
  1620             if (nameClasses == null) {
  1621                 nameClasses = new ParsedNameClass[INIT_CHILD_ALLOC];
  1622             } else if (nNameClasses >= nameClasses.length) {
  1623                 ParsedNameClass[] newNameClasses = new ParsedNameClass[nameClasses.length * 2];
  1624                 System.arraycopy(nameClasses, 0, newNameClasses, 0, nameClasses.length);
  1625                 nameClasses = newNameClasses;
  1627             nameClasses[nNameClasses++] = nc;
  1630         @Override
  1631         void endForeignChild(ParsedElementAnnotation ea) {
  1632             if (nNameClasses == 0) {
  1633                 super.endForeignChild(ea);
  1634             } else {
  1635                 nameClasses[nNameClasses - 1] = nameClassBuilder.annotateAfter(nameClasses[nNameClasses - 1], ea);
  1639         void end() throws SAXException {
  1640             if (nNameClasses == 0) {
  1641                 error("missing_name_class");
  1642                 parent.endChild(nameClassBuilder.makeErrorNameClass());
  1643                 return;
  1645             if (comments != null) {
  1646                 nameClasses[nNameClasses - 1] = nameClassBuilder.commentAfter(nameClasses[nNameClasses - 1], comments);
  1647                 comments = null;
  1649             parent.endChild(nameClassBuilder.makeChoice(Arrays.asList(nameClasses).subList(0, nNameClasses), startLocation, annotations));
  1653     private void initPatternTable() {
  1654         patternTable = new Hashtable();
  1655         patternTable.put("zeroOrMore", new ZeroOrMoreState());
  1656         patternTable.put("oneOrMore", new OneOrMoreState());
  1657         patternTable.put("optional", new OptionalState());
  1658         patternTable.put("list", new ListState());
  1659         patternTable.put("choice", new ChoiceState());
  1660         patternTable.put("interleave", new InterleaveState());
  1661         patternTable.put("group", new GroupState());
  1662         patternTable.put("mixed", new MixedState());
  1663         patternTable.put("element", new ElementState());
  1664         patternTable.put("attribute", new AttributeState());
  1665         patternTable.put("empty", new EmptyState());
  1666         patternTable.put("text", new TextState());
  1667         patternTable.put("value", new ValueState());
  1668         patternTable.put("data", new DataState());
  1669         patternTable.put("notAllowed", new NotAllowedState());
  1670         patternTable.put("grammar", new GrammarState());
  1671         patternTable.put("ref", new RefState());
  1672         patternTable.put("parentRef", new ParentRefState());
  1673         patternTable.put("externalRef", new ExternalRefState());
  1676     private void initNameClassTable() {
  1677         nameClassTable = new Hashtable();
  1678         nameClassTable.put("name", new NameState());
  1679         nameClassTable.put("anyName", new AnyNameState());
  1680         nameClassTable.put("nsName", new NsNameState());
  1681         nameClassTable.put("choice", new NameClassChoiceState());
  1684     public ParsedPattern getParsedPattern() throws IllegalSchemaException {
  1685         if (hadError) {
  1686             throw new IllegalSchemaException();
  1688         return startPattern;
  1691     private void error(String key) throws SAXException {
  1692         error(key, locator);
  1695     private void error(String key, String arg) throws SAXException {
  1696         error(key, arg, locator);
  1699     void error(String key, String arg1, String arg2) throws SAXException {
  1700         error(key, arg1, arg2, locator);
  1703     private void error(String key, Locator loc) throws SAXException {
  1704         error(new SAXParseException(localizer.message(key), loc));
  1707     private void error(String key, String arg, Locator loc) throws SAXException {
  1708         error(new SAXParseException(localizer.message(key, arg), loc));
  1711     private void error(String key, String arg1, String arg2, Locator loc)
  1712             throws SAXException {
  1713         error(new SAXParseException(localizer.message(key, arg1, arg2), loc));
  1716     private void error(SAXParseException e) throws SAXException {
  1717         hadError = true;
  1718         if (eh != null) {
  1719             eh.error(e);
  1723     void warning(String key) throws SAXException {
  1724         warning(key, locator);
  1727     private void warning(String key, String arg) throws SAXException {
  1728         warning(key, arg, locator);
  1731     private void warning(String key, String arg1, String arg2) throws SAXException {
  1732         warning(key, arg1, arg2, locator);
  1735     private void warning(String key, Locator loc) throws SAXException {
  1736         warning(new SAXParseException(localizer.message(key), loc));
  1739     private void warning(String key, String arg, Locator loc) throws SAXException {
  1740         warning(new SAXParseException(localizer.message(key, arg), loc));
  1743     private void warning(String key, String arg1, String arg2, Locator loc)
  1744             throws SAXException {
  1745         warning(new SAXParseException(localizer.message(key, arg1, arg2), loc));
  1748     private void warning(SAXParseException e) throws SAXException {
  1749         if (eh != null) {
  1750             eh.warning(e);
  1754     SchemaParser(SAXParseable parseable,
  1755             XMLReader xr,
  1756             ErrorHandler eh,
  1757             SchemaBuilder schemaBuilder,
  1758             IncludedGrammar grammar,
  1759             Scope scope,
  1760             String inheritedNs) throws SAXException {
  1761         this.parseable = parseable;
  1762         this.xr = xr;
  1763         this.eh = eh;
  1764         this.schemaBuilder = schemaBuilder;
  1765         this.nameClassBuilder = schemaBuilder.getNameClassBuilder();
  1766         if (eh != null) {
  1767             xr.setErrorHandler(eh);
  1769         xr.setDTDHandler(context);
  1770         if (schemaBuilder.usesComments()) {
  1771             try {
  1772                 xr.setProperty("http://xml.org/sax/properties/lexical-handler", new LexicalHandlerImpl());
  1773             } catch (SAXNotRecognizedException e) {
  1774                 warning("no_comment_support", xr.getClass().getName());
  1775             } catch (SAXNotSupportedException e) {
  1776                 warning("no_comment_support", xr.getClass().getName());
  1779         initPatternTable();
  1780         initNameClassTable();
  1781         new RootState(grammar, scope, inheritedNs).set();
  1784     private Context getContext() {
  1785         return context;
  1788     class LexicalHandlerImpl extends AbstractLexicalHandler {
  1790         private boolean inDtd = false;
  1792         @Override
  1793         public void startDTD(String s, String s1, String s2) throws SAXException {
  1794             inDtd = true;
  1797         @Override
  1798         public void endDTD() throws SAXException {
  1799             inDtd = false;
  1802         @Override
  1803         public void comment(char[] chars, int start, int length) throws SAXException {
  1804             if (!inDtd) {
  1805                 ((CommentHandler) xr.getContentHandler()).comment(new String(chars, start, length));
  1810     private ParsedNameClass expandName(String name, String ns, Annotations anno) throws SAXException {
  1811         int ic = name.indexOf(':');
  1812         if (ic == -1) {
  1813             return nameClassBuilder.makeName(ns, checkNCName(name), null, null, anno);
  1815         String prefix = checkNCName(name.substring(0, ic));
  1816         String localName = checkNCName(name.substring(ic + 1));
  1817         for (PrefixMapping tem = context.prefixMapping; tem != null; tem = tem.next) {
  1818             if (tem.prefix.equals(prefix)) {
  1819                 return nameClassBuilder.makeName(tem.uri, localName, prefix, null, anno);
  1822         error("undefined_prefix", prefix);
  1823         return nameClassBuilder.makeName("", localName, null, null, anno);
  1826     private String findPrefix(String qName, String uri) {
  1827         String prefix = null;
  1828         if (qName == null || qName.equals("")) {
  1829             for (PrefixMapping p = context.prefixMapping; p != null; p = p.next) {
  1830                 if (p.uri.equals(uri)) {
  1831                     prefix = p.prefix;
  1832                     break;
  1835         } else {
  1836             int off = qName.indexOf(':');
  1837             if (off > 0) {
  1838                 prefix = qName.substring(0, off);
  1841         return prefix;
  1844     private String checkNCName(String str) throws SAXException {
  1845         if (!Naming.isNcname(str)) {
  1846             error("invalid_ncname", str);
  1848         return str;
  1851     private String resolve(String systemId) throws SAXException {
  1852         if (Uri.hasFragmentId(systemId)) {
  1853             error("href_fragment_id");
  1855         systemId = Uri.escapeDisallowedChars(systemId);
  1856         return Uri.resolve(xmlBaseHandler.getBaseUri(), systemId);
  1859     private Location makeLocation() {
  1860         if (locator == null) {
  1861             return null;
  1863         return schemaBuilder.makeLocation(locator.getSystemId(),
  1864                 locator.getLineNumber(),
  1865                 locator.getColumnNumber());
  1868     private void checkUri(String s) throws SAXException {
  1869         if (!Uri.isValid(s)) {
  1870             error("invalid_uri", s);

mercurial