KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thaiopensource > relaxng > parse > sax > SchemaParser


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