1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.parsers; 22 23 import com.sun.org.apache.xerces.internal.dom.AttrImpl; 24 import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl; 25 import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl; 26 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter; 27 import com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl; 28 import com.sun.org.apache.xerces.internal.dom.DocumentImpl; 29 import com.sun.org.apache.xerces.internal.dom.DocumentTypeImpl; 30 import com.sun.org.apache.xerces.internal.dom.ElementDefinitionImpl; 31 import com.sun.org.apache.xerces.internal.dom.ElementImpl; 32 import com.sun.org.apache.xerces.internal.dom.ElementNSImpl; 33 import com.sun.org.apache.xerces.internal.dom.EntityImpl; 34 import com.sun.org.apache.xerces.internal.dom.EntityReferenceImpl; 35 import com.sun.org.apache.xerces.internal.dom.NodeImpl; 36 import com.sun.org.apache.xerces.internal.dom.NotationImpl; 37 import com.sun.org.apache.xerces.internal.dom.PSVIAttrNSImpl; 38 import com.sun.org.apache.xerces.internal.dom.PSVIDocumentImpl; 39 import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl; 40 import com.sun.org.apache.xerces.internal.dom.TextImpl; 41 import com.sun.org.apache.xerces.internal.impl.Constants; 42 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; 43 import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper; 44 import com.sun.org.apache.xerces.internal.utils.ObjectFactory; 45 import com.sun.org.apache.xerces.internal.xni.Augmentations; 46 import com.sun.org.apache.xerces.internal.xni.NamespaceContext; 47 import com.sun.org.apache.xerces.internal.xni.QName; 48 import com.sun.org.apache.xerces.internal.xni.XMLAttributes; 49 import com.sun.org.apache.xerces.internal.xni.XMLLocator; 50 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; 51 import com.sun.org.apache.xerces.internal.xni.XMLString; 52 import com.sun.org.apache.xerces.internal.xni.XNIException; 53 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; 54 import com.sun.org.apache.xerces.internal.xs.AttributePSVI; 55 import com.sun.org.apache.xerces.internal.xs.ElementPSVI; 56 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 57 import java.util.Locale; 58 import java.util.Stack; 59 import org.w3c.dom.Attr; 60 import org.w3c.dom.CDATASection; 61 import org.w3c.dom.Comment; 62 import org.w3c.dom.DOMError; 63 import org.w3c.dom.Document; 64 import org.w3c.dom.DocumentType; 65 import org.w3c.dom.Element; 66 import org.w3c.dom.EntityReference; 67 import org.w3c.dom.NamedNodeMap; 68 import org.w3c.dom.Node; 69 import org.w3c.dom.NodeList; 70 import org.w3c.dom.ProcessingInstruction; 71 import org.w3c.dom.Text; 72 import org.w3c.dom.ls.LSParserFilter; 73 import org.w3c.dom.traversal.NodeFilter; 74 import org.xml.sax.SAXException; 75 76 /** 77 * This is the base class of all DOM parsers. It implements the XNI 78 * callback methods to create the DOM tree. After a successful parse of 79 * an XML document, the DOM Document object can be queried using the 80 * <code>getDocument</code> method. The actual pipeline is defined in 81 * parser configuration. 82 * 83 * @author Arnaud Le Hors, IBM 84 * @author Andy Clark, IBM 85 * @author Elena Litani, IBM 86 * 87 * @LastModified: Nov 2017 88 */ 89 public class AbstractDOMParser extends AbstractXMLDocumentParser { 90 91 // 92 // Constants 93 // 94 95 // feature ids 96 97 /** Feature id: namespace. */ 98 protected static final String NAMESPACES = 99 Constants.SAX_FEATURE_PREFIX+Constants.NAMESPACES_FEATURE; 100 101 /** Feature id: create entity ref nodes. */ 102 protected static final String CREATE_ENTITY_REF_NODES = 103 Constants.XERCES_FEATURE_PREFIX + Constants.CREATE_ENTITY_REF_NODES_FEATURE; 104 105 /** Feature id: include comments. */ 106 protected static final String INCLUDE_COMMENTS_FEATURE = 107 Constants.XERCES_FEATURE_PREFIX + Constants.INCLUDE_COMMENTS_FEATURE; 108 109 /** Feature id: create cdata nodes. */ 110 protected static final String CREATE_CDATA_NODES_FEATURE = 111 Constants.XERCES_FEATURE_PREFIX + Constants.CREATE_CDATA_NODES_FEATURE; 112 113 /** Feature id: include ignorable whitespace. */ 114 protected static final String INCLUDE_IGNORABLE_WHITESPACE = 115 Constants.XERCES_FEATURE_PREFIX + Constants.INCLUDE_IGNORABLE_WHITESPACE; 116 117 /** Feature id: defer node expansion. */ 118 protected static final String DEFER_NODE_EXPANSION = 119 Constants.XERCES_FEATURE_PREFIX + Constants.DEFER_NODE_EXPANSION_FEATURE; 120 121 122 /** Recognized features. */ 123 private static final String[] RECOGNIZED_FEATURES = { 124 NAMESPACES, 125 CREATE_ENTITY_REF_NODES, 126 INCLUDE_COMMENTS_FEATURE, 127 CREATE_CDATA_NODES_FEATURE, 128 INCLUDE_IGNORABLE_WHITESPACE, 129 DEFER_NODE_EXPANSION 130 }; 131 132 // property ids 133 134 /** Property id: document class name. */ 135 protected static final String DOCUMENT_CLASS_NAME = 136 Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_CLASS_NAME_PROPERTY; 137 138 protected static final String CURRENT_ELEMENT_NODE= 139 Constants.XERCES_PROPERTY_PREFIX + Constants.CURRENT_ELEMENT_NODE_PROPERTY; 140 141 // protected static final String GRAMMAR_POOL = 142 // Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; 143 144 /** Recognized properties. */ 145 private static final String[] RECOGNIZED_PROPERTIES = { 146 DOCUMENT_CLASS_NAME, 147 CURRENT_ELEMENT_NODE, 148 }; 149 150 // other 151 152 /** Default document class name. */ 153 protected static final String DEFAULT_DOCUMENT_CLASS_NAME = 154 "com.sun.org.apache.xerces.internal.dom.DocumentImpl"; 155 156 protected static final String CORE_DOCUMENT_CLASS_NAME = 157 "com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl"; 158 159 protected static final String PSVI_DOCUMENT_CLASS_NAME = 160 "com.sun.org.apache.xerces.internal.dom.PSVIDocumentImpl"; 161 162 /** 163 * If the user stops the process, this exception will be thrown. 164 */ 165 static final class Abort extends RuntimeException { 166 private static final long serialVersionUID = 1687848994976808490L; 167 static final Abort INSTANCE = new Abort(); 168 private Abort() {} 169 public Throwable fillInStackTrace() { 170 return this; 171 } 172 } 173 174 // debugging 175 176 private static final boolean DEBUG_EVENTS = false; 177 private static final boolean DEBUG_BASEURI = false; 178 179 // 180 // Data 181 // 182 183 /** DOM L3 error handler */ 184 protected DOMErrorHandlerWrapper fErrorHandler = null; 185 186 /** True if inside DTD. */ 187 protected boolean fInDTD; 188 189 // features 190 191 /** Create entity reference nodes. */ 192 protected boolean fCreateEntityRefNodes; 193 194 /** Include ignorable whitespace. */ 195 protected boolean fIncludeIgnorableWhitespace; 196 197 /** Include Comments. */ 198 protected boolean fIncludeComments; 199 200 /** Create cdata nodes. */ 201 protected boolean fCreateCDATANodes; 202 203 // dom information 204 205 /** The document. */ 206 protected Document fDocument; 207 208 /** The default Xerces document implementation, if used. */ 209 protected CoreDocumentImpl fDocumentImpl; 210 211 /** Whether to store PSVI information in DOM tree. */ 212 protected boolean fStorePSVI; 213 214 /** The document class name to use. */ 215 protected String fDocumentClassName; 216 217 /** The document type node. */ 218 protected DocumentType fDocumentType; 219 220 /** Current node. */ 221 protected Node fCurrentNode; 222 protected CDATASection fCurrentCDATASection; 223 protected EntityImpl fCurrentEntityDecl; 224 protected int fDeferredEntityDecl; 225 226 /** Character buffer */ 227 protected final StringBuilder fStringBuilder = new StringBuilder (50); 228 229 // internal subset 230 231 /** Internal subset buffer. */ 232 protected StringBuilder fInternalSubset; 233 234 // deferred expansion data 235 236 protected boolean fDeferNodeExpansion; 237 protected boolean fNamespaceAware; 238 protected DeferredDocumentImpl fDeferredDocumentImpl; 239 protected int fDocumentIndex; 240 protected int fDocumentTypeIndex; 241 protected int fCurrentNodeIndex; 242 protected int fCurrentCDATASectionIndex; 243 244 // state 245 246 /** True if inside DTD external subset. */ 247 protected boolean fInDTDExternalSubset; 248 249 /** Root element node. */ 250 protected Node fRoot; 251 252 /** True if inside CDATA section. */ 253 protected boolean fInCDATASection; 254 255 /** True if saw the first chunk of characters*/ 256 protected boolean fFirstChunk = false; 257 258 259 /** LSParserFilter: specifies that element with given QNAME and all its children 260 * must be rejected */ 261 protected boolean fFilterReject = false; 262 263 // data 264 265 /** Base uri stack*/ 266 protected final Stack<String> fBaseURIStack = new Stack<>(); 267 268 /** LSParserFilter: tracks the element depth within a rejected subtree. */ 269 protected int fRejectedElementDepth = 0; 270 271 /** LSParserFilter: store depth of skipped elements */ 272 protected Stack<Boolean> fSkippedElemStack = null; 273 274 /** LSParserFilter: true if inside entity reference */ 275 protected boolean fInEntityRef = false; 276 277 /** Attribute QName. */ 278 private final QName fAttrQName = new QName(); 279 280 /** Document locator. */ 281 private XMLLocator fLocator; 282 283 // handlers 284 285 protected LSParserFilter fDOMFilter = null; 286 287 // 288 // Constructors 289 // 290 291 /** Default constructor. */ 292 protected AbstractDOMParser (XMLParserConfiguration config) { 293 294 super (config); 295 296 297 // add recognized features 298 fConfiguration.addRecognizedFeatures (RECOGNIZED_FEATURES); 299 300 // set default values 301 fConfiguration.setFeature (CREATE_ENTITY_REF_NODES, true); 302 fConfiguration.setFeature (INCLUDE_IGNORABLE_WHITESPACE, true); 303 fConfiguration.setFeature (DEFER_NODE_EXPANSION, true); 304 fConfiguration.setFeature (INCLUDE_COMMENTS_FEATURE, true); 305 fConfiguration.setFeature (CREATE_CDATA_NODES_FEATURE, true); 306 307 // add recognized properties 308 fConfiguration.addRecognizedProperties (RECOGNIZED_PROPERTIES); 309 310 // set default values 311 fConfiguration.setProperty (DOCUMENT_CLASS_NAME, 312 DEFAULT_DOCUMENT_CLASS_NAME); 313 314 } // <init>(XMLParserConfiguration) 315 316 /** 317 * This method retrieves the name of current document class. 318 */ 319 protected String getDocumentClassName () { 320 return fDocumentClassName; 321 } 322 323 /** 324 * This method allows the programmer to decide which document 325 * factory to use when constructing the DOM tree. However, doing 326 * so will lose the functionality of the default factory. Also, 327 * a document class other than the default will lose the ability 328 * to defer node expansion on the DOM tree produced. 329 * 330 * @param documentClassName The fully qualified class name of the 331 * document factory to use when constructing 332 * the DOM tree. 333 * 334 * @see #getDocumentClassName 335 * @see #DEFAULT_DOCUMENT_CLASS_NAME 336 */ 337 protected void setDocumentClassName (String documentClassName) { 338 339 // normalize class name 340 if (documentClassName == null) { 341 documentClassName = DEFAULT_DOCUMENT_CLASS_NAME; 342 } 343 344 if (!documentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME) && 345 !documentClassName.equals(PSVI_DOCUMENT_CLASS_NAME)) { 346 // verify that this class exists and is of the right type 347 try { 348 Class<?> _class = ObjectFactory.findProviderClass (documentClassName, true); 349 //if (!_class.isAssignableFrom(Document.class)) { 350 if (!Document.class.isAssignableFrom (_class)) { 351 throw new IllegalArgumentException ( 352 DOMMessageFormatter.formatMessage( 353 DOMMessageFormatter.DOM_DOMAIN, 354 "InvalidDocumentClassName", new Object [] {documentClassName})); 355 } 356 } 357 catch (ClassNotFoundException e) { 358 throw new IllegalArgumentException ( 359 DOMMessageFormatter.formatMessage( 360 DOMMessageFormatter.DOM_DOMAIN, 361 "MissingDocumentClassName", new Object [] {documentClassName})); 362 } 363 } 364 365 // set document class name 366 fDocumentClassName = documentClassName; 367 if (!documentClassName.equals (DEFAULT_DOCUMENT_CLASS_NAME)) { 368 fDeferNodeExpansion = false; 369 } 370 371 } // setDocumentClassName(String) 372 373 // 374 // Public methods 375 // 376 377 /** Returns the DOM document object. */ 378 public Document getDocument () { 379 return fDocument; 380 } // getDocument():Document 381 382 /** 383 * Drops all references to the last DOM which was built by this parser. 384 */ 385 public final void dropDocumentReferences() { 386 fDocument = null; 387 fDocumentImpl = null; 388 fDeferredDocumentImpl = null; 389 fDocumentType = null; 390 fCurrentNode = null; 391 fCurrentCDATASection = null; 392 fCurrentEntityDecl = null; 393 fRoot = null; 394 } // dropDocumentReferences() 395 396 // 397 // XMLDocumentParser methods 398 // 399 400 /** 401 * Resets the parser state. 402 * 403 * @throws SAXException Thrown on initialization error. 404 */ 405 public void reset () throws XNIException { 406 super.reset (); 407 408 409 // get feature state 410 fCreateEntityRefNodes = 411 fConfiguration.getFeature (CREATE_ENTITY_REF_NODES); 412 413 fIncludeIgnorableWhitespace = 414 fConfiguration.getFeature (INCLUDE_IGNORABLE_WHITESPACE); 415 416 fDeferNodeExpansion = 417 fConfiguration.getFeature (DEFER_NODE_EXPANSION); 418 419 fNamespaceAware = fConfiguration.getFeature (NAMESPACES); 420 421 fIncludeComments = fConfiguration.getFeature (INCLUDE_COMMENTS_FEATURE); 422 423 fCreateCDATANodes = fConfiguration.getFeature (CREATE_CDATA_NODES_FEATURE); 424 425 // get property 426 setDocumentClassName ((String) 427 fConfiguration.getProperty (DOCUMENT_CLASS_NAME)); 428 429 // reset dom information 430 fDocument = null; 431 fDocumentImpl = null; 432 fStorePSVI = false; 433 fDocumentType = null; 434 fDocumentTypeIndex = -1; 435 fDeferredDocumentImpl = null; 436 fCurrentNode = null; 437 438 // reset string buffer 439 fStringBuilder.setLength (0); 440 441 // reset state information 442 fRoot = null; 443 fInDTD = false; 444 fInDTDExternalSubset = false; 445 fInCDATASection = false; 446 fFirstChunk = false; 447 fCurrentCDATASection = null; 448 fCurrentCDATASectionIndex = -1; 449 450 fBaseURIStack.removeAllElements (); 451 452 453 } // reset() 454 455 /** 456 * Set the locale to use for messages. 457 * 458 * @param locale The locale object to use for localization of messages. 459 * 460 */ 461 public void setLocale (Locale locale) { 462 fConfiguration.setLocale (locale); 463 464 } // setLocale(Locale) 465 466 // 467 // XMLDocumentHandler methods 468 // 469 470 /** 471 * This method notifies the start of a general entity. 472 * <p> 473 * <strong>Note:</strong> This method is not called for entity references 474 * appearing as part of attribute values. 475 * 476 * @param name The name of the general entity. 477 * @param identifier The resource identifier. 478 * @param encoding The auto-detected IANA encoding name of the entity 479 * stream. This value will be null in those situations 480 * where the entity encoding is not auto-detected (e.g. 481 * internal entities or a document entity that is 482 * parsed from a java.io.Reader). 483 * @param augs Additional information that may include infoset augmentations 484 * 485 * @exception XNIException Thrown by handler to signal an error. 486 */ 487 public void startGeneralEntity (String name, 488 XMLResourceIdentifier identifier, 489 String encoding, Augmentations augs) 490 throws XNIException { 491 if (DEBUG_EVENTS) { 492 System.out.println ("==>startGeneralEntity ("+name+")"); 493 if (DEBUG_BASEURI) { 494 System.out.println (" expandedSystemId( **baseURI): "+identifier.getExpandedSystemId ()); 495 System.out.println (" baseURI:"+ identifier.getBaseSystemId ()); 496 } 497 } 498 499 // Always create entity reference nodes to be able to recreate 500 // entity as a part of doctype 501 if (!fDeferNodeExpansion) { 502 if (fFilterReject) { 503 return; 504 } 505 setCharacterData (true); 506 EntityReference er = fDocument.createEntityReference (name); 507 if (fDocumentImpl != null) { 508 // REVISIT: baseURI/actualEncoding 509 // remove dependency on our implementation when DOM L3 is REC 510 // 511 512 EntityReferenceImpl erImpl =(EntityReferenceImpl)er; 513 514 // set base uri 515 erImpl.setBaseURI (identifier.getExpandedSystemId ()); 516 if (fDocumentType != null) { 517 // set actual encoding 518 NamedNodeMap entities = fDocumentType.getEntities (); 519 fCurrentEntityDecl = (EntityImpl) entities.getNamedItem (name); 520 if (fCurrentEntityDecl != null) { 521 fCurrentEntityDecl.setInputEncoding (encoding); 522 } 523 524 } 525 // we don't need synchronization now, because entity ref will be 526 // expanded anyway. Synch only needed when user creates entityRef node 527 erImpl.needsSyncChildren (false); 528 } 529 fInEntityRef = true; 530 fCurrentNode.appendChild (er); 531 fCurrentNode = er; 532 } 533 else { 534 535 int er = 536 fDeferredDocumentImpl.createDeferredEntityReference (name, identifier.getExpandedSystemId ()); 537 if (fDocumentTypeIndex != -1) { 538 // find corresponding Entity decl 539 int node = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false); 540 while (node != -1) { 541 short nodeType = fDeferredDocumentImpl.getNodeType (node, false); 542 if (nodeType == Node.ENTITY_NODE) { 543 String nodeName = 544 fDeferredDocumentImpl.getNodeName (node, false); 545 if (nodeName.equals (name)) { 546 fDeferredEntityDecl = node; 547 fDeferredDocumentImpl.setInputEncoding (node, encoding); 548 break; 549 } 550 } 551 node = fDeferredDocumentImpl.getRealPrevSibling (node, false); 552 } 553 } 554 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, er); 555 fCurrentNodeIndex = er; 556 } 557 558 } // startGeneralEntity(String,XMLResourceIdentifier, Augmentations) 559 560 /** 561 * Notifies of the presence of a TextDecl line in an entity. If present, 562 * this method will be called immediately following the startEntity call. 563 * <p> 564 * <strong>Note:</strong> This method will never be called for the 565 * document entity; it is only called for external general entities 566 * referenced in document content. 567 * <p> 568 * <strong>Note:</strong> This method is not called for entity references 569 * appearing as part of attribute values. 570 * 571 * @param version The XML version, or null if not specified. 572 * @param encoding The IANA encoding name of the entity. 573 * @param augs Additional information that may include infoset augmentations 574 * 575 * @throws XNIException Thrown by handler to signal an error. 576 */ 577 public void textDecl (String version, String encoding, Augmentations augs) throws XNIException { 578 if (fInDTD){ 579 return; 580 } 581 if (!fDeferNodeExpansion) { 582 if (fCurrentEntityDecl != null && !fFilterReject) { 583 fCurrentEntityDecl.setXmlEncoding (encoding); 584 if (version != null) 585 fCurrentEntityDecl.setXmlVersion (version); 586 } 587 } 588 else { 589 if (fDeferredEntityDecl !=-1) { 590 fDeferredDocumentImpl.setEntityInfo (fDeferredEntityDecl, version, encoding); 591 } 592 } 593 } // textDecl(String,String) 594 595 /** 596 * A comment. 597 * 598 * @param text The text in the comment. 599 * @param augs Additional information that may include infoset augmentations 600 * 601 * @throws XNIException Thrown by application to signal an error. 602 */ 603 @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_SKIP 604 public void comment (XMLString text, Augmentations augs) throws XNIException { 605 if (fInDTD) { 606 if (fInternalSubset != null && !fInDTDExternalSubset) { 607 fInternalSubset.append ("<!--"); 608 if (text.length > 0) { 609 fInternalSubset.append (text.ch, text.offset, text.length); 610 } 611 fInternalSubset.append ("-->"); 612 } 613 return; 614 } 615 if (!fIncludeComments || fFilterReject) { 616 return; 617 } 618 if (!fDeferNodeExpansion) { 619 Comment comment = fDocument.createComment (text.toString ()); 620 621 setCharacterData (false); 622 fCurrentNode.appendChild (comment); 623 if (fDOMFilter !=null && !fInEntityRef && 624 (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_COMMENT)!= 0) { 625 short code = fDOMFilter.acceptNode (comment); 626 switch (code) { 627 case LSParserFilter.FILTER_INTERRUPT:{ 628 throw Abort.INSTANCE; 629 } 630 case LSParserFilter.FILTER_REJECT:{ 631 // REVISIT: the constant FILTER_REJECT should be changed when new 632 // DOM LS specs gets published 633 634 // fall through to SKIP since comment has no children. 635 } 636 case LSParserFilter.FILTER_SKIP: { 637 // REVISIT: the constant FILTER_SKIP should be changed when new 638 // DOM LS specs gets published 639 fCurrentNode.removeChild (comment); 640 // make sure we don't loose chars if next event is characters() 641 fFirstChunk = true; 642 return; 643 } 644 645 default: { 646 // accept node 647 } 648 } 649 } 650 651 } 652 else { 653 int comment = 654 fDeferredDocumentImpl.createDeferredComment (text.toString ()); 655 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, comment); 656 } 657 658 } // comment(XMLString) 659 660 /** 661 * A processing instruction. Processing instructions consist of a 662 * target name and, optionally, text data. The data is only meaningful 663 * to the application. 664 * <p> 665 * Typically, a processing instruction's data will contain a series 666 * of pseudo-attributes. These pseudo-attributes follow the form of 667 * element attributes but are <strong>not</strong> parsed or presented 668 * to the application as anything other than text. The application is 669 * responsible for parsing the data. 670 * 671 * @param target The target. 672 * @param data The data or null if none specified. 673 * @param augs Additional information that may include infoset augmentations 674 * 675 * @throws XNIException Thrown by handler to signal an error. 676 */ 677 @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT 678 public void processingInstruction (String target, XMLString data, Augmentations augs) 679 throws XNIException { 680 681 if (fInDTD) { 682 if (fInternalSubset != null && !fInDTDExternalSubset) { 683 fInternalSubset.append ("<?"); 684 fInternalSubset.append (target); 685 if (data.length > 0) { 686 fInternalSubset.append (' ').append (data.ch, data.offset, data.length); 687 } 688 fInternalSubset.append ("?>"); 689 } 690 return; 691 } 692 693 if (DEBUG_EVENTS) { 694 System.out.println ("==>processingInstruction ("+target+")"); 695 } 696 if (!fDeferNodeExpansion) { 697 if (fFilterReject) { 698 return; 699 } 700 ProcessingInstruction pi = 701 fDocument.createProcessingInstruction (target, data.toString ()); 702 703 704 setCharacterData (false); 705 fCurrentNode.appendChild (pi); 706 if (fDOMFilter !=null && !fInEntityRef && 707 (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_PROCESSING_INSTRUCTION)!= 0) { 708 short code = fDOMFilter.acceptNode (pi); 709 switch (code) { 710 case LSParserFilter.FILTER_INTERRUPT:{ 711 throw Abort.INSTANCE; 712 } 713 case LSParserFilter.FILTER_REJECT:{ 714 // fall through to SKIP since PI has no children. 715 } 716 case LSParserFilter.FILTER_SKIP: { 717 fCurrentNode.removeChild (pi); 718 // fFirstChunk must be set to true so that data 719 // won't be lost in the case where the child before PI is 720 // a text node and the next event is characters. 721 fFirstChunk = true; 722 return; 723 } 724 default: { 725 } 726 } 727 } 728 } 729 else { 730 int pi = fDeferredDocumentImpl. 731 createDeferredProcessingInstruction (target, data.toString ()); 732 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, pi); 733 } 734 735 } // processingInstruction(String,XMLString) 736 737 /** 738 * The start of the document. 739 * 740 * @param locator The system identifier of the entity if the entity 741 * is external, null otherwise. 742 * @param encoding The auto-detected IANA encoding name of the entity 743 * stream. This value will be null in those situations 744 * where the entity encoding is not auto-detected (e.g. 745 * internal entities or a document entity that is 746 * parsed from a java.io.Reader). 747 * @param namespaceContext 748 * The namespace context in effect at the 749 * start of this document. 750 * This object represents the current context. 751 * Implementors of this class are responsible 752 * for copying the namespace bindings from the 753 * the current context (and its parent contexts) 754 * if that information is important. 755 * @param augs Additional information that may include infoset augmentations 756 * 757 * @throws XNIException Thrown by handler to signal an error. 758 */ 759 public void startDocument (XMLLocator locator, String encoding, 760 NamespaceContext namespaceContext, Augmentations augs) 761 throws XNIException { 762 763 fLocator = locator; 764 if (!fDeferNodeExpansion) { 765 if (fDocumentClassName.equals (DEFAULT_DOCUMENT_CLASS_NAME)) { 766 fDocument = new DocumentImpl (); 767 fDocumentImpl = (CoreDocumentImpl)fDocument; 768 // REVISIT: when DOM Level 3 is REC rely on Document.support 769 // instead of specific class 770 // set DOM error checking off 771 fDocumentImpl.setStrictErrorChecking (false); 772 // set actual encoding 773 fDocumentImpl.setInputEncoding (encoding); 774 // set documentURI 775 fDocumentImpl.setDocumentURI (locator.getExpandedSystemId ()); 776 } 777 else if (fDocumentClassName.equals (PSVI_DOCUMENT_CLASS_NAME)) { 778 fDocument = new PSVIDocumentImpl(); 779 fDocumentImpl = (CoreDocumentImpl)fDocument; 780 fStorePSVI = true; 781 // REVISIT: when DOM Level 3 is REC rely on Document.support 782 // instead of specific class 783 // set DOM error checking off 784 fDocumentImpl.setStrictErrorChecking (false); 785 // set actual encoding 786 fDocumentImpl.setInputEncoding (encoding); 787 // set documentURI 788 fDocumentImpl.setDocumentURI (locator.getExpandedSystemId ()); 789 } 790 else { 791 // use specified document class 792 try { 793 Class<?> documentClass = ObjectFactory.findProviderClass (fDocumentClassName, true); 794 fDocument = (Document)documentClass.getConstructor().newInstance(); 795 796 // if subclass of our own class that's cool too 797 Class<?> defaultDocClass = 798 ObjectFactory.findProviderClass (CORE_DOCUMENT_CLASS_NAME, true); 799 if (defaultDocClass.isAssignableFrom (documentClass)) { 800 fDocumentImpl = (CoreDocumentImpl)fDocument; 801 802 Class<?> psviDocClass = ObjectFactory.findProviderClass (PSVI_DOCUMENT_CLASS_NAME, true); 803 if (psviDocClass.isAssignableFrom (documentClass)) { 804 fStorePSVI = true; 805 } 806 807 // REVISIT: when DOM Level 3 is REC rely on 808 // Document.support instead of specific class 809 // set DOM error checking off 810 fDocumentImpl.setStrictErrorChecking (false); 811 // set actual encoding 812 fDocumentImpl.setInputEncoding (encoding); 813 // set documentURI 814 if (locator != null) { 815 fDocumentImpl.setDocumentURI (locator.getExpandedSystemId ()); 816 } 817 } 818 } 819 catch (ClassNotFoundException e) { 820 // won't happen we already checked that earlier 821 } 822 catch (Exception e) { 823 throw new RuntimeException ( 824 DOMMessageFormatter.formatMessage( 825 DOMMessageFormatter.DOM_DOMAIN, 826 "CannotCreateDocumentClass", 827 new Object [] {fDocumentClassName})); 828 } 829 } 830 fCurrentNode = fDocument; 831 } 832 else { 833 fDeferredDocumentImpl = new DeferredDocumentImpl (fNamespaceAware); 834 fDocument = fDeferredDocumentImpl; 835 fDocumentIndex = fDeferredDocumentImpl.createDeferredDocument (); 836 // REVISIT: strict error checking is not implemented in deferred dom. 837 // Document.support instead of specific class 838 839 // set actual encoding 840 fDeferredDocumentImpl.setInputEncoding (encoding); 841 // set documentURI 842 fDeferredDocumentImpl.setDocumentURI (locator.getExpandedSystemId ()); 843 fCurrentNodeIndex = fDocumentIndex; 844 845 } 846 847 } // startDocument(String,String) 848 849 /** 850 * Notifies of the presence of an XMLDecl line in the document. If 851 * present, this method will be called immediately following the 852 * startDocument call. 853 * 854 * @param version The XML version. 855 * @param encoding The IANA encoding name of the document, or null if 856 * not specified. 857 * @param standalone The standalone value, or null if not specified. 858 * @param augs Additional information that may include infoset augmentations 859 * 860 * @throws XNIException Thrown by handler to signal an error. 861 */ 862 public void xmlDecl (String version, String encoding, String standalone, 863 Augmentations augs) 864 throws XNIException { 865 if (!fDeferNodeExpansion) { 866 // REVISIT: when DOM Level 3 is REC rely on Document.support 867 // instead of specific class 868 if (fDocumentImpl != null) { 869 if (version != null) 870 fDocumentImpl.setXmlVersion (version); 871 fDocumentImpl.setXmlEncoding (encoding); 872 fDocumentImpl.setXmlStandalone ("yes".equals (standalone)); 873 } 874 } 875 else { 876 if (version != null) 877 fDeferredDocumentImpl.setXmlVersion (version); 878 fDeferredDocumentImpl.setXmlEncoding (encoding); 879 fDeferredDocumentImpl.setXmlStandalone ("yes".equals (standalone)); 880 } 881 } // xmlDecl(String,String,String) 882 883 /** 884 * Notifies of the presence of the DOCTYPE line in the document. 885 * 886 * @param rootElement The name of the root element. 887 * @param publicId The public identifier if an external DTD or null 888 * if the external DTD is specified using SYSTEM. 889 * @param systemId The system identifier if an external DTD, null 890 * otherwise. 891 * @param augs Additional information that may include infoset augmentations 892 * 893 * @throws XNIException Thrown by handler to signal an error. 894 */ 895 public void doctypeDecl (String rootElement, 896 String publicId, String systemId, Augmentations augs) 897 throws XNIException { 898 899 if (!fDeferNodeExpansion) { 900 if (fDocumentImpl != null) { 901 fDocumentType = fDocumentImpl.createDocumentType ( 902 rootElement, publicId, systemId); 903 fCurrentNode.appendChild (fDocumentType); 904 } 905 } 906 else { 907 fDocumentTypeIndex = fDeferredDocumentImpl. 908 createDeferredDocumentType (rootElement, publicId, systemId); 909 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, fDocumentTypeIndex); 910 } 911 912 } // doctypeDecl(String,String,String) 913 914 /** 915 * The start of an element. If the document specifies the start element 916 * by using an empty tag, then the startElement method will immediately 917 * be followed by the endElement method, with no intervening methods. 918 * 919 * @param element The name of the element. 920 * @param attributes The element attributes. 921 * @param augs Additional information that may include infoset augmentations 922 * 923 * @throws XNIException Thrown by handler to signal an error. 924 */ 925 public void startElement (QName element, XMLAttributes attributes, Augmentations augs) 926 throws XNIException { 927 if (DEBUG_EVENTS) { 928 System.out.println ("==>startElement ("+element.rawname+")"); 929 } 930 if (!fDeferNodeExpansion) { 931 if (fFilterReject) { 932 ++fRejectedElementDepth; 933 return; 934 } 935 Element el = createElementNode (element); 936 int attrCount = attributes.getLength (); 937 boolean seenSchemaDefault = false; 938 for (int i = 0; i < attrCount; i++) { 939 attributes.getName (i, fAttrQName); 940 Attr attr = createAttrNode (fAttrQName); 941 942 String attrValue = attributes.getValue (i); 943 944 AttributePSVI attrPSVI =(AttributePSVI) attributes.getAugmentations (i).getItem (Constants.ATTRIBUTE_PSVI); 945 if (fStorePSVI && attrPSVI != null){ 946 ((PSVIAttrNSImpl) attr).setPSVI (attrPSVI); 947 } 948 949 attr.setValue (attrValue); 950 boolean specified = attributes.isSpecified(i); 951 // Take special care of schema defaulted attributes. Calling the 952 // non-namespace aware setAttributeNode() method could overwrite 953 // another attribute with the same local name. 954 if (!specified && (seenSchemaDefault || (fAttrQName.uri != null && 955 fAttrQName.uri != NamespaceContext.XMLNS_URI && fAttrQName.prefix == null))) { 956 el.setAttributeNodeNS(attr); 957 seenSchemaDefault = true; 958 } 959 else { 960 el.setAttributeNode(attr); 961 } 962 // NOTE: The specified value MUST be set after you set 963 // the node value because that turns the "specified" 964 // flag to "true" which may overwrite a "false" 965 // value from the attribute list. -Ac 966 if (fDocumentImpl != null) { 967 AttrImpl attrImpl = (AttrImpl) attr; 968 Object type = null; 969 boolean id = false; 970 971 // REVISIT: currently it is possible that someone turns off 972 // namespaces and turns on xml schema validation 973 // To avoid classcast exception in AttrImpl check for namespaces 974 // however the correct solution should probably disallow setting 975 // namespaces to false when schema processing is turned on. 976 if (attrPSVI != null && fNamespaceAware) { 977 // XML Schema 978 type = attrPSVI.getMemberTypeDefinition (); 979 if (type == null) { 980 type = attrPSVI.getTypeDefinition (); 981 if (type != null) { 982 id = ((XSSimpleType) type).isIDType (); 983 attrImpl.setType (type); 984 } 985 } 986 else { 987 id = ((XSSimpleType) type).isIDType (); 988 attrImpl.setType (type); 989 } 990 } 991 else { 992 // DTD 993 boolean isDeclared = Boolean.TRUE.equals (attributes.getAugmentations (i).getItem (Constants.ATTRIBUTE_DECLARED)); 994 // For DOM Level 3 TypeInfo, the type name must 995 // be null if this attribute has not been declared 996 // in the DTD. 997 if (isDeclared) { 998 type = attributes.getType (i); 999 id = "ID".equals (type); 1000 } 1001 attrImpl.setType (type); 1002 } 1003 1004 if (id) { 1005 ((ElementImpl) el).setIdAttributeNode (attr, true); 1006 } 1007 1008 attrImpl.setSpecified (specified); 1009 // REVISIT: Handle entities in attribute value. 1010 } 1011 } 1012 setCharacterData (false); 1013 1014 if (augs != null) { 1015 ElementPSVI elementPSVI = (ElementPSVI)augs.getItem (Constants.ELEMENT_PSVI); 1016 if (elementPSVI != null && fNamespaceAware) { 1017 XSTypeDefinition type = elementPSVI.getMemberTypeDefinition (); 1018 if (type == null) { 1019 type = elementPSVI.getTypeDefinition (); 1020 } 1021 ((ElementNSImpl)el).setType (type); 1022 } 1023 } 1024 1025 1026 // filter nodes 1027 if (fDOMFilter != null && !fInEntityRef) { 1028 if (fRoot == null) { 1029 // fill value of the root element 1030 fRoot = el; 1031 } else { 1032 short code = fDOMFilter.startElement(el); 1033 switch (code) { 1034 case LSParserFilter.FILTER_INTERRUPT : 1035 { 1036 throw Abort.INSTANCE; 1037 } 1038 case LSParserFilter.FILTER_REJECT : 1039 { 1040 fFilterReject = true; 1041 fRejectedElementDepth = 0; 1042 return; 1043 } 1044 case LSParserFilter.FILTER_SKIP : 1045 { 1046 // make sure that if any char data is available 1047 // the fFirstChunk is true, so that if the next event 1048 // is characters(), and the last node is text, we will copy 1049 // the value already in the text node to fStringBuffer 1050 // (not to lose it). 1051 fFirstChunk = true; 1052 fSkippedElemStack.push(Boolean.TRUE); 1053 return; 1054 } 1055 default : 1056 { 1057 if (!fSkippedElemStack.isEmpty()) { 1058 fSkippedElemStack.push(Boolean.FALSE); 1059 } 1060 } 1061 } 1062 } 1063 } 1064 fCurrentNode.appendChild (el); 1065 fCurrentNode = el; 1066 } 1067 else { 1068 int el = fDeferredDocumentImpl.createDeferredElement (fNamespaceAware ? 1069 element.uri : null, element.rawname); 1070 Object type = null; 1071 int attrCount = attributes.getLength (); 1072 // Need to loop in reverse order so that the attributes 1073 // are processed in document order when the DOM is expanded. 1074 for (int i = attrCount - 1; i >= 0; --i) { 1075 1076 // set type information 1077 AttributePSVI attrPSVI = (AttributePSVI)attributes.getAugmentations (i).getItem (Constants.ATTRIBUTE_PSVI); 1078 boolean id = false; 1079 1080 // REVISIT: currently it is possible that someone turns off 1081 // namespaces and turns on xml schema validation 1082 // To avoid classcast exception in AttrImpl check for namespaces 1083 // however the correct solution should probably disallow setting 1084 // namespaces to false when schema processing is turned on. 1085 if (attrPSVI != null && fNamespaceAware) { 1086 // XML Schema 1087 type = attrPSVI.getMemberTypeDefinition (); 1088 if (type == null) { 1089 type = attrPSVI.getTypeDefinition (); 1090 if (type != null){ 1091 id = ((XSSimpleType) type).isIDType (); 1092 } 1093 } 1094 else { 1095 id = ((XSSimpleType) type).isIDType (); 1096 } 1097 } 1098 else { 1099 // DTD 1100 boolean isDeclared = Boolean.TRUE.equals (attributes.getAugmentations (i).getItem (Constants.ATTRIBUTE_DECLARED)); 1101 // For DOM Level 3 TypeInfo, the type name must 1102 // be null if this attribute has not been declared 1103 // in the DTD. 1104 if (isDeclared) { 1105 type = attributes.getType (i); 1106 id = "ID".equals (type); 1107 } 1108 } 1109 1110 // create attribute 1111 fDeferredDocumentImpl.setDeferredAttribute ( 1112 el, 1113 attributes.getQName (i), 1114 attributes.getURI (i), 1115 attributes.getValue (i), 1116 attributes.isSpecified (i), 1117 id, 1118 type); 1119 } 1120 1121 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, el); 1122 fCurrentNodeIndex = el; 1123 } 1124 } // startElement(QName,XMLAttributes) 1125 1126 1127 /** 1128 * An empty element. 1129 * 1130 * @param element The name of the element. 1131 * @param attributes The element attributes. 1132 * @param augs Additional information that may include infoset augmentations 1133 * 1134 * @throws XNIException Thrown by handler to signal an error. 1135 */ 1136 public void emptyElement (QName element, XMLAttributes attributes, Augmentations augs) 1137 throws XNIException { 1138 1139 startElement (element, attributes, augs); 1140 endElement (element, augs); 1141 1142 } // emptyElement(QName,XMLAttributes) 1143 1144 /** 1145 * Character content. 1146 * 1147 * @param text The content. 1148 * @param augs Additional information that may include infoset augmentations 1149 * 1150 * @throws XNIException Thrown by handler to signal an error. 1151 */ 1152 public void characters (XMLString text, Augmentations augs) throws XNIException { 1153 1154 if (DEBUG_EVENTS) { 1155 System.out.println ("==>characters(): "+text.toString ()); 1156 } 1157 1158 if (!fDeferNodeExpansion) { 1159 1160 if (fFilterReject) { 1161 return; 1162 } 1163 if (fInCDATASection && fCreateCDATANodes) { 1164 if (fCurrentCDATASection == null) { 1165 fCurrentCDATASection = 1166 fDocument.createCDATASection (text.toString ()); 1167 fCurrentNode.appendChild (fCurrentCDATASection); 1168 fCurrentNode = fCurrentCDATASection; 1169 } 1170 else { 1171 fCurrentCDATASection.appendData (text.toString ()); 1172 } 1173 } 1174 else if (!fInDTD) { 1175 // if type is union (XML Schema) it is possible that we receive 1176 // character call with empty data 1177 if (text.length == 0) { 1178 return; 1179 } 1180 1181 Node child = fCurrentNode.getLastChild (); 1182 if (child != null && child.getNodeType () == Node.TEXT_NODE) { 1183 // collect all the data into the string buffer. 1184 if (fFirstChunk) { 1185 if (fDocumentImpl != null) { 1186 fStringBuilder.append (((TextImpl)child).removeData ()); 1187 } else { 1188 fStringBuilder.append (((Text)child).getData ()); 1189 ((Text)child).setNodeValue (null); 1190 } 1191 fFirstChunk = false; 1192 } 1193 if (text.length > 0) { 1194 fStringBuilder.append (text.ch, text.offset, text.length); 1195 } 1196 } 1197 else { 1198 fFirstChunk = true; 1199 Text textNode = fDocument.createTextNode (text.toString()); 1200 fCurrentNode.appendChild (textNode); 1201 } 1202 1203 } 1204 } 1205 else { 1206 // The Text and CDATASection normalization is taken care of within 1207 // the DOM in the deferred case. 1208 if (fInCDATASection && fCreateCDATANodes) { 1209 if (fCurrentCDATASectionIndex == -1) { 1210 int cs = fDeferredDocumentImpl. 1211 createDeferredCDATASection (text.toString ()); 1212 1213 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, cs); 1214 fCurrentCDATASectionIndex = cs; 1215 fCurrentNodeIndex = cs; 1216 } 1217 else { 1218 int txt = fDeferredDocumentImpl. 1219 createDeferredTextNode (text.toString (), false); 1220 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, txt); 1221 } 1222 } else if (!fInDTD) { 1223 // if type is union (XML Schema) it is possible that we receive 1224 // character call with empty data 1225 if (text.length == 0) { 1226 return; 1227 } 1228 1229 String value = text.toString (); 1230 int txt = fDeferredDocumentImpl. 1231 createDeferredTextNode (value, false); 1232 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, txt); 1233 1234 } 1235 } 1236 } // characters(XMLString) 1237 1238 /** 1239 * Ignorable whitespace. For this method to be called, the document 1240 * source must have some way of determining that the text containing 1241 * only whitespace characters should be considered ignorable. For 1242 * example, the validator can determine if a length of whitespace 1243 * characters in the document are ignorable based on the element 1244 * content model. 1245 * 1246 * @param text The ignorable whitespace. 1247 * @param augs Additional information that may include infoset augmentations 1248 * 1249 * @throws XNIException Thrown by handler to signal an error. 1250 */ 1251 public void ignorableWhitespace (XMLString text, Augmentations augs) throws XNIException { 1252 1253 if (!fIncludeIgnorableWhitespace || fFilterReject) { 1254 return; 1255 } 1256 if (!fDeferNodeExpansion) { 1257 Node child = fCurrentNode.getLastChild (); 1258 if (child != null && child.getNodeType () == Node.TEXT_NODE) { 1259 Text textNode = (Text)child; 1260 textNode.appendData (text.toString ()); 1261 } 1262 else { 1263 Text textNode = fDocument.createTextNode (text.toString ()); 1264 if (fDocumentImpl != null) { 1265 TextImpl textNodeImpl = (TextImpl)textNode; 1266 textNodeImpl.setIgnorableWhitespace (true); 1267 } 1268 fCurrentNode.appendChild (textNode); 1269 } 1270 } 1271 else { 1272 // The Text normalization is taken care of within the DOM in the 1273 // deferred case. 1274 int txt = fDeferredDocumentImpl. 1275 createDeferredTextNode (text.toString (), true); 1276 fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, txt); 1277 } 1278 1279 } // ignorableWhitespace(XMLString) 1280 1281 /** 1282 * The end of an element. 1283 * 1284 * @param element The name of the element. 1285 * @param augs Additional information that may include infoset augmentations 1286 * 1287 * @throws XNIException Thrown by handler to signal an error. 1288 */ 1289 public void endElement (QName element, Augmentations augs) throws XNIException { 1290 if (DEBUG_EVENTS) { 1291 System.out.println ("==>endElement ("+element.rawname+")"); 1292 } 1293 if (!fDeferNodeExpansion) { 1294 1295 // REVISIT: Should this happen after we call the filter? 1296 if (augs != null && fDocumentImpl != null && (fNamespaceAware || fStorePSVI)) { 1297 ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI); 1298 if (elementPSVI != null) { 1299 // Updating TypeInfo. If the declared type is a union the 1300 // [member type definition] will only be available at the 1301 // end of an element. 1302 if (fNamespaceAware) { 1303 XSTypeDefinition type = elementPSVI.getMemberTypeDefinition(); 1304 if (type == null) { 1305 type = elementPSVI.getTypeDefinition(); 1306 } 1307 ((ElementNSImpl)fCurrentNode).setType(type); 1308 } 1309 if (fStorePSVI) { 1310 ((PSVIElementNSImpl)fCurrentNode).setPSVI (elementPSVI); 1311 } 1312 } 1313 } 1314 1315 if (fDOMFilter != null) { 1316 if (fFilterReject) { 1317 if (fRejectedElementDepth-- == 0) { 1318 fFilterReject = false; 1319 } 1320 return; 1321 } 1322 if (!fSkippedElemStack.isEmpty()) { 1323 if (fSkippedElemStack.pop() == Boolean.TRUE) { 1324 return; 1325 } 1326 } 1327 setCharacterData (false); 1328 if ((fCurrentNode != fRoot) && !fInEntityRef && (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_ELEMENT)!=0) { 1329 short code = fDOMFilter.acceptNode (fCurrentNode); 1330 switch (code) { 1331 case LSParserFilter.FILTER_INTERRUPT:{ 1332 throw Abort.INSTANCE; 1333 } 1334 case LSParserFilter.FILTER_REJECT:{ 1335 Node parent = fCurrentNode.getParentNode (); 1336 parent.removeChild (fCurrentNode); 1337 fCurrentNode = parent; 1338 return; 1339 } 1340 case LSParserFilter.FILTER_SKIP: { 1341 // make sure that if any char data is available 1342 // the fFirstChunk is true, so that if the next event 1343 // is characters(), and the last node is text, we will copy 1344 // the value already in the text node to fStringBuffer 1345 // (not to lose it). 1346 fFirstChunk = true; 1347 1348 // replace children 1349 Node parent = fCurrentNode.getParentNode (); 1350 NodeList ls = fCurrentNode.getChildNodes (); 1351 int length = ls.getLength (); 1352 1353 for (int i=0;i<length;i++) { 1354 parent.appendChild (ls.item (0)); 1355 } 1356 parent.removeChild (fCurrentNode); 1357 fCurrentNode = parent; 1358 1359 return; 1360 } 1361 1362 default: { } 1363 } 1364 } 1365 fCurrentNode = fCurrentNode.getParentNode (); 1366 1367 } // end-if DOMFilter 1368 else { 1369 setCharacterData (false); 1370 fCurrentNode = fCurrentNode.getParentNode (); 1371 } 1372 1373 } 1374 else { 1375 if (augs != null) { 1376 ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI); 1377 if (elementPSVI != null) { 1378 // Setting TypeInfo. If the declared type is a union the 1379 // [member type definition] will only be available at the 1380 // end of an element. 1381 XSTypeDefinition type = elementPSVI.getMemberTypeDefinition(); 1382 if (type == null) { 1383 type = elementPSVI.getTypeDefinition(); 1384 } 1385 fDeferredDocumentImpl.setTypeInfo(fCurrentNodeIndex, type); 1386 } 1387 } 1388 fCurrentNodeIndex = 1389 fDeferredDocumentImpl.getParentNode (fCurrentNodeIndex, false); 1390 } 1391 1392 1393 } // endElement(QName) 1394 1395 1396 /** 1397 * The start of a CDATA section. 1398 * @param augs Additional information that may include infoset augmentations 1399 * 1400 * @throws XNIException Thrown by handler to signal an error. 1401 */ 1402 public void startCDATA (Augmentations augs) throws XNIException { 1403 1404 fInCDATASection = true; 1405 if (!fDeferNodeExpansion) { 1406 if (fFilterReject) { 1407 return; 1408 } 1409 if (fCreateCDATANodes) { 1410 setCharacterData (false); 1411 } 1412 } 1413 } // startCDATA() 1414 1415 /** 1416 * The end of a CDATA section. 1417 * @param augs Additional information that may include infoset augmentations 1418 * 1419 * @throws XNIException Thrown by handler to signal an error. 1420 */ 1421 @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT 1422 public void endCDATA (Augmentations augs) throws XNIException { 1423 1424 fInCDATASection = false; 1425 if (!fDeferNodeExpansion) { 1426 1427 if (fFilterReject) { 1428 return; 1429 } 1430 1431 if (fCurrentCDATASection !=null) { 1432 1433 if (fDOMFilter !=null && !fInEntityRef && 1434 (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_CDATA_SECTION)!= 0) { 1435 short code = fDOMFilter.acceptNode (fCurrentCDATASection); 1436 switch (code) { 1437 case LSParserFilter.FILTER_INTERRUPT:{ 1438 throw Abort.INSTANCE; 1439 } 1440 case LSParserFilter.FILTER_REJECT:{ 1441 // fall through to SKIP since CDATA section has no children. 1442 } 1443 case LSParserFilter.FILTER_SKIP: { 1444 Node parent = fCurrentNode.getParentNode (); 1445 parent.removeChild (fCurrentCDATASection); 1446 fCurrentNode = parent; 1447 return; 1448 } 1449 1450 default: { 1451 // accept node 1452 } 1453 } 1454 } 1455 1456 fCurrentNode = fCurrentNode.getParentNode (); 1457 fCurrentCDATASection = null; 1458 } 1459 } 1460 else { 1461 if (fCurrentCDATASectionIndex !=-1) { 1462 fCurrentNodeIndex = 1463 fDeferredDocumentImpl.getParentNode (fCurrentNodeIndex, false); 1464 fCurrentCDATASectionIndex = -1; 1465 } 1466 } 1467 1468 } // endCDATA() 1469 1470 /** 1471 * The end of the document. 1472 * @param augs Additional information that may include infoset augmentations 1473 * 1474 * @throws XNIException Thrown by handler to signal an error. 1475 */ 1476 public void endDocument (Augmentations augs) throws XNIException { 1477 1478 if (!fDeferNodeExpansion) { 1479 // REVISIT: when DOM Level 3 is REC rely on Document.support 1480 // instead of specific class 1481 // set the actual encoding and set DOM error checking back on 1482 if (fDocumentImpl != null) { 1483 if (fLocator != null) { 1484 if (fLocator.getEncoding() != null) 1485 fDocumentImpl.setInputEncoding (fLocator.getEncoding()); 1486 } 1487 fDocumentImpl.setStrictErrorChecking (true); 1488 } 1489 fCurrentNode = null; 1490 } 1491 else { 1492 // set the actual encoding 1493 if (fLocator != null) { 1494 if (fLocator.getEncoding() != null) 1495 fDeferredDocumentImpl.setInputEncoding (fLocator.getEncoding()); 1496 } 1497 fCurrentNodeIndex = -1; 1498 } 1499 1500 } // endDocument() 1501 1502 /** 1503 * This method notifies the end of a general entity. 1504 * <p> 1505 * <strong>Note:</strong> This method is not called for entity references 1506 * appearing as part of attribute values. 1507 * 1508 * @param name The name of the entity. 1509 * @param augs Additional information that may include infoset augmentations 1510 * 1511 * @exception XNIException 1512 * Thrown by handler to signal an error. 1513 */ 1514 public void endGeneralEntity (String name, Augmentations augs) throws XNIException { 1515 if (DEBUG_EVENTS) { 1516 System.out.println ("==>endGeneralEntity: ("+name+")"); 1517 } 1518 if (!fDeferNodeExpansion) { 1519 1520 if (fFilterReject) { 1521 return; 1522 } 1523 setCharacterData (true); 1524 1525 if (fDocumentType != null) { 1526 // get current entity declaration 1527 NamedNodeMap entities = fDocumentType.getEntities (); 1528 fCurrentEntityDecl = (EntityImpl) entities.getNamedItem (name); 1529 if (fCurrentEntityDecl != null) { 1530 if (fCurrentEntityDecl != null && fCurrentEntityDecl.getFirstChild () == null) { 1531 fCurrentEntityDecl.setReadOnly (false, true); 1532 Node child = fCurrentNode.getFirstChild (); 1533 while (child != null) { 1534 Node copy = child.cloneNode (true); 1535 fCurrentEntityDecl.appendChild (copy); 1536 child = child.getNextSibling (); 1537 } 1538 fCurrentEntityDecl.setReadOnly (true, true); 1539 1540 //entities.setNamedItem(fCurrentEntityDecl); 1541 } 1542 fCurrentEntityDecl = null; 1543 } 1544 1545 } 1546 fInEntityRef = false; 1547 boolean removeEntityRef = false; 1548 if (fCreateEntityRefNodes) { 1549 if (fDocumentImpl != null) { 1550 // Make entity ref node read only 1551 ((NodeImpl)fCurrentNode).setReadOnly (true, true); 1552 } 1553 1554 if (fDOMFilter !=null && 1555 (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_ENTITY_REFERENCE)!= 0) { 1556 short code = fDOMFilter.acceptNode (fCurrentNode); 1557 switch (code) { 1558 case LSParserFilter.FILTER_INTERRUPT:{ 1559 throw Abort.INSTANCE; 1560 } 1561 case LSParserFilter.FILTER_REJECT:{ 1562 Node parent = fCurrentNode.getParentNode (); 1563 parent.removeChild (fCurrentNode); 1564 fCurrentNode = parent; 1565 return; 1566 1567 } 1568 case LSParserFilter.FILTER_SKIP: { 1569 // make sure we don't loose chars if next event is characters() 1570 fFirstChunk = true; 1571 removeEntityRef = true; 1572 break; 1573 } 1574 1575 default: { 1576 fCurrentNode = fCurrentNode.getParentNode (); 1577 } 1578 } 1579 } else { 1580 fCurrentNode = fCurrentNode.getParentNode (); 1581 } 1582 } 1583 1584 if (!fCreateEntityRefNodes || removeEntityRef) { 1585 // move entity reference children to the list of 1586 // siblings of its parent and remove entity reference 1587 NodeList children = fCurrentNode.getChildNodes (); 1588 Node parent = fCurrentNode.getParentNode (); 1589 int length = children.getLength (); 1590 if (length > 0) { 1591 1592 // get previous sibling of the entity reference 1593 Node node = fCurrentNode.getPreviousSibling (); 1594 // normalize text nodes 1595 Node child = children.item (0); 1596 if (node != null && node.getNodeType () == Node.TEXT_NODE && 1597 child.getNodeType () == Node.TEXT_NODE) { 1598 ((Text)node).appendData (child.getNodeValue ()); 1599 fCurrentNode.removeChild (child); 1600 1601 } else { 1602 node = parent.insertBefore (child, fCurrentNode); 1603 handleBaseURI (node); 1604 } 1605 1606 for (int i=1;i <length;i++) { 1607 node = parent.insertBefore (children.item (0), fCurrentNode); 1608 handleBaseURI (node); 1609 } 1610 } // length > 0 1611 parent.removeChild (fCurrentNode); 1612 fCurrentNode = parent; 1613 } 1614 } 1615 else { 1616 1617 if (fDocumentTypeIndex != -1) { 1618 // find corresponding Entity decl 1619 int node = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false); 1620 while (node != -1) { 1621 short nodeType = fDeferredDocumentImpl.getNodeType (node, false); 1622 if (nodeType == Node.ENTITY_NODE) { 1623 String nodeName = 1624 fDeferredDocumentImpl.getNodeName (node, false); 1625 if (nodeName.equals (name)) { 1626 fDeferredEntityDecl = node; 1627 break; 1628 } 1629 } 1630 node = fDeferredDocumentImpl.getRealPrevSibling (node, false); 1631 } 1632 } 1633 1634 if (fDeferredEntityDecl != -1 && 1635 fDeferredDocumentImpl.getLastChild (fDeferredEntityDecl, false) == -1) { 1636 // entity definition exists and it does not have any children 1637 int prevIndex = -1; 1638 int childIndex = fDeferredDocumentImpl.getLastChild (fCurrentNodeIndex, false); 1639 while (childIndex != -1) { 1640 int cloneIndex = fDeferredDocumentImpl.cloneNode (childIndex, true); 1641 fDeferredDocumentImpl.insertBefore (fDeferredEntityDecl, cloneIndex, prevIndex); 1642 prevIndex = cloneIndex; 1643 childIndex = fDeferredDocumentImpl.getRealPrevSibling (childIndex, false); 1644 } 1645 } 1646 if (fCreateEntityRefNodes) { 1647 fCurrentNodeIndex = 1648 fDeferredDocumentImpl.getParentNode (fCurrentNodeIndex, 1649 false); 1650 } else { //!fCreateEntityRefNodes 1651 // move children of entity ref before the entity ref. 1652 // remove entity ref. 1653 1654 // holds a child of entity ref 1655 int childIndex = fDeferredDocumentImpl.getLastChild (fCurrentNodeIndex, false); 1656 int parentIndex = 1657 fDeferredDocumentImpl.getParentNode (fCurrentNodeIndex, 1658 false); 1659 1660 int prevIndex = fCurrentNodeIndex; 1661 int lastChild = childIndex; 1662 int sibling = -1; 1663 while (childIndex != -1) { 1664 handleBaseURI (childIndex); 1665 sibling = fDeferredDocumentImpl.getRealPrevSibling (childIndex, false); 1666 fDeferredDocumentImpl.insertBefore (parentIndex, childIndex, prevIndex); 1667 prevIndex = childIndex; 1668 childIndex = sibling; 1669 } 1670 if(lastChild != -1) 1671 fDeferredDocumentImpl.setAsLastChild (parentIndex, lastChild); 1672 else{ 1673 sibling = fDeferredDocumentImpl.getRealPrevSibling (prevIndex, false); 1674 fDeferredDocumentImpl.setAsLastChild (parentIndex, sibling); 1675 } 1676 fCurrentNodeIndex = parentIndex; 1677 } 1678 fDeferredEntityDecl = -1; 1679 } 1680 1681 1682 } // endGeneralEntity(String, Augmentations) 1683 1684 1685 /** 1686 * Record baseURI information for the Element (by adding xml:base attribute) 1687 * or for the ProcessingInstruction (by setting a baseURI field) 1688 * Non deferred DOM. 1689 * 1690 * @param node 1691 */ 1692 protected final void handleBaseURI (Node node){ 1693 if (fDocumentImpl != null) { 1694 // REVISIT: remove dependency on our implementation when 1695 // DOM L3 becomes REC 1696 1697 String baseURI = null; 1698 short nodeType = node.getNodeType (); 1699 1700 if (nodeType == Node.ELEMENT_NODE) { 1701 // if an element already has xml:base attribute 1702 // do nothing 1703 if (fNamespaceAware) { 1704 if (((Element)node).getAttributeNodeNS ("http://www.w3.org/XML/1998/namespace","base")!=null) { 1705 return; 1706 } 1707 } else if (((Element)node).getAttributeNode ("xml:base") != null) { 1708 return; 1709 } 1710 // retrive the baseURI from the entity reference 1711 baseURI = ((EntityReferenceImpl)fCurrentNode).getBaseURI (); 1712 if (baseURI !=null && !baseURI.equals (fDocumentImpl.getDocumentURI ())) { 1713 if (fNamespaceAware) { 1714 ((Element)node).setAttributeNS ("http://www.w3.org/XML/1998/namespace", "xml:base", baseURI); 1715 } else { 1716 ((Element)node).setAttribute ("xml:base", baseURI); 1717 } 1718 } 1719 } 1720 else if (nodeType == Node.PROCESSING_INSTRUCTION_NODE) { 1721 1722 baseURI = ((EntityReferenceImpl)fCurrentNode).getBaseURI (); 1723 if (baseURI !=null && fErrorHandler != null) { 1724 DOMErrorImpl error = new DOMErrorImpl (); 1725 error.fType = "pi-base-uri-not-preserved"; 1726 error.fRelatedData = baseURI; 1727 error.fSeverity = DOMError.SEVERITY_WARNING; 1728 fErrorHandler.getErrorHandler ().handleError (error); 1729 } 1730 } 1731 } 1732 } 1733 1734 /** 1735 * 1736 * Record baseURI information for the Element (by adding xml:base attribute) 1737 * or for the ProcessingInstruction (by setting a baseURI field) 1738 * Deferred DOM. 1739 * 1740 * @param node 1741 */ 1742 protected final void handleBaseURI (int node){ 1743 short nodeType = fDeferredDocumentImpl.getNodeType (node, false); 1744 1745 if (nodeType == Node.ELEMENT_NODE) { 1746 String baseURI = fDeferredDocumentImpl.getNodeValueString (fCurrentNodeIndex, false); 1747 if (baseURI == null) { 1748 baseURI = fDeferredDocumentImpl.getDeferredEntityBaseURI (fDeferredEntityDecl); 1749 } 1750 if (baseURI !=null && !baseURI.equals (fDeferredDocumentImpl.getDocumentURI ())) { 1751 fDeferredDocumentImpl.setDeferredAttribute (node, 1752 "xml:base", 1753 "http://www.w3.org/XML/1998/namespace", 1754 baseURI, 1755 true, 1756 false, 1757 null); 1758 } 1759 } 1760 else if (nodeType == Node.PROCESSING_INSTRUCTION_NODE) { 1761 1762 1763 // retrieve baseURI from the entity reference 1764 String baseURI = fDeferredDocumentImpl.getNodeValueString (fCurrentNodeIndex, false); 1765 1766 if (baseURI == null) { 1767 // try baseURI of the entity declaration 1768 baseURI = fDeferredDocumentImpl.getDeferredEntityBaseURI (fDeferredEntityDecl); 1769 } 1770 1771 if (baseURI != null && fErrorHandler != null) { 1772 DOMErrorImpl error = new DOMErrorImpl (); 1773 error.fType = "pi-base-uri-not-preserved"; 1774 error.fRelatedData = baseURI; 1775 error.fSeverity = DOMError.SEVERITY_WARNING; 1776 fErrorHandler.getErrorHandler ().handleError (error); 1777 } 1778 } 1779 } 1780 1781 1782 // 1783 // XMLDTDHandler methods 1784 // 1785 1786 /** 1787 * The start of the DTD. 1788 * 1789 * @param locator The document locator, or null if the document 1790 * location cannot be reported during the parsing of 1791 * the document DTD. However, it is <em>strongly</em> 1792 * recommended that a locator be supplied that can 1793 * at least report the base system identifier of the 1794 * DTD. 1795 * @param augs Additional information that may include infoset 1796 * augmentations. 1797 * 1798 * @throws XNIException Thrown by handler to signal an error. 1799 */ 1800 public void startDTD (XMLLocator locator, Augmentations augs) throws XNIException { 1801 if (DEBUG_EVENTS) { 1802 System.out.println ("==>startDTD"); 1803 if (DEBUG_BASEURI) { 1804 System.out.println (" expandedSystemId: "+locator.getExpandedSystemId ()); 1805 System.out.println (" baseURI:"+ locator.getBaseSystemId ()); 1806 } 1807 } 1808 1809 fInDTD = true; 1810 if (locator != null) { 1811 fBaseURIStack.push (locator.getBaseSystemId ()); 1812 } 1813 if (fDeferNodeExpansion || fDocumentImpl != null) { 1814 fInternalSubset = new StringBuilder (1024); 1815 } 1816 } // startDTD(XMLLocator) 1817 1818 1819 /** 1820 * The end of the DTD. 1821 * 1822 * @param augs Additional information that may include infoset 1823 * augmentations. 1824 * 1825 * @throws XNIException Thrown by handler to signal an error. 1826 */ 1827 public void endDTD (Augmentations augs) throws XNIException { 1828 if (DEBUG_EVENTS) { 1829 System.out.println ("==>endDTD()"); 1830 } 1831 fInDTD = false; 1832 if (!fBaseURIStack.isEmpty ()) { 1833 fBaseURIStack.pop (); 1834 } 1835 String internalSubset = fInternalSubset != null && fInternalSubset.length () > 0 1836 ? fInternalSubset.toString () : null; 1837 if (fDeferNodeExpansion) { 1838 if (internalSubset != null) { 1839 fDeferredDocumentImpl.setInternalSubset (fDocumentTypeIndex, internalSubset); 1840 } 1841 } 1842 else if (fDocumentImpl != null) { 1843 if (internalSubset != null) { 1844 ((DocumentTypeImpl)fDocumentType).setInternalSubset (internalSubset); 1845 } 1846 } 1847 } // endDTD() 1848 1849 /** 1850 * The start of a conditional section. 1851 * 1852 * @param type The type of the conditional section. This value will 1853 * either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE. 1854 * @param augs Additional information that may include infoset 1855 * augmentations. 1856 * 1857 * @throws XNIException Thrown by handler to signal an error. 1858 * 1859 * @see #CONDITIONAL_INCLUDE 1860 * @see #CONDITIONAL_IGNORE 1861 */ 1862 public void startConditional (short type, Augmentations augs) throws XNIException { 1863 } // startConditional(short) 1864 1865 /** 1866 * The end of a conditional section. 1867 * 1868 * @param augs Additional information that may include infoset 1869 * augmentations. 1870 * 1871 * @throws XNIException Thrown by handler to signal an error. 1872 */ 1873 public void endConditional (Augmentations augs) throws XNIException { 1874 } // endConditional() 1875 1876 1877 /** 1878 * The start of the DTD external subset. 1879 * 1880 * @param augs Additional information that may include infoset 1881 * augmentations. 1882 * 1883 * @throws XNIException Thrown by handler to signal an error. 1884 */ 1885 public void startExternalSubset (XMLResourceIdentifier identifier, 1886 Augmentations augs) throws XNIException { 1887 if (DEBUG_EVENTS) { 1888 System.out.println ("==>startExternalSubset"); 1889 if (DEBUG_BASEURI) { 1890 System.out.println (" expandedSystemId: "+identifier.getExpandedSystemId ()); 1891 System.out.println (" baseURI:"+ identifier.getBaseSystemId ()); 1892 } 1893 } 1894 fBaseURIStack.push (identifier.getBaseSystemId ()); 1895 fInDTDExternalSubset = true; 1896 } // startExternalSubset(Augmentations) 1897 1898 /** 1899 * The end of the DTD external subset. 1900 * 1901 * @param augs Additional information that may include infoset 1902 * augmentations. 1903 * 1904 * @throws XNIException Thrown by handler to signal an error. 1905 */ 1906 public void endExternalSubset (Augmentations augs) throws XNIException { 1907 fInDTDExternalSubset = false; 1908 fBaseURIStack.pop (); 1909 } // endExternalSubset(Augmentations) 1910 1911 /** 1912 * An internal entity declaration. 1913 * 1914 * @param name The name of the entity. Parameter entity names start with 1915 * '%', whereas the name of a general entity is just the 1916 * entity name. 1917 * @param text The value of the entity. 1918 * @param nonNormalizedText The non-normalized value of the entity. This 1919 * value contains the same sequence of characters that was in 1920 * the internal entity declaration, without any entity 1921 * references expanded. 1922 * @param augs Additional information that may include infoset 1923 * augmentations. 1924 * 1925 * @throws XNIException Thrown by handler to signal an error. 1926 */ 1927 public void internalEntityDecl (String name, XMLString text, 1928 XMLString nonNormalizedText, 1929 Augmentations augs) throws XNIException { 1930 1931 if (DEBUG_EVENTS) { 1932 System.out.println ("==>internalEntityDecl: "+name); 1933 if (DEBUG_BASEURI) { 1934 System.out.println (" baseURI:"+ fBaseURIStack.peek ()); 1935 } 1936 } 1937 // internal subset string 1938 if (fInternalSubset != null && !fInDTDExternalSubset) { 1939 fInternalSubset.append ("<!ENTITY "); 1940 if (name.startsWith ("%")) { 1941 fInternalSubset.append ("% "); 1942 fInternalSubset.append (name.substring (1)); 1943 } 1944 else { 1945 fInternalSubset.append (name); 1946 } 1947 fInternalSubset.append (' '); 1948 String value = nonNormalizedText.toString (); 1949 boolean singleQuote = value.indexOf ('\'') == -1; 1950 fInternalSubset.append (singleQuote ? '\'' : '"'); 1951 fInternalSubset.append (value); 1952 fInternalSubset.append (singleQuote ? '\'' : '"'); 1953 fInternalSubset.append (">\n"); 1954 } 1955 1956 // NOTE: We only know how to create these nodes for the Xerces 1957 // DOM implementation because DOM Level 2 does not specify 1958 // that functionality. -Ac 1959 1960 // create full node 1961 // don't add parameter entities! 1962 if(name.startsWith ("%")) 1963 return; 1964 if (fDocumentType != null) { 1965 NamedNodeMap entities = fDocumentType.getEntities (); 1966 EntityImpl entity = (EntityImpl)entities.getNamedItem (name); 1967 if (entity == null) { 1968 entity = (EntityImpl)fDocumentImpl.createEntity (name); 1969 entity.setBaseURI (fBaseURIStack.peek ()); 1970 entities.setNamedItem (entity); 1971 } 1972 } 1973 1974 // create deferred node 1975 if (fDocumentTypeIndex != -1) { 1976 boolean found = false; 1977 int node = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false); 1978 while (node != -1) { 1979 short nodeType = fDeferredDocumentImpl.getNodeType (node, false); 1980 if (nodeType == Node.ENTITY_NODE) { 1981 String nodeName = fDeferredDocumentImpl.getNodeName (node, false); 1982 if (nodeName.equals (name)) { 1983 found = true; 1984 break; 1985 } 1986 } 1987 node = fDeferredDocumentImpl.getRealPrevSibling (node, false); 1988 } 1989 if (!found) { 1990 int entityIndex = 1991 fDeferredDocumentImpl.createDeferredEntity (name, null, null, null, fBaseURIStack.peek ()); 1992 fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, entityIndex); 1993 } 1994 } 1995 1996 } // internalEntityDecl(String,XMLString,XMLString) 1997 1998 /** 1999 * An external entity declaration. 2000 * 2001 * @param name The name of the entity. Parameter entity names start 2002 * with '%', whereas the name of a general entity is just 2003 * the entity name. 2004 * @param identifier An object containing all location information 2005 * pertinent to this notation. 2006 * @param augs Additional information that may include infoset 2007 * augmentations. 2008 * 2009 * @throws XNIException Thrown by handler to signal an error. 2010 */ 2011 public void externalEntityDecl (String name, XMLResourceIdentifier identifier, 2012 Augmentations augs) throws XNIException { 2013 2014 2015 if (DEBUG_EVENTS) { 2016 System.out.println ("==>externalEntityDecl: "+name); 2017 if (DEBUG_BASEURI) { 2018 System.out.println (" expandedSystemId:"+ identifier.getExpandedSystemId ()); 2019 System.out.println (" baseURI:"+ identifier.getBaseSystemId ()); 2020 } 2021 } 2022 // internal subset string 2023 String publicId = identifier.getPublicId (); 2024 String literalSystemId = identifier.getLiteralSystemId (); 2025 if (fInternalSubset != null && !fInDTDExternalSubset) { 2026 fInternalSubset.append ("<!ENTITY "); 2027 if (name.startsWith ("%")) { 2028 fInternalSubset.append ("% "); 2029 fInternalSubset.append (name.substring (1)); 2030 } 2031 else { 2032 fInternalSubset.append (name); 2033 } 2034 fInternalSubset.append (' '); 2035 if (publicId != null) { 2036 fInternalSubset.append ("PUBLIC '"); 2037 fInternalSubset.append (publicId); 2038 fInternalSubset.append ("' '"); 2039 } 2040 else { 2041 fInternalSubset.append ("SYSTEM '"); 2042 } 2043 fInternalSubset.append (literalSystemId); 2044 fInternalSubset.append ("'>\n"); 2045 } 2046 2047 // NOTE: We only know how to create these nodes for the Xerces 2048 // DOM implementation because DOM Level 2 does not specify 2049 // that functionality. -Ac 2050 2051 // create full node 2052 // don't add parameter entities! 2053 if(name.startsWith ("%")) 2054 return; 2055 if (fDocumentType != null) { 2056 NamedNodeMap entities = fDocumentType.getEntities (); 2057 EntityImpl entity = (EntityImpl)entities.getNamedItem (name); 2058 if (entity == null) { 2059 entity = (EntityImpl)fDocumentImpl.createEntity (name); 2060 entity.setPublicId (publicId); 2061 entity.setSystemId (literalSystemId); 2062 entity.setBaseURI (identifier.getBaseSystemId ()); 2063 entities.setNamedItem (entity); 2064 } 2065 } 2066 2067 // create deferred node 2068 if (fDocumentTypeIndex != -1) { 2069 boolean found = false; 2070 int nodeIndex = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false); 2071 while (nodeIndex != -1) { 2072 short nodeType = fDeferredDocumentImpl.getNodeType (nodeIndex, false); 2073 if (nodeType == Node.ENTITY_NODE) { 2074 String nodeName = fDeferredDocumentImpl.getNodeName (nodeIndex, false); 2075 if (nodeName.equals (name)) { 2076 found = true; 2077 break; 2078 } 2079 } 2080 nodeIndex = fDeferredDocumentImpl.getRealPrevSibling (nodeIndex, false); 2081 } 2082 if (!found) { 2083 int entityIndex = fDeferredDocumentImpl.createDeferredEntity ( 2084 name, publicId, literalSystemId, null, identifier.getBaseSystemId ()); 2085 fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, entityIndex); 2086 } 2087 } 2088 2089 } // externalEntityDecl(String,XMLResourceIdentifier, Augmentations) 2090 2091 2092 /** 2093 * This method notifies of the start of a parameter entity. The parameter 2094 * entity name start with a '%' character. 2095 * 2096 * @param name The name of the parameter entity. 2097 * @param identifier The resource identifier. 2098 * @param encoding The auto-detected IANA encoding name of the entity 2099 * stream. This value will be null in those situations 2100 * where the entity encoding is not auto-detected (e.g. 2101 * internal parameter entities). 2102 * @param augs Additional information that may include infoset 2103 * augmentations. 2104 * 2105 * @throws XNIException Thrown by handler to signal an error. 2106 */ 2107 public void startParameterEntity (String name, 2108 XMLResourceIdentifier identifier, 2109 String encoding, 2110 Augmentations augs) throws XNIException { 2111 if (DEBUG_EVENTS) { 2112 System.out.println ("==>startParameterEntity: "+name); 2113 if (DEBUG_BASEURI) { 2114 System.out.println (" expandedSystemId: "+identifier.getExpandedSystemId ()); 2115 System.out.println (" baseURI:"+ identifier.getBaseSystemId ()); 2116 } 2117 } 2118 if (augs != null && fInternalSubset != null && 2119 !fInDTDExternalSubset && 2120 Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) { 2121 fInternalSubset.append(name).append(";\n"); 2122 } 2123 fBaseURIStack.push (identifier.getExpandedSystemId ()); 2124 } 2125 2126 2127 /** 2128 * This method notifies the end of a parameter entity. Parameter entity 2129 * names begin with a '%' character. 2130 * 2131 * @param name The name of the parameter entity. 2132 * @param augs Additional information that may include infoset 2133 * augmentations. 2134 * 2135 * @throws XNIException Thrown by handler to signal an error. 2136 */ 2137 public void endParameterEntity (String name, Augmentations augs) throws XNIException { 2138 2139 if (DEBUG_EVENTS) { 2140 System.out.println ("==>endParameterEntity: "+name); 2141 } 2142 fBaseURIStack.pop (); 2143 } 2144 2145 /** 2146 * An unparsed entity declaration. 2147 * 2148 * @param name The name of the entity. 2149 * @param identifier An object containing all location information 2150 * pertinent to this entity. 2151 * @param notation The name of the notation. 2152 * @param augs Additional information that may include infoset 2153 * augmentations. 2154 * 2155 * @throws XNIException Thrown by handler to signal an error. 2156 */ 2157 public void unparsedEntityDecl (String name, XMLResourceIdentifier identifier, 2158 String notation, Augmentations augs) 2159 throws XNIException { 2160 2161 if (DEBUG_EVENTS) { 2162 System.out.println ("==>unparsedEntityDecl: "+name); 2163 if (DEBUG_BASEURI) { 2164 System.out.println (" expandedSystemId:"+ identifier.getExpandedSystemId ()); 2165 System.out.println (" baseURI:"+ identifier.getBaseSystemId ()); 2166 } 2167 } 2168 // internal subset string 2169 String publicId = identifier.getPublicId (); 2170 String literalSystemId = identifier.getLiteralSystemId (); 2171 if (fInternalSubset != null && !fInDTDExternalSubset) { 2172 fInternalSubset.append ("<!ENTITY "); 2173 fInternalSubset.append (name); 2174 fInternalSubset.append (' '); 2175 if (publicId != null) { 2176 fInternalSubset.append ("PUBLIC '"); 2177 fInternalSubset.append (publicId); 2178 if (literalSystemId != null) { 2179 fInternalSubset.append ("' '"); 2180 fInternalSubset.append (literalSystemId); 2181 } 2182 } 2183 else { 2184 fInternalSubset.append ("SYSTEM '"); 2185 fInternalSubset.append (literalSystemId); 2186 } 2187 fInternalSubset.append ("' NDATA "); 2188 fInternalSubset.append (notation); 2189 fInternalSubset.append (">\n"); 2190 } 2191 2192 // NOTE: We only know how to create these nodes for the Xerces 2193 // DOM implementation because DOM Level 2 does not specify 2194 // that functionality. -Ac 2195 2196 // create full node 2197 if (fDocumentType != null) { 2198 NamedNodeMap entities = fDocumentType.getEntities (); 2199 EntityImpl entity = (EntityImpl)entities.getNamedItem (name); 2200 if (entity == null) { 2201 entity = (EntityImpl)fDocumentImpl.createEntity (name); 2202 entity.setPublicId (publicId); 2203 entity.setSystemId (literalSystemId); 2204 entity.setNotationName (notation); 2205 entity.setBaseURI (identifier.getBaseSystemId ()); 2206 entities.setNamedItem (entity); 2207 } 2208 } 2209 2210 // create deferred node 2211 if (fDocumentTypeIndex != -1) { 2212 boolean found = false; 2213 int nodeIndex = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false); 2214 while (nodeIndex != -1) { 2215 short nodeType = fDeferredDocumentImpl.getNodeType (nodeIndex, false); 2216 if (nodeType == Node.ENTITY_NODE) { 2217 String nodeName = fDeferredDocumentImpl.getNodeName (nodeIndex, false); 2218 if (nodeName.equals (name)) { 2219 found = true; 2220 break; 2221 } 2222 } 2223 nodeIndex = fDeferredDocumentImpl.getRealPrevSibling (nodeIndex, false); 2224 } 2225 if (!found) { 2226 int entityIndex = fDeferredDocumentImpl.createDeferredEntity ( 2227 name, publicId, literalSystemId, notation, identifier.getBaseSystemId ()); 2228 fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, entityIndex); 2229 } 2230 } 2231 2232 } // unparsedEntityDecl(String,XMLResourceIdentifier, String, Augmentations) 2233 2234 /** 2235 * A notation declaration 2236 * 2237 * @param name The name of the notation. 2238 * @param identifier An object containing all location information 2239 * pertinent to this notation. 2240 * @param augs Additional information that may include infoset 2241 * augmentations. 2242 * 2243 * @throws XNIException Thrown by handler to signal an error. 2244 */ 2245 public void notationDecl (String name, XMLResourceIdentifier identifier, 2246 Augmentations augs) throws XNIException { 2247 2248 // internal subset string 2249 String publicId = identifier.getPublicId (); 2250 String literalSystemId = identifier.getLiteralSystemId (); 2251 if (fInternalSubset != null && !fInDTDExternalSubset) { 2252 fInternalSubset.append ("<!NOTATION "); 2253 fInternalSubset.append (name); 2254 if (publicId != null) { 2255 fInternalSubset.append (" PUBLIC '"); 2256 fInternalSubset.append (publicId); 2257 if (literalSystemId != null) { 2258 fInternalSubset.append ("' '"); 2259 fInternalSubset.append (literalSystemId); 2260 } 2261 } 2262 else { 2263 fInternalSubset.append (" SYSTEM '"); 2264 fInternalSubset.append (literalSystemId); 2265 } 2266 fInternalSubset.append ("'>\n"); 2267 } 2268 2269 // NOTE: We only know how to create these nodes for the Xerces 2270 // DOM implementation because DOM Level 2 does not specify 2271 // that functionality. -Ac 2272 2273 // create full node 2274 if (fDocumentImpl !=null && fDocumentType != null) { 2275 NamedNodeMap notations = fDocumentType.getNotations (); 2276 if (notations.getNamedItem (name) == null) { 2277 NotationImpl notation = (NotationImpl)fDocumentImpl.createNotation (name); 2278 notation.setPublicId (publicId); 2279 notation.setSystemId (literalSystemId); 2280 notation.setBaseURI (identifier.getBaseSystemId ()); 2281 notations.setNamedItem (notation); 2282 } 2283 } 2284 2285 // create deferred node 2286 if (fDocumentTypeIndex != -1) { 2287 boolean found = false; 2288 int nodeIndex = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false); 2289 while (nodeIndex != -1) { 2290 short nodeType = fDeferredDocumentImpl.getNodeType (nodeIndex, false); 2291 if (nodeType == Node.NOTATION_NODE) { 2292 String nodeName = fDeferredDocumentImpl.getNodeName (nodeIndex, false); 2293 if (nodeName.equals (name)) { 2294 found = true; 2295 break; 2296 } 2297 } 2298 nodeIndex = fDeferredDocumentImpl.getPrevSibling (nodeIndex, false); 2299 } 2300 if (!found) { 2301 int notationIndex = fDeferredDocumentImpl.createDeferredNotation ( 2302 name, publicId, literalSystemId, identifier.getBaseSystemId ()); 2303 fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, notationIndex); 2304 } 2305 } 2306 2307 } // notationDecl(String,XMLResourceIdentifier, Augmentations) 2308 2309 /** 2310 * Characters within an IGNORE conditional section. 2311 * 2312 * @param text The ignored text. 2313 * @param augs Additional information that may include infoset 2314 * augmentations. 2315 * 2316 * @throws XNIException Thrown by handler to signal an error. 2317 */ 2318 public void ignoredCharacters (XMLString text, Augmentations augs) throws XNIException { 2319 } // ignoredCharacters(XMLString, Augmentations) 2320 2321 2322 /** 2323 * An element declaration. 2324 * 2325 * @param name The name of the element. 2326 * @param contentModel The element content model. 2327 * @param augs Additional information that may include infoset 2328 * augmentations. 2329 * 2330 * @throws XNIException Thrown by handler to signal an error. 2331 */ 2332 public void elementDecl (String name, String contentModel, Augmentations augs) 2333 throws XNIException { 2334 2335 // internal subset string 2336 if (fInternalSubset != null && !fInDTDExternalSubset) { 2337 fInternalSubset.append ("<!ELEMENT "); 2338 fInternalSubset.append (name); 2339 fInternalSubset.append (' '); 2340 fInternalSubset.append (contentModel); 2341 fInternalSubset.append (">\n"); 2342 } 2343 2344 } // elementDecl(String,String) 2345 2346 /** 2347 * An attribute declaration. 2348 * 2349 * @param elementName The name of the element that this attribute 2350 * is associated with. 2351 * @param attributeName The name of the attribute. 2352 * @param type The attribute type. This value will be one of 2353 * the following: "CDATA", "ENTITY", "ENTITIES", 2354 * "ENUMERATION", "ID", "IDREF", "IDREFS", 2355 * "NMTOKEN", "NMTOKENS", or "NOTATION". 2356 * @param enumeration If the type has the value "ENUMERATION" or 2357 * "NOTATION", this array holds the allowed attribute 2358 * values; otherwise, this array is null. 2359 * @param defaultType The attribute default type. This value will be 2360 * one of the following: "#FIXED", "#IMPLIED", 2361 * "#REQUIRED", or null. 2362 * @param defaultValue The attribute default value, or null if no 2363 * default value is specified. 2364 * @param nonNormalizedDefaultValue The attribute default value with no normalization 2365 * performed, or null if no default value is specified. 2366 * @param augs Additional information that may include infoset 2367 * augmentations. 2368 * 2369 * @throws XNIException Thrown by handler to signal an error. 2370 */ 2371 public void attributeDecl (String elementName, String attributeName, 2372 String type, String[] enumeration, 2373 String defaultType, XMLString defaultValue, 2374 XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException { 2375 2376 // internal subset string 2377 if (fInternalSubset != null && !fInDTDExternalSubset) { 2378 fInternalSubset.append ("<!ATTLIST "); 2379 fInternalSubset.append (elementName); 2380 fInternalSubset.append (' '); 2381 fInternalSubset.append (attributeName); 2382 fInternalSubset.append (' '); 2383 if (type.equals ("ENUMERATION")) { 2384 fInternalSubset.append ('('); 2385 for (int i = 0; i < enumeration.length; i++) { 2386 if (i > 0) { 2387 fInternalSubset.append ('|'); 2388 } 2389 fInternalSubset.append (enumeration[i]); 2390 } 2391 fInternalSubset.append (')'); 2392 } 2393 else { 2394 fInternalSubset.append (type); 2395 } 2396 if (defaultType != null) { 2397 fInternalSubset.append (' '); 2398 fInternalSubset.append (defaultType); 2399 } 2400 if (defaultValue != null) { 2401 fInternalSubset.append (" '"); 2402 for (int i = 0; i < defaultValue.length; i++) { 2403 char c = defaultValue.ch[defaultValue.offset + i]; 2404 if (c == '\'') { 2405 fInternalSubset.append ("'"); 2406 } 2407 else { 2408 fInternalSubset.append (c); 2409 } 2410 } 2411 fInternalSubset.append ('\''); 2412 } 2413 fInternalSubset.append (">\n"); 2414 } 2415 // REVISIT: This code applies to the support of domx/grammar-access 2416 // feature in Xerces 1 2417 2418 // deferred expansion 2419 if (fDeferredDocumentImpl != null) { 2420 2421 // get the default value 2422 if (defaultValue != null) { 2423 2424 // get element definition 2425 int elementDefIndex = fDeferredDocumentImpl.lookupElementDefinition (elementName); 2426 2427 // create element definition if not already there 2428 if (elementDefIndex == -1) { 2429 elementDefIndex = fDeferredDocumentImpl.createDeferredElementDefinition (elementName); 2430 fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, elementDefIndex); 2431 } 2432 // add default attribute 2433 boolean nsEnabled = fNamespaceAware; 2434 String namespaceURI = null; 2435 if (nsEnabled) { 2436 // DOM Level 2 wants all namespace declaration attributes 2437 // to be bound to "http://www.w3.org/2000/xmlns/" 2438 // So as long as the XML parser doesn't do it, it needs to 2439 // done here. 2440 if (attributeName.startsWith("xmlns:") || 2441 attributeName.equals("xmlns")) { 2442 namespaceURI = NamespaceContext.XMLNS_URI; 2443 } 2444 else if (attributeName.startsWith("xml:")) { 2445 namespaceURI = NamespaceContext.XML_URI; 2446 } 2447 } 2448 int attrIndex = fDeferredDocumentImpl.createDeferredAttribute ( 2449 attributeName, namespaceURI, defaultValue.toString(), false); 2450 if ("ID".equals (type)) { 2451 fDeferredDocumentImpl.setIdAttribute (attrIndex); 2452 } 2453 // REVISIT: set ID type correctly 2454 fDeferredDocumentImpl.appendChild (elementDefIndex, attrIndex); 2455 } 2456 2457 } // if deferred 2458 2459 // full expansion 2460 else if (fDocumentImpl != null) { 2461 2462 // get the default value 2463 if (defaultValue != null) { 2464 2465 // get element definition node 2466 NamedNodeMap elements = ((DocumentTypeImpl)fDocumentType).getElements (); 2467 ElementDefinitionImpl elementDef = (ElementDefinitionImpl)elements.getNamedItem (elementName); 2468 if (elementDef == null) { 2469 elementDef = fDocumentImpl.createElementDefinition (elementName); 2470 ((DocumentTypeImpl)fDocumentType).getElements ().setNamedItem (elementDef); 2471 } 2472 2473 // REVISIT: Check for uniqueness of element name? -Ac 2474 2475 // create attribute and set properties 2476 boolean nsEnabled = fNamespaceAware; 2477 AttrImpl attr; 2478 if (nsEnabled) { 2479 String namespaceURI = null; 2480 // DOM Level 2 wants all namespace declaration attributes 2481 // to be bound to "http://www.w3.org/2000/xmlns/" 2482 // So as long as the XML parser doesn't do it, it needs to 2483 // done here. 2484 if (attributeName.startsWith("xmlns:") || 2485 attributeName.equals("xmlns")) { 2486 namespaceURI = NamespaceContext.XMLNS_URI; 2487 } 2488 else if (attributeName.startsWith("xml:")) { 2489 namespaceURI = NamespaceContext.XML_URI; 2490 } 2491 attr = (AttrImpl)fDocumentImpl.createAttributeNS (namespaceURI, 2492 attributeName); 2493 } 2494 else { 2495 attr = (AttrImpl)fDocumentImpl.createAttribute (attributeName); 2496 } 2497 attr.setValue (defaultValue.toString ()); 2498 attr.setSpecified (false); 2499 attr.setIdAttribute ("ID".equals (type)); 2500 2501 // add default attribute to element definition 2502 if (nsEnabled){ 2503 elementDef.getAttributes ().setNamedItemNS (attr); 2504 } 2505 else { 2506 elementDef.getAttributes ().setNamedItem (attr); 2507 } 2508 } 2509 2510 } // if NOT defer-node-expansion 2511 2512 } // attributeDecl(String,String,String,String[],String,XMLString, XMLString, Augmentations) 2513 2514 2515 /** 2516 * The start of an attribute list. 2517 * 2518 * @param elementName The name of the element that this attribute 2519 * list is associated with. 2520 * @param augs Additional information that may include infoset 2521 * augmentations. 2522 * 2523 * @throws XNIException Thrown by handler to signal an error. 2524 */ 2525 public void startAttlist (String elementName, Augmentations augs) throws XNIException { 2526 } // startAttlist(String) 2527 2528 2529 /** 2530 * The end of an attribute list. 2531 * 2532 * @param augs Additional information that may include infoset 2533 * augmentations. 2534 * 2535 * @throws XNIException Thrown by handler to signal an error. 2536 */ 2537 public void endAttlist (Augmentations augs) throws XNIException { 2538 } // endAttlist() 2539 2540 2541 // method to create an element node. 2542 // subclasses can override this method to create element nodes in other ways. 2543 protected Element createElementNode (QName element) { 2544 Element el = null; 2545 2546 if (fNamespaceAware) { 2547 // if we are using xerces DOM implementation, call our 2548 // own constructor to reuse the strings we have here. 2549 if (fDocumentImpl != null) { 2550 el = fDocumentImpl.createElementNS (element.uri, element.rawname, 2551 element.localpart); 2552 } 2553 else { 2554 el = fDocument.createElementNS (element.uri, element.rawname); 2555 } 2556 } 2557 else { 2558 el = fDocument.createElement (element.rawname); 2559 } 2560 2561 return el; 2562 } 2563 2564 // method to create an attribute node. 2565 // subclasses can override this method to create attribute nodes in other ways. 2566 protected Attr createAttrNode (QName attrQName) { 2567 Attr attr = null; 2568 2569 if (fNamespaceAware) { 2570 if (fDocumentImpl != null) { 2571 // if we are using xerces DOM implementation, call our 2572 // own constructor to reuse the strings we have here. 2573 attr = fDocumentImpl.createAttributeNS (attrQName.uri, 2574 attrQName.rawname, 2575 attrQName.localpart); 2576 } 2577 else { 2578 attr = fDocument.createAttributeNS (attrQName.uri, 2579 attrQName.rawname); 2580 } 2581 } 2582 else { 2583 attr = fDocument.createAttribute (attrQName.rawname); 2584 } 2585 2586 return attr; 2587 } 2588 2589 /* 2590 * When the first characters() call is received, the data is stored in 2591 * a new Text node. If right after the first characters() we receive another chunk of data, 2592 * the data from the Text node, following the new characters are appended 2593 * to the fStringBuffer and the text node data is set to empty. 2594 * 2595 * This function is called when the state is changed and the 2596 * data must be appended to the current node. 2597 * 2598 * Note: if DOMFilter is set, you must make sure that if Node is skipped, 2599 * or removed fFistChunk must be set to true, otherwise some data can be lost. 2600 * 2601 */ 2602 @SuppressWarnings("fallthrough") // by design at case LSParserFilter.FILTER_REJECT 2603 protected void setCharacterData (boolean sawChars){ 2604 2605 // handle character data 2606 fFirstChunk = sawChars; 2607 2608 2609 // if we have data in the buffer we must have created 2610 // a text node already. 2611 2612 Node child = fCurrentNode.getLastChild (); 2613 if (child != null) { 2614 if (fStringBuilder.length () > 0) { 2615 // REVISIT: should this check be performed? 2616 if (child.getNodeType () == Node.TEXT_NODE) { 2617 if (fDocumentImpl != null) { 2618 ((TextImpl)child).replaceData (fStringBuilder.toString ()); 2619 } 2620 else { 2621 ((Text)child).setData (fStringBuilder.toString ()); 2622 } 2623 } 2624 // reset string buffer 2625 fStringBuilder.setLength (0); 2626 } 2627 2628 if (fDOMFilter !=null && !fInEntityRef) { 2629 if ( (child.getNodeType () == Node.TEXT_NODE ) && 2630 ((fDOMFilter.getWhatToShow () & NodeFilter.SHOW_TEXT)!= 0) ) { 2631 short code = fDOMFilter.acceptNode (child); 2632 switch (code) { 2633 case LSParserFilter.FILTER_INTERRUPT:{ 2634 throw Abort.INSTANCE; 2635 } 2636 case LSParserFilter.FILTER_REJECT:{ 2637 // fall through to SKIP since Comment has no children. 2638 } 2639 case LSParserFilter.FILTER_SKIP: { 2640 fCurrentNode.removeChild (child); 2641 return; 2642 } 2643 default: { 2644 // accept node -- do nothing 2645 } 2646 } 2647 } 2648 } // end-if fDOMFilter !=null 2649 2650 } // end-if child !=null 2651 } 2652 2653 2654 /** 2655 * @see org.w3c.dom.ls.LSParser#abort() 2656 */ 2657 public void abort () { 2658 throw Abort.INSTANCE; 2659 } 2660 2661 2662 } // class AbstractDOMParser