src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/sax/SAXBufferProcessor.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.xml.internal.stream.buffer.sax;
aoqi@0 27
aoqi@0 28 import com.sun.xml.internal.stream.buffer.AbstractProcessor;
aoqi@0 29 import com.sun.xml.internal.stream.buffer.AttributesHolder;
aoqi@0 30 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
aoqi@0 31 import org.xml.sax.ContentHandler;
aoqi@0 32 import org.xml.sax.DTDHandler;
aoqi@0 33 import org.xml.sax.EntityResolver;
aoqi@0 34 import org.xml.sax.ErrorHandler;
aoqi@0 35 import org.xml.sax.InputSource;
aoqi@0 36 import org.xml.sax.SAXException;
aoqi@0 37 import org.xml.sax.SAXNotRecognizedException;
aoqi@0 38 import org.xml.sax.SAXNotSupportedException;
aoqi@0 39 import org.xml.sax.SAXParseException;
aoqi@0 40 import org.xml.sax.XMLReader;
aoqi@0 41 import org.xml.sax.ext.LexicalHandler;
aoqi@0 42 import org.xml.sax.helpers.LocatorImpl;
aoqi@0 43
aoqi@0 44 import javax.xml.XMLConstants;
aoqi@0 45 import java.io.IOException;
aoqi@0 46 import java.util.Collections;
aoqi@0 47 import java.util.HashSet;
aoqi@0 48 import java.util.Map;
aoqi@0 49 import java.util.Set;
aoqi@0 50
aoqi@0 51 /**
aoqi@0 52 * A processor of a {@link XMLStreamBuffer} that that reads the XML infoset as
aoqi@0 53 * {@link XMLReader}.
aoqi@0 54 */
aoqi@0 55 public class SAXBufferProcessor extends AbstractProcessor implements XMLReader {
aoqi@0 56 /**
aoqi@0 57 * Reference to entity resolver.
aoqi@0 58 */
aoqi@0 59 protected EntityResolver _entityResolver = DEFAULT_LEXICAL_HANDLER;
aoqi@0 60
aoqi@0 61 /**
aoqi@0 62 * Reference to dtd handler.
aoqi@0 63 */
aoqi@0 64 protected DTDHandler _dtdHandler = DEFAULT_LEXICAL_HANDLER;
aoqi@0 65
aoqi@0 66 /**
aoqi@0 67 * Reference to content handler.
aoqi@0 68 */
aoqi@0 69 protected ContentHandler _contentHandler = DEFAULT_LEXICAL_HANDLER;
aoqi@0 70
aoqi@0 71 /**
aoqi@0 72 * Reference to error handler.
aoqi@0 73 */
aoqi@0 74 protected ErrorHandler _errorHandler = DEFAULT_LEXICAL_HANDLER;
aoqi@0 75
aoqi@0 76 /**
aoqi@0 77 * Reference to lexical handler.
aoqi@0 78 */
aoqi@0 79 protected LexicalHandler _lexicalHandler = DEFAULT_LEXICAL_HANDLER;
aoqi@0 80
aoqi@0 81 /**
aoqi@0 82 * SAX Namespace attributes features
aoqi@0 83 */
aoqi@0 84 protected boolean _namespacePrefixesFeature = false;
aoqi@0 85
aoqi@0 86 protected AttributesHolder _attributes = new AttributesHolder();
aoqi@0 87
aoqi@0 88 protected String[] _namespacePrefixes = new String[16];
aoqi@0 89 protected int _namespacePrefixesIndex;
aoqi@0 90
aoqi@0 91 protected int[] _namespaceAttributesStartingStack = new int[16];
aoqi@0 92 protected int[] _namespaceAttributesStack = new int[16];
aoqi@0 93 protected int _namespaceAttributesStackIndex;
aoqi@0 94
aoqi@0 95 public SAXBufferProcessor() {
aoqi@0 96 }
aoqi@0 97
aoqi@0 98 /**
aoqi@0 99 * @deprecated
aoqi@0 100 * Use {@link #SAXBufferProcessor(XMLStreamBuffer, boolean)}
aoqi@0 101 */
aoqi@0 102 public SAXBufferProcessor(XMLStreamBuffer buffer) {
aoqi@0 103 setXMLStreamBuffer(buffer);
aoqi@0 104 }
aoqi@0 105
aoqi@0 106 /**
aoqi@0 107 * @param produceFragmentEvent
aoqi@0 108 * True to generate fragment SAX events without start/endDocument.
aoqi@0 109 * False to generate a full document SAX events.
aoqi@0 110 */
aoqi@0 111 public SAXBufferProcessor(XMLStreamBuffer buffer, boolean produceFragmentEvent) {
aoqi@0 112 setXMLStreamBuffer(buffer,produceFragmentEvent);
aoqi@0 113 }
aoqi@0 114
aoqi@0 115 public boolean getFeature(String name)
aoqi@0 116 throws SAXNotRecognizedException, SAXNotSupportedException {
aoqi@0 117 if (name.equals(Features.NAMESPACES_FEATURE)) {
aoqi@0 118 return true;
aoqi@0 119 } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
aoqi@0 120 return _namespacePrefixesFeature;
aoqi@0 121 } else if (name.equals(Features.EXTERNAL_GENERAL_ENTITIES)) {
aoqi@0 122 return true;
aoqi@0 123 } else if (name.equals(Features.EXTERNAL_PARAMETER_ENTITIES)) {
aoqi@0 124 return true;
aoqi@0 125 } else if (name.equals(Features.STRING_INTERNING_FEATURE)) {
aoqi@0 126 return _stringInterningFeature;
aoqi@0 127 } else {
aoqi@0 128 throw new SAXNotRecognizedException(
aoqi@0 129 "Feature not supported: " + name);
aoqi@0 130 }
aoqi@0 131 }
aoqi@0 132
aoqi@0 133 public void setFeature(String name, boolean value)
aoqi@0 134 throws SAXNotRecognizedException, SAXNotSupportedException {
aoqi@0 135 if (name.equals(Features.NAMESPACES_FEATURE)) {
aoqi@0 136 if (!value) {
aoqi@0 137 throw new SAXNotSupportedException(name + ":" + value);
aoqi@0 138 }
aoqi@0 139 } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
aoqi@0 140 _namespacePrefixesFeature = value;
aoqi@0 141 } else if (name.equals(Features.EXTERNAL_GENERAL_ENTITIES)) {
aoqi@0 142 // ignore
aoqi@0 143 } else if (name.equals(Features.EXTERNAL_PARAMETER_ENTITIES)) {
aoqi@0 144 // ignore
aoqi@0 145 } else if (name.equals(Features.STRING_INTERNING_FEATURE)) {
aoqi@0 146 if (value != _stringInterningFeature) {
aoqi@0 147 throw new SAXNotSupportedException(name + ":" + value);
aoqi@0 148 }
aoqi@0 149 } else {
aoqi@0 150 throw new SAXNotRecognizedException(
aoqi@0 151 "Feature not supported: " + name);
aoqi@0 152 }
aoqi@0 153 }
aoqi@0 154
aoqi@0 155 public Object getProperty(String name)
aoqi@0 156 throws SAXNotRecognizedException, SAXNotSupportedException {
aoqi@0 157 if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
aoqi@0 158 return getLexicalHandler();
aoqi@0 159 } else {
aoqi@0 160 throw new SAXNotRecognizedException("Property not recognized: " + name);
aoqi@0 161 }
aoqi@0 162 }
aoqi@0 163
aoqi@0 164 public void setProperty(String name, Object value)
aoqi@0 165 throws SAXNotRecognizedException, SAXNotSupportedException {
aoqi@0 166 if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
aoqi@0 167 if (value instanceof LexicalHandler) {
aoqi@0 168 setLexicalHandler((LexicalHandler)value);
aoqi@0 169 } else {
aoqi@0 170 throw new SAXNotSupportedException(Properties.LEXICAL_HANDLER_PROPERTY);
aoqi@0 171 }
aoqi@0 172 } else {
aoqi@0 173 throw new SAXNotRecognizedException("Property not recognized: " + name);
aoqi@0 174 }
aoqi@0 175 }
aoqi@0 176
aoqi@0 177 public void setEntityResolver(EntityResolver resolver) {
aoqi@0 178 _entityResolver = resolver;
aoqi@0 179 }
aoqi@0 180
aoqi@0 181 public EntityResolver getEntityResolver() {
aoqi@0 182 return _entityResolver;
aoqi@0 183 }
aoqi@0 184
aoqi@0 185 public void setDTDHandler(DTDHandler handler) {
aoqi@0 186 _dtdHandler = handler;
aoqi@0 187 }
aoqi@0 188
aoqi@0 189 public DTDHandler getDTDHandler() {
aoqi@0 190 return _dtdHandler;
aoqi@0 191 }
aoqi@0 192
aoqi@0 193 public void setContentHandler(ContentHandler handler) {
aoqi@0 194 _contentHandler = handler;
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 public ContentHandler getContentHandler() {
aoqi@0 198 return _contentHandler;
aoqi@0 199 }
aoqi@0 200
aoqi@0 201 public void setErrorHandler(ErrorHandler handler) {
aoqi@0 202 _errorHandler = handler;
aoqi@0 203 }
aoqi@0 204
aoqi@0 205 public ErrorHandler getErrorHandler() {
aoqi@0 206 return _errorHandler;
aoqi@0 207 }
aoqi@0 208
aoqi@0 209 public void setLexicalHandler(LexicalHandler handler) {
aoqi@0 210 _lexicalHandler = handler;
aoqi@0 211 }
aoqi@0 212
aoqi@0 213 public LexicalHandler getLexicalHandler() {
aoqi@0 214 return _lexicalHandler;
aoqi@0 215 }
aoqi@0 216
aoqi@0 217 public void parse(InputSource input) throws IOException, SAXException {
aoqi@0 218 // InputSource is ignored
aoqi@0 219 process();
aoqi@0 220 }
aoqi@0 221
aoqi@0 222 public void parse(String systemId) throws IOException, SAXException {
aoqi@0 223 // systemId is ignored
aoqi@0 224 process();
aoqi@0 225 }
aoqi@0 226
aoqi@0 227 /**
aoqi@0 228 * Short-hand for {@link #setXMLStreamBuffer(XMLStreamBuffer)} then {@link #process()}.
aoqi@0 229 *
aoqi@0 230 * @deprecated
aoqi@0 231 * Use {@link #process(XMLStreamBuffer, boolean)}
aoqi@0 232 */
aoqi@0 233 public final void process(XMLStreamBuffer buffer) throws SAXException {
aoqi@0 234 setXMLStreamBuffer(buffer);
aoqi@0 235 process();
aoqi@0 236 }
aoqi@0 237
aoqi@0 238 /**
aoqi@0 239 * Short-hand for {@link #setXMLStreamBuffer(XMLStreamBuffer,boolean)} then {@link #process()}.
aoqi@0 240 *
aoqi@0 241 * @param produceFragmentEvent
aoqi@0 242 * True to generate fragment SAX events without start/endDocument.
aoqi@0 243 * False to generate a full document SAX events.
aoqi@0 244 */
aoqi@0 245 public final void process(XMLStreamBuffer buffer, boolean produceFragmentEvent) throws SAXException {
aoqi@0 246 setXMLStreamBuffer(buffer);
aoqi@0 247 process();
aoqi@0 248 }
aoqi@0 249
aoqi@0 250 /**
aoqi@0 251 * Resets the parser to read from the beginning of the given {@link XMLStreamBuffer}.
aoqi@0 252 *
aoqi@0 253 * @deprecated
aoqi@0 254 * Use {@link #setXMLStreamBuffer(XMLStreamBuffer, boolean)}.
aoqi@0 255 */
aoqi@0 256 public void setXMLStreamBuffer(XMLStreamBuffer buffer) {
aoqi@0 257 setBuffer(buffer);
aoqi@0 258 }
aoqi@0 259
aoqi@0 260 /**
aoqi@0 261 * Resets the parser to read from the beginning of the given {@link XMLStreamBuffer}.
aoqi@0 262 *
aoqi@0 263 * @param produceFragmentEvent
aoqi@0 264 * True to generate fragment SAX events without start/endDocument.
aoqi@0 265 * False to generate a full document SAX events.
aoqi@0 266 */
aoqi@0 267 public void setXMLStreamBuffer(XMLStreamBuffer buffer, boolean produceFragmentEvent) {
aoqi@0 268 if(!produceFragmentEvent && _treeCount>1)
aoqi@0 269 throw new IllegalStateException("Can't write a forest to a full XML infoset");
aoqi@0 270 setBuffer(buffer,produceFragmentEvent);
aoqi@0 271 }
aoqi@0 272
aoqi@0 273 /**
aoqi@0 274 * Parse the sub-tree (or a whole document) that {@link XMLStreamBuffer}
aoqi@0 275 * points to, and sends events to handlers.
aoqi@0 276 *
aoqi@0 277 * <p>
aoqi@0 278 * TODO:
aoqi@0 279 * We probably need two modes for a sub-tree event generation. One for
aoqi@0 280 * firing a sub-tree as if it's a whole document (in which case start/endDocument
aoqi@0 281 * and appropriate additional namespace bindings are necessary), and the other
aoqi@0 282 * mode for firing a subtree as a subtree, like it does today.
aoqi@0 283 * A stream buffer SAX feature could be used to specify this.
aoqi@0 284 *
aoqi@0 285 * @throws SAXException
aoqi@0 286 * Follow the same semantics as {@link XMLReader#parse(InputSource)}.
aoqi@0 287 */
aoqi@0 288 public final void process() throws SAXException {
aoqi@0 289 if(!_fragmentMode) {
aoqi@0 290 LocatorImpl nullLocator = new LocatorImpl();
aoqi@0 291 nullLocator.setSystemId(_buffer.getSystemId());
aoqi@0 292 nullLocator.setLineNumber(-1);
aoqi@0 293 nullLocator.setColumnNumber(-1);
aoqi@0 294 _contentHandler.setDocumentLocator(nullLocator);
aoqi@0 295
aoqi@0 296 _contentHandler.startDocument();
aoqi@0 297 // TODO: if we are writing a fragment stream buffer as a full XML document,
aoqi@0 298 // we need to declare in-scope namespaces as if they are on the root element.
aoqi@0 299 }
aoqi@0 300
aoqi@0 301 while (_treeCount>0) {
aoqi@0 302 final int item = readEiiState();
aoqi@0 303 switch(item) {
aoqi@0 304 case STATE_DOCUMENT:
aoqi@0 305 processDocument();
aoqi@0 306 _treeCount--;
aoqi@0 307 break;
aoqi@0 308 case STATE_END:
aoqi@0 309 // Empty buffer
aoqi@0 310 return;
aoqi@0 311 case STATE_ELEMENT_U_LN_QN:
aoqi@0 312 processElement(readStructureString(), readStructureString(), readStructureString(), isInscope());
aoqi@0 313 _treeCount--;
aoqi@0 314 break;
aoqi@0 315 case STATE_ELEMENT_P_U_LN:
aoqi@0 316 {
aoqi@0 317 final String prefix = readStructureString();
aoqi@0 318 final String uri = readStructureString();
aoqi@0 319 final String localName = readStructureString();
aoqi@0 320 processElement(uri, localName, getQName(prefix, localName),isInscope());
aoqi@0 321 _treeCount--;
aoqi@0 322 break;
aoqi@0 323 }
aoqi@0 324 case STATE_ELEMENT_U_LN: {
aoqi@0 325 final String uri = readStructureString();
aoqi@0 326 final String localName = readStructureString();
aoqi@0 327 processElement(uri, localName, localName,isInscope());
aoqi@0 328 _treeCount--;
aoqi@0 329 break;
aoqi@0 330 }
aoqi@0 331 case STATE_ELEMENT_LN:
aoqi@0 332 {
aoqi@0 333 final String localName = readStructureString();
aoqi@0 334 processElement("", localName, localName,isInscope());
aoqi@0 335 _treeCount--;
aoqi@0 336 break;
aoqi@0 337 }
aoqi@0 338 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
aoqi@0 339 processCommentAsCharArraySmall();
aoqi@0 340 break;
aoqi@0 341 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
aoqi@0 342 processCommentAsCharArrayMedium();
aoqi@0 343 break;
aoqi@0 344 case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
aoqi@0 345 processCommentAsCharArrayCopy();
aoqi@0 346 break;
aoqi@0 347 case STATE_COMMENT_AS_STRING:
aoqi@0 348 processComment(readContentString());
aoqi@0 349 break;
aoqi@0 350 case STATE_PROCESSING_INSTRUCTION:
aoqi@0 351 processProcessingInstruction(readStructureString(), readStructureString());
aoqi@0 352 break;
aoqi@0 353 default:
aoqi@0 354 throw reportFatalError("Illegal state for DIIs: "+item);
aoqi@0 355 }
aoqi@0 356 }
aoqi@0 357
aoqi@0 358 if(!_fragmentMode)
aoqi@0 359 _contentHandler.endDocument();
aoqi@0 360 }
aoqi@0 361
aoqi@0 362 private void processCommentAsCharArraySmall() throws SAXException {
aoqi@0 363 final int length = readStructure();
aoqi@0 364 final int start = readContentCharactersBuffer(length);
aoqi@0 365 processComment(_contentCharactersBuffer, start, length);
aoqi@0 366 }
aoqi@0 367
aoqi@0 368 /**
aoqi@0 369 * Report a fatal error and abort.
aoqi@0 370 *
aoqi@0 371 * This is necessary to follow the SAX semantics of error handling.
aoqi@0 372 */
aoqi@0 373 private SAXParseException reportFatalError(String msg) throws SAXException {
aoqi@0 374 SAXParseException spe = new SAXParseException(msg, null);
aoqi@0 375 if(_errorHandler!=null)
aoqi@0 376 _errorHandler.fatalError(spe);
aoqi@0 377 return spe;
aoqi@0 378 }
aoqi@0 379
aoqi@0 380 private boolean isInscope() {
aoqi@0 381 return _buffer.getInscopeNamespaces().size() > 0;
aoqi@0 382 }
aoqi@0 383
aoqi@0 384 private void processDocument() throws SAXException {
aoqi@0 385 while(true) {
aoqi@0 386 int item = readEiiState();
aoqi@0 387 switch(item) {
aoqi@0 388 case STATE_ELEMENT_U_LN_QN:
aoqi@0 389 processElement(readStructureString(), readStructureString(), readStructureString(),isInscope());
aoqi@0 390 break;
aoqi@0 391 case STATE_ELEMENT_P_U_LN:
aoqi@0 392 {
aoqi@0 393 final String prefix = readStructureString();
aoqi@0 394 final String uri = readStructureString();
aoqi@0 395 final String localName = readStructureString();
aoqi@0 396 processElement(uri, localName, getQName(prefix, localName),isInscope());
aoqi@0 397 break;
aoqi@0 398 }
aoqi@0 399 case STATE_ELEMENT_U_LN: {
aoqi@0 400 final String uri = readStructureString();
aoqi@0 401 final String localName = readStructureString();
aoqi@0 402 processElement(uri, localName, localName,isInscope());
aoqi@0 403 break;
aoqi@0 404 }
aoqi@0 405 case STATE_ELEMENT_LN:
aoqi@0 406 {
aoqi@0 407 final String localName = readStructureString();
aoqi@0 408 processElement("", localName, localName,isInscope());
aoqi@0 409 break;
aoqi@0 410 }
aoqi@0 411 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
aoqi@0 412 processCommentAsCharArraySmall();
aoqi@0 413 break;
aoqi@0 414 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
aoqi@0 415 processCommentAsCharArrayMedium();
aoqi@0 416 break;
aoqi@0 417 case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
aoqi@0 418 processCommentAsCharArrayCopy();
aoqi@0 419 break;
aoqi@0 420 case STATE_COMMENT_AS_STRING:
aoqi@0 421 processComment(readContentString());
aoqi@0 422 break;
aoqi@0 423 case STATE_PROCESSING_INSTRUCTION:
aoqi@0 424 processProcessingInstruction(readStructureString(), readStructureString());
aoqi@0 425 break;
aoqi@0 426 case STATE_END:
aoqi@0 427 return;
aoqi@0 428 default:
aoqi@0 429 throw reportFatalError("Illegal state for child of DII: "+item);
aoqi@0 430 }
aoqi@0 431 }
aoqi@0 432 }
aoqi@0 433
aoqi@0 434 protected void processElement(String uri, String localName, String qName, boolean inscope) throws SAXException {
aoqi@0 435 boolean hasAttributes = false;
aoqi@0 436 boolean hasNamespaceAttributes = false;
aoqi@0 437 int item = peekStructure();
aoqi@0 438 Set<String> prefixSet = inscope ? new HashSet<String>() : Collections.<String>emptySet();
aoqi@0 439 if ((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE) {
aoqi@0 440 cacheNamespacePrefixStartingIndex();
aoqi@0 441 hasNamespaceAttributes = true;
aoqi@0 442 item = processNamespaceAttributes(item, inscope, prefixSet);
aoqi@0 443 }
aoqi@0 444 if (inscope) {
aoqi@0 445 readInscopeNamespaces(prefixSet);
aoqi@0 446 }
aoqi@0 447
aoqi@0 448 if ((item & TYPE_MASK) == T_ATTRIBUTE) {
aoqi@0 449 hasAttributes = true;
aoqi@0 450 processAttributes(item);
aoqi@0 451 }
aoqi@0 452
aoqi@0 453 _contentHandler.startElement(uri, localName, qName, _attributes);
aoqi@0 454
aoqi@0 455 if (hasAttributes) {
aoqi@0 456 _attributes.clear();
aoqi@0 457 }
aoqi@0 458
aoqi@0 459 do {
aoqi@0 460 item = readEiiState();
aoqi@0 461 switch(item) {
aoqi@0 462 case STATE_ELEMENT_U_LN_QN:
aoqi@0 463 processElement(readStructureString(), readStructureString(), readStructureString(), false);
aoqi@0 464 break;
aoqi@0 465 case STATE_ELEMENT_P_U_LN:
aoqi@0 466 {
aoqi@0 467 final String p = readStructureString();
aoqi@0 468 final String u = readStructureString();
aoqi@0 469 final String ln = readStructureString();
aoqi@0 470 processElement(u, ln, getQName(p, ln),false);
aoqi@0 471 break;
aoqi@0 472 }
aoqi@0 473 case STATE_ELEMENT_U_LN: {
aoqi@0 474 final String u = readStructureString();
aoqi@0 475 final String ln = readStructureString();
aoqi@0 476 processElement(u, ln, ln,false);
aoqi@0 477 break;
aoqi@0 478 }
aoqi@0 479 case STATE_ELEMENT_LN: {
aoqi@0 480 final String ln = readStructureString();
aoqi@0 481 processElement("", ln, ln,false);
aoqi@0 482 break;
aoqi@0 483 }
aoqi@0 484 case STATE_TEXT_AS_CHAR_ARRAY_SMALL:
aoqi@0 485 {
aoqi@0 486 final int length = readStructure();
aoqi@0 487 int start = readContentCharactersBuffer(length);
aoqi@0 488 _contentHandler.characters(_contentCharactersBuffer, start, length);
aoqi@0 489 break;
aoqi@0 490 }
aoqi@0 491 case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM:
aoqi@0 492 {
aoqi@0 493 final int length = readStructure16();
aoqi@0 494 int start = readContentCharactersBuffer(length);
aoqi@0 495 _contentHandler.characters(_contentCharactersBuffer, start, length);
aoqi@0 496 break;
aoqi@0 497 }
aoqi@0 498 case STATE_TEXT_AS_CHAR_ARRAY_COPY:
aoqi@0 499 {
aoqi@0 500 final char[] ch = readContentCharactersCopy();
aoqi@0 501
aoqi@0 502 _contentHandler.characters(ch, 0, ch.length);
aoqi@0 503 break;
aoqi@0 504 }
aoqi@0 505 case STATE_TEXT_AS_STRING:
aoqi@0 506 {
aoqi@0 507 final String s = readContentString();
aoqi@0 508 _contentHandler.characters(s.toCharArray(), 0, s.length());
aoqi@0 509 break;
aoqi@0 510 }
aoqi@0 511 case STATE_TEXT_AS_OBJECT:
aoqi@0 512 {
aoqi@0 513 final CharSequence c = (CharSequence)readContentObject();
aoqi@0 514 final String s = c.toString();
aoqi@0 515 _contentHandler.characters(s.toCharArray(), 0, s.length());
aoqi@0 516 break;
aoqi@0 517 }
aoqi@0 518 case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
aoqi@0 519 processCommentAsCharArraySmall();
aoqi@0 520 break;
aoqi@0 521 case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
aoqi@0 522 processCommentAsCharArrayMedium();
aoqi@0 523 break;
aoqi@0 524 case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
aoqi@0 525 processCommentAsCharArrayCopy();
aoqi@0 526 break;
aoqi@0 527 case T_COMMENT_AS_STRING:
aoqi@0 528 processComment(readContentString());
aoqi@0 529 break;
aoqi@0 530 case STATE_PROCESSING_INSTRUCTION:
aoqi@0 531 processProcessingInstruction(readStructureString(), readStructureString());
aoqi@0 532 break;
aoqi@0 533 case STATE_END:
aoqi@0 534 break;
aoqi@0 535 default:
aoqi@0 536 throw reportFatalError("Illegal state for child of EII: "+item);
aoqi@0 537 }
aoqi@0 538 } while(item != STATE_END);
aoqi@0 539
aoqi@0 540 _contentHandler.endElement(uri, localName, qName);
aoqi@0 541
aoqi@0 542 if (hasNamespaceAttributes) {
aoqi@0 543 processEndPrefixMapping();
aoqi@0 544 }
aoqi@0 545 }
aoqi@0 546
aoqi@0 547 private void readInscopeNamespaces(Set<String> prefixSet) throws SAXException {
aoqi@0 548 for (Map.Entry<String, String> e : _buffer.getInscopeNamespaces().entrySet()) {
aoqi@0 549 String key = fixNull(e.getKey());
aoqi@0 550 // If the prefix is already written, do not write the prefix
aoqi@0 551 if (!prefixSet.contains(key)) {
aoqi@0 552 processNamespaceAttribute(key,e.getValue());
aoqi@0 553 }
aoqi@0 554 }
aoqi@0 555
aoqi@0 556 }
aoqi@0 557
aoqi@0 558 private static String fixNull(String s) {
aoqi@0 559 if (s == null) return "";
aoqi@0 560 else return s;
aoqi@0 561 }
aoqi@0 562 private void processCommentAsCharArrayCopy() throws SAXException {
aoqi@0 563 final char[] ch = readContentCharactersCopy();
aoqi@0 564 processComment(ch, 0, ch.length);
aoqi@0 565 }
aoqi@0 566
aoqi@0 567 private void processCommentAsCharArrayMedium() throws SAXException {
aoqi@0 568 final int length = readStructure16();
aoqi@0 569 final int start = readContentCharactersBuffer(length);
aoqi@0 570 processComment(_contentCharactersBuffer, start, length);
aoqi@0 571 }
aoqi@0 572
aoqi@0 573 private void processEndPrefixMapping() throws SAXException {
aoqi@0 574 final int end = _namespaceAttributesStack[--_namespaceAttributesStackIndex];
aoqi@0 575 // final int start = (_namespaceAttributesStackIndex > 0) ? _namespaceAttributesStack[_namespaceAttributesStackIndex] : 0;
aoqi@0 576 final int start = (_namespaceAttributesStackIndex >= 0) ? _namespaceAttributesStartingStack[_namespaceAttributesStackIndex] : 0;
aoqi@0 577
aoqi@0 578 for (int i = end - 1; i >= start; i--) {
aoqi@0 579 _contentHandler.endPrefixMapping(_namespacePrefixes[i]);
aoqi@0 580 }
aoqi@0 581 _namespacePrefixesIndex = start;
aoqi@0 582 }
aoqi@0 583
aoqi@0 584 private int processNamespaceAttributes(int item,boolean collectPrefixes, Set<String> prefixSet) throws SAXException {
aoqi@0 585 do {
aoqi@0 586 String prefix;
aoqi@0 587 switch(getNIIState(item)) {
aoqi@0 588 case STATE_NAMESPACE_ATTRIBUTE:
aoqi@0 589 // Undeclaration of default namespace
aoqi@0 590 processNamespaceAttribute("", "");
aoqi@0 591 if(collectPrefixes) {
aoqi@0 592 prefixSet.add("");
aoqi@0 593 }
aoqi@0 594 break;
aoqi@0 595 case STATE_NAMESPACE_ATTRIBUTE_P:
aoqi@0 596 // Undeclaration of namespace
aoqi@0 597 prefix = readStructureString();
aoqi@0 598 processNamespaceAttribute(prefix, "");
aoqi@0 599 if(collectPrefixes) {
aoqi@0 600 prefixSet.add(prefix);
aoqi@0 601 }
aoqi@0 602 break;
aoqi@0 603 case STATE_NAMESPACE_ATTRIBUTE_P_U:
aoqi@0 604 // Declaration with prefix
aoqi@0 605 prefix = readStructureString();
aoqi@0 606 processNamespaceAttribute(prefix, readStructureString());
aoqi@0 607 if(collectPrefixes) {
aoqi@0 608 prefixSet.add(prefix);
aoqi@0 609 }
aoqi@0 610 break;
aoqi@0 611 case STATE_NAMESPACE_ATTRIBUTE_U:
aoqi@0 612 // Default declaration
aoqi@0 613 processNamespaceAttribute("", readStructureString());
aoqi@0 614 if(collectPrefixes) {
aoqi@0 615 prefixSet.add("");
aoqi@0 616 }
aoqi@0 617 break;
aoqi@0 618 default:
aoqi@0 619 throw reportFatalError("Illegal state: "+item);
aoqi@0 620 }
aoqi@0 621 readStructure();
aoqi@0 622
aoqi@0 623 item = peekStructure();
aoqi@0 624 } while((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE);
aoqi@0 625
aoqi@0 626
aoqi@0 627 cacheNamespacePrefixIndex();
aoqi@0 628
aoqi@0 629 return item;
aoqi@0 630 }
aoqi@0 631
aoqi@0 632 private void processAttributes(int item) throws SAXException {
aoqi@0 633 do {
aoqi@0 634 switch(getAIIState(item)) {
aoqi@0 635 case STATE_ATTRIBUTE_U_LN_QN:
aoqi@0 636 _attributes.addAttributeWithQName(readStructureString(), readStructureString(), readStructureString(), readStructureString(), readContentString());
aoqi@0 637 break;
aoqi@0 638 case STATE_ATTRIBUTE_P_U_LN:
aoqi@0 639 {
aoqi@0 640 final String p = readStructureString();
aoqi@0 641 final String u = readStructureString();
aoqi@0 642 final String ln = readStructureString();
aoqi@0 643 _attributes.addAttributeWithQName(u, ln, getQName(p, ln), readStructureString(), readContentString());
aoqi@0 644 break;
aoqi@0 645 }
aoqi@0 646 case STATE_ATTRIBUTE_U_LN: {
aoqi@0 647 final String u = readStructureString();
aoqi@0 648 final String ln = readStructureString();
aoqi@0 649 _attributes.addAttributeWithQName(u, ln, ln, readStructureString(), readContentString());
aoqi@0 650 break;
aoqi@0 651 }
aoqi@0 652 case STATE_ATTRIBUTE_LN: {
aoqi@0 653 final String ln = readStructureString();
aoqi@0 654 _attributes.addAttributeWithQName("", ln, ln, readStructureString(), readContentString());
aoqi@0 655 break;
aoqi@0 656 }
aoqi@0 657 default:
aoqi@0 658 throw reportFatalError("Illegal state: "+item);
aoqi@0 659 }
aoqi@0 660 readStructure();
aoqi@0 661
aoqi@0 662 item = peekStructure();
aoqi@0 663 } while((item & TYPE_MASK) == T_ATTRIBUTE);
aoqi@0 664 }
aoqi@0 665
aoqi@0 666 private void processNamespaceAttribute(String prefix, String uri) throws SAXException {
aoqi@0 667 _contentHandler.startPrefixMapping(prefix, uri);
aoqi@0 668
aoqi@0 669 if (_namespacePrefixesFeature) {
aoqi@0 670 // Add the namespace delcaration as an attribute
aoqi@0 671 if (prefix != "") {
aoqi@0 672 _attributes.addAttributeWithQName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, prefix,
aoqi@0 673 getQName(XMLConstants.XMLNS_ATTRIBUTE, prefix),
aoqi@0 674 "CDATA", uri);
aoqi@0 675 } else {
aoqi@0 676 _attributes.addAttributeWithQName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE,
aoqi@0 677 XMLConstants.XMLNS_ATTRIBUTE,
aoqi@0 678 "CDATA", uri);
aoqi@0 679 }
aoqi@0 680 }
aoqi@0 681
aoqi@0 682 cacheNamespacePrefix(prefix);
aoqi@0 683 }
aoqi@0 684
aoqi@0 685 private void cacheNamespacePrefix(String prefix) {
aoqi@0 686 if (_namespacePrefixesIndex == _namespacePrefixes.length) {
aoqi@0 687 final String[] namespaceAttributes = new String[_namespacePrefixesIndex * 3 / 2 + 1];
aoqi@0 688 System.arraycopy(_namespacePrefixes, 0, namespaceAttributes, 0, _namespacePrefixesIndex);
aoqi@0 689 _namespacePrefixes = namespaceAttributes;
aoqi@0 690 }
aoqi@0 691
aoqi@0 692 _namespacePrefixes[_namespacePrefixesIndex++] = prefix;
aoqi@0 693 }
aoqi@0 694
aoqi@0 695 private void cacheNamespacePrefixIndex() {
aoqi@0 696 if (_namespaceAttributesStackIndex == _namespaceAttributesStack.length) {
aoqi@0 697 final int[] namespaceAttributesStack = new int[_namespaceAttributesStackIndex * 3 /2 + 1];
aoqi@0 698 System.arraycopy(_namespaceAttributesStack, 0, namespaceAttributesStack, 0, _namespaceAttributesStackIndex);
aoqi@0 699 _namespaceAttributesStack = namespaceAttributesStack;
aoqi@0 700 }
aoqi@0 701
aoqi@0 702 _namespaceAttributesStack[_namespaceAttributesStackIndex++] = _namespacePrefixesIndex;
aoqi@0 703 }
aoqi@0 704
aoqi@0 705 private void cacheNamespacePrefixStartingIndex() {
aoqi@0 706 if (_namespaceAttributesStackIndex == _namespaceAttributesStartingStack.length) {
aoqi@0 707 final int[] namespaceAttributesStart = new int[_namespaceAttributesStackIndex * 3 /2 + 1];
aoqi@0 708 System.arraycopy(_namespaceAttributesStartingStack, 0, namespaceAttributesStart, 0, _namespaceAttributesStackIndex);
aoqi@0 709 _namespaceAttributesStartingStack = namespaceAttributesStart;
aoqi@0 710 }
aoqi@0 711 _namespaceAttributesStartingStack[_namespaceAttributesStackIndex] = _namespacePrefixesIndex;
aoqi@0 712 }
aoqi@0 713
aoqi@0 714 private void processComment(String s) throws SAXException {
aoqi@0 715 processComment(s.toCharArray(), 0, s.length());
aoqi@0 716 }
aoqi@0 717
aoqi@0 718 private void processComment(char[] ch, int start, int length) throws SAXException {
aoqi@0 719 _lexicalHandler.comment(ch, start, length);
aoqi@0 720 }
aoqi@0 721
aoqi@0 722 private void processProcessingInstruction(String target, String data) throws SAXException {
aoqi@0 723 _contentHandler.processingInstruction(target, data);
aoqi@0 724 }
aoqi@0 725
aoqi@0 726 private static final DefaultWithLexicalHandler DEFAULT_LEXICAL_HANDLER = new DefaultWithLexicalHandler();
aoqi@0 727 }

mercurial