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