1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Licensed to the Apache Software Foundation (ASF) under one or more
7  * contributor license agreements.  See the NOTICE file distributed with
8  * this work for additional information regarding copyright ownership.
9  * The ASF licenses this file to You under the Apache License, Version 2.0
10  * (the "License"); you may not use this file except in compliance with
11  * the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 package com.sun.org.apache.xerces.internal.parsers;
23 
24 import java.io.IOException;
25 
26 import com.sun.org.apache.xerces.internal.impl.Constants;
27 import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper;
28 import com.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper;
29 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
30 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
31 import com.sun.org.apache.xerces.internal.util.Status;
32 import com.sun.org.apache.xerces.internal.util.SymbolTable;
33 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
34 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
35 import com.sun.org.apache.xerces.internal.xni.XNIException;
36 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
37 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
38 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
39 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
40 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
41 import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
42 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
43 import java.io.CharConversionException;
44 import org.w3c.dom.Node;
45 import org.xml.sax.EntityResolver;
46 import org.xml.sax.ErrorHandler;
47 import org.xml.sax.InputSource;
48 import org.xml.sax.SAXException;
49 import org.xml.sax.SAXNotRecognizedException;
50 import org.xml.sax.SAXNotSupportedException;
51 import org.xml.sax.SAXParseException;
52 import org.xml.sax.ext.EntityResolver2;
53 import org.xml.sax.helpers.LocatorImpl;
54 
55 /**
56  * This is the main Xerces DOM parser class. It uses the abstract DOM
57  * parser with a document scanner, a dtd scanner, and a validator, as
58  * well as a grammar pool.
59  *
60  * @author Arnaud  Le Hors, IBM
61  * @author Andy Clark, IBM
62  *
63  */
64 public class DOMParser
65     extends AbstractDOMParser {
66 
67     //
68     // Constants
69     //
70 
71     // features
72 
73     /** Feature identifier: EntityResolver2. */
74     protected static final String USE_ENTITY_RESOLVER2 =
75         Constants.SAX_FEATURE_PREFIX + Constants.USE_ENTITY_RESOLVER2_FEATURE;
76 
77     protected static final String REPORT_WHITESPACE =
78             Constants.SUN_SCHEMA_FEATURE_PREFIX + Constants.SUN_REPORT_IGNORED_ELEMENT_CONTENT_WHITESPACE;
79 
80     /** Property identifier: Security property manager. */
81     private static final String XML_SECURITY_PROPERTY_MANAGER =
82             Constants.XML_SECURITY_PROPERTY_MANAGER;
83 
84     // recognized features:
85     private static final String[] RECOGNIZED_FEATURES = {
86         REPORT_WHITESPACE
87     };
88 
89     // properties
90 
91     /** Property identifier: symbol table. */
92     protected static final String SYMBOL_TABLE =
93         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
94 
95     /** Property identifier: XML grammar pool. */
96     protected static final String XMLGRAMMAR_POOL =
97         Constants.XERCES_PROPERTY_PREFIX+Constants.XMLGRAMMAR_POOL_PROPERTY;
98 
99     /** Recognized properties. */
100     private static final String[] RECOGNIZED_PROPERTIES = {
101         SYMBOL_TABLE,
102         XMLGRAMMAR_POOL,
103     };
104 
105     //
106     // Data
107     //
108 
109     // features
110 
111     /** Use EntityResolver2. */
112     protected boolean fUseEntityResolver2 = true;
113 
114     //
115     // Constructors
116     //
117 
118     /**
119      * Constructs a DOM parser using the specified parser configuration.
120      */
DOMParser(XMLParserConfiguration config)121     public DOMParser(XMLParserConfiguration config) {
122         super(config);
123     } // <init>(XMLParserConfiguration)
124 
125     /**
126      * Constructs a DOM parser using the dtd/xml schema parser configuration.
127      */
DOMParser()128     public DOMParser() {
129         this(null, null);
130     } // <init>()
131 
132     /**
133      * Constructs a DOM parser using the specified symbol table.
134      */
DOMParser(SymbolTable symbolTable)135     public DOMParser(SymbolTable symbolTable) {
136         this(symbolTable, null);
137     } // <init>(SymbolTable)
138 
139 
140     /**
141      * Constructs a DOM parser using the specified symbol table and
142      * grammar pool.
143      */
DOMParser(SymbolTable symbolTable, XMLGrammarPool grammarPool)144     public DOMParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
145         super(new XIncludeAwareParserConfiguration());
146 
147         // set properties
148         fConfiguration.addRecognizedProperties(RECOGNIZED_PROPERTIES);
149         if (symbolTable != null) {
150             fConfiguration.setProperty(SYMBOL_TABLE, symbolTable);
151         }
152         if (grammarPool != null) {
153             fConfiguration.setProperty(XMLGRAMMAR_POOL, grammarPool);
154         }
155 
156         fConfiguration.addRecognizedFeatures(RECOGNIZED_FEATURES);
157 
158     } // <init>(SymbolTable,XMLGrammarPool)
159 
160     //
161     // XMLReader methods
162     //
163 
164     /**
165      * Parses the input source specified by the given system identifier.
166      * <p>
167      * This method is equivalent to the following:
168      * <pre>
169      *     parse(new InputSource(systemId));
170      * </pre>
171      *
172      * @param systemId The system identifier (URI).
173      *
174      * @exception org.xml.sax.SAXException Throws exception on SAX error.
175      * @exception java.io.IOException Throws exception on i/o error.
176      */
parse(String systemId)177     public void parse(String systemId) throws SAXException, IOException {
178 
179         // parse document
180         XMLInputSource source = new XMLInputSource(null, systemId, null, false);
181         try {
182             parse(source);
183         }
184 
185         // wrap XNI exceptions as SAX exceptions
186         catch (XMLParseException e) {
187             Exception ex = e.getException();
188             if (ex == null || ex instanceof CharConversionException) {
189                 // must be a parser exception; mine it for locator info and throw
190                 // a SAXParseException
191                 LocatorImpl locatorImpl = new LocatorImpl();
192                 locatorImpl.setPublicId(e.getPublicId());
193                 locatorImpl.setSystemId(e.getExpandedSystemId());
194                 locatorImpl.setLineNumber(e.getLineNumber());
195                 locatorImpl.setColumnNumber(e.getColumnNumber());
196                 throw (ex == null) ?
197                         new SAXParseException(e.getMessage(), locatorImpl) :
198                         new SAXParseException(e.getMessage(), locatorImpl, ex);
199             }
200             if (ex instanceof SAXException) {
201                 // why did we create an XMLParseException?
202                 throw (SAXException)ex;
203             }
204             if (ex instanceof IOException) {
205                 throw (IOException)ex;
206             }
207             throw new SAXException(ex);
208         }
209         catch (XNIException e) {
210             e.printStackTrace();
211             Exception ex = e.getException();
212             if (ex == null) {
213                 throw new SAXException(e.getMessage());
214             }
215             if (ex instanceof SAXException) {
216                 throw (SAXException)ex;
217             }
218             if (ex instanceof IOException) {
219                 throw (IOException)ex;
220             }
221             throw new SAXException(ex);
222         }
223 
224     } // parse(String)
225 
226     /**
227      * parse
228      *
229      * @param inputSource
230      *
231      * @exception org.xml.sax.SAXException
232      * @exception java.io.IOException
233      */
parse(InputSource inputSource)234     public void parse(InputSource inputSource)
235         throws SAXException, IOException {
236 
237         // parse document
238         try {
239             XMLInputSource xmlInputSource =
240                 new XMLInputSource(inputSource.getPublicId(),
241                                    inputSource.getSystemId(),
242                                    null, false);
243             xmlInputSource.setByteStream(inputSource.getByteStream());
244             xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
245             xmlInputSource.setEncoding(inputSource.getEncoding());
246             parse(xmlInputSource);
247         }
248 
249         // wrap XNI exceptions as SAX exceptions
250         catch (XMLParseException e) {
251             Exception ex = e.getException();
252             if (ex == null || ex instanceof CharConversionException) {
253                 // must be a parser exception; mine it for locator info and throw
254                 // a SAXParseException
255                 LocatorImpl locatorImpl = new LocatorImpl();
256                 locatorImpl.setPublicId(e.getPublicId());
257                 locatorImpl.setSystemId(e.getExpandedSystemId());
258                 locatorImpl.setLineNumber(e.getLineNumber());
259                 locatorImpl.setColumnNumber(e.getColumnNumber());
260                 throw (ex == null) ?
261                         new SAXParseException(e.getMessage(), locatorImpl) :
262                         new SAXParseException(e.getMessage(), locatorImpl, ex);
263             }
264             if (ex instanceof SAXException) {
265                 // why did we create an XMLParseException?
266                 throw (SAXException)ex;
267             }
268             if (ex instanceof IOException) {
269                 throw (IOException)ex;
270             }
271             throw new SAXException(ex);
272         }
273         catch (XNIException e) {
274             Exception ex = e.getException();
275             if (ex == null) {
276                 throw new SAXException(e.getMessage());
277             }
278             if (ex instanceof SAXException) {
279                 throw (SAXException)ex;
280             }
281             if (ex instanceof IOException) {
282                 throw (IOException)ex;
283             }
284             throw new SAXException(ex);
285         }
286 
287     } // parse(InputSource)
288 
289     /**
290      * Sets the resolver used to resolve external entities. The EntityResolver
291      * interface supports resolution of public and system identifiers.
292      *
293      * @param resolver The new entity resolver. Passing a null value will
294      *                 uninstall the currently installed resolver.
295      */
setEntityResolver(EntityResolver resolver)296     public void setEntityResolver(EntityResolver resolver) {
297 
298         try {
299             XMLEntityResolver xer = (XMLEntityResolver) fConfiguration.getProperty(ENTITY_RESOLVER);
300             if (fUseEntityResolver2 && resolver instanceof EntityResolver2) {
301                 if (xer instanceof EntityResolver2Wrapper) {
302                     EntityResolver2Wrapper er2w = (EntityResolver2Wrapper) xer;
303                     er2w.setEntityResolver((EntityResolver2) resolver);
304                 }
305                 else {
306                     fConfiguration.setProperty(ENTITY_RESOLVER,
307                             new EntityResolver2Wrapper((EntityResolver2) resolver));
308                 }
309             }
310             else {
311                 if (xer instanceof EntityResolverWrapper) {
312                     EntityResolverWrapper erw = (EntityResolverWrapper) xer;
313                     erw.setEntityResolver(resolver);
314                 }
315                 else {
316                     fConfiguration.setProperty(ENTITY_RESOLVER,
317                             new EntityResolverWrapper(resolver));
318                 }
319             }
320         }
321         catch (XMLConfigurationException e) {
322             // do nothing
323         }
324 
325     } // setEntityResolver(EntityResolver)
326 
327     /**
328      * Return the current entity resolver.
329      *
330      * @return The current entity resolver, or null if none
331      *         has been registered.
332      * @see #setEntityResolver
333      */
getEntityResolver()334     public EntityResolver getEntityResolver() {
335 
336         EntityResolver entityResolver = null;
337         try {
338             XMLEntityResolver xmlEntityResolver =
339                 (XMLEntityResolver)fConfiguration.getProperty(ENTITY_RESOLVER);
340             if (xmlEntityResolver != null) {
341                 if (xmlEntityResolver instanceof EntityResolverWrapper) {
342                     entityResolver =
343                         ((EntityResolverWrapper) xmlEntityResolver).getEntityResolver();
344                 }
345                 else if (xmlEntityResolver instanceof EntityResolver2Wrapper) {
346                     entityResolver =
347                         ((EntityResolver2Wrapper) xmlEntityResolver).getEntityResolver();
348                 }
349             }
350         }
351         catch (XMLConfigurationException e) {
352             // do nothing
353         }
354         return entityResolver;
355 
356     } // getEntityResolver():EntityResolver
357 
358     /**
359      * Allow an application to register an error event handler.
360      *
361      * <p>If the application does not register an error handler, all
362      * error events reported by the SAX parser will be silently
363      * ignored; however, normal processing may not continue.  It is
364      * highly recommended that all SAX applications implement an
365      * error handler to avoid unexpected bugs.</p>
366      *
367      * <p>Applications may register a new or different handler in the
368      * middle of a parse, and the SAX parser must begin using the new
369      * handler immediately.</p>
370      *
371      * @param errorHandler The error handler.
372      * @exception java.lang.NullPointerException If the handler
373      *            argument is null.
374      * @see #getErrorHandler
375      */
setErrorHandler(ErrorHandler errorHandler)376     public void setErrorHandler(ErrorHandler errorHandler) {
377 
378         try {
379             XMLErrorHandler xeh = (XMLErrorHandler) fConfiguration.getProperty(ERROR_HANDLER);
380             if (xeh instanceof ErrorHandlerWrapper) {
381                 ErrorHandlerWrapper ehw = (ErrorHandlerWrapper) xeh;
382                 ehw.setErrorHandler(errorHandler);
383             }
384             else {
385                 fConfiguration.setProperty(ERROR_HANDLER,
386                         new ErrorHandlerWrapper(errorHandler));
387             }
388         }
389         catch (XMLConfigurationException e) {
390             // do nothing
391         }
392 
393     } // setErrorHandler(ErrorHandler)
394 
395     /**
396      * Return the current error handler.
397      *
398      * @return The current error handler, or null if none
399      *         has been registered.
400      * @see #setErrorHandler
401      */
getErrorHandler()402     public ErrorHandler getErrorHandler() {
403 
404         ErrorHandler errorHandler = null;
405         try {
406             XMLErrorHandler xmlErrorHandler =
407                 (XMLErrorHandler)fConfiguration.getProperty(ERROR_HANDLER);
408             if (xmlErrorHandler != null &&
409                 xmlErrorHandler instanceof ErrorHandlerWrapper) {
410                 errorHandler = ((ErrorHandlerWrapper)xmlErrorHandler).getErrorHandler();
411             }
412         }
413         catch (XMLConfigurationException e) {
414             // do nothing
415         }
416         return errorHandler;
417 
418     } // getErrorHandler():ErrorHandler
419 
420     /**
421      * Set the state of any feature in a SAX2 parser.  The parser
422      * might not recognize the feature, and if it does recognize
423      * it, it might not be able to fulfill the request.
424      *
425      * @param featureId The unique identifier (URI) of the feature.
426      * @param state The requested state of the feature (true or false).
427      *
428      * @exception SAXNotRecognizedException If the
429      *            requested feature is not known.
430      * @exception SAXNotSupportedException If the
431      *            requested feature is known, but the requested
432      *            state is not supported.
433      */
setFeature(String featureId, boolean state)434     public void setFeature(String featureId, boolean state)
435         throws SAXNotRecognizedException, SAXNotSupportedException {
436 
437         try {
438 
439             // http://xml.org/sax/features/use-entity-resolver2
440             //   controls whether the methods of an object implementing
441             //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
442             //
443             if (featureId.equals(USE_ENTITY_RESOLVER2)) {
444                 if (state != fUseEntityResolver2) {
445                     fUseEntityResolver2 = state;
446                     // Refresh EntityResolver wrapper.
447                     setEntityResolver(getEntityResolver());
448                 }
449                 return;
450             }
451 
452             //
453             // Default handling
454             //
455 
456             fConfiguration.setFeature(featureId, state);
457         }
458         catch (XMLConfigurationException e) {
459             String identifier = e.getIdentifier();
460             if (e.getType() == Status.NOT_RECOGNIZED) {
461                 throw new SAXNotRecognizedException(
462                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
463                     "feature-not-recognized", new Object [] {identifier}));
464             }
465             else {
466                 throw new SAXNotSupportedException(
467                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
468                     "feature-not-supported", new Object [] {identifier}));
469             }
470         }
471 
472     } // setFeature(String,boolean)
473 
474     /**
475      * Query the state of a feature.
476      *
477      * Query the current state of any feature in a SAX2 parser.  The
478      * parser might not recognize the feature.
479      *
480      * @param featureId The unique identifier (URI) of the feature
481      *                  being set.
482      * @return The current state of the feature.
483      * @exception org.xml.sax.SAXNotRecognizedException If the
484      *            requested feature is not known.
485      * @exception SAXNotSupportedException If the
486      *            requested feature is known but not supported.
487      */
getFeature(String featureId)488     public boolean getFeature(String featureId)
489         throws SAXNotRecognizedException, SAXNotSupportedException {
490 
491         try {
492 
493             // http://xml.org/sax/features/use-entity-resolver2
494             //   controls whether the methods of an object implementing
495             //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
496             //
497             if (featureId.equals(USE_ENTITY_RESOLVER2)) {
498                 return fUseEntityResolver2;
499             }
500 
501             //
502             // Default handling
503             //
504 
505             return fConfiguration.getFeature(featureId);
506         }
507         catch (XMLConfigurationException e) {
508             String identifier = e.getIdentifier();
509             if (e.getType() == Status.NOT_RECOGNIZED) {
510                 throw new SAXNotRecognizedException(
511                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
512                     "feature-not-recognized", new Object [] {identifier}));
513             }
514             else {
515                 throw new SAXNotSupportedException(
516                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
517                     "feature-not-supported", new Object [] {identifier}));
518             }
519         }
520 
521     } // getFeature(String):boolean
522 
523     /**
524      * Set the value of any property in a SAX2 parser.  The parser
525      * might not recognize the property, and if it does recognize
526      * it, it might not support the requested value.
527      *
528      * @param propertyId The unique identifier (URI) of the property
529      *                   being set.
530      * @param value The value to which the property is being set.
531      *
532      * @exception SAXNotRecognizedException If the
533      *            requested property is not known.
534      * @exception SAXNotSupportedException If the
535      *            requested property is known, but the requested
536      *            value is not supported.
537      */
setProperty(String propertyId, Object value)538     public void setProperty(String propertyId, Object value)
539         throws SAXNotRecognizedException, SAXNotSupportedException {
540         /**
541          * It's possible for users to set a security manager through the interface.
542          * If it's the old SecurityManager, convert it to the new XMLSecurityManager
543          */
544         if (propertyId.equals(Constants.SECURITY_MANAGER)) {
545             securityManager = XMLSecurityManager.convert(value, securityManager);
546             setProperty0(Constants.SECURITY_MANAGER, securityManager);
547             return;
548         }
549         if (propertyId.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) {
550             if (value == null) {
551                 securityPropertyManager = new XMLSecurityPropertyManager();
552             } else {
553                 securityPropertyManager = (XMLSecurityPropertyManager)value;
554             }
555             setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
556             return;
557         }
558 
559         if (securityManager == null) {
560             securityManager = new XMLSecurityManager(true);
561             setProperty0(Constants.SECURITY_MANAGER, securityManager);
562         }
563 
564         if (securityPropertyManager == null) {
565             securityPropertyManager = new XMLSecurityPropertyManager();
566             setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
567         }
568         int index = securityPropertyManager.getIndex(propertyId);
569 
570         if (index > -1) {
571             /**
572              * this is a direct call to this parser, not a subclass since
573              * internally the support of this property is done through
574              * XMLSecurityPropertyManager
575              */
576             securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
577         } else {
578             //check if the property is managed by security manager
579             if (!securityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) {
580                 //fall back to the default configuration to handle the property
581                 setProperty0(propertyId, value);
582             }
583         }
584     }
585 
setProperty0(String propertyId, Object value)586     public void setProperty0(String propertyId, Object value)
587         throws SAXNotRecognizedException, SAXNotSupportedException {
588         try {
589             fConfiguration.setProperty(propertyId, value);
590         }
591         catch (XMLConfigurationException e) {
592             String identifier = e.getIdentifier();
593             if (e.getType() == Status.NOT_RECOGNIZED) {
594                 throw new SAXNotRecognizedException(
595                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
596                     "property-not-recognized", new Object [] {identifier}));
597             }
598             else {
599                 throw new SAXNotSupportedException(
600                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
601                     "property-not-supported", new Object [] {identifier}));
602             }
603         }
604 
605     } // setProperty(String,Object)
606 
607     /**
608      * Query the value of a property.
609      *
610      * Return the current value of a property in a SAX2 parser.
611      * The parser might not recognize the property.
612      *
613      * @param propertyId The unique identifier (URI) of the property
614      *                   being set.
615      * @return The current value of the property.
616      * @exception org.xml.sax.SAXNotRecognizedException If the
617      *            requested property is not known.
618      * @exception SAXNotSupportedException If the
619      *            requested property is known but not supported.
620      */
getProperty(String propertyId)621     public Object getProperty(String propertyId)
622         throws SAXNotRecognizedException, SAXNotSupportedException {
623 
624        if (propertyId.equals(CURRENT_ELEMENT_NODE)) {
625            boolean deferred = false;
626            try {
627                deferred = getFeature(DEFER_NODE_EXPANSION);
628            }
629            catch (XMLConfigurationException e){
630                // ignore
631            }
632            if (deferred) {
633                throw new SAXNotSupportedException("Current element node cannot be queried when node expansion is deferred.");
634            }
635            return (fCurrentNode!=null &&
636                    fCurrentNode.getNodeType() == Node.ELEMENT_NODE)? fCurrentNode:null;
637        }
638 
639         try {
640             XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)
641                     fConfiguration.getProperty(XML_SECURITY_PROPERTY_MANAGER);
642             int index = spm.getIndex(propertyId);
643             if (index > -1) {
644                 return spm.getValueByIndex(index);
645             }
646 
647             return fConfiguration.getProperty(propertyId);
648         }
649         catch (XMLConfigurationException e) {
650             String identifier = e.getIdentifier();
651             if (e.getType() == Status.NOT_RECOGNIZED) {
652                 throw new SAXNotRecognizedException(
653                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
654                     "property-not-recognized", new Object [] {identifier}));
655             }
656             else {
657                 throw new SAXNotSupportedException(
658                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
659                     "property-not-supported", new Object [] {identifier}));
660             }
661         }
662 
663     } // getProperty(String):Object
664 
665     /**
666      * Returns this parser's XMLParserConfiguration.
667      */
getXMLParserConfiguration()668     public XMLParserConfiguration getXMLParserConfiguration() {
669         return fConfiguration;
670     } // getXMLParserConfiguration():XMLParserConfiguration
671 
672 } // class DOMParser
673