View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 2001-2005 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * 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  
21  package com.sun.org.apache.xerces.internal.parsers;
22  
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.HashMap;
26  import java.util.Locale;
27  import javax.xml.XMLConstants;
28  
29  import com.sun.org.apache.xerces.internal.impl.Constants;
30  import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl;
31  import com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl;
32  import com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl;
33  import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl;
34  import com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl;
35  import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
36  import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
37  import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
38  import com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl;
39  import com.sun.org.apache.xerces.internal.impl.XMLVersionDetector;
40  import com.sun.org.apache.xerces.internal.impl.dtd.XML11DTDProcessor;
41  import com.sun.org.apache.xerces.internal.impl.dtd.XML11DTDValidator;
42  import com.sun.org.apache.xerces.internal.impl.dtd.XML11NSDTDValidator;
43  import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDProcessor;
44  import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator;
45  import com.sun.org.apache.xerces.internal.impl.dtd.XMLNSDTDValidator;
46  import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory;
47  import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
48  import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
49  import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
50  import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
51  import com.sun.org.apache.xerces.internal.util.FeatureState;
52  import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
53  import com.sun.org.apache.xerces.internal.util.PropertyState;
54  import com.sun.org.apache.xerces.internal.util.SymbolTable;
55  import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
56  import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
57  import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
58  import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
59  import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
60  import com.sun.org.apache.xerces.internal.xni.XMLLocator;
61  import com.sun.org.apache.xerces.internal.xni.XNIException;
62  import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
63  import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
64  import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
65  import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
66  import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
67  import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner;
68  import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
69  import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
70  import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
71  import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
72  import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration;
73  
74  /**
75   * This class is the configuration used to parse XML 1.0 and XML 1.1 documents.
76   *
77   * @author Elena Litani, IBM
78   * @author Neil Graham, IBM
79   * @author Michael Glavassevich, IBM
80   *
81   * @version $Id: XML11Configuration.java,v 1.9 2010-11-01 04:40:10 joehw Exp $
82   */
83  public class XML11Configuration extends ParserConfigurationSettings
84      implements XMLPullParserConfiguration, XML11Configurable {
85  
86      //
87      // Constants
88      //
89      protected final static String XML11_DATATYPE_VALIDATOR_FACTORY =
90          "com.sun.org.apache.xerces.internal.impl.dv.dtd.XML11DTDDVFactoryImpl";
91  
92      // feature identifiers
93  
94      /** Feature identifier: warn on duplicate attribute definition. */
95      protected static final String WARN_ON_DUPLICATE_ATTDEF =
96          Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
97  
98      /** Feature identifier: warn on duplicate entity definition. */
99      protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
100         Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
101 
102     /** Feature identifier: warn on undeclared element definition. */
103     protected static final String WARN_ON_UNDECLARED_ELEMDEF =
104         Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
105 
106     /** Feature identifier: allow Java encodings. */
107     protected static final String ALLOW_JAVA_ENCODINGS =
108         Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
109 
110     /** Feature identifier: continue after fatal error. */
111     protected static final String CONTINUE_AFTER_FATAL_ERROR =
112         Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
113 
114     /** Feature identifier: load external DTD. */
115     protected static final String LOAD_EXTERNAL_DTD =
116         Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
117 
118     /** Feature identifier: notify built-in refereces. */
119     protected static final String NOTIFY_BUILTIN_REFS =
120         Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE;
121 
122     /** Feature identifier: notify character refereces. */
123     protected static final String NOTIFY_CHAR_REFS =
124         Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE;
125 
126     /** Feature identifier: expose schema normalized value */
127     protected static final String NORMALIZE_DATA =
128         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE;
129 
130     /** Feature identifier: send element default value via characters() */
131     protected static final String SCHEMA_ELEMENT_DEFAULT =
132         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT;
133 
134     /** Feature identifier: augment PSVI */
135     protected static final String SCHEMA_AUGMENT_PSVI =
136         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI;
137 
138     /** feature identifier: XML Schema validation */
139     protected static final String XMLSCHEMA_VALIDATION =
140         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
141 
142     /** feature identifier: XML Schema validation -- full checking */
143     protected static final String XMLSCHEMA_FULL_CHECKING =
144         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING;
145 
146     /** Feature: generate synthetic annotations */
147     protected static final String GENERATE_SYNTHETIC_ANNOTATIONS =
148         Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
149 
150     /** Feature identifier: validate annotations */
151     protected static final String VALIDATE_ANNOTATIONS =
152         Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATE_ANNOTATIONS_FEATURE;
153 
154     /** Feature identifier: honour all schemaLocations */
155     protected static final String HONOUR_ALL_SCHEMALOCATIONS =
156         Constants.XERCES_FEATURE_PREFIX + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
157 
158     /** Feature identifier: namespace growth */
159     protected static final String NAMESPACE_GROWTH =
160         Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACE_GROWTH_FEATURE;
161 
162     /** Feature identifier: tolerate duplicates */
163     protected static final String TOLERATE_DUPLICATES =
164         Constants.XERCES_FEATURE_PREFIX + Constants.TOLERATE_DUPLICATES_FEATURE;
165 
166     /** Feature identifier: use grammar pool only */
167     protected static final String USE_GRAMMAR_POOL_ONLY =
168         Constants.XERCES_FEATURE_PREFIX + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE;
169 
170         // feature identifiers
171 
172         /** Feature identifier: validation. */
173         protected static final String VALIDATION =
174                 Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
175 
176         /** Feature identifier: namespaces. */
177         protected static final String NAMESPACES =
178                 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
179 
180         /** Feature identifier: external general entities. */
181         protected static final String EXTERNAL_GENERAL_ENTITIES =
182                 Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE;
183 
184         /** Feature identifier: external parameter entities. */
185         protected static final String EXTERNAL_PARAMETER_ENTITIES =
186                 Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE;
187 
188 
189 
190     // property identifiers
191 
192 
193         /** Property identifier: xml string. */
194         protected static final String XML_STRING =
195                 Constants.SAX_PROPERTY_PREFIX + Constants.XML_STRING_PROPERTY;
196 
197         /** Property identifier: symbol table. */
198         protected static final String SYMBOL_TABLE =
199                 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
200 
201         /** Property identifier: error handler. */
202         protected static final String ERROR_HANDLER =
203                 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
204 
205         /** Property identifier: entity resolver. */
206         protected static final String ENTITY_RESOLVER =
207                 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
208 
209 
210     /** Property identifier: XML Schema validator. */
211     protected static final String SCHEMA_VALIDATOR =
212         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
213 
214     /** Property identifier: schema location. */
215     protected static final String SCHEMA_LOCATION =
216         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_LOCATION;
217 
218     /** Property identifier: no namespace schema location. */
219     protected static final String SCHEMA_NONS_LOCATION =
220         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_NONS_LOCATION;
221 
222     // property identifiers
223 
224     /** Property identifier: error reporter. */
225     protected static final String ERROR_REPORTER =
226         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
227 
228     /** Property identifier: entity manager. */
229     protected static final String ENTITY_MANAGER =
230         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
231 
232     /** Property identifier document scanner: */
233     protected static final String DOCUMENT_SCANNER =
234         Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY;
235 
236     /** Property identifier: DTD scanner. */
237     protected static final String DTD_SCANNER =
238         Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY;
239 
240     /** Property identifier: grammar pool. */
241     protected static final String XMLGRAMMAR_POOL =
242         Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
243 
244     /** Property identifier: DTD loader. */
245     protected static final String DTD_PROCESSOR =
246         Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_PROCESSOR_PROPERTY;
247 
248     /** Property identifier: DTD validator. */
249     protected static final String DTD_VALIDATOR =
250         Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
251 
252     /** Property identifier: namespace binder. */
253     protected static final String NAMESPACE_BINDER =
254         Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY;
255 
256     /** Property identifier: datatype validator factory. */
257     protected static final String DATATYPE_VALIDATOR_FACTORY =
258         Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
259 
260     protected static final String VALIDATION_MANAGER =
261         Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
262 
263     /** Property identifier: JAXP schema language / DOM schema-type. */
264     protected static final String JAXP_SCHEMA_LANGUAGE =
265         Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE;
266 
267     /** Property identifier: JAXP schema source/ DOM schema-location. */
268     protected static final String JAXP_SCHEMA_SOURCE =
269         Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
270 
271     /** Property identifier: locale. */
272     protected static final String LOCALE =
273         Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
274 
275     /** Property identifier: Schema DV Factory */
276     protected static final String SCHEMA_DV_FACTORY =
277         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
278 
279     /** Property identifier: Security property manager. */
280     private static final String XML_SECURITY_PROPERTY_MANAGER =
281             Constants.XML_SECURITY_PROPERTY_MANAGER;
282 
283     /** Property identifier: Security manager. */
284     private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
285 
286     // debugging
287 
288     /** Set to true and recompile to print exception stack trace. */
289     protected static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
290 
291     //
292     // Data
293     //
294 
295         protected SymbolTable fSymbolTable;
296     protected XMLInputSource fInputSource;
297     protected ValidationManager fValidationManager;
298         protected XMLVersionDetector fVersionDetector;
299     protected XMLLocator fLocator;
300         protected Locale fLocale;
301 
302         /** XML 1.0 Components. */
303         protected ArrayList fComponents;
304 
305         /** XML 1.1. Components. */
306         protected ArrayList fXML11Components = null;
307 
308         /** Common components: XMLEntityManager, XMLErrorReporter, XMLSchemaValidator */
309         protected ArrayList fCommonComponents = null;
310 
311         /** The document handler. */
312         protected XMLDocumentHandler fDocumentHandler;
313 
314         /** The DTD handler. */
315         protected XMLDTDHandler fDTDHandler;
316 
317         /** The DTD content model handler. */
318         protected XMLDTDContentModelHandler fDTDContentModelHandler;
319 
320         /** Last component in the document pipeline */
321         protected XMLDocumentSource fLastComponent;
322 
323     /**
324      * True if a parse is in progress. This state is needed because
325      * some features/properties cannot be set while parsing (e.g.
326      * validation and namespaces).
327      */
328     protected boolean fParseInProgress = false;
329 
330     /** fConfigUpdated is set to true if there has been any change to the configuration settings,
331      * i.e a feature or a property was changed.
332      */
333         protected boolean fConfigUpdated = false;
334 
335     //
336     // XML 1.0 components
337     //
338 
339     /** The XML 1.0 Datatype validator factory. */
340     protected DTDDVFactory fDatatypeValidatorFactory;
341 
342     /** The XML 1.0 Document scanner that does namespace binding. */
343     protected XMLNSDocumentScannerImpl fNamespaceScanner;
344     /** The XML 1.0 Non-namespace implementation of scanner */
345     protected XMLDocumentScannerImpl fNonNSScanner;
346     /** The XML 1.0 DTD Validator: binds namespaces */
347     protected XMLDTDValidator fDTDValidator;
348     /** The XML 1.0 DTD Validator that does not bind namespaces */
349     protected XMLDTDValidator fNonNSDTDValidator;
350     /** The XML 1.0 DTD scanner. */
351     protected XMLDTDScanner fDTDScanner;
352     /** The XML 1.0 DTD Processor . */
353     protected XMLDTDProcessor fDTDProcessor;
354 
355     //
356     // XML 1.1 components
357     //
358 
359     /** The XML 1.1 datatype factory. **/
360     protected DTDDVFactory fXML11DatatypeFactory = null;
361 
362     /** The XML 1.1 document scanner that does namespace binding. **/
363     protected XML11NSDocumentScannerImpl fXML11NSDocScanner = null;
364 
365     /** The XML 1.1 document scanner that does not do namespace binding. **/
366     protected XML11DocumentScannerImpl fXML11DocScanner = null;
367 
368     /** The XML 1.1 DTD validator that does namespace binding. **/
369     protected XML11NSDTDValidator fXML11NSDTDValidator = null;
370 
371     /** The XML 1.1 DTD validator that does not do namespace binding. **/
372     protected XML11DTDValidator fXML11DTDValidator = null;
373 
374     /** The XML 1.1 DTD scanner. **/
375     protected XML11DTDScannerImpl fXML11DTDScanner = null;
376     /** The XML 1.1 DTD processor. **/
377     protected XML11DTDProcessor fXML11DTDProcessor = null;
378 
379     //
380     // Common components
381     //
382 
383     /** Grammar pool. */
384     protected XMLGrammarPool fGrammarPool;
385 
386     /** Error reporter. */
387     protected XMLErrorReporter fErrorReporter;
388 
389     /** Entity manager. */
390     protected XMLEntityManager fEntityManager;
391 
392     /** XML Schema Validator. */
393     protected XMLSchemaValidator fSchemaValidator;
394 
395     /** Current scanner */
396     protected XMLDocumentScanner fCurrentScanner;
397     /** Current Datatype validator factory. */
398     protected DTDDVFactory fCurrentDVFactory;
399     /** Current DTD scanner. */
400     protected XMLDTDScanner fCurrentDTDScanner;
401 
402     /** Flag indiciating whether XML11 components have been initialized. */
403     private boolean f11Initialized = false;
404 
405     //
406     // Constructors
407     //
408 
409     /** Default constructor. */
410     public XML11Configuration() {
411         this(null, null, null);
412     } // <init>()
413 
414     /**
415      * Constructs a parser configuration using the specified symbol table.
416      *
417      * @param symbolTable The symbol table to use.
418      */
419     public XML11Configuration(SymbolTable symbolTable) {
420         this(symbolTable, null, null);
421     } // <init>(SymbolTable)
422 
423     /**
424      * Constructs a parser configuration using the specified symbol table and
425      * grammar pool.
426      * <p>
427      * <strong>REVISIT:</strong>
428      * Grammar pool will be updated when the new validation engine is
429      * implemented.
430      *
431      * @param symbolTable The symbol table to use.
432      * @param grammarPool The grammar pool to use.
433      */
434     public XML11Configuration(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
435         this(symbolTable, grammarPool, null);
436     } // <init>(SymbolTable,XMLGrammarPool)
437 
438     /**
439      * Constructs a parser configuration using the specified symbol table,
440      * grammar pool, and parent settings.
441      * <p>
442      * <strong>REVISIT:</strong>
443      * Grammar pool will be updated when the new validation engine is
444      * implemented.
445      *
446      * @param symbolTable    The symbol table to use.
447      * @param grammarPool    The grammar pool to use.
448      * @param parentSettings The parent settings.
449      */
450     public XML11Configuration(
451         SymbolTable symbolTable,
452         XMLGrammarPool grammarPool,
453         XMLComponentManager parentSettings) {
454 
455         super(parentSettings);
456 
457         // create a vector to hold all the components in use
458         // XML 1.0 specialized components
459         fComponents = new ArrayList();
460         // XML 1.1 specialized components
461         fXML11Components = new ArrayList();
462         // Common components for XML 1.1. and XML 1.0
463         fCommonComponents = new ArrayList();
464 
465         // create table for features and properties
466         fFeatures = new HashMap();
467         fProperties = new HashMap();
468 
469         // add default recognized features
470         final String[] recognizedFeatures =
471             {
472                 CONTINUE_AFTER_FATAL_ERROR, LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl
473                 VALIDATION,
474                 NAMESPACES,
475                 NORMALIZE_DATA, SCHEMA_ELEMENT_DEFAULT, SCHEMA_AUGMENT_PSVI,
476                 GENERATE_SYNTHETIC_ANNOTATIONS, VALIDATE_ANNOTATIONS,
477                 HONOUR_ALL_SCHEMALOCATIONS, NAMESPACE_GROWTH,
478                 TOLERATE_DUPLICATES,
479                 USE_GRAMMAR_POOL_ONLY,
480                 // NOTE: These shouldn't really be here but since the XML Schema
481                 //       validator is constructed dynamically, its recognized
482                 //       features might not have been set and it would cause a
483                 //       not-recognized exception to be thrown. -Ac
484                 XMLSCHEMA_VALIDATION, XMLSCHEMA_FULL_CHECKING,
485                 EXTERNAL_GENERAL_ENTITIES,
486                 EXTERNAL_PARAMETER_ENTITIES,
487                 PARSER_SETTINGS,
488                 XMLConstants.FEATURE_SECURE_PROCESSING
489                         };
490         addRecognizedFeatures(recognizedFeatures);
491         // set state for default features
492         fFeatures.put(VALIDATION, Boolean.FALSE);
493         fFeatures.put(NAMESPACES, Boolean.TRUE);
494         fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE);
495         fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE);
496         fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE);
497         fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE);
498         fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE);
499         fFeatures.put(NORMALIZE_DATA, Boolean.TRUE);
500         fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE);
501         fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE);
502         fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE);
503         fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE);
504         fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE);
505         fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE);
506         fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE);
507         fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
508         fFeatures.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
509 
510         // add default recognized properties
511         final String[] recognizedProperties =
512             {
513                                 SYMBOL_TABLE,
514                                 ERROR_HANDLER,
515                                 ENTITY_RESOLVER,
516                 ERROR_REPORTER,
517                 ENTITY_MANAGER,
518                 DOCUMENT_SCANNER,
519                 DTD_SCANNER,
520                 DTD_PROCESSOR,
521                 DTD_VALIDATOR,
522                                 DATATYPE_VALIDATOR_FACTORY,
523                                 VALIDATION_MANAGER,
524                                 SCHEMA_VALIDATOR,
525                                 XML_STRING,
526                 XMLGRAMMAR_POOL,
527                 JAXP_SCHEMA_SOURCE,
528                 JAXP_SCHEMA_LANGUAGE,
529                 // NOTE: These shouldn't really be here but since the XML Schema
530                 //       validator is constructed dynamically, its recognized
531                 //       properties might not have been set and it would cause a
532                 //       not-recognized exception to be thrown. -Ac
533                 SCHEMA_LOCATION,
534                 SCHEMA_NONS_LOCATION,
535                 LOCALE,
536                 SCHEMA_DV_FACTORY,
537                 SECURITY_MANAGER,
538                 XML_SECURITY_PROPERTY_MANAGER
539         };
540         addRecognizedProperties(recognizedProperties);
541 
542                 if (symbolTable == null) {
543                         symbolTable = new SymbolTable();
544                 }
545                 fSymbolTable = symbolTable;
546                 fProperties.put(SYMBOL_TABLE, fSymbolTable);
547 
548         fGrammarPool = grammarPool;
549         if (fGrammarPool != null) {
550                         fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
551         }
552 
553         fEntityManager = new XMLEntityManager();
554                 fProperties.put(ENTITY_MANAGER, fEntityManager);
555         addCommonComponent(fEntityManager);
556 
557         fErrorReporter = new XMLErrorReporter();
558         fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
559                 fProperties.put(ERROR_REPORTER, fErrorReporter);
560         addCommonComponent(fErrorReporter);
561 
562         fNamespaceScanner = new XMLNSDocumentScannerImpl();
563                 fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner);
564         addComponent((XMLComponent) fNamespaceScanner);
565 
566         fDTDScanner = new XMLDTDScannerImpl();
567                 fProperties.put(DTD_SCANNER, fDTDScanner);
568         addComponent((XMLComponent) fDTDScanner);
569 
570         fDTDProcessor = new XMLDTDProcessor();
571                 fProperties.put(DTD_PROCESSOR, fDTDProcessor);
572         addComponent((XMLComponent) fDTDProcessor);
573 
574         fDTDValidator = new XMLNSDTDValidator();
575                 fProperties.put(DTD_VALIDATOR, fDTDValidator);
576         addComponent(fDTDValidator);
577 
578         fDatatypeValidatorFactory = DTDDVFactory.getInstance();
579                 fProperties.put(DATATYPE_VALIDATOR_FACTORY, fDatatypeValidatorFactory);
580 
581         fValidationManager = new ValidationManager();
582                 fProperties.put(VALIDATION_MANAGER, fValidationManager);
583 
584         fVersionDetector = new XMLVersionDetector();
585 
586         // add message formatters
587         if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
588             XMLMessageFormatter xmft = new XMLMessageFormatter();
589             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
590             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
591         }
592 
593         // set locale
594         try {
595             setLocale(Locale.getDefault());
596         } catch (XNIException e) {
597             // do nothing
598             // REVISIT: What is the right thing to do? -Ac
599         }
600 
601                 fConfigUpdated = false;
602 
603     } // <init>(SymbolTable,XMLGrammarPool)
604 
605     //
606     // Public methods
607     //
608     /**
609      * Sets the input source for the document to parse.
610      *
611      * @param inputSource The document's input source.
612      *
613      * @exception XMLConfigurationException Thrown if there is a
614      *                        configuration error when initializing the
615      *                        parser.
616      * @exception IOException Thrown on I/O error.
617      *
618      * @see #parse(boolean)
619      */
620     public void setInputSource(XMLInputSource inputSource)
621         throws XMLConfigurationException, IOException {
622 
623         // REVISIT: this method used to reset all the components and
624         //          construct the pipeline. Now reset() is called
625         //          in parse (boolean) just before we parse the document
626         //          Should this method still throw exceptions..?
627 
628         fInputSource = inputSource;
629 
630     } // setInputSource(XMLInputSource)
631 
632     /**
633      * Set the locale to use for messages.
634      *
635      * @param locale The locale object to use for localization of messages.
636      *
637      * @exception XNIException Thrown if the parser does not support the
638      *                         specified locale.
639      */
640     public void setLocale(Locale locale) throws XNIException {
641         fLocale = locale;
642         fErrorReporter.setLocale(locale);
643     } // setLocale(Locale)
644         /**
645          * Sets the document handler on the last component in the pipeline
646          * to receive information about the document.
647          *
648          * @param documentHandler   The document handler.
649          */
650         public void setDocumentHandler(XMLDocumentHandler documentHandler) {
651                 fDocumentHandler = documentHandler;
652                 if (fLastComponent != null) {
653                         fLastComponent.setDocumentHandler(fDocumentHandler);
654                         if (fDocumentHandler !=null){
655                                 fDocumentHandler.setDocumentSource(fLastComponent);
656                         }
657                 }
658         } // setDocumentHandler(XMLDocumentHandler)
659 
660         /** Returns the registered document handler. */
661         public XMLDocumentHandler getDocumentHandler() {
662                 return fDocumentHandler;
663         } // getDocumentHandler():XMLDocumentHandler
664 
665         /**
666          * Sets the DTD handler.
667          *
668          * @param dtdHandler The DTD handler.
669          */
670         public void setDTDHandler(XMLDTDHandler dtdHandler) {
671                 fDTDHandler = dtdHandler;
672         } // setDTDHandler(XMLDTDHandler)
673 
674         /** Returns the registered DTD handler. */
675         public XMLDTDHandler getDTDHandler() {
676                 return fDTDHandler;
677         } // getDTDHandler():XMLDTDHandler
678 
679         /**
680          * Sets the DTD content model handler.
681          *
682          * @param handler The DTD content model handler.
683          */
684         public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) {
685                 fDTDContentModelHandler = handler;
686         } // setDTDContentModelHandler(XMLDTDContentModelHandler)
687 
688         /** Returns the registered DTD content model handler. */
689         public XMLDTDContentModelHandler getDTDContentModelHandler() {
690                 return fDTDContentModelHandler;
691         } // getDTDContentModelHandler():XMLDTDContentModelHandler
692 
693         /**
694          * Sets the resolver used to resolve external entities. The EntityResolver
695          * interface supports resolution of public and system identifiers.
696          *
697          * @param resolver The new entity resolver. Passing a null value will
698          *                 uninstall the currently installed resolver.
699          */
700         public void setEntityResolver(XMLEntityResolver resolver) {
701                 fProperties.put(ENTITY_RESOLVER, resolver);
702         } // setEntityResolver(XMLEntityResolver)
703 
704         /**
705          * Return the current entity resolver.
706          *
707          * @return The current entity resolver, or null if none
708          *         has been registered.
709          * @see #setEntityResolver
710          */
711         public XMLEntityResolver getEntityResolver() {
712                 return (XMLEntityResolver)fProperties.get(ENTITY_RESOLVER);
713         } // getEntityResolver():XMLEntityResolver
714 
715         /**
716          * Allow an application to register an error event handler.
717          *
718          * <p>If the application does not register an error handler, all
719          * error events reported by the SAX parser will be silently
720          * ignored; however, normal processing may not continue.  It is
721          * highly recommended that all SAX applications implement an
722          * error handler to avoid unexpected bugs.</p>
723          *
724          * <p>Applications may register a new or different handler in the
725          * middle of a parse, and the SAX parser must begin using the new
726          * handler immediately.</p>
727          *
728          * @param errorHandler The error handler.
729          * @exception java.lang.NullPointerException If the handler
730          *            argument is null.
731          * @see #getErrorHandler
732          */
733         public void setErrorHandler(XMLErrorHandler errorHandler) {
734                 fProperties.put(ERROR_HANDLER, errorHandler);
735         } // setErrorHandler(XMLErrorHandler)
736 
737         /**
738          * Return the current error handler.
739          *
740          * @return The current error handler, or null if none
741          *         has been registered.
742          * @see #setErrorHandler
743          */
744         public XMLErrorHandler getErrorHandler() {
745                 // REVISIT: Should this be a property?
746                 return (XMLErrorHandler)fProperties.get(ERROR_HANDLER);
747         } // getErrorHandler():XMLErrorHandler
748 
749 
750     /**
751      * If the application decides to terminate parsing before the xml document
752      * is fully parsed, the application should call this method to free any
753      * resource allocated during parsing. For example, close all opened streams.
754      */
755     public void cleanup() {
756         fEntityManager.closeReaders();
757     }
758 
759     /**
760      * Parses the specified input source.
761      *
762      * @param source The input source.
763      *
764      * @exception XNIException Throws exception on XNI error.
765      * @exception java.io.IOException Throws exception on i/o error.
766      */
767     public void parse(XMLInputSource source) throws XNIException, IOException {
768 
769         if (fParseInProgress) {
770             // REVISIT - need to add new error message
771             throw new XNIException("FWK005 parse may not be called while parsing.");
772         }
773         fParseInProgress = true;
774 
775         try {
776             setInputSource(source);
777             parse(true);
778         } catch (XNIException ex) {
779             if (PRINT_EXCEPTION_STACK_TRACE)
780                 ex.printStackTrace();
781             throw ex;
782         } catch (IOException ex) {
783             if (PRINT_EXCEPTION_STACK_TRACE)
784                 ex.printStackTrace();
785             throw ex;
786         } catch (RuntimeException ex) {
787             if (PRINT_EXCEPTION_STACK_TRACE)
788                 ex.printStackTrace();
789             throw ex;
790         } catch (Exception ex) {
791             if (PRINT_EXCEPTION_STACK_TRACE)
792                 ex.printStackTrace();
793             throw new XNIException(ex);
794         } finally {
795             fParseInProgress = false;
796             // close all streams opened by xerces
797             this.cleanup();
798         }
799 
800     } // parse(InputSource)
801 
802     public boolean parse(boolean complete) throws XNIException, IOException {
803         //
804         // reset and configure pipeline and set InputSource.
805         if (fInputSource != null) {
806             try {
807                 fValidationManager.reset();
808                 fVersionDetector.reset(this);
809                 fConfigUpdated = true;
810                 resetCommon();
811 
812                 short version = fVersionDetector.determineDocVersion(fInputSource);
813                 if (version == Constants.XML_VERSION_1_1) {
814                     initXML11Components();
815                     configureXML11Pipeline();
816                     resetXML11();
817                 } else {
818                     configurePipeline();
819                     reset();
820                 }
821 
822                 // mark configuration as fixed
823                 fConfigUpdated = false;
824 
825                 // resets and sets the pipeline.
826                 fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version);
827                 fInputSource = null;
828             } catch (XNIException ex) {
829                 if (PRINT_EXCEPTION_STACK_TRACE)
830                     ex.printStackTrace();
831                 throw ex;
832             } catch (IOException ex) {
833                 if (PRINT_EXCEPTION_STACK_TRACE)
834                     ex.printStackTrace();
835                 throw ex;
836             } catch (RuntimeException ex) {
837                 if (PRINT_EXCEPTION_STACK_TRACE)
838                     ex.printStackTrace();
839                 throw ex;
840             } catch (Exception ex) {
841                 if (PRINT_EXCEPTION_STACK_TRACE)
842                     ex.printStackTrace();
843                 throw new XNIException(ex);
844             }
845         }
846 
847         try {
848             return fCurrentScanner.scanDocument(complete);
849         } catch (XNIException ex) {
850             if (PRINT_EXCEPTION_STACK_TRACE)
851                 ex.printStackTrace();
852             throw ex;
853         } catch (IOException ex) {
854             if (PRINT_EXCEPTION_STACK_TRACE)
855                 ex.printStackTrace();
856             throw ex;
857         } catch (RuntimeException ex) {
858             if (PRINT_EXCEPTION_STACK_TRACE)
859                 ex.printStackTrace();
860             throw ex;
861         } catch (Exception ex) {
862             if (PRINT_EXCEPTION_STACK_TRACE)
863                 ex.printStackTrace();
864             throw new XNIException(ex);
865         }
866 
867     } // parse(boolean):boolean
868 
869         /**
870          * Returns the state of a feature.
871          *
872          * @param featureId The feature identifier.
873          * @return true if the feature is supported
874          *
875          * @throws XMLConfigurationException Thrown for configuration error.
876          *                                   In general, components should
877          *                                   only throw this exception if
878          *                                   it is <strong>really</strong>
879          *                                   a critical error.
880          */
881         public FeatureState getFeatureState(String featureId)
882                 throws XMLConfigurationException {
883                         // make this feature special
884         if (featureId.equals(PARSER_SETTINGS)){
885                 return FeatureState.is(fConfigUpdated);
886         }
887         return super.getFeatureState(featureId);
888 
889         } // getFeature(String):boolean
890 
891         /**
892          * Set the state of a feature.
893          *
894          * Set the state of any feature in a SAX2 parser.  The parser
895          * might not recognize the feature, and if it does recognize
896          * it, it might not be able to fulfill the request.
897          *
898          * @param featureId The unique identifier (URI) of the feature.
899          * @param state The requested state of the feature (true or false).
900          *
901          * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the
902          *            requested feature is not known.
903          */
904         public void setFeature(String featureId, boolean state)
905                 throws XMLConfigurationException {
906                 fConfigUpdated = true;
907                 // forward to every XML 1.0 component
908                 int count = fComponents.size();
909                 for (int i = 0; i < count; i++) {
910                         XMLComponent c = (XMLComponent) fComponents.get(i);
911                         c.setFeature(featureId, state);
912                 }
913                 // forward it to common components
914                 count = fCommonComponents.size();
915                 for (int i = 0; i < count; i++) {
916                         XMLComponent c = (XMLComponent) fCommonComponents.get(i);
917                         c.setFeature(featureId, state);
918                 }
919 
920                 // forward to every XML 1.1 component
921                 count = fXML11Components.size();
922                 for (int i = 0; i < count; i++) {
923                         XMLComponent c = (XMLComponent) fXML11Components.get(i);
924                         try{
925                                 c.setFeature(featureId, state);
926                         }
927                         catch (Exception e){
928                                 // no op
929                         }
930                 }
931                 // save state if noone "objects"
932                 super.setFeature(featureId, state);
933 
934         } // setFeature(String,boolean)
935 
936     /**
937      * Returns the value of a property.
938      *
939      * @param propertyId The property identifier.
940      * @return the value of the property
941      *
942      * @throws XMLConfigurationException Thrown for configuration error.
943      *                                   In general, components should
944      *                                   only throw this exception if
945      *                                   it is <strong>really</strong>
946      *                                   a critical error.
947      */
948     public PropertyState getPropertyState(String propertyId)
949         throws XMLConfigurationException {
950         if (LOCALE.equals(propertyId)) {
951             return PropertyState.is(getLocale());
952         }
953         return super.getPropertyState(propertyId);
954     }
955 
956         /**
957          * setProperty
958          *
959          * @param propertyId
960          * @param value
961          */
962         public void setProperty(String propertyId, Object value)
963                 throws XMLConfigurationException {
964                 fConfigUpdated = true;
965                 if (LOCALE.equals(propertyId)) {
966                     setLocale((Locale) value);
967                 }
968                 // forward to every XML 1.0 component
969                 int count = fComponents.size();
970                 for (int i = 0; i < count; i++) {
971                         XMLComponent c = (XMLComponent) fComponents.get(i);
972                         c.setProperty(propertyId, value);
973                 }
974                 // forward it to every common Component
975                 count = fCommonComponents.size();
976                 for (int i = 0; i < count; i++) {
977                         XMLComponent c = (XMLComponent) fCommonComponents.get(i);
978                         c.setProperty(propertyId, value);
979                 }
980                 // forward it to every XML 1.1 component
981                 count = fXML11Components.size();
982                 for (int i = 0; i < count; i++) {
983                         XMLComponent c = (XMLComponent) fXML11Components.get(i);
984                         try{
985                                 c.setProperty(propertyId, value);
986                         }
987                         catch (Exception e){
988                                 // ignore it
989                         }
990                 }
991 
992                 // store value if noone "objects"
993                 super.setProperty(propertyId, value);
994 
995         } // setProperty(String,Object)
996 
997 
998         /** Returns the locale. */
999         public Locale getLocale() {
1000                 return fLocale;
1001         } // getLocale():Locale
1002 
1003         /**
1004          * reset all XML 1.0 components before parsing and namespace context
1005          */
1006         protected void reset() throws XNIException {
1007                 int count = fComponents.size();
1008                 for (int i = 0; i < count; i++) {
1009                         XMLComponent c = (XMLComponent) fComponents.get(i);
1010                         c.reset(this);
1011                 }
1012 
1013         } // reset()
1014 
1015         /**
1016          * reset all common components before parsing
1017          */
1018         protected void resetCommon() throws XNIException {
1019                 // reset common components
1020                 int count = fCommonComponents.size();
1021                 for (int i = 0; i < count; i++) {
1022                         XMLComponent c = (XMLComponent) fCommonComponents.get(i);
1023                         c.reset(this);
1024                 }
1025 
1026         } // resetCommon()
1027 
1028 
1029         /**
1030          * reset all components before parsing and namespace context
1031          */
1032         protected void resetXML11() throws XNIException {
1033                 // reset every component
1034                 int count = fXML11Components.size();
1035                 for (int i = 0; i < count; i++) {
1036                         XMLComponent c = (XMLComponent) fXML11Components.get(i);
1037                         c.reset(this);
1038                 }
1039 
1040         } // resetXML11()
1041 
1042 
1043     /**
1044      *  Configures the XML 1.1 pipeline.
1045      *  Note: this method also resets the new XML11 components.
1046      */
1047     protected void configureXML11Pipeline() {
1048         if (fCurrentDVFactory != fXML11DatatypeFactory) {
1049             fCurrentDVFactory = fXML11DatatypeFactory;
1050             setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
1051         }
1052         if (fCurrentDTDScanner != fXML11DTDScanner) {
1053             fCurrentDTDScanner = fXML11DTDScanner;
1054             setProperty(DTD_SCANNER, fCurrentDTDScanner);
1055                         setProperty(DTD_PROCESSOR, fXML11DTDProcessor);
1056         }
1057 
1058         fXML11DTDScanner.setDTDHandler(fXML11DTDProcessor);
1059         fXML11DTDProcessor.setDTDSource(fXML11DTDScanner);
1060         fXML11DTDProcessor.setDTDHandler(fDTDHandler);
1061         if (fDTDHandler != null) {
1062             fDTDHandler.setDTDSource(fXML11DTDProcessor);
1063         }
1064 
1065         fXML11DTDScanner.setDTDContentModelHandler(fXML11DTDProcessor);
1066         fXML11DTDProcessor.setDTDContentModelSource(fXML11DTDScanner);
1067         fXML11DTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler);
1068         if (fDTDContentModelHandler != null) {
1069             fDTDContentModelHandler.setDTDContentModelSource(fXML11DTDProcessor);
1070         }
1071 
1072         // setup XML 1.1 document pipeline
1073         if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
1074             if (fCurrentScanner != fXML11NSDocScanner) {
1075                 fCurrentScanner = fXML11NSDocScanner;
1076                 setProperty(DOCUMENT_SCANNER, fXML11NSDocScanner);
1077                 setProperty(DTD_VALIDATOR, fXML11NSDTDValidator);
1078             }
1079 
1080             fXML11NSDocScanner.setDTDValidator(fXML11NSDTDValidator);
1081             fXML11NSDocScanner.setDocumentHandler(fXML11NSDTDValidator);
1082             fXML11NSDTDValidator.setDocumentSource(fXML11NSDocScanner);
1083             fXML11NSDTDValidator.setDocumentHandler(fDocumentHandler);
1084 
1085             if (fDocumentHandler != null) {
1086                 fDocumentHandler.setDocumentSource(fXML11NSDTDValidator);
1087             }
1088             fLastComponent = fXML11NSDTDValidator;
1089 
1090         } else {
1091                         // create components
1092                           if (fXML11DocScanner == null) {
1093                                         // non namespace document pipeline
1094                                         fXML11DocScanner = new XML11DocumentScannerImpl();
1095                                         addXML11Component(fXML11DocScanner);
1096                                         fXML11DTDValidator = new XML11DTDValidator();
1097                                         addXML11Component(fXML11DTDValidator);
1098                           }
1099             if (fCurrentScanner != fXML11DocScanner) {
1100                 fCurrentScanner = fXML11DocScanner;
1101                 setProperty(DOCUMENT_SCANNER, fXML11DocScanner);
1102                 setProperty(DTD_VALIDATOR, fXML11DTDValidator);
1103             }
1104             fXML11DocScanner.setDocumentHandler(fXML11DTDValidator);
1105             fXML11DTDValidator.setDocumentSource(fXML11DocScanner);
1106             fXML11DTDValidator.setDocumentHandler(fDocumentHandler);
1107 
1108             if (fDocumentHandler != null) {
1109                 fDocumentHandler.setDocumentSource(fXML11DTDValidator);
1110             }
1111             fLastComponent = fXML11DTDValidator;
1112         }
1113 
1114         // setup document pipeline
1115         if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
1116             // If schema validator was not in the pipeline insert it.
1117             if (fSchemaValidator == null) {
1118                 fSchemaValidator = new XMLSchemaValidator();
1119                 // add schema component
1120                 setProperty(SCHEMA_VALIDATOR, fSchemaValidator);
1121                                 addCommonComponent(fSchemaValidator);
1122                                 fSchemaValidator.reset(this);
1123                 // add schema message formatter
1124                 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
1125                     XSMessageFormatter xmft = new XSMessageFormatter();
1126                     fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft);
1127                 }
1128             }
1129 
1130             fLastComponent.setDocumentHandler(fSchemaValidator);
1131             fSchemaValidator.setDocumentSource(fLastComponent);
1132             fSchemaValidator.setDocumentHandler(fDocumentHandler);
1133             if (fDocumentHandler != null) {
1134                 fDocumentHandler.setDocumentSource(fSchemaValidator);
1135             }
1136             fLastComponent = fSchemaValidator;
1137         }
1138 
1139     } // configureXML11Pipeline()
1140 
1141     /** Configures the pipeline. */
1142     protected void configurePipeline() {
1143         if (fCurrentDVFactory != fDatatypeValidatorFactory) {
1144             fCurrentDVFactory = fDatatypeValidatorFactory;
1145             // use XML 1.0 datatype library
1146             setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
1147         }
1148 
1149         // setup DTD pipeline
1150         if (fCurrentDTDScanner != fDTDScanner) {
1151             fCurrentDTDScanner = fDTDScanner;
1152             setProperty(DTD_SCANNER, fCurrentDTDScanner);
1153             setProperty(DTD_PROCESSOR, fDTDProcessor);
1154         }
1155         fDTDScanner.setDTDHandler(fDTDProcessor);
1156         fDTDProcessor.setDTDSource(fDTDScanner);
1157         fDTDProcessor.setDTDHandler(fDTDHandler);
1158         if (fDTDHandler != null) {
1159             fDTDHandler.setDTDSource(fDTDProcessor);
1160         }
1161 
1162         fDTDScanner.setDTDContentModelHandler(fDTDProcessor);
1163         fDTDProcessor.setDTDContentModelSource(fDTDScanner);
1164         fDTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler);
1165         if (fDTDContentModelHandler != null) {
1166             fDTDContentModelHandler.setDTDContentModelSource(fDTDProcessor);
1167         }
1168 
1169         // setup document pipeline
1170         if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
1171             if (fCurrentScanner != fNamespaceScanner) {
1172                 fCurrentScanner = fNamespaceScanner;
1173                 setProperty(DOCUMENT_SCANNER, fNamespaceScanner);
1174                 setProperty(DTD_VALIDATOR, fDTDValidator);
1175             }
1176             fNamespaceScanner.setDTDValidator(fDTDValidator);
1177             fNamespaceScanner.setDocumentHandler(fDTDValidator);
1178             fDTDValidator.setDocumentSource(fNamespaceScanner);
1179             fDTDValidator.setDocumentHandler(fDocumentHandler);
1180             if (fDocumentHandler != null) {
1181                 fDocumentHandler.setDocumentSource(fDTDValidator);
1182             }
1183             fLastComponent = fDTDValidator;
1184         } else {
1185             // create components
1186             if (fNonNSScanner == null) {
1187                 fNonNSScanner = new XMLDocumentScannerImpl();
1188                 fNonNSDTDValidator = new XMLDTDValidator();
1189                 // add components
1190                 addComponent((XMLComponent) fNonNSScanner);
1191                 addComponent((XMLComponent) fNonNSDTDValidator);
1192             }
1193             if (fCurrentScanner != fNonNSScanner) {
1194                 fCurrentScanner = fNonNSScanner;
1195                 setProperty(DOCUMENT_SCANNER, fNonNSScanner);
1196                 setProperty(DTD_VALIDATOR, fNonNSDTDValidator);
1197             }
1198 
1199             fNonNSScanner.setDocumentHandler(fNonNSDTDValidator);
1200             fNonNSDTDValidator.setDocumentSource(fNonNSScanner);
1201             fNonNSDTDValidator.setDocumentHandler(fDocumentHandler);
1202             if (fDocumentHandler != null) {
1203                 fDocumentHandler.setDocumentSource(fNonNSDTDValidator);
1204             }
1205             fLastComponent = fNonNSDTDValidator;
1206         }
1207 
1208         // add XML Schema validator if needed
1209         if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
1210             // If schema validator was not in the pipeline insert it.
1211             if (fSchemaValidator == null) {
1212                 fSchemaValidator = new XMLSchemaValidator();
1213                 // add schema component
1214                 setProperty(SCHEMA_VALIDATOR, fSchemaValidator);
1215                 addCommonComponent(fSchemaValidator);
1216                 fSchemaValidator.reset(this);
1217                 // add schema message formatter
1218                 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
1219                     XSMessageFormatter xmft = new XSMessageFormatter();
1220                     fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft);
1221                 }
1222 
1223             }
1224             fLastComponent.setDocumentHandler(fSchemaValidator);
1225             fSchemaValidator.setDocumentSource(fLastComponent);
1226             fSchemaValidator.setDocumentHandler(fDocumentHandler);
1227             if (fDocumentHandler != null) {
1228                 fDocumentHandler.setDocumentSource(fSchemaValidator);
1229             }
1230             fLastComponent = fSchemaValidator;
1231         }
1232     } // configurePipeline()
1233 
1234 
1235     // features and properties
1236 
1237     /**
1238      * Check a feature. If feature is know and supported, this method simply
1239      * returns. Otherwise, the appropriate exception is thrown.
1240      *
1241      * @param featureId The unique identifier (URI) of the feature.
1242      *
1243      * @throws XMLConfigurationException Thrown for configuration error.
1244      *                                   In general, components should
1245      *                                   only throw this exception if
1246      *                                   it is <strong>really</strong>
1247      *                                   a critical error.
1248      */
1249     protected FeatureState checkFeature(String featureId) throws XMLConfigurationException {
1250 
1251         //
1252         // Xerces Features
1253         //
1254 
1255         if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
1256             final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
1257 
1258             //
1259             // http://apache.org/xml/features/validation/dynamic
1260             //   Allows the parser to validate a document only when it
1261             //   contains a grammar. Validation is turned on/off based
1262             //   on each document instance, automatically.
1263             //
1264             if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() &&
1265                 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
1266                 return FeatureState.RECOGNIZED;
1267             }
1268 
1269             //
1270             // http://apache.org/xml/features/validation/default-attribute-values
1271             //
1272             if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() &&
1273                 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
1274                 // REVISIT
1275                 return FeatureState.NOT_SUPPORTED;
1276             }
1277             //
1278             // http://apache.org/xml/features/validation/default-attribute-values
1279             //
1280             if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() &&
1281                 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
1282                 // REVISIT
1283                 return FeatureState.NOT_SUPPORTED;
1284             }
1285             //
1286             // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
1287             //
1288             if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() &&
1289                 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
1290                 return FeatureState.RECOGNIZED;
1291             }
1292             //
1293             // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
1294             //
1295             if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
1296                 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
1297                 return FeatureState.RECOGNIZED;
1298             }
1299 
1300             //
1301             // http://apache.org/xml/features/validation/default-attribute-values
1302             //
1303             if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() &&
1304                 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
1305                 return FeatureState.NOT_SUPPORTED;
1306             }
1307 
1308             //
1309             // http://apache.org/xml/features/validation/schema
1310             //   Lets the user turn Schema validation support on/off.
1311             //
1312             if (suffixLength == Constants.SCHEMA_VALIDATION_FEATURE.length() &&
1313                 featureId.endsWith(Constants.SCHEMA_VALIDATION_FEATURE)) {
1314                 return FeatureState.RECOGNIZED;
1315             }
1316             // activate full schema checking
1317             if (suffixLength == Constants.SCHEMA_FULL_CHECKING.length() &&
1318                 featureId.endsWith(Constants.SCHEMA_FULL_CHECKING)) {
1319                 return FeatureState.RECOGNIZED;
1320             }
1321             // Feature identifier: expose schema normalized value
1322             //  http://apache.org/xml/features/validation/schema/normalized-value
1323             if (suffixLength == Constants.SCHEMA_NORMALIZED_VALUE.length() &&
1324                 featureId.endsWith(Constants.SCHEMA_NORMALIZED_VALUE)) {
1325                 return FeatureState.RECOGNIZED;
1326             }
1327             // Feature identifier: send element default value via characters()
1328             // http://apache.org/xml/features/validation/schema/element-default
1329             if (suffixLength == Constants.SCHEMA_ELEMENT_DEFAULT.length() &&
1330                 featureId.endsWith(Constants.SCHEMA_ELEMENT_DEFAULT)) {
1331                 return FeatureState.RECOGNIZED;
1332             }
1333 
1334             // special performance feature: only component manager is allowed to set it.
1335             if (suffixLength == Constants.PARSER_SETTINGS.length() &&
1336                 featureId.endsWith(Constants.PARSER_SETTINGS)) {
1337                 return FeatureState.NOT_SUPPORTED;
1338             }
1339 
1340         }
1341 
1342         //
1343         // Not recognized
1344         //
1345 
1346         return super.checkFeature(featureId);
1347 
1348     } // checkFeature(String)
1349 
1350     /**
1351      * Check a property. If the property is know and supported, this method
1352      * simply returns. Otherwise, the appropriate exception is thrown.
1353      *
1354      * @param propertyId The unique identifier (URI) of the property
1355      *                   being set.
1356      *
1357      * @throws XMLConfigurationException Thrown for configuration error.
1358      *                                   In general, components should
1359      *                                   only throw this exception if
1360      *                                   it is <strong>really</strong>
1361      *                                   a critical error.
1362      */
1363     protected PropertyState checkProperty(String propertyId) throws XMLConfigurationException {
1364 
1365         //
1366         // Xerces Properties
1367         //
1368 
1369         if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
1370             final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
1371 
1372             if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
1373                 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
1374                 return PropertyState.RECOGNIZED;
1375             }
1376             if (suffixLength == Constants.SCHEMA_LOCATION.length() &&
1377                 propertyId.endsWith(Constants.SCHEMA_LOCATION)) {
1378                 return PropertyState.RECOGNIZED;
1379             }
1380             if (suffixLength == Constants.SCHEMA_NONS_LOCATION.length() &&
1381                 propertyId.endsWith(Constants.SCHEMA_NONS_LOCATION)) {
1382                 return PropertyState.RECOGNIZED;
1383             }
1384         }
1385 
1386         if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) {
1387             final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length();
1388 
1389             if (suffixLength == Constants.SCHEMA_SOURCE.length() &&
1390                 propertyId.endsWith(Constants.SCHEMA_SOURCE)) {
1391                 return PropertyState.RECOGNIZED;
1392             }
1393         }
1394 
1395         // special cases
1396         if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
1397             final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
1398 
1399             //
1400             // http://xml.org/sax/properties/xml-string
1401             // Value type: String
1402             // Access: read-only
1403             //   Get the literal string of characters associated with the
1404             //   current event.  If the parser recognises and supports this
1405             //   property but is not currently parsing text, it should return
1406             //   null (this is a good way to check for availability before the
1407             //   parse begins).
1408             //
1409             if (suffixLength == Constants.XML_STRING_PROPERTY.length() &&
1410                 propertyId.endsWith(Constants.XML_STRING_PROPERTY)) {
1411                 // REVISIT - we should probably ask xml-dev for a precise
1412                 // definition of what this is actually supposed to return, and
1413                 // in exactly which circumstances.
1414                 return PropertyState.NOT_SUPPORTED;
1415             }
1416         }
1417 
1418         //
1419         // Not recognized
1420         //
1421 
1422         return super.checkProperty(propertyId);
1423 
1424     } // checkProperty(String)
1425 
1426 
1427     /**
1428      * Adds a component to the parser configuration. This method will
1429      * also add all of the component's recognized features and properties
1430      * to the list of default recognized features and properties.
1431      *
1432      * @param component The component to add.
1433      */
1434     protected void addComponent(XMLComponent component) {
1435 
1436         // don't add a component more than once
1437         if (fComponents.contains(component)) {
1438             return;
1439         }
1440         fComponents.add(component);
1441         addRecognizedParamsAndSetDefaults(component);
1442 
1443     } // addComponent(XMLComponent)
1444 
1445     /**
1446      * Adds common component to the parser configuration. This method will
1447      * also add all of the component's recognized features and properties
1448      * to the list of default recognized features and properties.
1449      *
1450      * @param component The component to add.
1451      */
1452     protected void addCommonComponent(XMLComponent component) {
1453 
1454         // don't add a component more than once
1455         if (fCommonComponents.contains(component)) {
1456             return;
1457         }
1458         fCommonComponents.add(component);
1459         addRecognizedParamsAndSetDefaults(component);
1460 
1461     } // addCommonComponent(XMLComponent)
1462 
1463     /**
1464      * Adds an XML 1.1 component to the parser configuration. This method will
1465      * also add all of the component's recognized features and properties
1466      * to the list of default recognized features and properties.
1467      *
1468      * @param component The component to add.
1469      */
1470     protected void addXML11Component(XMLComponent component) {
1471 
1472         // don't add a component more than once
1473         if (fXML11Components.contains(component)) {
1474             return;
1475         }
1476         fXML11Components.add(component);
1477         addRecognizedParamsAndSetDefaults(component);
1478 
1479     } // addXML11Component(XMLComponent)
1480 
1481     /**
1482      * Adds all of the component's recognized features and properties
1483      * to the list of default recognized features and properties, and
1484      * sets default values on the configuration for features and
1485      * properties which were previously absent from the configuration.
1486      *
1487      * @param component The component whose recognized features
1488      * and properties will be added to the configuration
1489      */
1490     protected void addRecognizedParamsAndSetDefaults(XMLComponent component) {
1491 
1492         // register component's recognized features
1493         String[] recognizedFeatures = component.getRecognizedFeatures();
1494         addRecognizedFeatures(recognizedFeatures);
1495 
1496         // register component's recognized properties
1497         String[] recognizedProperties = component.getRecognizedProperties();
1498         addRecognizedProperties(recognizedProperties);
1499 
1500         // set default values
1501         if (recognizedFeatures != null) {
1502             for (int i = 0; i < recognizedFeatures.length; ++i) {
1503                 String featureId = recognizedFeatures[i];
1504                 Boolean state = component.getFeatureDefault(featureId);
1505                 if (state != null) {
1506                     // Do not overwrite values already set on the configuration.
1507                     if (!fFeatures.containsKey(featureId)) {
1508                         fFeatures.put(featureId, state);
1509                         // For newly added components who recognize this feature
1510                         // but did not offer a default value, we need to make
1511                         // sure these components will get an opportunity to read
1512                         // the value before parsing begins.
1513                         fConfigUpdated = true;
1514                     }
1515                 }
1516             }
1517         }
1518         if (recognizedProperties != null) {
1519             for (int i = 0; i < recognizedProperties.length; ++i) {
1520                 String propertyId = recognizedProperties[i];
1521                 Object value = component.getPropertyDefault(propertyId);
1522                 if (value != null) {
1523                     // Do not overwrite values already set on the configuration.
1524                     if (!fProperties.containsKey(propertyId)) {
1525                         fProperties.put(propertyId, value);
1526                         // For newly added components who recognize this property
1527                         // but did not offer a default value, we need to make
1528                         // sure these components will get an opportunity to read
1529                         // the value before parsing begins.
1530                         fConfigUpdated = true;
1531                     }
1532                 }
1533             }
1534         }
1535     }
1536 
1537     private void initXML11Components() {
1538         if (!f11Initialized) {
1539 
1540             // create datatype factory
1541             fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY);
1542 
1543             // setup XML 1.1 DTD pipeline
1544             fXML11DTDScanner = new XML11DTDScannerImpl();
1545             addXML11Component(fXML11DTDScanner);
1546             fXML11DTDProcessor = new XML11DTDProcessor();
1547             addXML11Component(fXML11DTDProcessor);
1548 
1549             // setup XML 1.1. document pipeline - namespace aware
1550             fXML11NSDocScanner = new XML11NSDocumentScannerImpl();
1551             addXML11Component(fXML11NSDocScanner);
1552             fXML11NSDTDValidator = new XML11NSDTDValidator();
1553             addXML11Component(fXML11NSDTDValidator);
1554 
1555             f11Initialized = true;
1556         }
1557     }
1558 
1559     /**
1560      * Returns the state of a feature. This method calls getFeature()
1561      * on ParserConfigurationSettings, bypassing getFeature() on this
1562      * class.
1563      */
1564     FeatureState getFeatureState0(String featureId)
1565         throws XMLConfigurationException {
1566         return super.getFeatureState(featureId);
1567     }
1568 
1569 } // class XML11Configuration