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