Save This Page
Home » openjdk-7 » com.sun.xml.internal.rngom » parse » xml » [javadoc | source]
    1   /*
    2    * Copyright 2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package com.sun.xml.internal.rngom.parse.xml;
   27   
   28   import java.util.Enumeration;
   29   import java.util.Hashtable;
   30   import java.util.Stack;
   31   import java.util.Vector;
   32   import java.util.List;
   33   import java.util.ArrayList;
   34   import java.util.Arrays;
   35   
   36   import com.sun.xml.internal.rngom.ast.builder.Annotations;
   37   import com.sun.xml.internal.rngom.ast.builder.CommentList;
   38   import com.sun.xml.internal.rngom.ast.builder.DataPatternBuilder;
   39   import com.sun.xml.internal.rngom.ast.builder.Div;
   40   import com.sun.xml.internal.rngom.ast.builder.ElementAnnotationBuilder;
   41   import com.sun.xml.internal.rngom.ast.builder.Grammar;
   42   import com.sun.xml.internal.rngom.ast.builder.GrammarSection;
   43   import com.sun.xml.internal.rngom.ast.builder.Include;
   44   import com.sun.xml.internal.rngom.ast.builder.IncludedGrammar;
   45   import com.sun.xml.internal.rngom.ast.builder.NameClassBuilder;
   46   import com.sun.xml.internal.rngom.ast.builder.SchemaBuilder;
   47   import com.sun.xml.internal.rngom.ast.builder.Scope;
   48   import com.sun.xml.internal.rngom.ast.om.Location;
   49   import com.sun.xml.internal.rngom.ast.om.ParsedElementAnnotation;
   50   import com.sun.xml.internal.rngom.ast.om.ParsedNameClass;
   51   import com.sun.xml.internal.rngom.ast.om.ParsedPattern;
   52   import com.sun.xml.internal.rngom.parse.Context;
   53   import com.sun.xml.internal.rngom.parse.IllegalSchemaException;
   54   import com.sun.xml.internal.rngom.parse.Parseable;
   55   import com.sun.xml.internal.rngom.util.Localizer;
   56   import com.sun.xml.internal.rngom.util.Uri;
   57   import com.sun.xml.internal.rngom.xml.sax.AbstractLexicalHandler;
   58   import com.sun.xml.internal.rngom.xml.sax.XmlBaseHandler;
   59   import com.sun.xml.internal.rngom.xml.util.Naming;
   60   import com.sun.xml.internal.rngom.xml.util.WellKnownNamespaces;
   61   import org.xml.sax.Attributes;
   62   import org.xml.sax.ContentHandler;
   63   import org.xml.sax.ErrorHandler;
   64   import org.xml.sax.Locator;
   65   import org.xml.sax.SAXException;
   66   import org.xml.sax.SAXNotRecognizedException;
   67   import org.xml.sax.SAXNotSupportedException;
   68   import org.xml.sax.SAXParseException;
   69   import org.xml.sax.XMLReader;
   70   import org.xml.sax.helpers.DefaultHandler;
   71   
   72   class SchemaParser {
   73   
   74     private static final String relaxngURIPrefix =
   75             WellKnownNamespaces.RELAX_NG.substring(0, WellKnownNamespaces.RELAX_NG.lastIndexOf('/') + 1);
   76     static final String relaxng10URI = WellKnownNamespaces.RELAX_NG;
   77     private static final Localizer localizer = new Localizer(new Localizer(Parseable.class),SchemaParser.class);
   78   
   79     private String relaxngURI;
   80     private final XMLReader xr;
   81     private final ErrorHandler eh;
   82     private final SchemaBuilder schemaBuilder;
   83     /**
   84      * The value of the {@link SchemaBuilder#getNameClassBuilder()}
   85      * for the {@link #schemaBuilder} object.
   86      */
   87     private final NameClassBuilder nameClassBuilder;
   88     private ParsedPattern startPattern;
   89     private Locator locator;
   90     private final XmlBaseHandler xmlBaseHandler = new XmlBaseHandler();
   91     private final ContextImpl context = new ContextImpl();
   92   
   93     private boolean hadError = false;
   94   
   95     private Hashtable patternTable;
   96     private Hashtable nameClassTable;
   97   
   98     static class PrefixMapping {
   99       final String prefix;
  100       final String uri;
  101       final PrefixMapping next;
  102   
  103       PrefixMapping(String prefix, String uri, PrefixMapping next) {
  104         this.prefix = prefix;
  105         this.uri = uri;
  106         this.next = next;
  107       }
  108     }
  109   
  110     static abstract class AbstractContext extends DtdContext implements Context {
  111       PrefixMapping prefixMapping;
  112   
  113       AbstractContext() {
  114         prefixMapping = new PrefixMapping("xml", WellKnownNamespaces.XML, null);
  115       }
  116   
  117       AbstractContext(AbstractContext context) {
  118         super(context);
  119         prefixMapping = context.prefixMapping;
  120       }
  121   
  122       public String resolveNamespacePrefix(String prefix) {
  123         for (PrefixMapping p = prefixMapping; p != null; p = p.next)
  124           if (p.prefix.equals(prefix))
  125             return p.uri;
  126         return null;
  127       }
  128   
  129       public Enumeration prefixes() {
  130         Vector v = new Vector();
  131         for (PrefixMapping p = prefixMapping; p != null; p = p.next) {
  132           if (!v.contains(p.prefix))
  133             v.addElement(p.prefix);
  134         }
  135         return v.elements();
  136       }
  137   
  138       public Context copy() {
  139         return new SavedContext(this);
  140       }
  141     }
  142   
  143     static class SavedContext extends AbstractContext {
  144       private final String baseUri;
  145       SavedContext(AbstractContext context) {
  146         super(context);
  147         this.baseUri = context.getBaseUri();
  148       }
  149   
  150       public String getBaseUri() {
  151         return baseUri;
  152       }
  153     }
  154   
  155     class ContextImpl extends AbstractContext {
  156       public String getBaseUri() {
  157         return xmlBaseHandler.getBaseUri();
  158       }
  159     }
  160   
  161     static interface CommentHandler {
  162       void comment(String value);
  163     }
  164   
  165     abstract class Handler implements ContentHandler, CommentHandler {
  166       CommentList comments;
  167   
  168       CommentList getComments() {
  169         CommentList tem = comments;
  170         comments = null;
  171         return tem;
  172       }
  173   
  174       public void comment(String value) {
  175         if (comments == null)
  176           comments = schemaBuilder.makeCommentList();
  177         comments.addComment(value, makeLocation());
  178       }
  179       public void processingInstruction(String target, String date) { }
  180       public void skippedEntity(String name) { }
  181       public void ignorableWhitespace(char[] ch, int start, int len) { }
  182       public void startDocument() { }
  183       public void endDocument() { }
  184       public void startPrefixMapping(String prefix, String uri) {
  185         context.prefixMapping = new PrefixMapping(prefix, uri, context.prefixMapping);
  186       }
  187   
  188       public void endPrefixMapping(String prefix) {
  189         context.prefixMapping = context.prefixMapping.next;
  190       }
  191   
  192       public void setDocumentLocator(Locator loc) {
  193         locator = loc;
  194         xmlBaseHandler.setLocator(loc);
  195       }
  196     }
  197   
  198     abstract class State extends Handler {
  199       State parent;
  200       String nsInherit;
  201       String ns;
  202       String datatypeLibrary;
  203       /**
  204        * The current scope, or null if there's none.
  205        */
  206       Scope scope;
  207       Location startLocation;
  208       Annotations annotations;
  209   
  210       void set() {
  211         xr.setContentHandler(this);
  212       }
  213   
  214       abstract State create();
  215       abstract State createChildState(String localName) throws SAXException;
  216   
  217   
  218       void setParent(State parent) {
  219         this.parent = parent;
  220         this.nsInherit = parent.getNs();
  221         this.datatypeLibrary = parent.datatypeLibrary;
  222         this.scope = parent.scope;
  223         this.startLocation = makeLocation();
  224         if (parent.comments != null) {
  225           annotations = schemaBuilder.makeAnnotations(parent.comments, getContext());
  226           parent.comments = null;
  227         }
  228         else if (parent instanceof RootState)
  229           annotations = schemaBuilder.makeAnnotations(null, getContext());
  230       }
  231   
  232       String getNs() {
  233         return ns == null ? nsInherit : ns;
  234       }
  235   
  236       boolean isRelaxNGElement(String uri) throws SAXException {
  237         return uri.equals(relaxngURI);
  238       }
  239   
  240       public void startElement(String namespaceURI,
  241                                String localName,
  242                                String qName,
  243                                Attributes atts) throws SAXException {
  244         xmlBaseHandler.startElement();
  245         if (isRelaxNGElement(namespaceURI)) {
  246           State state = createChildState(localName);
  247           if (state == null) {
  248             xr.setContentHandler(new Skipper(this));
  249             return;
  250           }
  251           state.setParent(this);
  252           state.set();
  253           state.attributes(atts);
  254         }
  255         else {
  256           checkForeignElement();
  257           ForeignElementHandler feh = new ForeignElementHandler(this, getComments());
  258           feh.startElement(namespaceURI, localName, qName, atts);
  259           xr.setContentHandler(feh);
  260         }
  261       }
  262   
  263       public void endElement(String namespaceURI,
  264                              String localName,
  265                              String qName) throws SAXException {
  266         xmlBaseHandler.endElement();
  267         parent.set();
  268         end();
  269       }
  270   
  271       void setName(String name) throws SAXException {
  272         error("illegal_name_attribute");
  273       }
  274   
  275       void setOtherAttribute(String name, String value) throws SAXException {
  276         error("illegal_attribute_ignored", name);
  277       }
  278   
  279       void endAttributes() throws SAXException {
  280       }
  281   
  282       void checkForeignElement() throws SAXException {
  283       }
  284   
  285       void attributes(Attributes atts) throws SAXException {
  286         int len = atts.getLength();
  287         for (int i = 0; i < len; i++) {
  288           String uri = atts.getURI(i);
  289           if (uri.length() == 0) {
  290             String name = atts.getLocalName(i);
  291             if (name.equals("name"))
  292               setName(atts.getValue(i).trim());
  293             else if (name.equals("ns"))
  294               ns = atts.getValue(i);
  295             else if (name.equals("datatypeLibrary")) {
  296               datatypeLibrary = atts.getValue(i);
  297               checkUri(datatypeLibrary);
  298               if (!datatypeLibrary.equals("")
  299                   && !Uri.isAbsolute(datatypeLibrary))
  300                 error("relative_datatype_library");
  301               if (Uri.hasFragmentId(datatypeLibrary))
  302                 error("fragment_identifier_datatype_library");
  303               datatypeLibrary = Uri.escapeDisallowedChars(datatypeLibrary);
  304             }
  305             else
  306               setOtherAttribute(name, atts.getValue(i));
  307           }
  308           else if (uri.equals(relaxngURI))
  309             error("qualified_attribute", atts.getLocalName(i));
  310           else if (uri.equals(WellKnownNamespaces.XML)
  311                    && atts.getLocalName(i).equals("base"))
  312             xmlBaseHandler.xmlBaseAttribute(atts.getValue(i));
  313           else {
  314             if (annotations == null)
  315               annotations = schemaBuilder.makeAnnotations(null, getContext());
  316             annotations.addAttribute(uri, atts.getLocalName(i), findPrefix(atts.getQName(i), uri),
  317                                      atts.getValue(i), startLocation);
  318           }
  319         }
  320         endAttributes();
  321       }
  322   
  323       abstract void end() throws SAXException;
  324   
  325       void endChild(ParsedPattern pattern) {
  326         // XXX cannot happen; throw exception
  327       }
  328   
  329       void endChild(ParsedNameClass nc) {
  330         // XXX cannot happen; throw exception
  331       }
  332   
  333       public void startDocument() { }
  334       public void endDocument() {
  335         if (comments != null && startPattern != null) {
  336           startPattern = schemaBuilder.commentAfter(startPattern, comments);
  337           comments = null;
  338         }
  339       }
  340   
  341       public void characters(char[] ch, int start, int len) throws SAXException {
  342         for (int i = 0; i < len; i++) {
  343           switch(ch[start + i]) {
  344           case ' ':
  345           case '\r':
  346           case '\n':
  347           case '\t':
  348             break;
  349           default:
  350             error("illegal_characters_ignored");
  351             break;
  352           }
  353         }
  354       }
  355   
  356       boolean isPatternNamespaceURI(String s) {
  357         return s.equals(relaxngURI);
  358       }
  359   
  360       void endForeignChild(ParsedElementAnnotation ea) {
  361         if (annotations == null)
  362           annotations = schemaBuilder.makeAnnotations(null, getContext());
  363         annotations.addElement(ea);
  364       }
  365   
  366       void mergeLeadingComments() {
  367         if (comments != null) {
  368           if (annotations == null)
  369             annotations = schemaBuilder.makeAnnotations(comments, getContext());
  370           else
  371             annotations.addLeadingComment(comments);
  372           comments = null;
  373         }
  374       }
  375     }
  376   
  377     class ForeignElementHandler extends Handler {
  378       final State nextState;
  379       ElementAnnotationBuilder builder;
  380       final Stack builderStack = new Stack();
  381       StringBuffer textBuf;
  382       Location textLoc;
  383   
  384       ForeignElementHandler(State nextState, CommentList comments) {
  385         this.nextState = nextState;
  386         this.comments = comments;
  387       }
  388   
  389       public void startElement(String namespaceURI, String localName,
  390                                String qName, Attributes atts) {
  391         flushText();
  392         if (builder != null)
  393           builderStack.push(builder);
  394         Location loc = makeLocation();
  395         builder = schemaBuilder.makeElementAnnotationBuilder(namespaceURI,
  396                                                              localName,
  397                                                              findPrefix(qName, namespaceURI),
  398                                                              loc,
  399                                                              getComments(),
  400                                                              getContext());
  401         int len = atts.getLength();
  402         for (int i = 0; i < len; i++) {
  403           String uri = atts.getURI(i);
  404           builder.addAttribute(uri, atts.getLocalName(i), findPrefix(atts.getQName(i), uri),
  405                                atts.getValue(i), loc);
  406         }
  407       }
  408   
  409       public void endElement(String namespaceURI, String localName,
  410                              String qName) {
  411         flushText();
  412         if (comments != null)
  413           builder.addComment(getComments());
  414         ParsedElementAnnotation ea = builder.makeElementAnnotation();
  415         if (builderStack.empty()) {
  416           nextState.endForeignChild(ea);
  417           nextState.set();
  418         }
  419         else {
  420           builder = (ElementAnnotationBuilder)builderStack.pop();
  421           builder.addElement(ea);
  422         }
  423       }
  424   
  425       public void characters(char ch[], int start, int length) {
  426         if (textBuf == null)
  427           textBuf = new StringBuffer();
  428         textBuf.append(ch, start, length);
  429         if (textLoc == null)
  430           textLoc = makeLocation();
  431       }
  432   
  433       public void comment(String value) {
  434         flushText();
  435         super.comment(value);
  436       }
  437   
  438       void flushText() {
  439         if (textBuf != null && textBuf.length() != 0) {
  440           builder.addText(textBuf.toString(), textLoc, getComments());
  441           textBuf.setLength(0);
  442         }
  443         textLoc = null;
  444       }
  445     }
  446   
  447     class Skipper extends DefaultHandler implements CommentHandler {
  448       int level = 1;
  449       final State nextState;
  450   
  451       Skipper(State nextState) {
  452         this.nextState = nextState;
  453       }
  454   
  455       public void startElement(String namespaceURI,
  456                                String localName,
  457                                String qName,
  458                                Attributes atts) throws SAXException {
  459         ++level;
  460       }
  461   
  462       public void endElement(String namespaceURI,
  463                              String localName,
  464                              String qName) throws SAXException {
  465         if (--level == 0)
  466           nextState.set();
  467       }
  468   
  469       public void comment(String value) {
  470       }
  471     }
  472   
  473     abstract class EmptyContentState extends State {
  474   
  475       State createChildState(String localName) throws SAXException {
  476         error("expected_empty", localName);
  477         return null;
  478       }
  479   
  480       abstract ParsedPattern makePattern() throws SAXException;
  481   
  482       void end() throws SAXException {
  483         if (comments != null) {
  484           if (annotations == null)
  485             annotations = schemaBuilder.makeAnnotations(null, getContext());
  486           annotations.addComment(comments);
  487           comments = null;
  488         }
  489         parent.endChild(makePattern());
  490       }
  491     }
  492   
  493     static private final int INIT_CHILD_ALLOC = 5;
  494   
  495     abstract class PatternContainerState extends State {
  496       List<ParsedPattern> childPatterns;
  497   
  498       State createChildState(String localName) throws SAXException {
  499         State state = (State)patternTable.get(localName);
  500         if (state == null) {
  501           error("expected_pattern", localName);
  502           return null;
  503         }
  504         return state.create();
  505       }
  506   
  507       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  508         if (patterns.size() == 1 && anno == null)
  509           return patterns.get(0);
  510         return schemaBuilder.makeGroup(patterns, loc, anno);
  511       }
  512   
  513       void endChild(ParsedPattern pattern) {
  514         if (childPatterns == null)
  515           childPatterns = new ArrayList<ParsedPattern>(INIT_CHILD_ALLOC);
  516         childPatterns.add(pattern);
  517       }
  518   
  519       void endForeignChild(ParsedElementAnnotation ea) {
  520         if (childPatterns == null)
  521           super.endForeignChild(ea);
  522         else {
  523           int idx = childPatterns.size()-1;
  524           childPatterns.set(idx, schemaBuilder.annotateAfter(childPatterns.get(idx), ea));
  525         }
  526       }
  527   
  528       void end() throws SAXException {
  529         if (childPatterns == null) {
  530           error("missing_children");
  531           endChild(schemaBuilder.makeErrorPattern());
  532         }
  533         if (comments != null) {
  534           int idx = childPatterns.size()-1;
  535           childPatterns.set(idx,schemaBuilder.commentAfter(childPatterns.get(idx), comments));
  536           comments = null;
  537         }
  538         sendPatternToParent(buildPattern(childPatterns, startLocation, annotations));
  539       }
  540   
  541       void sendPatternToParent(ParsedPattern p) {
  542         parent.endChild(p);
  543       }
  544     }
  545   
  546     class GroupState extends PatternContainerState {
  547       State create() {
  548         return new GroupState();
  549       }
  550     }
  551   
  552     class ZeroOrMoreState extends PatternContainerState {
  553       State create() {
  554         return new ZeroOrMoreState();
  555       }
  556   
  557       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  558         return schemaBuilder.makeZeroOrMore(super.buildPattern(patterns, loc, null), loc, anno);
  559       }
  560     }
  561   
  562     class OneOrMoreState extends PatternContainerState {
  563       State create() {
  564         return new OneOrMoreState();
  565       }
  566       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  567         return schemaBuilder.makeOneOrMore(super.buildPattern(patterns, loc, null), loc, anno);
  568       }
  569     }
  570   
  571     class OptionalState extends PatternContainerState {
  572       State create() {
  573         return new OptionalState();
  574       }
  575       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  576         return schemaBuilder.makeOptional(super.buildPattern(patterns, loc, null), loc, anno);
  577       }
  578     }
  579   
  580     class ListState extends PatternContainerState {
  581       State create() {
  582         return new ListState();
  583       }
  584       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  585         return schemaBuilder.makeList(super.buildPattern(patterns, loc, null), loc, anno);
  586       }
  587     }
  588   
  589     class ChoiceState extends PatternContainerState {
  590       State create() {
  591         return new ChoiceState();
  592       }
  593       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  594         return schemaBuilder.makeChoice(patterns, loc, anno);
  595       }
  596     }
  597   
  598     class InterleaveState extends PatternContainerState {
  599       State create() {
  600         return new InterleaveState();
  601       }
  602       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) {
  603         return schemaBuilder.makeInterleave(patterns, loc, anno);
  604       }
  605     }
  606   
  607     class MixedState extends PatternContainerState {
  608       State create() {
  609         return new MixedState();
  610       }
  611       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  612         return schemaBuilder.makeMixed(super.buildPattern(patterns, loc, null), loc, anno);
  613       }
  614     }
  615   
  616     static interface NameClassRef {
  617       void setNameClass(ParsedNameClass nc);
  618     }
  619   
  620     class ElementState extends PatternContainerState implements NameClassRef {
  621       ParsedNameClass nameClass;
  622       boolean nameClassWasAttribute;
  623       String name;
  624   
  625       void setName(String name) {
  626         this.name = name;
  627       }
  628   
  629       public void setNameClass(ParsedNameClass nc) {
  630         nameClass = nc;
  631       }
  632   
  633       void endAttributes() throws SAXException {
  634         if (name != null) {
  635           nameClass = expandName(name, getNs(), null);
  636           nameClassWasAttribute = true;
  637         }
  638         else
  639           new NameClassChildState(this, this).set();
  640       }
  641   
  642       State create() {
  643         return new ElementState();
  644       }
  645   
  646       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  647         return schemaBuilder.makeElement(nameClass, super.buildPattern(patterns, loc, null), loc, anno);
  648       }
  649   
  650       void endForeignChild(ParsedElementAnnotation ea) {
  651         if (nameClassWasAttribute || childPatterns!=null || nameClass == null)
  652           super.endForeignChild(ea);
  653         else
  654           nameClass = nameClassBuilder.annotateAfter(nameClass, ea);
  655       }
  656     }
  657   
  658     class RootState extends PatternContainerState {
  659       IncludedGrammar grammar;
  660   
  661       RootState() {
  662       }
  663   
  664       RootState(IncludedGrammar grammar, Scope scope, String ns) {
  665         this.grammar = grammar;
  666         this.scope = scope;
  667         this.nsInherit = ns;
  668         this.datatypeLibrary = "";
  669       }
  670   
  671       State create() {
  672         return new RootState();
  673       }
  674   
  675       State createChildState(String localName) throws SAXException {
  676         if (grammar == null)
  677           return super.createChildState(localName);
  678         if (localName.equals("grammar"))
  679           return new MergeGrammarState(grammar);
  680         error("expected_grammar", localName);
  681         return null;
  682       }
  683   
  684       void checkForeignElement() throws SAXException {
  685         error("root_bad_namespace_uri", WellKnownNamespaces.RELAX_NG);
  686       }
  687   
  688       void endChild(ParsedPattern pattern) {
  689         startPattern = pattern;
  690       }
  691   
  692       boolean isRelaxNGElement(String uri) throws SAXException {
  693         if (!uri.startsWith(relaxngURIPrefix))
  694           return false;
  695         if (!uri.equals(WellKnownNamespaces.RELAX_NG))
  696           warning("wrong_uri_version",
  697                   WellKnownNamespaces.RELAX_NG.substring(relaxngURIPrefix.length()),
  698                   uri.substring(relaxngURIPrefix.length()));
  699         relaxngURI = uri;
  700         return true;
  701       }
  702   
  703     }
  704   
  705     class NotAllowedState extends EmptyContentState {
  706       State create() {
  707         return new NotAllowedState();
  708       }
  709   
  710       ParsedPattern makePattern() {
  711         return schemaBuilder.makeNotAllowed(startLocation, annotations);
  712       }
  713     }
  714   
  715     class EmptyState extends EmptyContentState {
  716       State create() {
  717         return new EmptyState();
  718       }
  719   
  720       ParsedPattern makePattern() {
  721         return schemaBuilder.makeEmpty(startLocation, annotations);
  722       }
  723     }
  724   
  725     class TextState extends EmptyContentState {
  726       State create() {
  727         return new TextState();
  728       }
  729   
  730       ParsedPattern makePattern() {
  731         return schemaBuilder.makeText(startLocation, annotations);
  732       }
  733     }
  734   
  735     class ValueState extends EmptyContentState {
  736       final StringBuffer buf = new StringBuffer();
  737       String type;
  738   
  739       State create() {
  740         return new ValueState();
  741       }
  742   
  743       void setOtherAttribute(String name, String value) throws SAXException {
  744         if (name.equals("type"))
  745           type = checkNCName(value.trim());
  746         else
  747           super.setOtherAttribute(name, value);
  748       }
  749   
  750       public void characters(char[] ch, int start, int len) {
  751         buf.append(ch, start, len);
  752       }
  753   
  754       void checkForeignElement() throws SAXException {
  755         error("value_contains_foreign_element");
  756       }
  757   
  758       ParsedPattern makePattern() throws SAXException {
  759         if (type == null)
  760           return makePattern("", "token");
  761         else
  762           return makePattern(datatypeLibrary, type);
  763       }
  764   
  765       void end() throws SAXException {
  766         mergeLeadingComments();
  767         super.end();
  768       }
  769   
  770       ParsedPattern makePattern(String datatypeLibrary, String type) {
  771         return schemaBuilder.makeValue(datatypeLibrary,
  772                                        type,
  773                                        buf.toString(),
  774                                        getContext(),
  775                                        getNs(),
  776                                        startLocation,
  777                                        annotations);
  778       }
  779   
  780     }
  781   
  782     class DataState extends State {
  783       String type;
  784       ParsedPattern except = null;
  785       DataPatternBuilder dpb = null;
  786   
  787       State create() {
  788         return new DataState();
  789       }
  790   
  791       State createChildState(String localName) throws SAXException {
  792         if (localName.equals("param")) {
  793           if (except != null)
  794             error("param_after_except");
  795           return new ParamState(dpb);
  796         }
  797         if (localName.equals("except")) {
  798           if (except != null)
  799             error("multiple_except");
  800           return new ChoiceState();
  801         }
  802         error("expected_param_except", localName);
  803         return null;
  804       }
  805   
  806       void setOtherAttribute(String name, String value) throws SAXException {
  807         if (name.equals("type"))
  808           type = checkNCName(value.trim());
  809         else
  810           super.setOtherAttribute(name, value);
  811       }
  812   
  813       void endAttributes() throws SAXException {
  814         if (type == null)
  815           error("missing_type_attribute");
  816         else
  817           dpb = schemaBuilder.makeDataPatternBuilder(datatypeLibrary, type, startLocation);
  818       }
  819   
  820       void endForeignChild(ParsedElementAnnotation ea) {
  821         dpb.annotation(ea);
  822       }
  823   
  824       void end() throws SAXException {
  825         ParsedPattern p;
  826         if (dpb != null) {
  827           if (except != null)
  828             p = dpb.makePattern(except, startLocation, annotations);
  829           else
  830             p = dpb.makePattern(startLocation, annotations);
  831         }
  832         else
  833           p = schemaBuilder.makeErrorPattern();
  834         // XXX need to capture comments
  835         parent.endChild(p);
  836       }
  837   
  838       void endChild(ParsedPattern pattern) {
  839         except = pattern;
  840       }
  841   
  842     }
  843   
  844     class ParamState extends State {
  845       private final StringBuffer buf = new StringBuffer();
  846       private final DataPatternBuilder dpb;
  847       private String name;
  848   
  849       ParamState(DataPatternBuilder dpb) {
  850         this.dpb = dpb;
  851       }
  852   
  853       State create() {
  854         return new ParamState(null);
  855       }
  856   
  857       void setName(String name) throws SAXException {
  858         this.name = checkNCName(name);
  859       }
  860   
  861       void endAttributes() throws SAXException {
  862         if (name == null)
  863           error("missing_name_attribute");
  864       }
  865   
  866       State createChildState(String localName) throws SAXException {
  867         error("expected_empty", localName);
  868         return null;
  869       }
  870   
  871       public void characters(char[] ch, int start, int len) {
  872         buf.append(ch, start, len);
  873       }
  874   
  875       void checkForeignElement() throws SAXException {
  876         error("param_contains_foreign_element");
  877       }
  878   
  879       void end() throws SAXException {
  880         if (name == null)
  881           return;
  882         if (dpb == null)
  883           return;
  884         mergeLeadingComments();
  885         dpb.addParam(name, buf.toString(), getContext(), getNs(), startLocation, annotations);
  886       }
  887     }
  888   
  889     class AttributeState extends PatternContainerState implements NameClassRef {
  890       ParsedNameClass nameClass;
  891       boolean nameClassWasAttribute;
  892       String name;
  893   
  894       State create() {
  895         return new AttributeState();
  896       }
  897   
  898       void setName(String name) {
  899         this.name = name;
  900       }
  901   
  902       public void setNameClass(ParsedNameClass nc) {
  903         nameClass = nc;
  904       }
  905   
  906       void endAttributes() throws SAXException {
  907         if (name != null) {
  908           String nsUse;
  909           if (ns != null)
  910             nsUse = ns;
  911           else
  912             nsUse = "";
  913           nameClass = expandName(name, nsUse, null);
  914           nameClassWasAttribute = true;
  915         }
  916         else
  917           new NameClassChildState(this, this).set();
  918       }
  919   
  920       void endForeignChild(ParsedElementAnnotation ea) {
  921         if (nameClassWasAttribute || childPatterns!=null || nameClass == null)
  922           super.endForeignChild(ea);
  923         else
  924           nameClass = nameClassBuilder.annotateAfter(nameClass, ea);
  925       }
  926   
  927       void end() throws SAXException {
  928         if (childPatterns == null)
  929           endChild(schemaBuilder.makeText(startLocation, null));
  930         super.end();
  931       }
  932   
  933       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
  934         return schemaBuilder.makeAttribute(nameClass, super.buildPattern(patterns, loc, null), loc, anno);
  935       }
  936   
  937       State createChildState(String localName) throws SAXException {
  938         State tem = super.createChildState(localName);
  939         if (tem != null && childPatterns!=null)
  940           error("attribute_multi_pattern");
  941         return tem;
  942       }
  943   
  944     }
  945   
  946     abstract class SinglePatternContainerState extends PatternContainerState {
  947       State createChildState(String localName) throws SAXException {
  948         if (childPatterns==null)
  949           return super.createChildState(localName);
  950         error("too_many_children");
  951         return null;
  952       }
  953     }
  954   
  955     class GrammarSectionState extends State {
  956       GrammarSection section;
  957   
  958       GrammarSectionState() { }
  959   
  960       GrammarSectionState(GrammarSection section) {
  961         this.section = section;
  962       }
  963   
  964       State create() {
  965         return new GrammarSectionState(null);
  966       }
  967   
  968       State createChildState(String localName) throws SAXException {
  969         if (localName.equals("define"))
  970           return new DefineState(section);
  971         if (localName.equals("start"))
  972           return new StartState(section);
  973         if (localName.equals("include")) {
  974           Include include = section.makeInclude();
  975           if (include != null)
  976             return new IncludeState(include);
  977         }
  978         if (localName.equals("div"))
  979           return new DivState(section.makeDiv());
  980         error("expected_define", localName);
  981         // XXX better errors
  982         return null;
  983       }
  984   
  985       void end() throws SAXException {
  986         if (comments != null) {
  987           section.topLevelComment(comments);
  988           comments = null;
  989         }
  990       }
  991   
  992       void endForeignChild(ParsedElementAnnotation ea) {
  993         section.topLevelAnnotation(ea);
  994       }
  995     }
  996   
  997     class DivState extends GrammarSectionState {
  998       final Div div;
  999       DivState(Div div) {
 1000         super(div);
 1001         this.div = div;
 1002       }
 1003   
 1004       void end() throws SAXException {
 1005         super.end();
 1006         div.endDiv(startLocation, annotations);
 1007       }
 1008     }
 1009   
 1010     class IncludeState extends GrammarSectionState {
 1011       String href;
 1012       final Include include;
 1013   
 1014       IncludeState(Include include) {
 1015         super(include);
 1016         this.include = include;
 1017       }
 1018   
 1019       void setOtherAttribute(String name, String value) throws SAXException {
 1020         if (name.equals("href")) {
 1021           href = value;
 1022           checkUri(href);
 1023         }
 1024         else
 1025           super.setOtherAttribute(name, value);
 1026       }
 1027   
 1028       void endAttributes() throws SAXException {
 1029         if (href == null)
 1030           error("missing_href_attribute");
 1031         else
 1032           href = resolve(href);
 1033       }
 1034   
 1035       void end() throws SAXException {
 1036         super.end();
 1037         if (href != null) {
 1038           try {
 1039             include.endInclude(parseable, href, getNs(), startLocation, annotations);
 1040           }
 1041           catch (IllegalSchemaException e) {
 1042           }
 1043         }
 1044       }
 1045     }
 1046   
 1047     class MergeGrammarState extends GrammarSectionState {
 1048       final IncludedGrammar grammar;
 1049       MergeGrammarState(IncludedGrammar grammar) {
 1050         super(grammar);
 1051         this.grammar = grammar;
 1052       }
 1053   
 1054       void end() throws SAXException {
 1055         super.end();
 1056         parent.endChild(grammar.endIncludedGrammar(startLocation, annotations));
 1057       }
 1058     }
 1059   
 1060     class GrammarState extends GrammarSectionState {
 1061       Grammar grammar;
 1062   
 1063       void setParent(State parent) {
 1064         super.setParent(parent);
 1065         grammar = schemaBuilder.makeGrammar(scope);
 1066         section = grammar;
 1067         scope = grammar;
 1068       }
 1069   
 1070       State create() {
 1071         return new GrammarState();
 1072       }
 1073   
 1074       void end() throws SAXException {
 1075         super.end();
 1076         parent.endChild(grammar.endGrammar(startLocation, annotations));
 1077       }
 1078     }
 1079   
 1080     class RefState extends EmptyContentState {
 1081       String name;
 1082   
 1083       State create() {
 1084         return new RefState();
 1085       }
 1086   
 1087   
 1088       void endAttributes() throws SAXException {
 1089         if (name == null)
 1090           error("missing_name_attribute");
 1091       }
 1092   
 1093       void setName(String name) throws SAXException {
 1094         this.name = checkNCName(name);
 1095       }
 1096   
 1097       ParsedPattern makePattern() throws SAXException {
 1098         if (name == null)
 1099           return schemaBuilder.makeErrorPattern();
 1100         if(scope==null) {
 1101             error("ref_outside_grammar",name);
 1102             return schemaBuilder.makeErrorPattern();
 1103         } else
 1104             return scope.makeRef(name, startLocation, annotations);
 1105       }
 1106     }
 1107   
 1108     class ParentRefState extends RefState {
 1109       State create() {
 1110         return new ParentRefState();
 1111       }
 1112   
 1113       ParsedPattern makePattern() throws SAXException {
 1114         if (name == null)
 1115           return schemaBuilder.makeErrorPattern();
 1116         if(scope==null) {
 1117           error("parent_ref_outside_grammar",name);
 1118           return schemaBuilder.makeErrorPattern();
 1119         } else
 1120           return scope.makeParentRef(name, startLocation, annotations);
 1121       }
 1122     }
 1123   
 1124     class ExternalRefState extends EmptyContentState {
 1125       String href;
 1126       ParsedPattern includedPattern;
 1127   
 1128       State create() {
 1129         return new ExternalRefState();
 1130       }
 1131   
 1132       void setOtherAttribute(String name, String value) throws SAXException {
 1133         if (name.equals("href")) {
 1134           href = value;
 1135           checkUri(href);
 1136         }
 1137         else
 1138           super.setOtherAttribute(name, value);
 1139       }
 1140   
 1141       void endAttributes() throws SAXException {
 1142         if (href == null)
 1143           error("missing_href_attribute");
 1144         else
 1145           href = resolve(href);
 1146       }
 1147   
 1148       ParsedPattern makePattern() {
 1149         if (href != null) {
 1150           try {
 1151             return schemaBuilder.makeExternalRef(parseable,
 1152                                                  href,
 1153                                                  getNs(),
 1154                                                  scope,
 1155                                                  startLocation,
 1156                                                  annotations);
 1157           }
 1158           catch (IllegalSchemaException e) { }
 1159         }
 1160         return schemaBuilder.makeErrorPattern();
 1161       }
 1162     }
 1163   
 1164     abstract class DefinitionState extends PatternContainerState {
 1165       GrammarSection.Combine combine = null;
 1166       final GrammarSection section;
 1167   
 1168       DefinitionState(GrammarSection section) {
 1169         this.section = section;
 1170       }
 1171   
 1172       void setOtherAttribute(String name, String value) throws SAXException {
 1173         if (name.equals("combine")) {
 1174           value = value.trim();
 1175           if (value.equals("choice"))
 1176             combine = GrammarSection.COMBINE_CHOICE;
 1177           else if (value.equals("interleave"))
 1178             combine = GrammarSection.COMBINE_INTERLEAVE;
 1179           else
 1180             error("combine_attribute_bad_value", value);
 1181         }
 1182         else
 1183           super.setOtherAttribute(name, value);
 1184       }
 1185   
 1186       ParsedPattern buildPattern(List<ParsedPattern> patterns, Location loc, Annotations anno) throws SAXException {
 1187         return super.buildPattern(patterns, loc, null);
 1188       }
 1189     }
 1190   
 1191     class DefineState extends DefinitionState {
 1192       String name;
 1193   
 1194       DefineState(GrammarSection section) {
 1195         super(section);
 1196       }
 1197   
 1198       State create() {
 1199         return new DefineState(null);
 1200       }
 1201   
 1202       void setName(String name) throws SAXException {
 1203         this.name = checkNCName(name);
 1204       }
 1205   
 1206       void endAttributes() throws SAXException {
 1207         if (name == null)
 1208           error("missing_name_attribute");
 1209       }
 1210   
 1211       void sendPatternToParent(ParsedPattern p) {
 1212         if (name != null)
 1213           section.define(name, combine, p, startLocation, annotations);
 1214       }
 1215   
 1216     }
 1217   
 1218     class StartState extends DefinitionState {
 1219   
 1220       StartState(GrammarSection section) {
 1221         super(section);
 1222       }
 1223   
 1224       State create() {
 1225         return new StartState(null);
 1226       }
 1227   
 1228       void sendPatternToParent(ParsedPattern p) {
 1229         section.define(GrammarSection.START, combine, p, startLocation, annotations);
 1230       }
 1231   
 1232       State createChildState(String localName) throws SAXException {
 1233         State tem = super.createChildState(localName);
 1234         if (tem != null && childPatterns!=null)
 1235           error("start_multi_pattern");
 1236         return tem;
 1237       }
 1238   
 1239     }
 1240   
 1241     abstract class NameClassContainerState extends State {
 1242       State createChildState(String localName) throws SAXException {
 1243         State state = (State)nameClassTable.get(localName);
 1244         if (state == null) {
 1245           error("expected_name_class", localName);
 1246           return null;
 1247         }
 1248         return state.create();
 1249       }
 1250     }
 1251   
 1252     class NameClassChildState extends NameClassContainerState {
 1253       final State prevState;
 1254       final NameClassRef nameClassRef;
 1255   
 1256       State create() {
 1257         return null;
 1258       }
 1259   
 1260       NameClassChildState(State prevState, NameClassRef nameClassRef) {
 1261         this.prevState = prevState;
 1262         this.nameClassRef = nameClassRef;
 1263         setParent(prevState.parent);
 1264         this.ns = prevState.ns;
 1265       }
 1266   
 1267       void endChild(ParsedNameClass nameClass) {
 1268         nameClassRef.setNameClass(nameClass);
 1269         prevState.set();
 1270       }
 1271   
 1272       void endForeignChild(ParsedElementAnnotation ea) {
 1273         prevState.endForeignChild(ea);
 1274       }
 1275   
 1276       void end() throws SAXException {
 1277         nameClassRef.setNameClass(nameClassBuilder.makeErrorNameClass());
 1278         error("missing_name_class");
 1279         prevState.set();
 1280         prevState.end();
 1281       }
 1282     }
 1283   
 1284     abstract class NameClassBaseState extends State {
 1285   
 1286       abstract ParsedNameClass makeNameClass() throws SAXException;
 1287   
 1288       void end() throws SAXException {
 1289         parent.endChild(makeNameClass());
 1290       }
 1291     }
 1292   
 1293     class NameState extends NameClassBaseState {
 1294       final StringBuffer buf = new StringBuffer();
 1295   
 1296       State createChildState(String localName) throws SAXException {
 1297         error("expected_name", localName);
 1298         return null;
 1299       }
 1300   
 1301       State create() {
 1302         return new NameState();
 1303       }
 1304   
 1305       public void characters(char[] ch, int start, int len) {
 1306         buf.append(ch, start, len);
 1307       }
 1308   
 1309       void checkForeignElement() throws SAXException {
 1310         error("name_contains_foreign_element");
 1311       }
 1312   
 1313       ParsedNameClass makeNameClass() throws SAXException {
 1314         mergeLeadingComments();
 1315         return expandName(buf.toString().trim(), getNs(), annotations);
 1316       }
 1317   
 1318     }
 1319   
 1320     private static final int PATTERN_CONTEXT = 0;
 1321     private static final int ANY_NAME_CONTEXT = 1;
 1322     private static final int NS_NAME_CONTEXT = 2;
 1323   private SAXParseable parseable;
 1324   
 1325     class AnyNameState extends NameClassBaseState {
 1326       ParsedNameClass except = null;
 1327   
 1328       State create() {
 1329         return new AnyNameState();
 1330       }
 1331   
 1332       State createChildState(String localName) throws SAXException {
 1333         if (localName.equals("except")) {
 1334           if (except != null)
 1335             error("multiple_except");
 1336           return new NameClassChoiceState(getContext());
 1337         }
 1338         error("expected_except", localName);
 1339         return null;
 1340       }
 1341   
 1342       int getContext() {
 1343         return ANY_NAME_CONTEXT;
 1344       }
 1345   
 1346       ParsedNameClass makeNameClass() {
 1347         if (except == null)
 1348           return makeNameClassNoExcept();
 1349         else
 1350           return makeNameClassExcept(except);
 1351       }
 1352   
 1353       ParsedNameClass makeNameClassNoExcept() {
 1354         return nameClassBuilder.makeAnyName(startLocation, annotations);
 1355       }
 1356   
 1357       ParsedNameClass makeNameClassExcept(ParsedNameClass except) {
 1358         return nameClassBuilder.makeAnyName(except, startLocation, annotations);
 1359       }
 1360   
 1361       void endChild(ParsedNameClass nameClass) {
 1362         except = nameClass;
 1363       }
 1364   
 1365     }
 1366   
 1367     class NsNameState extends AnyNameState {
 1368       State create() {
 1369         return new NsNameState();
 1370       }
 1371   
 1372       ParsedNameClass makeNameClassNoExcept() {
 1373         return nameClassBuilder.makeNsName(getNs(), null, null);
 1374       }
 1375   
 1376       ParsedNameClass makeNameClassExcept(ParsedNameClass except) {
 1377         return nameClassBuilder.makeNsName(getNs(), except, null, null);
 1378       }
 1379   
 1380       int getContext() {
 1381         return NS_NAME_CONTEXT;
 1382       }
 1383   
 1384     }
 1385   
 1386     class NameClassChoiceState extends NameClassContainerState {
 1387       private ParsedNameClass[] nameClasses;
 1388       private int nNameClasses;
 1389       private int context;
 1390   
 1391       NameClassChoiceState() {
 1392         this.context = PATTERN_CONTEXT;
 1393       }
 1394   
 1395       NameClassChoiceState(int context) {
 1396         this.context = context;
 1397       }
 1398   
 1399       void setParent(State parent) {
 1400         super.setParent(parent);
 1401         if (parent instanceof NameClassChoiceState)
 1402           this.context = ((NameClassChoiceState)parent).context;
 1403       }
 1404   
 1405       State create() {
 1406         return new NameClassChoiceState();
 1407       }
 1408   
 1409       State createChildState(String localName) throws SAXException {
 1410         if (localName.equals("anyName")) {
 1411           if (context >= ANY_NAME_CONTEXT) {
 1412             error(context == ANY_NAME_CONTEXT
 1413                   ? "any_name_except_contains_any_name"
 1414                   : "ns_name_except_contains_any_name");
 1415             return null;
 1416           }
 1417         }
 1418         else if (localName.equals("nsName")) {
 1419           if (context == NS_NAME_CONTEXT) {
 1420             error("ns_name_except_contains_ns_name");
 1421             return null;
 1422           }
 1423         }
 1424         return super.createChildState(localName);
 1425       }
 1426   
 1427       void endChild(ParsedNameClass nc) {
 1428         if (nameClasses == null)
 1429           nameClasses = new ParsedNameClass[INIT_CHILD_ALLOC];
 1430         else if (nNameClasses >= nameClasses.length) {
 1431           ParsedNameClass[] newNameClasses = new ParsedNameClass[nameClasses.length * 2];
 1432           System.arraycopy(nameClasses, 0, newNameClasses, 0, nameClasses.length);
 1433           nameClasses = newNameClasses;
 1434         }
 1435         nameClasses[nNameClasses++] = nc;
 1436       }
 1437   
 1438       void endForeignChild(ParsedElementAnnotation ea) {
 1439         if (nNameClasses == 0)
 1440           super.endForeignChild(ea);
 1441         else
 1442           nameClasses[nNameClasses - 1] = nameClassBuilder.annotateAfter(nameClasses[nNameClasses - 1], ea);
 1443       }
 1444   
 1445       void end() throws SAXException {
 1446         if (nNameClasses == 0) {
 1447           error("missing_name_class");
 1448           parent.endChild(nameClassBuilder.makeErrorNameClass());
 1449           return;
 1450         }
 1451         if (comments != null) {
 1452           nameClasses[nNameClasses - 1] = nameClassBuilder.commentAfter(nameClasses[nNameClasses - 1], comments);
 1453           comments = null;
 1454         }
 1455         parent.endChild(nameClassBuilder.makeChoice(Arrays.asList(nameClasses).subList(0,nNameClasses), startLocation, annotations));
 1456       }
 1457     }
 1458   
 1459     private void initPatternTable() {
 1460       patternTable = new Hashtable();
 1461       patternTable.put("zeroOrMore", new ZeroOrMoreState());
 1462       patternTable.put("oneOrMore", new OneOrMoreState());
 1463       patternTable.put("optional", new OptionalState());
 1464       patternTable.put("list", new ListState());
 1465       patternTable.put("choice", new ChoiceState());
 1466       patternTable.put("interleave", new InterleaveState());
 1467       patternTable.put("group", new GroupState());
 1468       patternTable.put("mixed", new MixedState());
 1469       patternTable.put("element", new ElementState());
 1470       patternTable.put("attribute", new AttributeState());
 1471       patternTable.put("empty", new EmptyState());
 1472       patternTable.put("text", new TextState());
 1473       patternTable.put("value", new ValueState());
 1474       patternTable.put("data", new DataState());
 1475       patternTable.put("notAllowed", new NotAllowedState());
 1476       patternTable.put("grammar", new GrammarState());
 1477       patternTable.put("ref", new RefState());
 1478       patternTable.put("parentRef", new ParentRefState());
 1479       patternTable.put("externalRef", new ExternalRefState());
 1480     }
 1481   
 1482     private void initNameClassTable() {
 1483       nameClassTable = new Hashtable();
 1484       nameClassTable.put("name", new NameState());
 1485       nameClassTable.put("anyName", new AnyNameState());
 1486       nameClassTable.put("nsName", new NsNameState());
 1487       nameClassTable.put("choice", new NameClassChoiceState());
 1488     }
 1489   
 1490     public ParsedPattern getParsedPattern() throws IllegalSchemaException {
 1491       if (hadError)
 1492         throw new IllegalSchemaException();
 1493       return startPattern;
 1494     }
 1495   
 1496     private void error(String key) throws SAXException {
 1497       error(key, locator);
 1498     }
 1499   
 1500     private void error(String key, String arg) throws SAXException {
 1501       error(key, arg, locator);
 1502     }
 1503   
 1504     void error(String key, String arg1, String arg2) throws SAXException {
 1505       error(key, arg1, arg2, locator);
 1506     }
 1507   
 1508     private void error(String key, Locator loc) throws SAXException {
 1509       error(new SAXParseException(localizer.message(key), loc));
 1510     }
 1511   
 1512     private void error(String key, String arg, Locator loc) throws SAXException {
 1513       error(new SAXParseException(localizer.message(key, arg), loc));
 1514     }
 1515   
 1516     private void error(String key, String arg1, String arg2, Locator loc)
 1517       throws SAXException {
 1518       error(new SAXParseException(localizer.message(key, arg1, arg2), loc));
 1519     }
 1520   
 1521     private void error(SAXParseException e) throws SAXException {
 1522       hadError = true;
 1523       if (eh != null)
 1524         eh.error(e);
 1525     }
 1526   
 1527     void warning(String key) throws SAXException {
 1528       warning(key, locator);
 1529     }
 1530   
 1531     private void warning(String key, String arg) throws SAXException {
 1532       warning(key, arg, locator);
 1533     }
 1534   
 1535     private void warning(String key, String arg1, String arg2) throws SAXException {
 1536       warning(key, arg1, arg2, locator);
 1537     }
 1538   
 1539     private void warning(String key, Locator loc) throws SAXException {
 1540       warning(new SAXParseException(localizer.message(key), loc));
 1541     }
 1542   
 1543     private void warning(String key, String arg, Locator loc) throws SAXException {
 1544       warning(new SAXParseException(localizer.message(key, arg), loc));
 1545     }
 1546   
 1547     private void warning(String key, String arg1, String arg2, Locator loc)
 1548       throws SAXException {
 1549       warning(new SAXParseException(localizer.message(key, arg1, arg2), loc));
 1550     }
 1551   
 1552     private void warning(SAXParseException e) throws SAXException {
 1553       if (eh != null)
 1554         eh.warning(e);
 1555     }
 1556   
 1557     SchemaParser(SAXParseable parseable,
 1558                  XMLReader xr,
 1559                  ErrorHandler eh,
 1560                  SchemaBuilder schemaBuilder,
 1561                  IncludedGrammar grammar,
 1562                  Scope scope,
 1563                  String inheritedNs) throws SAXException {
 1564       this.parseable = parseable;
 1565       this.xr = xr;
 1566       this.eh = eh;
 1567       this.schemaBuilder = schemaBuilder;
 1568       this.nameClassBuilder = schemaBuilder.getNameClassBuilder();
 1569       if (eh != null)
 1570         xr.setErrorHandler(eh);
 1571       xr.setDTDHandler(context);
 1572       if (schemaBuilder.usesComments()) {
 1573         try {
 1574           xr.setProperty("http://xml.org/sax/properties/lexical-handler", new LexicalHandlerImpl());
 1575         }
 1576         catch (SAXNotRecognizedException e) {
 1577           warning("no_comment_support", xr.getClass().getName());
 1578         }
 1579         catch (SAXNotSupportedException e) {
 1580           warning("no_comment_support", xr.getClass().getName());
 1581         }
 1582       }
 1583       initPatternTable();
 1584       initNameClassTable();
 1585       new RootState(grammar, scope, inheritedNs).set();
 1586     }
 1587   
 1588   
 1589     private Context getContext() {
 1590       return context;
 1591     }
 1592   
 1593     class LexicalHandlerImpl extends AbstractLexicalHandler {
 1594       private boolean inDtd = false;
 1595   
 1596       public void startDTD(String s, String s1, String s2) throws SAXException {
 1597         inDtd = true;
 1598       }
 1599   
 1600       public void endDTD() throws SAXException {
 1601         inDtd = false;
 1602       }
 1603   
 1604       public void comment(char[] chars, int start, int length) throws SAXException {
 1605         if (!inDtd)
 1606           ((CommentHandler)xr.getContentHandler()).comment(new String(chars, start, length));
 1607       }
 1608     }
 1609   
 1610     private ParsedNameClass expandName(String name, String ns, Annotations anno) throws SAXException {
 1611       int ic = name.indexOf(':');
 1612       if (ic == -1)
 1613         return nameClassBuilder.makeName(ns, checkNCName(name), null, null, anno);
 1614       String prefix = checkNCName(name.substring(0, ic));
 1615       String localName = checkNCName(name.substring(ic + 1));
 1616       for (PrefixMapping tem = context.prefixMapping; tem != null; tem = tem.next)
 1617         if (tem.prefix.equals(prefix))
 1618           return nameClassBuilder.makeName(tem.uri, localName, prefix, null, anno);
 1619       error("undefined_prefix", prefix);
 1620       return nameClassBuilder.makeName("", localName, null, null, anno);
 1621     }
 1622   
 1623     private String findPrefix(String qName, String uri) {
 1624       String prefix = null;
 1625       if (qName == null || qName.equals("")) {
 1626         for (PrefixMapping p = context.prefixMapping; p != null; p = p.next)
 1627           if (p.uri.equals(uri)) {
 1628             prefix = p.prefix;
 1629             break;
 1630           }
 1631       }
 1632       else {
 1633         int off = qName.indexOf(':');
 1634         if (off > 0)
 1635           prefix = qName.substring(0, off);
 1636       }
 1637       return prefix;
 1638     }
 1639     private String checkNCName(String str) throws SAXException {
 1640       if (!Naming.isNcname(str))
 1641         error("invalid_ncname", str);
 1642       return str;
 1643     }
 1644   
 1645     private String resolve(String systemId) throws SAXException {
 1646       if (Uri.hasFragmentId(systemId))
 1647         error("href_fragment_id");
 1648       systemId = Uri.escapeDisallowedChars(systemId);
 1649       return Uri.resolve(xmlBaseHandler.getBaseUri(), systemId);
 1650     }
 1651   
 1652     private Location makeLocation() {
 1653       if (locator == null)
 1654         return null;
 1655       return schemaBuilder.makeLocation(locator.getSystemId(),
 1656                                         locator.getLineNumber(),
 1657                                         locator.getColumnNumber());
 1658     }
 1659   
 1660     private void checkUri(String s) throws SAXException {
 1661       if (!Uri.isValid(s))
 1662         error("invalid_uri", s);
 1663     }
 1664   }

Save This Page
Home » openjdk-7 » com.sun.xml.internal.rngom » parse » xml » [javadoc | source]