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

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

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

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

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

mercurial