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