1/*
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
3 */
4/*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements.  See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License.  You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package com.sun.org.apache.xerces.internal.parsers;
22
23import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
24import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
25import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl;
26import com.sun.org.apache.xerces.internal.impl.Constants;
27import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper;
28import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper;
29import com.sun.org.apache.xerces.internal.util.DOMUtil;
30import com.sun.org.apache.xerces.internal.util.SymbolTable;
31import com.sun.org.apache.xerces.internal.util.XMLSymbols;
32import com.sun.org.apache.xerces.internal.xni.Augmentations;
33import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
34import com.sun.org.apache.xerces.internal.xni.QName;
35import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
36import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
37import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
38import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
39import com.sun.org.apache.xerces.internal.xni.XMLLocator;
40import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
41import com.sun.org.apache.xerces.internal.xni.XMLString;
42import com.sun.org.apache.xerces.internal.xni.XNIException;
43import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
44import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
45import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDContentModelSource;
46import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource;
47import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
48import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
49import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
50import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
51import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
52import java.io.StringReader;
53import java.util.ArrayList;
54import java.util.Locale;
55import java.util.Stack;
56import java.util.StringTokenizer;
57import org.w3c.dom.DOMConfiguration;
58import org.w3c.dom.DOMError;
59import org.w3c.dom.DOMErrorHandler;
60import org.w3c.dom.DOMException;
61import org.w3c.dom.DOMStringList;
62import org.w3c.dom.Document;
63import org.w3c.dom.Node;
64import org.w3c.dom.ls.LSException;
65import org.w3c.dom.ls.LSInput;
66import org.w3c.dom.ls.LSParser;
67import org.w3c.dom.ls.LSParserFilter;
68import org.w3c.dom.ls.LSResourceResolver;
69import org.xml.sax.SAXException;
70
71
72/**
73 * This is Xerces DOM Builder class. It uses the abstract DOM
74 * parser with a document scanner, a dtd scanner, and a validator, as
75 * well as a grammar pool.
76 *
77 * @author Pavani Mukthipudi, Sun Microsystems Inc.
78 * @author Elena Litani, IBM
79 * @author Rahul Srivastava, Sun Microsystems Inc.
80 */
81
82
83public class DOMParserImpl
84extends AbstractDOMParser implements LSParser, DOMConfiguration {
85
86
87
88    // SAX & Xerces feature ids
89
90    /** Feature identifier: namespaces. */
91    protected static final String NAMESPACES =
92    Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
93
94    /** Feature id: validation. */
95    protected static final String VALIDATION_FEATURE =
96    Constants.SAX_FEATURE_PREFIX+Constants.VALIDATION_FEATURE;
97
98    /** XML Schema validation */
99    protected static final String XMLSCHEMA =
100    Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
101
102    /** XML Schema full checking */
103    protected static final String XMLSCHEMA_FULL_CHECKING =
104    Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING;
105
106    /** Dynamic validation */
107    protected static final String DYNAMIC_VALIDATION =
108    Constants.XERCES_FEATURE_PREFIX + Constants.DYNAMIC_VALIDATION_FEATURE;
109
110    /** Feature identifier: expose schema normalized value */
111    protected static final String NORMALIZE_DATA =
112    Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE;
113
114    /** Feature identifier: disallow docType Decls. */
115    protected static final String DISALLOW_DOCTYPE_DECL_FEATURE =
116        Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
117
118    /** Feature identifier: namespace growth */
119    protected static final String NAMESPACE_GROWTH =
120        Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACE_GROWTH_FEATURE;
121
122    /** Feature identifier: tolerate duplicates */
123    protected static final String TOLERATE_DUPLICATES =
124        Constants.XERCES_FEATURE_PREFIX + Constants.TOLERATE_DUPLICATES_FEATURE;
125
126    // internal properties
127    protected static final String SYMBOL_TABLE =
128    Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
129
130    protected static final String PSVI_AUGMENT =
131    Constants.XERCES_FEATURE_PREFIX +Constants.SCHEMA_AUGMENT_PSVI;
132
133
134    //
135    // Data
136    //
137
138    /** Include namespace declaration attributes in the document. **/
139    protected boolean fNamespaceDeclarations = true;
140
141    // REVISIT: this value should be null by default and should be set during creation of
142    //          LSParser
143    protected String fSchemaType = null;
144
145    protected boolean fBusy = false;
146
147    private boolean abortNow = false;
148
149    private Thread currentThread;
150
151    protected final static boolean DEBUG = false;
152
153    private String fSchemaLocation = null;
154        private DOMStringList fRecognizedParameters;
155
156    private AbortHandler abortHandler = null;
157
158    //
159    // Constructors
160    //
161
162    /**
163     * Constructs a DOM Builder using the standard parser configuration.
164     */
165    public DOMParserImpl (XMLParserConfiguration config, String schemaType) {
166        this (config);
167        if (schemaType != null) {
168            if (schemaType.equals (Constants.NS_DTD)) {
169                //Schema validation is false by default and hence there is no
170                //need to set it to false here.  Also, schema validation is
171                //not a recognized feature for DTDConfiguration's and so
172                //setting this feature here would result in a Configuration
173                //Exception.
174                fConfiguration.setProperty (
175                Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE,
176                Constants.NS_DTD);
177                fSchemaType = Constants.NS_DTD;
178            }
179            else if (schemaType.equals (Constants.NS_XMLSCHEMA)) {
180                // XML Schem validation
181                fConfiguration.setProperty (
182                Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE,
183                Constants.NS_XMLSCHEMA);
184            }
185        }
186
187    }
188
189    /**
190     * Constructs a DOM Builder using the specified parser configuration.
191     */
192    public DOMParserImpl (XMLParserConfiguration config) {
193        super (config);
194
195        // add recognized features
196        final String[] domRecognizedFeatures = {
197            Constants.DOM_CANONICAL_FORM,
198            Constants.DOM_CDATA_SECTIONS,
199            Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING,
200            Constants.DOM_INFOSET,
201            Constants.DOM_NAMESPACE_DECLARATIONS,
202            Constants.DOM_SPLIT_CDATA,
203            Constants.DOM_SUPPORTED_MEDIATYPES_ONLY,
204            Constants.DOM_CERTIFIED,
205            Constants.DOM_WELLFORMED,
206            Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS,
207        };
208
209        fConfiguration.addRecognizedFeatures (domRecognizedFeatures);
210
211        // turn off deferred DOM
212        fConfiguration.setFeature (DEFER_NODE_EXPANSION, false);
213
214        // Set values so that the value of the
215        // infoset parameter is true (its default value).
216        //
217        // true: namespace-declarations, well-formed,
218        // element-content-whitespace, comments, namespaces
219        //
220        // false: validate-if-schema, entities,
221        // datatype-normalization, cdata-sections
222
223        fConfiguration.setFeature(Constants.DOM_NAMESPACE_DECLARATIONS, true);
224        fConfiguration.setFeature(Constants.DOM_WELLFORMED, true);
225        fConfiguration.setFeature(INCLUDE_COMMENTS_FEATURE, true);
226        fConfiguration.setFeature(INCLUDE_IGNORABLE_WHITESPACE, true);
227        fConfiguration.setFeature(NAMESPACES, true);
228
229        fConfiguration.setFeature(DYNAMIC_VALIDATION, false);
230        fConfiguration.setFeature(CREATE_ENTITY_REF_NODES, false);
231        fConfiguration.setFeature(CREATE_CDATA_NODES_FEATURE, false);
232
233        // set other default values
234        fConfiguration.setFeature (Constants.DOM_CANONICAL_FORM, false);
235        fConfiguration.setFeature (Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING, true);
236        fConfiguration.setFeature (Constants.DOM_SPLIT_CDATA, true);
237        fConfiguration.setFeature (Constants.DOM_SUPPORTED_MEDIATYPES_ONLY, false);
238        fConfiguration.setFeature (Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS, true);
239
240        // REVISIT: by default Xerces assumes that input is certified.
241        //          default is different from the one specified in the DOM spec
242        fConfiguration.setFeature (Constants.DOM_CERTIFIED, true);
243
244        // Xerces datatype-normalization feature is on by default
245        // This is a recognized feature only for XML Schemas. If the
246        // configuration doesn't support this feature, ignore it.
247        try {
248            fConfiguration.setFeature ( NORMALIZE_DATA, false );
249        }
250        catch (XMLConfigurationException exc) {}
251
252    } // <init>(XMLParserConfiguration)
253
254    /**
255     * Constructs a DOM Builder using the specified symbol table.
256     */
257    public DOMParserImpl (SymbolTable symbolTable) {
258        this (new XIncludeAwareParserConfiguration());
259        fConfiguration.setProperty (
260        Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY,
261        symbolTable);
262    } // <init>(SymbolTable)
263
264
265    /**
266     * Constructs a DOM Builder using the specified symbol table and
267     * grammar pool.
268     */
269    public DOMParserImpl (SymbolTable symbolTable, XMLGrammarPool grammarPool) {
270        this (new XIncludeAwareParserConfiguration());
271        fConfiguration.setProperty (
272        Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY,
273        symbolTable);
274        fConfiguration.setProperty (
275        Constants.XERCES_PROPERTY_PREFIX
276        + Constants.XMLGRAMMAR_POOL_PROPERTY,
277        grammarPool);
278    }
279
280    /**
281     * Resets the parser state.
282     *
283     * @throws SAXException Thrown on initialization error.
284     */
285    public void reset () {
286        super.reset();
287
288        // get state of namespace-declarations parameter.
289        fNamespaceDeclarations =
290            fConfiguration.getFeature(Constants.DOM_NAMESPACE_DECLARATIONS);
291
292        // DOM Filter
293        if (fSkippedElemStack != null) {
294            fSkippedElemStack.removeAllElements();
295        }
296
297        fRejectedElementDepth = 0;
298        fFilterReject = false;
299        fSchemaType = null;
300
301    } // reset()
302
303    //
304    // DOMParser methods
305    //
306
307    public DOMConfiguration getDomConfig (){
308        return this;
309    }
310
311
312    /**
313     *  When the application provides a filter, the parser will call out to
314     * the filter at the completion of the construction of each
315     * <code>Element</code> node. The filter implementation can choose to
316     * remove the element from the document being constructed (unless the
317     * element is the document element) or to terminate the parse early. If
318     * the document is being validated when it's loaded the validation
319     * happens before the filter is called.
320     */
321    public LSParserFilter getFilter () {
322        return fDOMFilter;
323    }
324
325    /**
326     *  When the application provides a filter, the parser will call out to
327     * the filter at the completion of the construction of each
328     * <code>Element</code> node. The filter implementation can choose to
329     * remove the element from the document being constructed (unless the
330     * element is the document element) or to terminate the parse early. If
331     * the document is being validated when it's loaded the validation
332     * happens before the filter is called.
333     */
334    public void setFilter (LSParserFilter filter) {
335        fDOMFilter = filter;
336        if (fSkippedElemStack == null) {
337            fSkippedElemStack = new Stack ();
338        }
339    }
340
341    /**
342     * Set parameters and properties
343     */
344    public void setParameter (String name, Object value) throws DOMException {
345        // set features
346
347        if(value instanceof Boolean){
348            boolean state = ((Boolean)value).booleanValue ();
349            try {
350                if (name.equalsIgnoreCase (Constants.DOM_COMMENTS)) {
351                    fConfiguration.setFeature (INCLUDE_COMMENTS_FEATURE, state);
352                }
353                else if (name.equalsIgnoreCase (Constants.DOM_DATATYPE_NORMALIZATION)) {
354                    fConfiguration.setFeature (NORMALIZE_DATA, state);
355                }
356                else if (name.equalsIgnoreCase (Constants.DOM_ENTITIES)) {
357                    fConfiguration.setFeature (CREATE_ENTITY_REF_NODES, state);
358                }
359                else if (name.equalsIgnoreCase (Constants.DOM_DISALLOW_DOCTYPE)) {
360                    fConfiguration.setFeature (DISALLOW_DOCTYPE_DECL_FEATURE, state);
361                }
362                else if (name.equalsIgnoreCase (Constants.DOM_SUPPORTED_MEDIATYPES_ONLY)
363                || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)
364                || name.equalsIgnoreCase (Constants.DOM_CHECK_CHAR_NORMALIZATION)
365                || name.equalsIgnoreCase (Constants.DOM_CANONICAL_FORM)) {
366                    if (state) { // true is not supported
367                        String msg =
368                        DOMMessageFormatter.formatMessage (
369                        DOMMessageFormatter.DOM_DOMAIN,
370                        "FEATURE_NOT_SUPPORTED",
371                        new Object[] { name });
372                        throw new DOMException (DOMException.NOT_SUPPORTED_ERR, msg);
373                    }
374                    // setting those features to false is no-op
375                }
376                else if (name.equalsIgnoreCase (Constants.DOM_NAMESPACES)) {
377                    fConfiguration.setFeature (NAMESPACES, state);
378                }
379                else if (name.equalsIgnoreCase (Constants.DOM_INFOSET)) {
380                    // Setting false has no effect.
381                    if (state) {
382                        // true: namespaces, namespace-declarations,
383                        // comments, element-content-whitespace
384                        fConfiguration.setFeature(NAMESPACES, true);
385                        fConfiguration.setFeature(Constants.DOM_NAMESPACE_DECLARATIONS, true);
386                        fConfiguration.setFeature(INCLUDE_COMMENTS_FEATURE, true);
387                        fConfiguration.setFeature(INCLUDE_IGNORABLE_WHITESPACE, true);
388
389                        // false: validate-if-schema, entities,
390                        // datatype-normalization, cdata-sections
391                        fConfiguration.setFeature(DYNAMIC_VALIDATION, false);
392                        fConfiguration.setFeature(CREATE_ENTITY_REF_NODES, false);
393                        fConfiguration.setFeature(NORMALIZE_DATA, false);
394                        fConfiguration.setFeature(CREATE_CDATA_NODES_FEATURE, false);
395                    }
396                }
397                else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
398                    fConfiguration.setFeature(CREATE_CDATA_NODES_FEATURE, state);
399                }
400                else if (name.equalsIgnoreCase (Constants.DOM_NAMESPACE_DECLARATIONS)) {
401                    fConfiguration.setFeature(Constants.DOM_NAMESPACE_DECLARATIONS, state);
402                }
403                else if (name.equalsIgnoreCase (Constants.DOM_WELLFORMED)
404                || name.equalsIgnoreCase (Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
405                    if (!state) { // false is not supported
406                        String msg =
407                        DOMMessageFormatter.formatMessage (
408                        DOMMessageFormatter.DOM_DOMAIN,
409                        "FEATURE_NOT_SUPPORTED",
410                        new Object[] { name });
411                        throw new DOMException (DOMException.NOT_SUPPORTED_ERR, msg);
412                    }
413                    // setting these features to true is no-op
414                    // REVISIT: implement "namespace-declaration" feature
415                }
416                else if (name.equalsIgnoreCase (Constants.DOM_VALIDATE)) {
417                    fConfiguration.setFeature (VALIDATION_FEATURE, state);
418                    if (fSchemaType != Constants.NS_DTD) {
419                        fConfiguration.setFeature (XMLSCHEMA, state);
420                        fConfiguration.setFeature (XMLSCHEMA_FULL_CHECKING, state);
421                    }
422                    if (state){
423                        fConfiguration.setFeature (DYNAMIC_VALIDATION, false);
424                    }
425                }
426                else if (name.equalsIgnoreCase (Constants.DOM_VALIDATE_IF_SCHEMA)) {
427                    fConfiguration.setFeature (DYNAMIC_VALIDATION, state);
428                    // Note: validation and dynamic validation are mutually exclusive
429                    if (state){
430                        fConfiguration.setFeature (VALIDATION_FEATURE, false);
431                    }
432                }
433                else if (name.equalsIgnoreCase (Constants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
434                    fConfiguration.setFeature (INCLUDE_IGNORABLE_WHITESPACE, state);
435                }
436                else if (name.equalsIgnoreCase (Constants.DOM_PSVI)){
437                    //XSModel - turn on PSVI augmentation
438                    fConfiguration.setFeature (PSVI_AUGMENT, true);
439                    fConfiguration.setProperty (DOCUMENT_CLASS_NAME,
440                    "com.sun.org.apache.xerces.internal.dom.PSVIDocumentImpl");
441                }
442                else {
443                    // Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING feature,
444                    // Constants.DOM_SPLIT_CDATA feature,
445                    // or any Xerces feature
446                    String normalizedName;
447                    if (name.equals(NAMESPACE_GROWTH)) {
448                        normalizedName = NAMESPACE_GROWTH;
449                    }
450                    else if (name.equals(TOLERATE_DUPLICATES)) {
451                        normalizedName = TOLERATE_DUPLICATES;
452                    }
453                    else {
454                        normalizedName = name.toLowerCase(Locale.ENGLISH);
455                    }
456                    fConfiguration.setFeature (normalizedName, state);
457                }
458
459            }
460            catch (XMLConfigurationException e) {
461                String msg =
462                DOMMessageFormatter.formatMessage (
463                DOMMessageFormatter.DOM_DOMAIN,
464                "FEATURE_NOT_FOUND",
465                new Object[] { name });
466                throw new DOMException (DOMException.NOT_FOUND_ERR, msg);
467            }
468        }
469        else { // set properties
470            if (name.equalsIgnoreCase (Constants.DOM_ERROR_HANDLER)) {
471                if (value instanceof DOMErrorHandler || value == null) {
472                    try {
473                        fErrorHandler = new DOMErrorHandlerWrapper ((DOMErrorHandler) value);
474                        fConfiguration.setProperty (ERROR_HANDLER, fErrorHandler);
475                    }
476                    catch (XMLConfigurationException e) {}
477                }
478                else {
479                    // REVISIT: type mismatch
480                    String msg =
481                    DOMMessageFormatter.formatMessage (
482                    DOMMessageFormatter.DOM_DOMAIN,
483                    "TYPE_MISMATCH_ERR",
484                    new Object[] { name });
485                    throw new DOMException (DOMException.TYPE_MISMATCH_ERR, msg);
486                }
487
488            }
489            else if (name.equalsIgnoreCase (Constants.DOM_RESOURCE_RESOLVER)) {
490                if (value instanceof LSResourceResolver || value == null) {
491                    try {
492                        fConfiguration.setProperty (ENTITY_RESOLVER, new DOMEntityResolverWrapper ((LSResourceResolver) value));
493                    }
494                    catch (XMLConfigurationException e) {}
495                }
496                else {
497                    // REVISIT: type mismatch
498                    String msg =
499                    DOMMessageFormatter.formatMessage (
500                    DOMMessageFormatter.DOM_DOMAIN,
501                    "TYPE_MISMATCH_ERR",
502                    new Object[] { name });
503                    throw new DOMException (DOMException.TYPE_MISMATCH_ERR, msg);
504                }
505
506            }
507            else if (name.equalsIgnoreCase (Constants.DOM_SCHEMA_LOCATION)) {
508                if (value instanceof String || value == null) {
509                    try {
510                        if (value == null) {
511                            fSchemaLocation = null;
512                            fConfiguration.setProperty (
513                                Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE,
514                                null);
515                        }
516                        else {
517                            fSchemaLocation = (String)value;
518                            // map DOM schema-location to JAXP schemaSource property
519                            // tokenize location string
520                            StringTokenizer t = new StringTokenizer (fSchemaLocation, " \n\t\r");
521                            if (t.hasMoreTokens()) {
522                                ArrayList locations = new ArrayList();
523                                locations.add (t.nextToken());
524                                while (t.hasMoreTokens()) {
525                                    locations.add (t.nextToken());
526                                }
527                                fConfiguration.setProperty (
528                                Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE,
529                                locations.toArray());
530                            }
531                            else {
532                                fConfiguration.setProperty (
533                                Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE,
534                                value);
535                            }
536                        }
537                    }
538                    catch (XMLConfigurationException e) {}
539                }
540                else {
541                    // REVISIT: type mismatch
542                    String msg =
543                    DOMMessageFormatter.formatMessage (
544                    DOMMessageFormatter.DOM_DOMAIN,
545                    "TYPE_MISMATCH_ERR",
546                    new Object[] { name });
547                    throw new DOMException (DOMException.TYPE_MISMATCH_ERR, msg);
548                }
549
550            }
551            else if (name.equalsIgnoreCase (Constants.DOM_SCHEMA_TYPE)) {
552                if (value instanceof String || value == null) {
553                    try {
554                        if (value == null) {
555                            // turn off schema features
556                            fConfiguration.setFeature (XMLSCHEMA, false);
557                            fConfiguration.setFeature (XMLSCHEMA_FULL_CHECKING, false);
558                            // map to JAXP schemaLanguage
559                            fConfiguration.setProperty ( Constants.JAXP_PROPERTY_PREFIX
560                            + Constants.SCHEMA_LANGUAGE,
561                            null);
562                            fSchemaType = null;
563                        }
564                        else if (value.equals (Constants.NS_XMLSCHEMA)) {
565                            // turn on schema features
566                            fConfiguration.setFeature (XMLSCHEMA, true);
567                            fConfiguration.setFeature (XMLSCHEMA_FULL_CHECKING, true);
568                            // map to JAXP schemaLanguage
569                            fConfiguration.setProperty ( Constants.JAXP_PROPERTY_PREFIX
570                            + Constants.SCHEMA_LANGUAGE,
571                            Constants.NS_XMLSCHEMA);
572                            fSchemaType = Constants.NS_XMLSCHEMA;
573                        }
574                        else if (value.equals (Constants.NS_DTD)) {
575                            // turn off schema features
576                            fConfiguration.setFeature (XMLSCHEMA, false);
577                            fConfiguration.setFeature (XMLSCHEMA_FULL_CHECKING, false);
578                            // map to JAXP schemaLanguage
579                            fConfiguration.setProperty ( Constants.JAXP_PROPERTY_PREFIX
580                            + Constants.SCHEMA_LANGUAGE,
581                            Constants.NS_DTD);
582                            fSchemaType = Constants.NS_DTD;
583                        }
584                    }
585                    catch (XMLConfigurationException e) {}
586                }
587                else {
588                    String msg =
589                    DOMMessageFormatter.formatMessage (
590                    DOMMessageFormatter.DOM_DOMAIN,
591                    "TYPE_MISMATCH_ERR",
592                    new Object[] { name });
593                    throw new DOMException (DOMException.TYPE_MISMATCH_ERR, msg);
594                }
595
596            }
597            else if (name.equalsIgnoreCase (DOCUMENT_CLASS_NAME)) {
598                fConfiguration.setProperty (DOCUMENT_CLASS_NAME, value);
599            }
600            else {
601                // Try to set the property.
602                String normalizedName = name.toLowerCase(Locale.ENGLISH);
603                try {
604                    fConfiguration.setProperty(normalizedName, value);
605                    return;
606                }
607                catch (XMLConfigurationException e) {}
608
609                // If this is a boolean parameter a type mismatch should be thrown.
610                try {
611                    if (name.equals(NAMESPACE_GROWTH)) {
612                        normalizedName = NAMESPACE_GROWTH;
613                    }
614                    else if (name.equals(TOLERATE_DUPLICATES)) {
615                        normalizedName = TOLERATE_DUPLICATES;
616                    }
617                    fConfiguration.getFeature(normalizedName);
618                    throw newTypeMismatchError(name);
619
620                }
621                catch (XMLConfigurationException e) {}
622
623                // Parameter is not recognized
624                throw newFeatureNotFoundError(name);
625            }
626        }
627    }
628
629    /**
630     * Look up the value of a feature or a property.
631     */
632    public Object getParameter (String name) throws DOMException {
633        if (name.equalsIgnoreCase (Constants.DOM_COMMENTS)) {
634            return (fConfiguration.getFeature (INCLUDE_COMMENTS_FEATURE))
635            ? Boolean.TRUE
636            : Boolean.FALSE;
637        }
638        else if (name.equalsIgnoreCase (Constants.DOM_DATATYPE_NORMALIZATION)) {
639            return (fConfiguration.getFeature (NORMALIZE_DATA))
640            ? Boolean.TRUE
641            : Boolean.FALSE;
642        }
643        else if (name.equalsIgnoreCase (Constants.DOM_ENTITIES)) {
644            return (fConfiguration.getFeature (CREATE_ENTITY_REF_NODES))
645            ? Boolean.TRUE
646            : Boolean.FALSE;
647        }
648        else if (name.equalsIgnoreCase (Constants.DOM_NAMESPACES)) {
649            return (fConfiguration.getFeature (NAMESPACES))
650            ? Boolean.TRUE
651            : Boolean.FALSE;
652        }
653        else if (name.equalsIgnoreCase (Constants.DOM_VALIDATE)) {
654            return (fConfiguration.getFeature (VALIDATION_FEATURE))
655            ? Boolean.TRUE
656            : Boolean.FALSE;
657        }
658        else if (name.equalsIgnoreCase (Constants.DOM_VALIDATE_IF_SCHEMA)) {
659            return (fConfiguration.getFeature (DYNAMIC_VALIDATION))
660            ? Boolean.TRUE
661            : Boolean.FALSE;
662        }
663        else if (name.equalsIgnoreCase (Constants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
664            return (fConfiguration.getFeature (INCLUDE_IGNORABLE_WHITESPACE))
665            ? Boolean.TRUE
666            : Boolean.FALSE;
667        }
668        else if (name.equalsIgnoreCase (Constants.DOM_DISALLOW_DOCTYPE)) {
669            return (fConfiguration.getFeature (DISALLOW_DOCTYPE_DECL_FEATURE))
670            ? Boolean.TRUE
671            : Boolean.FALSE;
672        }
673        else if (name.equalsIgnoreCase (Constants.DOM_INFOSET)) {
674            // REVISIT: This is somewhat expensive to compute
675            // but it's possible that the user has a reference
676            // to the configuration and is changing the values
677            // of these features directly on it.
678            boolean infoset = fConfiguration.getFeature(NAMESPACES) &&
679                fConfiguration.getFeature(Constants.DOM_NAMESPACE_DECLARATIONS) &&
680                fConfiguration.getFeature(INCLUDE_COMMENTS_FEATURE) &&
681                fConfiguration.getFeature(INCLUDE_IGNORABLE_WHITESPACE) &&
682                !fConfiguration.getFeature(DYNAMIC_VALIDATION) &&
683                !fConfiguration.getFeature(CREATE_ENTITY_REF_NODES) &&
684                !fConfiguration.getFeature(NORMALIZE_DATA) &&
685                !fConfiguration.getFeature(CREATE_CDATA_NODES_FEATURE);
686            return (infoset) ? Boolean.TRUE : Boolean.FALSE;
687        }
688        else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
689            return (fConfiguration.getFeature(CREATE_CDATA_NODES_FEATURE))
690                ? Boolean.TRUE : Boolean.FALSE;
691        }
692        else if (name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION ) ||
693                 name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)){
694            return Boolean.FALSE;
695        }
696        else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)
697        || name.equalsIgnoreCase (Constants.DOM_WELLFORMED)
698        || name.equalsIgnoreCase (Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)
699        || name.equalsIgnoreCase (Constants.DOM_CANONICAL_FORM)
700        || name.equalsIgnoreCase (Constants.DOM_SUPPORTED_MEDIATYPES_ONLY)
701        || name.equalsIgnoreCase (Constants.DOM_SPLIT_CDATA)
702        || name.equalsIgnoreCase (Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING)) {
703            return (fConfiguration.getFeature (name.toLowerCase(Locale.ENGLISH)))
704            ? Boolean.TRUE
705            : Boolean.FALSE;
706        }
707        else if (name.equalsIgnoreCase (Constants.DOM_ERROR_HANDLER)) {
708            if (fErrorHandler != null) {
709                return fErrorHandler.getErrorHandler ();
710            }
711            return null;
712        }
713        else if (name.equalsIgnoreCase (Constants.DOM_RESOURCE_RESOLVER)) {
714            try {
715                XMLEntityResolver entityResolver =
716                (XMLEntityResolver) fConfiguration.getProperty (ENTITY_RESOLVER);
717                if (entityResolver != null
718                && entityResolver instanceof DOMEntityResolverWrapper) {
719                    return ((DOMEntityResolverWrapper) entityResolver).getEntityResolver ();
720                }
721                return null;
722            }
723            catch (XMLConfigurationException e) {}
724        }
725        else if (name.equalsIgnoreCase (Constants.DOM_SCHEMA_TYPE)) {
726            return fConfiguration.getProperty (
727            Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE);
728        }
729        else if (name.equalsIgnoreCase (Constants.DOM_SCHEMA_LOCATION)) {
730            return fSchemaLocation;
731        }
732        else if (name.equalsIgnoreCase (SYMBOL_TABLE)){
733            return fConfiguration.getProperty (SYMBOL_TABLE);
734        }
735        else if (name.equalsIgnoreCase (DOCUMENT_CLASS_NAME)) {
736            return fConfiguration.getProperty (DOCUMENT_CLASS_NAME);
737        }
738        else {
739            // This could be a recognized feature or property.
740            String normalizedName;
741
742            if (name.equals(NAMESPACE_GROWTH)) {
743                normalizedName = NAMESPACE_GROWTH;
744            }
745            else if (name.equals(TOLERATE_DUPLICATES)) {
746                normalizedName = TOLERATE_DUPLICATES;
747            }
748            else {
749                normalizedName = name.toLowerCase(Locale.ENGLISH);
750            }
751            try {
752                return fConfiguration.getFeature(normalizedName)
753                    ? Boolean.TRUE : Boolean.FALSE;
754            }
755            catch (XMLConfigurationException e) {}
756
757            // This isn't a feature; perhaps it's a property
758            try {
759                return fConfiguration.getProperty(normalizedName);
760            }
761            catch (XMLConfigurationException e) {}
762
763            throw newFeatureNotFoundError(name);
764        }
765        return null;
766    }
767
768    public boolean canSetParameter (String name, Object value) {
769        if (value == null){
770                return true;
771        }
772
773        if(value instanceof Boolean){
774            boolean state = ((Boolean)value).booleanValue ();
775            if ( name.equalsIgnoreCase (Constants.DOM_SUPPORTED_MEDIATYPES_ONLY)
776            || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)
777            || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION )
778            || name.equalsIgnoreCase (Constants.DOM_CANONICAL_FORM) ) {
779                // true is not supported
780                return (state) ? false : true;
781            }
782            else if (name.equalsIgnoreCase (Constants.DOM_WELLFORMED)
783            || name.equalsIgnoreCase (Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
784                // false is not supported
785                return (state) ? true : false;
786            }
787            else if (name.equalsIgnoreCase (Constants.DOM_CDATA_SECTIONS)
788            || name.equalsIgnoreCase (Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING)
789            || name.equalsIgnoreCase (Constants.DOM_COMMENTS)
790            || name.equalsIgnoreCase (Constants.DOM_DATATYPE_NORMALIZATION)
791            || name.equalsIgnoreCase (Constants.DOM_DISALLOW_DOCTYPE)
792            || name.equalsIgnoreCase (Constants.DOM_ENTITIES)
793            || name.equalsIgnoreCase (Constants.DOM_INFOSET)
794            || name.equalsIgnoreCase (Constants.DOM_NAMESPACES)
795            || name.equalsIgnoreCase (Constants.DOM_NAMESPACE_DECLARATIONS)
796            || name.equalsIgnoreCase (Constants.DOM_VALIDATE)
797            || name.equalsIgnoreCase (Constants.DOM_VALIDATE_IF_SCHEMA)
798            || name.equalsIgnoreCase (Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
799            || name.equalsIgnoreCase (Constants.DOM_XMLDECL)) {
800                return true;
801            }
802
803            // Recognize Xerces features.
804            try {
805                String normalizedName;
806                if (name.equalsIgnoreCase(NAMESPACE_GROWTH)) {
807                    normalizedName = NAMESPACE_GROWTH;
808                }
809                else if (name.equalsIgnoreCase(TOLERATE_DUPLICATES)) {
810                    normalizedName = TOLERATE_DUPLICATES;
811                }
812                else {
813                    normalizedName = name.toLowerCase(Locale.ENGLISH);
814                }
815                fConfiguration.getFeature(normalizedName);
816                return true;
817            }
818            catch (XMLConfigurationException e) {
819                return false;
820            }
821        }
822        else { // check properties
823            if (name.equalsIgnoreCase (Constants.DOM_ERROR_HANDLER)) {
824                if (value instanceof DOMErrorHandler || value == null) {
825                    return true;
826                }
827                return false;
828            }
829            else if (name.equalsIgnoreCase (Constants.DOM_RESOURCE_RESOLVER)) {
830                if (value instanceof LSResourceResolver || value == null) {
831                    return true;
832                }
833                return false;
834            }
835            else if (name.equalsIgnoreCase (Constants.DOM_SCHEMA_TYPE)) {
836                if ((value instanceof String
837                && (value.equals (Constants.NS_XMLSCHEMA)
838                || value.equals (Constants.NS_DTD))) || value == null) {
839                    return true;
840                }
841                return false;
842            }
843            else if (name.equalsIgnoreCase (Constants.DOM_SCHEMA_LOCATION)) {
844                if (value instanceof String || value == null)
845                    return true;
846                return false;
847            }
848            else if (name.equalsIgnoreCase (DOCUMENT_CLASS_NAME)){
849                return true;
850            }
851            return false;
852        }
853    }
854
855    /**
856     *  DOM Level 3 CR - Experimental.
857     *
858     *  The list of the parameters supported by this
859     * <code>DOMConfiguration</code> object and for which at least one value
860     * can be set by the application. Note that this list can also contain
861     * parameter names defined outside this specification.
862     */
863    public DOMStringList getParameterNames () {
864        if (fRecognizedParameters == null){
865            ArrayList parameters = new ArrayList();
866
867            // REVISIT: add Xerces recognized properties/features
868            parameters.add(Constants.DOM_NAMESPACES);
869            parameters.add(Constants.DOM_CDATA_SECTIONS);
870            parameters.add(Constants.DOM_CANONICAL_FORM);
871            parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS);
872            parameters.add(Constants.DOM_SPLIT_CDATA);
873
874            parameters.add(Constants.DOM_ENTITIES);
875            parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA);
876            parameters.add(Constants.DOM_VALIDATE);
877            parameters.add(Constants.DOM_DATATYPE_NORMALIZATION);
878
879            parameters.add(Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING);
880            parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION);
881            parameters.add(Constants.DOM_SUPPORTED_MEDIATYPES_ONLY);
882            parameters.add(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS);
883
884            parameters.add(Constants.DOM_NORMALIZE_CHARACTERS);
885            parameters.add(Constants.DOM_WELLFORMED);
886            parameters.add(Constants.DOM_INFOSET);
887            parameters.add(Constants.DOM_DISALLOW_DOCTYPE);
888            parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE);
889            parameters.add(Constants.DOM_COMMENTS);
890
891            parameters.add(Constants.DOM_ERROR_HANDLER);
892            parameters.add(Constants.DOM_RESOURCE_RESOLVER);
893            parameters.add(Constants.DOM_SCHEMA_LOCATION);
894            parameters.add(Constants.DOM_SCHEMA_TYPE);
895
896            fRecognizedParameters = new DOMStringListImpl(parameters);
897
898        }
899
900        return fRecognizedParameters;
901    }
902
903    /**
904     * Parse an XML document from a location identified by an URI reference.
905     * If the URI contains a fragment identifier (see section 4.1 in ), the
906     * behavior is not defined by this specification.
907     *
908     */
909    public Document parseURI (String uri) throws LSException {
910
911        //If DOMParser insstance is already busy parsing another document when this
912        // method is called, then raise INVALID_STATE_ERR according to DOM L3 LS spec
913        if ( fBusy ) {
914            String msg = DOMMessageFormatter.formatMessage (
915            DOMMessageFormatter.DOM_DOMAIN,
916            "INVALID_STATE_ERR",null);
917            throw new DOMException ( DOMException.INVALID_STATE_ERR,msg);
918        }
919
920        XMLInputSource source = new XMLInputSource (null, uri, null, false);
921        try {
922            currentThread = Thread.currentThread();
923                        fBusy = true;
924            parse (source);
925            fBusy = false;
926            if (abortNow && currentThread.isInterrupted()) {
927                //reset interrupt state
928                abortNow = false;
929                Thread.interrupted();
930            }
931        } catch (Exception e){
932            fBusy = false;
933            if (abortNow && currentThread.isInterrupted()) {
934                Thread.interrupted();
935            }
936            if (abortNow) {
937                abortNow = false;
938                restoreHandlers();
939                return null;
940            }
941            // Consume this exception if the user
942            // issued an interrupt or an abort.
943            if (e != Abort.INSTANCE) {
944                if (!(e instanceof XMLParseException) && fErrorHandler != null) {
945                    DOMErrorImpl error = new DOMErrorImpl ();
946                    error.fException = e;
947                    error.fMessage = e.getMessage ();
948                    error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
949                    fErrorHandler.getErrorHandler ().handleError (error);
950                }
951                if (DEBUG) {
952                    e.printStackTrace ();
953                }
954                throw (LSException) DOMUtil.createLSException(LSException.PARSE_ERR, e).fillInStackTrace();
955            }
956        }
957        Document doc = getDocument();
958        dropDocumentReferences();
959        return doc;
960    }
961
962    /**
963     * Parse an XML document from a resource identified by an
964     * <code>LSInput</code>.
965     *
966     */
967    public Document parse (LSInput is) throws LSException {
968
969        // need to wrap the LSInput with an XMLInputSource
970        XMLInputSource xmlInputSource = dom2xmlInputSource (is);
971        if ( fBusy ) {
972            String msg = DOMMessageFormatter.formatMessage (
973            DOMMessageFormatter.DOM_DOMAIN,
974            "INVALID_STATE_ERR",null);
975            throw new DOMException ( DOMException.INVALID_STATE_ERR,msg);
976        }
977
978        try {
979            currentThread = Thread.currentThread();
980                        fBusy = true;
981            parse (xmlInputSource);
982            fBusy = false;
983            if (abortNow && currentThread.isInterrupted()) {
984                //reset interrupt state
985                abortNow = false;
986                Thread.interrupted();
987            }
988        } catch (Exception e) {
989            fBusy = false;
990            if (abortNow && currentThread.isInterrupted()) {
991                Thread.interrupted();
992            }
993            if (abortNow) {
994                abortNow = false;
995                restoreHandlers();
996                return null;
997            }
998            // Consume this exception if the user
999            // issued an interrupt or an abort.
1000            if (e != Abort.INSTANCE) {
1001                if (!(e instanceof XMLParseException) && fErrorHandler != null) {
1002                   DOMErrorImpl error = new DOMErrorImpl ();
1003                   error.fException = e;
1004                   error.fMessage = e.getMessage ();
1005                   error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
1006                   fErrorHandler.getErrorHandler().handleError (error);
1007                }
1008                if (DEBUG) {
1009                   e.printStackTrace ();
1010                }
1011                throw (LSException) DOMUtil.createLSException(LSException.PARSE_ERR, e).fillInStackTrace();
1012            }
1013        }
1014        Document doc = getDocument();
1015        dropDocumentReferences();
1016        return doc;
1017    }
1018
1019
1020    private void restoreHandlers() {
1021        fConfiguration.setDocumentHandler(this);
1022        fConfiguration.setDTDHandler(this);
1023        fConfiguration.setDTDContentModelHandler(this);
1024    }
1025
1026    /**
1027     *  Parse an XML document or fragment from a resource identified by an
1028     * <code>LSInput</code> and insert the content into an existing
1029     * document at the position epcified with the <code>contextNode</code>
1030     * and <code>action</code> arguments. When parsing the input stream the
1031     * context node is used for resolving unbound namespace prefixes.
1032     *
1033     * @param is  The <code>LSInput</code> from which the source
1034     *   document is to be read.
1035     * @param cnode  The <code>Node</code> that is used as the context for
1036     *   the data that is being parsed.
1037     * @param action This parameter describes which action should be taken
1038     *   between the new set of node being inserted and the existing
1039     *   children of the context node. The set of possible actions is
1040     *   defined above.
1041     * @exception DOMException
1042     *   HIERARCHY_REQUEST_ERR: Thrown if this action results in an invalid
1043     *   hierarchy (i.e. a Document with more than one document element).
1044     */
1045    public Node parseWithContext (LSInput is, Node cnode,
1046    short action) throws DOMException, LSException {
1047        // REVISIT: need to implement.
1048        throw new DOMException (DOMException.NOT_SUPPORTED_ERR, "Not supported");
1049    }
1050
1051
1052    /**
1053     * NON-DOM: convert LSInput to XNIInputSource
1054     *
1055     * @param is
1056     * @return
1057     */
1058    XMLInputSource dom2xmlInputSource (LSInput is) {
1059        // need to wrap the LSInput with an XMLInputSource
1060        XMLInputSource xis = null;
1061        // check whether there is a Reader
1062        // according to DOM, we need to treat such reader as "UTF-16".
1063        if (is.getCharacterStream () != null) {
1064            xis = new XMLInputSource (is.getPublicId (), is.getSystemId (),
1065            is.getBaseURI (), is.getCharacterStream (),
1066            "UTF-16");
1067        }
1068        // check whether there is an InputStream
1069        else if (is.getByteStream () != null) {
1070            xis = new XMLInputSource (is.getPublicId (), is.getSystemId (),
1071            is.getBaseURI (), is.getByteStream (),
1072            is.getEncoding ());
1073        }
1074        // if there is a string data, use a StringReader
1075        // according to DOM, we need to treat such data as "UTF-16".
1076        else if (is.getStringData () != null && is.getStringData().length() > 0) {
1077            xis = new XMLInputSource (is.getPublicId (), is.getSystemId (),
1078            is.getBaseURI (), new StringReader (is.getStringData ()),
1079            "UTF-16");
1080        }
1081        // otherwise, just use the public/system/base Ids
1082        else if ((is.getSystemId() != null && is.getSystemId().length() > 0) ||
1083            (is.getPublicId() != null && is.getPublicId().length() > 0)) {
1084            xis = new XMLInputSource (is.getPublicId (), is.getSystemId (),
1085            is.getBaseURI(), false);
1086        }
1087        else {
1088            // all inputs are null
1089            if (fErrorHandler != null) {
1090                DOMErrorImpl error = new DOMErrorImpl();
1091                error.fType = "no-input-specified";
1092                error.fMessage = "no-input-specified";
1093                error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
1094                fErrorHandler.getErrorHandler().handleError(error);
1095            }
1096            throw new LSException(LSException.PARSE_ERR, "no-input-specified");
1097        }
1098        return xis;
1099    }
1100
1101    /**
1102     * @see org.w3c.dom.ls.LSParser#getAsync()
1103     */
1104    public boolean getAsync () {
1105        return false;
1106    }
1107
1108    /**
1109     * @see org.w3c.dom.ls.LSParser#getBusy()
1110     */
1111    public boolean getBusy () {
1112        return fBusy;
1113    }
1114
1115    /**
1116     * @see org.w3c.dom.ls.LSParser#abort()
1117     */
1118    public void abort () {
1119        // If parse operation is in progress then reset it
1120        if ( fBusy ) {
1121            fBusy = false;
1122            if(currentThread != null) {
1123                abortNow = true;
1124                if (abortHandler == null) {
1125                    abortHandler = new AbortHandler();
1126                }
1127                fConfiguration.setDocumentHandler(abortHandler);
1128                fConfiguration.setDTDHandler(abortHandler);
1129                fConfiguration.setDTDContentModelHandler(abortHandler);
1130
1131                if(currentThread == Thread.currentThread())
1132                    throw Abort.INSTANCE;
1133
1134                currentThread.interrupt();
1135            }
1136        }
1137        return; // If not busy then this is noop
1138    }
1139
1140    /**
1141     * The start of an element. If the document specifies the start element
1142     * by using an empty tag, then the startElement method will immediately
1143     * be followed by the endElement method, with no intervening methods.
1144     * Overriding the parent to handle DOM_NAMESPACE_DECLARATIONS=false.
1145     *
1146     * @param element    The name of the element.
1147     * @param attributes The element attributes.
1148     * @param augs     Additional information that may include infoset augmentations
1149     *
1150     * @throws XNIException Thrown by handler to signal an error.
1151     */
1152    public void startElement (QName element, XMLAttributes attributes, Augmentations augs) {
1153        // namespace declarations parameter has no effect if namespaces is false.
1154        if (!fNamespaceDeclarations && fNamespaceAware) {
1155            int len = attributes.getLength();
1156            for (int i = len - 1; i >= 0; --i) {
1157                if (XMLSymbols.PREFIX_XMLNS == attributes.getPrefix(i) ||
1158                    XMLSymbols.PREFIX_XMLNS == attributes.getQName(i)) {
1159                    attributes.removeAttributeAt(i);
1160                }
1161            }
1162        }
1163        super.startElement(element, attributes, augs);
1164    }
1165
1166    private class AbortHandler implements XMLDocumentHandler, XMLDTDHandler, XMLDTDContentModelHandler  {
1167
1168        private XMLDocumentSource documentSource;
1169        private XMLDTDContentModelSource dtdContentSource;
1170        private XMLDTDSource dtdSource;
1171
1172        public void startDocument(XMLLocator locator, String encoding, NamespaceContext namespaceContext, Augmentations augs) throws XNIException {
1173            throw Abort.INSTANCE;
1174        }
1175
1176        public void xmlDecl(String version, String encoding, String standalone, Augmentations augs) throws XNIException {
1177            throw Abort.INSTANCE;
1178        }
1179
1180        public void doctypeDecl(String rootElement, String publicId, String systemId, Augmentations augs) throws XNIException {
1181            throw Abort.INSTANCE;
1182        }
1183
1184        public void comment(XMLString text, Augmentations augs) throws XNIException {
1185            throw Abort.INSTANCE;
1186        }
1187
1188        public void processingInstruction(String target, XMLString data, Augmentations augs) throws XNIException {
1189            throw Abort.INSTANCE;
1190        }
1191
1192        public void startElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException {
1193            throw Abort.INSTANCE;
1194        }
1195
1196        public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException {
1197            throw Abort.INSTANCE;
1198        }
1199
1200        public void startGeneralEntity(String name, XMLResourceIdentifier identifier, String encoding, Augmentations augs) throws XNIException {
1201            throw Abort.INSTANCE;
1202        }
1203
1204        public void textDecl(String version, String encoding, Augmentations augs) throws XNIException {
1205            throw Abort.INSTANCE;
1206        }
1207
1208        public void endGeneralEntity(String name, Augmentations augs) throws XNIException {
1209            throw Abort.INSTANCE;
1210        }
1211
1212        public void characters(XMLString text, Augmentations augs) throws XNIException {
1213            throw Abort.INSTANCE;
1214        }
1215
1216        public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException {
1217            throw Abort.INSTANCE;
1218        }
1219
1220        public void endElement(QName element, Augmentations augs) throws XNIException {
1221            throw Abort.INSTANCE;
1222        }
1223
1224        public void startCDATA(Augmentations augs) throws XNIException {
1225            throw Abort.INSTANCE;
1226        }
1227
1228        public void endCDATA(Augmentations augs) throws XNIException {
1229            throw Abort.INSTANCE;
1230        }
1231
1232        public void endDocument(Augmentations augs) throws XNIException {
1233            throw Abort.INSTANCE;
1234        }
1235
1236        public void setDocumentSource(XMLDocumentSource source) {
1237            documentSource = source;
1238        }
1239
1240        public XMLDocumentSource getDocumentSource() {
1241            return documentSource;
1242        }
1243
1244        public void startDTD(XMLLocator locator, Augmentations augmentations) throws XNIException {
1245            throw Abort.INSTANCE;
1246        }
1247
1248        public void startParameterEntity(String name, XMLResourceIdentifier identifier, String encoding, Augmentations augmentations) throws XNIException {
1249            throw Abort.INSTANCE;
1250        }
1251
1252        public void endParameterEntity(String name, Augmentations augmentations) throws XNIException {
1253            throw Abort.INSTANCE;
1254        }
1255
1256        public void startExternalSubset(XMLResourceIdentifier identifier, Augmentations augmentations) throws XNIException {
1257            throw Abort.INSTANCE;
1258        }
1259
1260        public void endExternalSubset(Augmentations augmentations) throws XNIException {
1261            throw Abort.INSTANCE;
1262        }
1263
1264        public void elementDecl(String name, String contentModel, Augmentations augmentations) throws XNIException {
1265            throw Abort.INSTANCE;
1266        }
1267
1268        public void startAttlist(String elementName, Augmentations augmentations) throws XNIException {
1269            throw Abort.INSTANCE;
1270        }
1271
1272        public void attributeDecl(String elementName, String attributeName, String type, String[] enumeration, String defaultType, XMLString defaultValue, XMLString nonNormalizedDefaultValue, Augmentations augmentations) throws XNIException {
1273            throw Abort.INSTANCE;
1274        }
1275
1276        public void endAttlist(Augmentations augmentations) throws XNIException {
1277            throw Abort.INSTANCE;
1278        }
1279
1280        public void internalEntityDecl(String name, XMLString text, XMLString nonNormalizedText, Augmentations augmentations) throws XNIException {
1281            throw Abort.INSTANCE;
1282        }
1283
1284        public void externalEntityDecl(String name, XMLResourceIdentifier identifier, Augmentations augmentations) throws XNIException {
1285            throw Abort.INSTANCE;
1286        }
1287
1288        public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier, String notation, Augmentations augmentations) throws XNIException {
1289            throw Abort.INSTANCE;
1290        }
1291
1292        public void notationDecl(String name, XMLResourceIdentifier identifier, Augmentations augmentations) throws XNIException {
1293            throw Abort.INSTANCE;
1294        }
1295
1296        public void startConditional(short type, Augmentations augmentations) throws XNIException {
1297            throw Abort.INSTANCE;
1298        }
1299
1300        public void ignoredCharacters(XMLString text, Augmentations augmentations) throws XNIException {
1301            throw Abort.INSTANCE;
1302        }
1303
1304        public void endConditional(Augmentations augmentations) throws XNIException {
1305            throw Abort.INSTANCE;
1306        }
1307
1308        public void endDTD(Augmentations augmentations) throws XNIException {
1309            throw Abort.INSTANCE;
1310        }
1311
1312        public void setDTDSource(XMLDTDSource source) {
1313            dtdSource = source;
1314        }
1315
1316        public XMLDTDSource getDTDSource() {
1317            return dtdSource;
1318        }
1319
1320        public void startContentModel(String elementName, Augmentations augmentations) throws XNIException {
1321            throw Abort.INSTANCE;
1322        }
1323
1324        public void any(Augmentations augmentations) throws XNIException {
1325            throw Abort.INSTANCE;
1326        }
1327
1328        public void empty(Augmentations augmentations) throws XNIException {
1329            throw Abort.INSTANCE;
1330        }
1331
1332        public void startGroup(Augmentations augmentations) throws XNIException {
1333            throw Abort.INSTANCE;
1334        }
1335
1336        public void pcdata(Augmentations augmentations) throws XNIException {
1337            throw Abort.INSTANCE;
1338        }
1339
1340        public void element(String elementName, Augmentations augmentations) throws XNIException {
1341            throw Abort.INSTANCE;
1342        }
1343
1344        public void separator(short separator, Augmentations augmentations) throws XNIException {
1345            throw Abort.INSTANCE;
1346        }
1347
1348        public void occurrence(short occurrence, Augmentations augmentations) throws XNIException {
1349            throw Abort.INSTANCE;
1350        }
1351
1352        public void endGroup(Augmentations augmentations) throws XNIException {
1353            throw Abort.INSTANCE;
1354        }
1355
1356        public void endContentModel(Augmentations augmentations) throws XNIException {
1357            throw Abort.INSTANCE;
1358        }
1359
1360        public void setDTDContentModelSource(XMLDTDContentModelSource source) {
1361            dtdContentSource = source;
1362        }
1363
1364        public XMLDTDContentModelSource getDTDContentModelSource() {
1365            return dtdContentSource;
1366        }
1367
1368    }
1369
1370    private static DOMException newFeatureNotFoundError(String name) {
1371        String msg =
1372            DOMMessageFormatter.formatMessage (
1373                    DOMMessageFormatter.DOM_DOMAIN,
1374                    "FEATURE_NOT_FOUND",
1375                    new Object[] { name });
1376        return new DOMException (DOMException.NOT_FOUND_ERR, msg);
1377    }
1378
1379    private static DOMException newTypeMismatchError(String name) {
1380        String msg =
1381            DOMMessageFormatter.formatMessage (
1382                    DOMMessageFormatter.DOM_DOMAIN,
1383                    "TYPE_MISMATCH_ERR",
1384                    new Object[] { name });
1385        return new DOMException (DOMException.TYPE_MISMATCH_ERR, msg);
1386    }
1387
1388} // class DOMParserImpl
1389