KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > parsers > DOMParser


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
6  * 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
58 package org.enhydra.apache.xerces.parsers;
59
60 import java.util.Enumeration JavaDoc;
61 import java.util.StringTokenizer JavaDoc;
62
63 import org.enhydra.apache.xerces.dom.AttrImpl;
64 import org.enhydra.apache.xerces.dom.DeferredDocumentImpl;
65 import org.enhydra.apache.xerces.dom.DocumentImpl;
66 import org.enhydra.apache.xerces.dom.DocumentTypeImpl;
67 import org.enhydra.apache.xerces.dom.ElementDefinitionImpl;
68 import org.enhydra.apache.xerces.dom.EntityImpl;
69 import org.enhydra.apache.xerces.dom.NotationImpl;
70 import org.enhydra.apache.xerces.dom.TextImpl;
71 import org.enhydra.apache.xerces.framework.XMLAttrList;
72 import org.enhydra.apache.xerces.framework.XMLContentSpec;
73 import org.enhydra.apache.xerces.framework.XMLDocumentHandler;
74 import org.enhydra.apache.xerces.framework.XMLParser;
75 import org.enhydra.apache.xerces.readers.XMLEntityHandler;
76 import org.enhydra.apache.xerces.utils.QName;
77 import org.enhydra.apache.xerces.utils.StringPool;
78 import org.enhydra.apache.xerces.validators.common.XMLAttributeDecl;
79 import org.enhydra.apache.xerces.validators.common.XMLElementDecl;
80 import org.enhydra.apache.xerces.validators.schema.SchemaSymbols;
81 import org.enhydra.apache.xerces.validators.schema.XUtil;
82 import org.w3c.dom.Attr JavaDoc;
83 import org.w3c.dom.Comment JavaDoc;
84 import org.w3c.dom.Document JavaDoc;
85 import org.w3c.dom.DocumentType JavaDoc;
86 import org.w3c.dom.Element JavaDoc;
87 import org.w3c.dom.Entity JavaDoc;
88 import org.w3c.dom.EntityReference JavaDoc;
89 import org.w3c.dom.NamedNodeMap JavaDoc;
90 import org.w3c.dom.Node JavaDoc;
91 import org.w3c.dom.ProcessingInstruction JavaDoc;
92 import org.w3c.dom.Text JavaDoc;
93 import org.xml.sax.SAXException JavaDoc;
94 import org.xml.sax.SAXNotRecognizedException JavaDoc;
95 import org.xml.sax.SAXNotSupportedException JavaDoc;
96
97 /**
98  * DOMParser provides a parser which produces a W3C DOM tree as its output
99  *
100  *
101  * @version $Id: DOMParser.java,v 1.3 2005/01/26 08:28:44 jkjome Exp $
102  */

103 public class DOMParser
104     extends XMLParser
105     implements XMLDocumentHandler
106     {
107
108     //
109
// Constants
110
//
111

112     // public
113

114     /** Default programmatic document class name (org.enhydra.apache.xerces.dom.DocumentImpl). */
115     public static final String JavaDoc DEFAULT_DOCUMENT_CLASS_NAME = "org.enhydra.apache.xerces.dom.DocumentImpl";
116
117     /** Default deferred document class name (org.enhydra.apache.xerces.dom.DeferredDocumentImpl). */
118     public static final String JavaDoc DEFAULT_DEFERRED_DOCUMENT_CLASS_NAME = "org.enhydra.apache.xerces.dom.DeferredDocumentImpl";
119
120     // debugging
121

122     /** Set to true to debug attribute list declaration calls. */
123     private static final boolean DEBUG_ATTLIST_DECL = false;
124
125     // features and properties
126

127     /** Features recognized by this parser. */
128     private static final String JavaDoc RECOGNIZED_FEATURES[] = {
129         // SAX2 core features
130
// Xerces features
131
"http://apache.org/xml/features/dom/defer-node-expansion",
132         "http://apache.org/xml/features/dom/create-entity-ref-nodes",
133         "http://apache.org/xml/features/dom/include-ignorable-whitespace",
134         // Experimental features
135
"http://apache.org/xml/features/domx/grammar-access",
136     };
137
138     /** Properties recognized by this parser. */
139     private static final String JavaDoc RECOGNIZED_PROPERTIES[] = {
140         // SAX2 core properties
141
// Xerces properties
142
"http://apache.org/xml/properties/dom/document-class-name",
143         "http://apache.org/xml/properties/dom/current-element-node",
144     };
145
146     //
147
// Data
148
//
149

150     // common data
151

152     protected Document JavaDoc fDocument;
153
154     // deferred expansion data
155

156     protected DeferredDocumentImpl fDeferredDocumentImpl;
157     protected int fDocumentIndex;
158     protected int fDocumentTypeIndex;
159     protected int fCurrentNodeIndex;
160
161     //DOM Level 3 WD - experimental
162

163     protected int fCurrentEntityName; //name of current entity reference
164
protected int fCurrentEntityNode; //index of entity node corresponding to current entity reference
165

166     // full expansion data
167

168     protected DocumentImpl fDocumentImpl;
169     protected DocumentType JavaDoc fDocumentType;
170     protected Node JavaDoc fCurrentElementNode;
171
172     // state
173

174     protected boolean fInDTD;
175     protected boolean fWithinElement;
176     protected boolean fInCDATA;
177
178     // features
179
private boolean fGrammarAccess;
180
181     // properties
182

183     // REVISIT: Even though these have setters and getters, should they
184
// be protected visibility? -Ac
185
private String JavaDoc fDocumentClassName;
186     private boolean fDeferNodeExpansion;
187     private boolean fCreateEntityReferenceNodes;
188     private boolean fIncludeIgnorableWhitespace;
189
190     // built-in entities
191

192     protected int fAmpIndex;
193     protected int fLtIndex;
194     protected int fGtIndex;
195     protected int fAposIndex;
196     protected int fQuotIndex;
197
198     private boolean fSeenRootElement;
199
200     private boolean fStringPoolInUse;
201
202     private XMLAttrList fAttrList;
203
204     //
205
// Constructors
206
//
207

208     /** Default constructor. */
209     public DOMParser() {
210
211         initHandlers(false, this, this);
212
213         // setup parser state
214
init();
215
216         // set default values
217
try {
218             setDocumentClassName(DEFAULT_DOCUMENT_CLASS_NAME);
219             setCreateEntityReferenceNodes(true);
220             setDeferNodeExpansion(true);
221             setIncludeIgnorableWhitespace(true);
222         } catch (SAXException JavaDoc e) {
223             throw new RuntimeException JavaDoc("PAR001 Fatal error constructing DOMParser.");
224         }
225
226     } // <init>()
227

228     //
229
// Public methods
230
//
231

232     // document
233

234     /** Returns the document. */
235     public Document JavaDoc getDocument() {
236         return fDocument;
237     }
238
239     // features and properties
240

241     /**
242      * Returns a list of features that this parser recognizes.
243      * This method will never return null; if no features are
244      * recognized, this method will return a zero length array.
245      *
246      * @see #isFeatureRecognized
247      * @see #setFeature
248      * @see #getFeature
249      */

250     public String JavaDoc[] getFeaturesRecognized() {
251
252         // get features that super/this recognizes
253
String JavaDoc superRecognized[] = super.getFeaturesRecognized();
254         String JavaDoc thisRecognized[] = RECOGNIZED_FEATURES;
255
256         // is one or the other the empty set?
257
int thisLength = thisRecognized.length;
258         if (thisLength == 0) {
259             return superRecognized;
260         }
261         int superLength = superRecognized.length;
262         if (superLength == 0) {
263             return thisRecognized;
264         }
265
266         // combine the two lists and return
267
String JavaDoc recognized[] = new String JavaDoc[superLength + thisLength];
268         System.arraycopy(superRecognized, 0, recognized, 0, superLength);
269         System.arraycopy(thisRecognized, 0, recognized, superLength, thisLength);
270         return recognized;
271
272     } // getFeaturesRecognized():String[]
273

274     /**
275      * Returns a list of properties that this parser recognizes.
276      * This method will never return null; if no properties are
277      * recognized, this method will return a zero length array.
278      *
279      * @see #isPropertyRecognized
280      * @see #setProperty
281      * @see #getProperty
282      */

283     public String JavaDoc[] getPropertiesRecognized() {
284
285         // get properties that super/this recognizes
286
String JavaDoc superRecognized[] = super.getPropertiesRecognized();
287         String JavaDoc thisRecognized[] = RECOGNIZED_PROPERTIES;
288
289         // is one or the other the empty set?
290
int thisLength = thisRecognized.length;
291         if (thisLength == 0) {
292             return superRecognized;
293         }
294         int superLength = superRecognized.length;
295         if (superLength == 0) {
296             return thisRecognized;
297         }
298
299         // combine the two lists and return
300
String JavaDoc recognized[] = new String JavaDoc[superLength + thisLength];
301         System.arraycopy(superRecognized, 0, recognized, 0, superLength);
302         System.arraycopy(thisRecognized, 0, recognized, superLength, thisLength);
303         return recognized;
304
305     }
306
307     // resetting
308

309     /** Resets the parser. */
310     public void reset() throws Exception JavaDoc {
311         if (fStringPoolInUse) {
312             // we can't reuse the string pool, let's create another one
313
fStringPool = new StringPool();
314             fStringPoolInUse = false;
315         }
316         super.reset();
317         init();
318     }
319
320     /** Resets or copies the parser. */
321     public void resetOrCopy() throws Exception JavaDoc {
322         super.resetOrCopy();
323         init();
324     }
325
326     //
327
// Protected methods
328
//
329

330     // initialization
331

332     /**
333      * Initializes the parser to a pre-parse state. This method is
334      * called between calls to <code>parse()</code>.
335      */

336     protected void init() {
337
338         // init common
339
fDocument = null;
340
341         // init deferred expansion
342
fDeferredDocumentImpl = null;
343         fDocumentIndex = -1;
344         fDocumentTypeIndex = -1;
345         fCurrentNodeIndex = -1;
346
347         //DOM Level 3 WD - experimental
348
fCurrentEntityNode = -1;
349         fCurrentEntityName = -1;
350
351         // init full expansion
352
fDocumentImpl = null;
353         fDocumentType = null;
354         fCurrentElementNode = null;
355
356         // state
357
fInDTD = false;
358         fWithinElement = false;
359         fInCDATA = false;
360
361         // built-in entities
362
fAmpIndex = fStringPool.addSymbol("amp");
363         fLtIndex = fStringPool.addSymbol("lt");
364         fGtIndex = fStringPool.addSymbol("gt");
365         fAposIndex = fStringPool.addSymbol("apos");
366         fQuotIndex = fStringPool.addSymbol("quot");
367
368         fSeenRootElement = false;
369         fStringPoolInUse = false;
370
371         fAttrList = new XMLAttrList(fStringPool);
372
373     } // init()
374

375     // features
376

377     /**
378      * This method sets whether the expansion of the nodes in the default
379      * DOM implementation are deferred.
380      *
381      * @see #getDeferNodeExpansion
382      * @see #setDocumentClassName
383      */

384     protected void setDeferNodeExpansion(boolean deferNodeExpansion)
385         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
386         fDeferNodeExpansion = deferNodeExpansion;
387     }
388
389     /**
390      * Returns true if the expansion of the nodes in the default DOM
391      * implementation are deferred.
392      *
393      * @see #setDeferNodeExpansion
394      */

395     protected boolean getDeferNodeExpansion()
396         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
397         return fDeferNodeExpansion;
398     }
399
400     /**
401      * This feature determines whether entity references within
402      * the document are included in the document tree as
403      * EntityReference nodes.
404      * <p>
405      * Note: The children of the entity reference are always
406      * added to the document. This feature only affects
407      * whether an EntityReference node is also included
408      * as the parent of the entity reference children.
409      *
410      * @param create True to create entity reference nodes; false
411      * to only insert the entity reference children.
412      *
413      * @see #getCreateEntityReferenceNodes
414      */

415     protected void setCreateEntityReferenceNodes(boolean create)
416         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
417         fCreateEntityReferenceNodes = create;
418     }
419
420     /**
421      * Returns true if entity references within the document are
422      * included in the document tree as EntityReference nodes.
423      *
424      * @see #setCreateEntityReferenceNodes
425      */

426     public boolean getCreateEntityReferenceNodes()
427         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
428         return fCreateEntityReferenceNodes;
429     }
430
431     /**
432      * This feature determines whether text nodes that can be
433      * considered "ignorable whitespace" are included in the DOM
434      * tree.
435      * <p>
436      * Note: The only way that the parser can determine if text
437      * is ignorable is by reading the associated grammar
438      * and having a content model for the document. When
439      * ignorable whitespace text nodes *are* included in
440      * the DOM tree, they will be flagged as ignorable.
441      * The ignorable flag can be queried by calling the
442      * TextImpl#isIgnorableWhitespace():boolean method.
443      *
444      * @param include True to include ignorable whitespace text nodes;
445      * false to not include ignorable whitespace text
446      * nodes.
447      *
448      * @see #getIncludeIgnorableWhitespace
449      */

450     public void setIncludeIgnorableWhitespace(boolean include)
451         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
452         fIncludeIgnorableWhitespace = include;
453     }
454
455     /**
456      * Returns true if ignorable whitespace text nodes are included
457      * in the DOM tree.
458      *
459      * @see #setIncludeIgnorableWhitespace
460      */

461     public boolean getIncludeIgnorableWhitespace()
462         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
463         return fIncludeIgnorableWhitespace;
464     }
465
466     // properties
467

468     /**
469      * This method allows the programmer to decide which document
470      * factory to use when constructing the DOM tree. However, doing
471      * so will lose the functionality of the default factory. Also,
472      * a document class other than the default will lose the ability
473      * to defer node expansion on the DOM tree produced.
474      *
475      * @param documentClassName The fully qualified class name of the
476      * document factory to use when constructing
477      * the DOM tree.
478      *
479      * @see #getDocumentClassName
480      * @see #setDeferNodeExpansion
481      * @see #DEFAULT_DOCUMENT_CLASS_NAME
482      */

483     protected void setDocumentClassName(String JavaDoc documentClassName)
484         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
485
486         // normalize class name
487
if (documentClassName == null) {
488             documentClassName = DEFAULT_DOCUMENT_CLASS_NAME;
489         }
490
491         // verify that this class exists and is of the right type
492
try {
493             //jrk_20021208.1_begin
494
//Class _class = Class.forName(documentClassName);
495
Class JavaDoc _class = Class.forName(documentClassName, true, getClass().getClassLoader());
496             //jrk_20021208.1_end
497
//if (!_class.isAssignableFrom(Document.class)) {
498
if (!Document JavaDoc.class.isAssignableFrom(_class)) {
499                 throw new IllegalArgumentException JavaDoc("PAR002 Class, \""+documentClassName+"\", is not of type org.w3c.dom.Document."+"\n"+documentClassName);
500             }
501         }
502         catch (ClassNotFoundException JavaDoc e) {
503             throw new IllegalArgumentException JavaDoc("PAR003 Class, \""+documentClassName+"\", not found."+"\n"+documentClassName);
504         }
505
506         // set document class name
507
fDocumentClassName = documentClassName;
508         if (!documentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME)) {
509             setDeferNodeExpansion(false);
510         }
511
512     } // setDocumentClassName(String)
513

514     /**
515      * Returns the fully qualified class name of the document factory
516      * used when constructing the DOM tree.
517      *
518      * @see #setDocumentClassName
519      */

520     protected String JavaDoc getDocumentClassName()
521         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
522         return fDocumentClassName;
523     }
524
525     /**
526      * Returns the current element node.
527      * <p>
528      * Note: This method is not supported when the "deferNodeExpansion"
529      * property is set to true and the document factory is set to
530      * the default factory.
531      */

532     protected Element JavaDoc getCurrentElementNode()
533         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
534
535         if (fCurrentElementNode != null &&
536             fCurrentElementNode.getNodeType() == Node.ELEMENT_NODE) {
537             return (Element JavaDoc)fCurrentElementNode;
538         }
539         return null;
540
541     } // getCurrentElementNode():Element
542

543     //
544
// Configurable methods
545
//
546

547     /**
548      * Set the state of any feature in a SAX2 parser. The parser
549      * might not recognize the feature, and if it does recognize
550      * it, it might not be able to fulfill the request.
551      *
552      * @param featureId The unique identifier (URI) of the feature.
553      * @param state The requested state of the feature (true or false).
554      *
555      * @exception SAXNotRecognizedException If the requested feature is
556      * not known.
557      * @exception SAXNotSupportedException If the requested feature is
558      * known, but the requested state
559      * is not supported.
560      */

561     public void setFeature(String JavaDoc featureId, boolean state)
562         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
563
564         //
565
// SAX2 core features
566
//
567

568         if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
569             //
570
// No additional SAX properties defined for DOMParser.
571
// Pass request off to XMLParser for the common cases.
572
//
573
}
574
575         //
576
// Xerces features
577
//
578

579         else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
580             String JavaDoc feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
581             //
582
// http://apache.org/xml/features/dom/defer-node-expansion
583
// Allows the document tree returned by getDocument()
584
// to be constructed lazily. In other words, the DOM
585
// nodes are constructed as the tree is traversed.
586
// This allows the document to be returned sooner with
587
// the expense of holding all of the blocks of character
588
// data held in memory. Then again, lots of DOM nodes
589
// use a lot of memory as well.
590
//
591
if (feature.equals("dom/defer-node-expansion")) {
592                 if (fParseInProgress) {
593                     throw new SAXNotSupportedException JavaDoc("PAR004 Cannot setFeature("+featureId + "): parse is in progress."+"\n"+featureId);
594                 }
595                 setDeferNodeExpansion(state);
596                 return;
597             }
598             //
599
// http://apache.org/xml/features/dom/create-entity-ref-nodes
600
// This feature determines whether entity references within
601
// the document are included in the document tree as
602
// EntityReference nodes.
603
// Note: The children of the entity reference are always
604
// added to the document. This feature only affects
605
// whether an EntityReference node is also included
606
// as the parent of the entity reference children.
607
//
608
if (feature.equals("dom/create-entity-ref-nodes")) {
609                 setCreateEntityReferenceNodes(state);
610                 return;
611             }
612
613             //
614
// http://apache.org/xml/features/dom/include-ignorable-whitespace
615
// This feature determines whether text nodes that can be
616
// considered "ignorable whitespace" are included in the DOM
617
// tree.
618
// Note: The only way that the parser can determine if text
619
// is ignorable is by reading the associated grammar
620
// and having a content model for the document. When
621
// ignorable whitespace text nodes *are* included in
622
// the DOM tree, they will be flagged as ignorable.
623
// The ignorable flag can be queried by calling the
624
// TextImpl#isIgnorableWhitespace():boolean method.
625
//
626
if (feature.equals("dom/include-ignorable-whitespace")) {
627                 setIncludeIgnorableWhitespace(state);
628                 return;
629             }
630
631             //
632
// Experimental features
633
//
634

635             //
636
// http://apache.org/xml/features/domx/grammar-access
637
// Allows grammar access in the DOM tree. Currently, this
638
// means that there is an XML Schema document tree as a
639
// child of the Doctype node.
640
//
641
if (feature.equals("domx/grammar-access")) {
642                 fGrammarAccess = state;
643                 return;
644             }
645
646             //
647
// Pass request off to XMLParser for the common cases.
648
//
649
}
650
651         //
652
// Pass request off to XMLParser for the common cases.
653
//
654
super.setFeature(featureId, state);
655
656     } // setFeature(String,boolean)
657

658     /**
659      * Query the current state of any feature in a SAX2 parser. The
660      * parser might not recognize the feature.
661      *
662      * @param featureId The unique identifier (URI) of the feature
663      * being set.
664      *
665      * @return The current state of the feature.
666      *
667      * @exception SAXNotRecognizedException If the requested feature is
668      * not known.
669      */

670     public boolean getFeature(String JavaDoc featureId)
671         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
672
673         //
674
// SAX2 core features
675
//
676

677         if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
678             //
679
// No additional SAX properties defined for DOMParser.
680
// Pass request off to XMLParser for the common cases.
681
//
682
}
683
684         //
685
// Xerces features
686
//
687

688         else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
689             String JavaDoc feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
690             //
691
// http://apache.org/xml/features/dom/defer-node-expansion
692
// Allows the document tree returned by getDocument()
693
// to be constructed lazily. In other words, the DOM
694
// nodes are constructed as the tree is traversed.
695
// This allows the document to be returned sooner with
696
// the expense of holding all of the blocks of character
697
// data held in memory. Then again, lots of DOM nodes
698
// use a lot of memory as well.
699
//
700
if (feature.equals("dom/defer-node-expansion")) {
701                 return getDeferNodeExpansion();
702             }
703             //
704
// http://apache.org/xml/features/dom/create-entity-ref-nodes
705
// This feature determines whether entity references within
706
// the document are included in the document tree as
707
// EntityReference nodes.
708
// Note: The children of the entity reference are always
709
// added to the document. This feature only affects
710
// whether an EntityReference node is also included
711
// as the parent of the entity reference children.
712
//
713
else if (feature.equals("dom/create-entity-ref-nodes")) {
714                 return getCreateEntityReferenceNodes();
715             }
716
717             //
718
// http://apache.org/xml/features/dom/include-ignorable-whitespace
719
// This feature determines whether text nodes that can be
720
// considered "ignorable whitespace" are included in the DOM
721
// tree.
722
// Note: The only way that the parser can determine if text
723
// is ignorable is by reading the associated grammar
724
// and having a content model for the document. When
725
// ignorable whitespace text nodes *are* included in
726
// the DOM tree, they will be flagged as ignorable.
727
// The ignorable flag can be queried by calling the
728
// TextImpl#isIgnorableWhitespace():boolean method.
729
//
730
if (feature.equals("dom/include-ignorable-whitespace")) {
731                 return getIncludeIgnorableWhitespace();
732             }
733
734             //
735
// Experimental features
736
//
737

738             //
739
// http://apache.org/xml/features/domx/grammar-access
740
// Allows grammar access in the DOM tree. Currently, this
741
// means that there is an XML Schema document tree as a
742
// child of the Doctype node.
743
//
744
if (feature.equals("domx/grammar-access")) {
745                 return fGrammarAccess;
746             }
747
748             //
749
// Pass request off to XMLParser for the common cases.
750
//
751
}
752
753         //
754
// Pass request off to XMLParser for the common cases.
755
//
756
return super.getFeature(featureId);
757
758     } // getFeature(String):boolean
759

760     /**
761      * Set the value of any property in a SAX2 parser. The parser
762      * might not recognize the property, and if it does recognize
763      * it, it might not support the requested value.
764      *
765      * @param propertyId The unique identifier (URI) of the property
766      * being set.
767      * @param Object The value to which the property is being set.
768      *
769      * @exception SAXNotRecognizedException If the requested property is
770      * not known.
771      * @exception SAXNotSupportedException If the requested property is
772      * known, but the requested
773      * value is not supported.
774      */

775     public void setProperty(String JavaDoc propertyId, Object JavaDoc value)
776         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
777
778         //
779
// Xerces properties
780
//
781

782         if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
783             String JavaDoc property = propertyId.substring(XERCES_PROPERTIES_PREFIX.length());
784             //
785
// http://apache.org/xml/properties/dom/current-element-node
786
// Returns the current element node as the DOM Parser is
787
// parsing. This property is useful for determining the
788
// relative location of the document when an error is
789
// encountered. Note that this feature does *not* work
790
// when the http://apache.org/xml/features/dom/defer-node-expansion
791
// is set to true.
792
//
793
if (property.equals("dom/current-element-node")) {
794                 throw new SAXNotSupportedException JavaDoc("PAR005 Property, \""+propertyId+"\" is read-only.\n"+propertyId);
795             }
796             //
797
// http://apache.org/xml/properties/dom/document-class-name
798
// This property can be used to set/query the name of the
799
// document factory.
800
//
801
else if (property.equals("dom/document-class-name")) {
802                 if (value != null && !(value instanceof String JavaDoc)) {
803                     throw new SAXNotSupportedException JavaDoc("PAR006 Property value must be of type java.lang.String.");
804                 }
805                 setDocumentClassName((String JavaDoc)value);
806                 return;
807             }
808         }
809
810         //
811
// Pass request off to XMLParser for the common cases.
812
//
813
super.setProperty(propertyId, value);
814
815     } // setProperty(String,Object)
816

817     /**
818      * Return the current value of a property in a SAX2 parser.
819      * The parser might not recognize the property.
820      *
821      * @param propertyId The unique identifier (URI) of the property
822      * being set.
823      *
824      * @return The current value of the property.
825      *
826      * @exception SAXNotRecognizedException If the requested property is
827      * not known.
828      *
829      * @see Configurable#getProperty
830      */

831     public Object JavaDoc getProperty(String JavaDoc propertyId)
832         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
833
834         //
835
// Xerces properties
836
//
837

838         if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
839             String JavaDoc property = propertyId.substring(XERCES_PROPERTIES_PREFIX.length());
840             //
841
// http://apache.org/xml/properties/dom/current-element-node
842
// Returns the current element node as the DOM Parser is
843
// parsing. This property is useful for determining the
844
// relative location of the document when an error is
845
// encountered. Note that this feature does *not* work
846
// when the http://apache.org/xml/features/dom/defer-node-expansion
847
// is set to true.
848
//
849
if (property.equals("dom/current-element-node")) {
850                 boolean throwException = false;
851                 try {
852                     throwException = getFeature(XERCES_FEATURES_PREFIX+"dom/defer-node-expansion");
853                 }
854                 catch (SAXNotSupportedException JavaDoc e) {
855                     // ignore
856
}
857                 catch (SAXNotRecognizedException JavaDoc e) {
858                     // ignore
859
}
860                 if (throwException) {
861                     throw new SAXNotSupportedException JavaDoc("PAR007 Current element node cannot be queried when node expansion is deferred.");
862                 }
863                 return getCurrentElementNode();
864             }
865             //
866
// http://apache.org/xml/properties/dom/document-class-name
867
// This property can be used to set/query the name of the
868
// document factory.
869
//
870
else if (property.equals("dom/document-class-name")) {
871                 return getDocumentClassName();
872             }
873         }
874
875         //
876
// Pass request off to XMLParser for the common cases.
877
//
878
return super.getProperty(propertyId);
879
880     } // getProperty(String):Object
881

882     //
883
// XMLParser methods
884
//
885

886     /** Start document. */
887     public void startDocument() {
888
889         // deferred expansion
890
String JavaDoc documentClassName = null;
891         try {
892             documentClassName = getDocumentClassName();
893         } catch (SAXException JavaDoc e) {