1/*
2 * Copyright (c) 2013, 2016, 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 java.io.IOException;
24import java.util.Locale;
25
26import com.sun.org.apache.xerces.internal.impl.Constants;
27import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl;
28import com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl;
29import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
30import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
31import com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl;
32import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory;
33import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
34import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
35import com.sun.org.apache.xerces.internal.util.FeatureState;
36import com.sun.org.apache.xerces.internal.util.PropertyState;
37import com.sun.org.apache.xerces.internal.util.Status;
38import com.sun.org.apache.xerces.internal.util.SymbolTable;
39import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
40import com.sun.org.apache.xerces.internal.xni.XMLLocator;
41import com.sun.org.apache.xerces.internal.xni.XNIException;
42import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
43import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
44import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
45import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
46import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
47import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner;
48import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
49import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration;
50import javax.xml.XMLConstants;
51import javax.xml.catalog.CatalogFeatures;
52import jdk.xml.internal.JdkXmlUtils;
53
54/**
55 * This is the non validating parser configuration. It extends the basic
56 * configuration with the set of following parser components:
57 * Document scanner, DTD scanner, namespace binder, document handler.
58 * <p>
59 * Xerces parser that uses this configuration is <strong>not</strong> <a href="http://www.w3.org/TR/REC-xml#sec-conformance">conformant</a>
60 * non-validating XML processor, since conformant non-validating processor is required
61 * to process "all the declarations they read in the internal DTD subset ... must use the information in those declarations to normalize attribute values,
62 * include the replacement text of internal entities, and supply default attribute values".
63 *
64 * @author Elena Litani, IBM
65 */
66public class NonValidatingConfiguration
67    extends BasicParserConfiguration
68    implements XMLPullParserConfiguration {
69
70    //
71    // Constants
72    //
73
74    // feature identifiers
75
76    /** Feature identifier: warn on duplicate attribute definition. */
77    protected static final String WARN_ON_DUPLICATE_ATTDEF =
78        Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
79
80    /** Feature identifier: warn on duplicate entity definition. */
81    protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
82        Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
83
84    /** Feature identifier: warn on undeclared element definition. */
85    protected static final String WARN_ON_UNDECLARED_ELEMDEF =
86        Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
87
88    /** Feature identifier: allow Java encodings. */
89    protected static final String ALLOW_JAVA_ENCODINGS =
90        Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
91
92    /** Feature identifier: continue after fatal error. */
93    protected static final String CONTINUE_AFTER_FATAL_ERROR =
94        Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
95
96    /** Feature identifier: load external DTD. */
97    protected static final String LOAD_EXTERNAL_DTD =
98        Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
99
100    /** Feature identifier: notify built-in refereces. */
101    protected static final String NOTIFY_BUILTIN_REFS =
102        Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE;
103
104    /** Feature identifier: notify character refereces. */
105    protected static final String NOTIFY_CHAR_REFS =
106        Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE;
107
108
109    /** Feature identifier: expose schema normalized value */
110    protected static final String NORMALIZE_DATA =
111    Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE;
112
113
114    /** Feature identifier: send element default value via characters() */
115    protected static final String SCHEMA_ELEMENT_DEFAULT =
116    Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT;
117
118    // property identifiers
119
120    /** Property identifier: error reporter. */
121    protected static final String ERROR_REPORTER =
122        Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
123
124    /** Property identifier: entity manager. */
125    protected static final String ENTITY_MANAGER =
126        Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
127
128    /** Property identifier document scanner: */
129    protected static final String DOCUMENT_SCANNER =
130        Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY;
131
132    /** Property identifier: DTD scanner. */
133    protected static final String DTD_SCANNER =
134        Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY;
135
136    /** Property identifier: grammar pool. */
137    protected static final String XMLGRAMMAR_POOL =
138        Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
139
140    /** Property identifier: DTD validator. */
141    protected static final String DTD_VALIDATOR =
142        Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
143
144    /** Property identifier: namespace binder. */
145    protected static final String NAMESPACE_BINDER =
146        Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY;
147
148    /** Property identifier: datatype validator factory. */
149    protected static final String DATATYPE_VALIDATOR_FACTORY =
150        Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
151
152    protected static final String VALIDATION_MANAGER =
153        Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
154
155    /** Property identifier: XML Schema validator. */
156    protected static final String SCHEMA_VALIDATOR =
157        Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
158
159    /** Property identifier: locale. */
160    protected static final String LOCALE =
161        Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
162
163      /** Property identifier: Security property manager. */
164      protected static final String XML_SECURITY_PROPERTY_MANAGER =
165              Constants.XML_SECURITY_PROPERTY_MANAGER;
166
167     /** Property identifier: Security manager. */
168     private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
169
170    // debugging
171
172    /** Set to true and recompile to print exception stack trace. */
173    private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
174
175    //
176    // Data
177    //
178
179    // components (non-configurable)
180
181    /** Grammar pool. */
182    protected XMLGrammarPool fGrammarPool;
183
184    /** Datatype validator factory. */
185    protected DTDDVFactory fDatatypeValidatorFactory;
186
187    // components (configurable)
188
189    /** Error reporter. */
190    protected XMLErrorReporter fErrorReporter;
191
192    /** Entity manager. */
193    protected XMLEntityManager fEntityManager;
194
195    /** Document scanner. */
196    protected XMLDocumentScanner fScanner;
197
198    /** Input Source */
199    protected XMLInputSource fInputSource;
200
201    /** DTD scanner. */
202    protected XMLDTDScanner fDTDScanner;
203
204
205    protected ValidationManager fValidationManager;
206
207    // private data
208
209    /** Document scanner that does namespace binding. */
210    private XMLNSDocumentScannerImpl fNamespaceScanner;
211
212    /** Default Xerces implementation of scanner*/
213    private XMLDocumentScannerImpl fNonNSScanner;
214
215
216        /** fConfigUpdated is set to true if there has been any change to the configuration settings,
217         * i.e a feature or a property was changed.
218         */
219        protected boolean fConfigUpdated = false;
220
221
222    // state
223
224    /** Locator */
225    protected XMLLocator fLocator;
226
227    /**
228     * True if a parse is in progress. This state is needed because
229     * some features/properties cannot be set while parsing (e.g.
230     * validation and namespaces).
231     */
232    protected boolean fParseInProgress = false;
233
234    //
235    // Constructors
236    //
237
238    /** Default constructor. */
239    public NonValidatingConfiguration() {
240        this(null, null, null);
241    } // <init>()
242
243    /**
244     * Constructs a parser configuration using the specified symbol table.
245     *
246     * @param symbolTable The symbol table to use.
247     */
248    public NonValidatingConfiguration(SymbolTable symbolTable) {
249        this(symbolTable, null, null);
250    } // <init>(SymbolTable)
251
252    /**
253     * Constructs a parser configuration using the specified symbol table and
254     * grammar pool.
255     * <p>
256     * <strong>REVISIT:</strong>
257     * Grammar pool will be updated when the new validation engine is
258     * implemented.
259     *
260     * @param symbolTable The symbol table to use.
261     * @param grammarPool The grammar pool to use.
262     */
263    public NonValidatingConfiguration(SymbolTable symbolTable,
264                                       XMLGrammarPool grammarPool) {
265        this(symbolTable, grammarPool, null);
266    } // <init>(SymbolTable,XMLGrammarPool)
267
268    /**
269     * Constructs a parser configuration using the specified symbol table,
270     * grammar pool, and parent settings.
271     * <p>
272     * <strong>REVISIT:</strong>
273     * Grammar pool will be updated when the new validation engine is
274     * implemented.
275     *
276     * @param symbolTable    The symbol table to use.
277     * @param grammarPool    The grammar pool to use.
278     * @param parentSettings The parent settings.
279     */
280    public NonValidatingConfiguration(SymbolTable symbolTable,
281                                       XMLGrammarPool grammarPool,
282                                       XMLComponentManager parentSettings) {
283        super(symbolTable, parentSettings);
284
285        // add default recognized features
286        final String[] recognizedFeatures = {
287            PARSER_SETTINGS,
288            NAMESPACES,
289            //WARN_ON_DUPLICATE_ATTDEF,     // from XMLDTDScannerImpl
290            //WARN_ON_UNDECLARED_ELEMDEF,   // from XMLDTDScannerImpl
291            //ALLOW_JAVA_ENCODINGS,         // from XMLEntityManager
292            CONTINUE_AFTER_FATAL_ERROR,
293            //LOAD_EXTERNAL_DTD,    // from XMLDTDScannerImpl
294            //NOTIFY_BUILTIN_REFS,  // from XMLDocumentFragmentScannerImpl
295            //NOTIFY_CHAR_REFS,         // from XMLDocumentFragmentScannerImpl
296            //WARN_ON_DUPLICATE_ENTITYDEF   // from XMLEntityManager
297            XMLConstants.USE_CATALOG
298        };
299        addRecognizedFeatures(recognizedFeatures);
300
301        // set state for default features
302        //setFeature(WARN_ON_DUPLICATE_ATTDEF, false);  // from XMLDTDScannerImpl
303        //setFeature(WARN_ON_UNDECLARED_ELEMDEF, false);    // from XMLDTDScannerImpl
304        //setFeature(ALLOW_JAVA_ENCODINGS, false);      // from XMLEntityManager
305        fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE);
306        fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
307        fFeatures.put(NAMESPACES, Boolean.TRUE);
308        //setFeature(LOAD_EXTERNAL_DTD, true);      // from XMLDTDScannerImpl
309        //setFeature(NOTIFY_BUILTIN_REFS, false);   // from XMLDocumentFragmentScannerImpl
310        //setFeature(NOTIFY_CHAR_REFS, false);      // from XMLDocumentFragmentScannerImpl
311        //setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false);   // from XMLEntityManager
312        fFeatures.put(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT);
313
314        // add default recognized properties
315        final String[] recognizedProperties = {
316            ERROR_REPORTER,
317            ENTITY_MANAGER,
318            DOCUMENT_SCANNER,
319            DTD_SCANNER,
320            DTD_VALIDATOR,
321            NAMESPACE_BINDER,
322            XMLGRAMMAR_POOL,
323            DATATYPE_VALIDATOR_FACTORY,
324            VALIDATION_MANAGER,
325            LOCALE,
326            SECURITY_MANAGER,
327            XML_SECURITY_PROPERTY_MANAGER,
328            JdkXmlUtils.CATALOG_DEFER,
329            JdkXmlUtils.CATALOG_FILES,
330            JdkXmlUtils.CATALOG_PREFER,
331            JdkXmlUtils.CATALOG_RESOLVE,
332            JdkXmlUtils.CDATA_CHUNK_SIZE
333        };
334        addRecognizedProperties(recognizedProperties);
335
336        fGrammarPool = grammarPool;
337        if(fGrammarPool != null){
338                        fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
339        }
340
341        fEntityManager = createEntityManager();
342                fProperties.put(ENTITY_MANAGER, fEntityManager);
343        addComponent(fEntityManager);
344
345        fErrorReporter = createErrorReporter();
346        fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
347                fProperties.put(ERROR_REPORTER, fErrorReporter);
348        addComponent(fErrorReporter);
349
350        // this configuration delays creation of the scanner
351        // till it is known if namespace processing should be performed
352
353        fDTDScanner = createDTDScanner();
354        if (fDTDScanner != null) {
355                        fProperties.put(DTD_SCANNER, fDTDScanner);
356            if (fDTDScanner instanceof XMLComponent) {
357                addComponent((XMLComponent)fDTDScanner);
358            }
359        }
360
361        fDatatypeValidatorFactory = createDatatypeValidatorFactory();
362        if (fDatatypeValidatorFactory != null) {
363                        fProperties.put(DATATYPE_VALIDATOR_FACTORY,
364                        fDatatypeValidatorFactory);
365        }
366        fValidationManager = createValidationManager();
367
368        if (fValidationManager != null) {
369                        fProperties.put(VALIDATION_MANAGER, fValidationManager);
370        }
371        // add message formatters
372        if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
373            XMLMessageFormatter xmft = new XMLMessageFormatter();
374            fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
375            fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
376        }
377
378                fConfigUpdated = false;
379
380        // set locale
381        try {
382            setLocale(Locale.getDefault());
383        }
384        catch (XNIException e) {
385            // do nothing
386            // REVISIT: What is the right thing to do? -Ac
387        }
388
389        setProperty(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager());
390
391        // Initialize Catalog features
392        for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
393            setProperty(f.getPropertyName(), null);
394        }
395
396        setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
397    } // <init>(SymbolTable,XMLGrammarPool)
398
399    //
400    // Public methods
401    //
402        public void setFeature(String featureId, boolean state)
403                throws XMLConfigurationException {
404                fConfigUpdated = true;
405                super.setFeature(featureId, state);
406        }
407
408        public PropertyState getPropertyState(String propertyId)
409             throws XMLConfigurationException {
410             if (LOCALE.equals(propertyId)) {
411                 return PropertyState.is(getLocale());
412             }
413             return super.getPropertyState(propertyId);
414         }
415
416        public void setProperty(String propertyId, Object value)
417             throws XMLConfigurationException {
418             fConfigUpdated = true;
419             if (LOCALE.equals(propertyId)) {
420                 setLocale((Locale) value);
421             }
422             super.setProperty(propertyId, value);
423         }
424
425    /**
426     * Set the locale to use for messages.
427     *
428     * @param locale The locale object to use for localization of messages.
429     *
430     * @exception XNIException Thrown if the parser does not support the
431     *                         specified locale.
432     */
433    public void setLocale(Locale locale) throws XNIException {
434        super.setLocale(locale);
435        fErrorReporter.setLocale(locale);
436    } // setLocale(Locale)
437
438        public FeatureState getFeatureState(String featureId)
439                throws XMLConfigurationException {
440                        // make this feature special
441                if (featureId.equals(PARSER_SETTINGS)){
442                        return FeatureState.is(fConfigUpdated);
443                }
444                return super.getFeatureState(featureId);
445
446        } // getFeature(String):boolean
447    //
448    // XMLPullParserConfiguration methods
449    //
450
451    // parsing
452
453    /**
454     * Sets the input source for the document to parse.
455     *
456     * @param inputSource The document's input source.
457     *
458     * @exception XMLConfigurationException Thrown if there is a
459     *                        configuration error when initializing the
460     *                        parser.
461     * @exception IOException Thrown on I/O error.
462     *
463     * @see #parse(boolean)
464     */
465    public void setInputSource(XMLInputSource inputSource)
466        throws XMLConfigurationException, IOException {
467
468        // REVISIT: this method used to reset all the components and
469        //          construct the pipeline. Now reset() is called
470        //          in parse (boolean) just before we parse the document
471        //          Should this method still throw exceptions..?
472
473        fInputSource = inputSource;
474
475    } // setInputSource(XMLInputSource)
476
477    /**
478     * Parses the document in a pull parsing fashion.
479     *
480     * @param complete True if the pull parser should parse the
481     *                 remaining document completely.
482     *
483     * @return True if there is more document to parse.
484     *
485     * @exception XNIException Any XNI exception, possibly wrapping
486     *                         another exception.
487     * @exception IOException  An IO exception from the parser, possibly
488     *                         from a byte stream or character stream
489     *                         supplied by the parser.
490     *
491     * @see #setInputSource
492     */
493    public boolean parse(boolean complete) throws XNIException, IOException {
494        //
495        // reset and configure pipeline and set InputSource.
496        if (fInputSource !=null) {
497            try {
498                // resets and sets the pipeline.
499                reset();
500                fScanner.setInputSource(fInputSource);
501                fInputSource = null;
502            }
503            catch (XNIException ex) {
504                if (PRINT_EXCEPTION_STACK_TRACE)
505                    ex.printStackTrace();
506                throw ex;
507            }
508            catch (IOException ex) {
509                if (PRINT_EXCEPTION_STACK_TRACE)
510                    ex.printStackTrace();
511                throw ex;
512            }
513            catch (RuntimeException ex) {
514                if (PRINT_EXCEPTION_STACK_TRACE)
515                    ex.printStackTrace();
516                throw ex;
517            }
518            catch (Exception ex) {
519                if (PRINT_EXCEPTION_STACK_TRACE)
520                    ex.printStackTrace();
521                throw new XNIException(ex);
522            }
523        }
524
525        try {
526            return fScanner.scanDocument(complete);
527        }
528        catch (XNIException ex) {
529            if (PRINT_EXCEPTION_STACK_TRACE)
530                ex.printStackTrace();
531            throw ex;
532        }
533        catch (IOException ex) {
534            if (PRINT_EXCEPTION_STACK_TRACE)
535                ex.printStackTrace();
536            throw ex;
537        }
538        catch (RuntimeException ex) {
539            if (PRINT_EXCEPTION_STACK_TRACE)
540                ex.printStackTrace();
541            throw ex;
542        }
543        catch (Exception ex) {
544            if (PRINT_EXCEPTION_STACK_TRACE)
545                ex.printStackTrace();
546            throw new XNIException(ex);
547        }
548
549    } // parse(boolean):boolean
550
551    /**
552     * If the application decides to terminate parsing before the xml document
553     * is fully parsed, the application should call this method to free any
554     * resource allocated during parsing. For example, close all opened streams.
555     */
556    public void cleanup() {
557        fEntityManager.closeReaders();
558    }
559
560    //
561    // XMLParserConfiguration methods
562    //
563
564    /**
565     * Parses the specified input source.
566     *
567     * @param source The input source.
568     *
569     * @exception XNIException Throws exception on XNI error.
570     * @exception java.io.IOException Throws exception on i/o error.
571     */
572    public void parse(XMLInputSource source) throws XNIException, IOException {
573
574        if (fParseInProgress) {
575            // REVISIT - need to add new error message
576            throw new XNIException("FWK005 parse may not be called while parsing.");
577        }
578        fParseInProgress = true;
579
580        try {
581            setInputSource(source);
582            parse(true);
583        }
584        catch (XNIException ex) {
585            if (PRINT_EXCEPTION_STACK_TRACE)
586                ex.printStackTrace();
587            throw ex;
588        }
589        catch (IOException ex) {
590            if (PRINT_EXCEPTION_STACK_TRACE)
591                ex.printStackTrace();
592            throw ex;
593        }
594        catch (RuntimeException ex) {
595            if (PRINT_EXCEPTION_STACK_TRACE)
596                ex.printStackTrace();
597            throw ex;
598        }
599        catch (Exception ex) {
600            if (PRINT_EXCEPTION_STACK_TRACE)
601                ex.printStackTrace();
602            throw new XNIException(ex);
603        }
604        finally {
605            fParseInProgress = false;
606            // close all streams opened by xerces
607            this.cleanup();
608        }
609
610    } // parse(InputSource)
611
612    //
613    // Protected methods
614    //
615
616    /**
617     * Reset all components before parsing.
618     *
619     * @throws XNIException Thrown if an error occurs during initialization.
620     */
621    protected void reset() throws XNIException {
622
623        if (fValidationManager != null)
624            fValidationManager.reset();
625        // configure the pipeline and initialize the components
626        configurePipeline();
627        super.reset();
628
629    } // reset()
630
631    /** Configures the pipeline. */
632    protected void configurePipeline() {
633        // create appropriate scanner
634        // and register it as one of the components.
635        if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
636            if (fNamespaceScanner == null) {
637                fNamespaceScanner = new XMLNSDocumentScannerImpl();
638                addComponent((XMLComponent)fNamespaceScanner);
639            }
640            fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner);
641            fNamespaceScanner.setDTDValidator(null);
642            fScanner = fNamespaceScanner;
643        }
644        else {
645            if (fNonNSScanner == null) {
646                fNonNSScanner = new XMLDocumentScannerImpl();
647                addComponent((XMLComponent)fNonNSScanner);
648            }
649            fProperties.put(DOCUMENT_SCANNER, fNonNSScanner);
650            fScanner = fNonNSScanner;
651        }
652
653        fScanner.setDocumentHandler(fDocumentHandler);
654        fLastComponent = fScanner;
655        // setup dtd pipeline
656        if (fDTDScanner != null) {
657                fDTDScanner.setDTDHandler(fDTDHandler);
658                fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler);
659        }
660
661
662    } // configurePipeline()
663
664    // features and properties
665
666    /**
667     * Check a feature. If feature is know and supported, this method simply
668     * returns. Otherwise, the appropriate exception is thrown.
669     *
670     * @param featureId The unique identifier (URI) of the feature.
671     *
672     * @throws XMLConfigurationException Thrown for configuration error.
673     *                                   In general, components should
674     *                                   only throw this exception if
675     *                                   it is <strong>really</strong>
676     *                                   a critical error.
677     */
678    protected FeatureState checkFeature(String featureId)
679        throws XMLConfigurationException {
680
681        //
682        // Xerces Features
683        //
684
685        if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
686            final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
687
688            //
689            // http://apache.org/xml/features/validation/dynamic
690            //   Allows the parser to validate a document only when it
691            //   contains a grammar. Validation is turned on/off based
692            //   on each document instance, automatically.
693            //
694            if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() &&
695                featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
696                return FeatureState.RECOGNIZED;
697            }
698            //
699            // http://apache.org/xml/features/validation/default-attribute-values
700            //
701            if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() &&
702                featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
703                // REVISIT
704                return FeatureState.NOT_SUPPORTED;
705            }
706            //
707            // http://apache.org/xml/features/validation/default-attribute-values
708            //
709            if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() &&
710                featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
711                // REVISIT
712                return FeatureState.NOT_SUPPORTED;
713            }
714            //
715            // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
716            //
717            if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() &&
718                featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
719                return FeatureState.RECOGNIZED;
720            }
721            //
722            // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
723            //
724            if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
725                featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
726                return FeatureState.RECOGNIZED;
727            }
728
729            //
730            // http://apache.org/xml/features/validation/default-attribute-values
731            //
732            if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() &&
733                featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
734                return FeatureState.NOT_SUPPORTED;
735            }
736        }
737
738        //
739        // Not recognized
740        //
741
742        return super.checkFeature(featureId);
743
744    } // checkFeature(String)
745
746    /**
747     * Check a property. If the property is know and supported, this method
748     * simply returns. Otherwise, the appropriate exception is thrown.
749     *
750     * @param propertyId The unique identifier (URI) of the property
751     *                   being set.
752     *
753     * @throws XMLConfigurationException Thrown for configuration error.
754     *                                   In general, components should
755     *                                   only throw this exception if
756     *                                   it is <strong>really</strong>
757     *                                   a critical error.
758     */
759    protected PropertyState checkProperty(String propertyId)
760        throws XMLConfigurationException {
761
762        //
763        // Xerces Properties
764        //
765
766        if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
767            final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
768
769            if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
770                propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
771                return PropertyState.RECOGNIZED;
772            }
773        }
774
775        if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) {
776            final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length();
777
778            if (suffixLength == Constants.SCHEMA_SOURCE.length() &&
779                propertyId.endsWith(Constants.SCHEMA_SOURCE)) {
780                return PropertyState.RECOGNIZED;
781            }
782        }
783
784        //
785        // Not recognized
786        //
787
788        return super.checkProperty(propertyId);
789
790    } // checkProperty(String)
791
792    // factory methods
793
794    /** Creates an entity manager. */
795    protected XMLEntityManager createEntityManager() {
796        return new XMLEntityManager();
797    } // createEntityManager():XMLEntityManager
798
799    /** Creates an error reporter. */
800    protected XMLErrorReporter createErrorReporter() {
801        return new XMLErrorReporter();
802    } // createErrorReporter():XMLErrorReporter
803
804    /** Create a document scanner. */
805    protected XMLDocumentScanner createDocumentScanner() {
806        return null;
807    } // createDocumentScanner():XMLDocumentScanner
808
809    /** Create a DTD scanner. */
810    protected XMLDTDScanner createDTDScanner() {
811        return new XMLDTDScannerImpl();
812    } // createDTDScanner():XMLDTDScanner
813
814    /** Create a datatype validator factory. */
815    protected DTDDVFactory createDatatypeValidatorFactory() {
816        return DTDDVFactory.getInstance();
817    } // createDatatypeValidatorFactory():DatatypeValidatorFactory
818    protected ValidationManager createValidationManager(){
819        return new ValidationManager();
820    }
821
822} // class NonValidatingConfiguration
823