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