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 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.impl.xs.XMLSchemaValidator;
  44 import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
  45 import com.sun.org.apache.xerces.internal.util.FeatureState;
  46 import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
  47 import com.sun.org.apache.xerces.internal.util.PropertyState;
  48 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  49 import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
  50 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
  51 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
  52 import com.sun.org.apache.xerces.internal.xni.XMLLocator;
  53 import com.sun.org.apache.xerces.internal.xni.XNIException;
  54 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  55 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
  56 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  57 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  58 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
  59 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner;
  60 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
  61 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  62 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  63 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  64 import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration;
  65 import java.io.IOException;
  66 import java.util.ArrayList;
  67 import java.util.Locale;
  68 import javax.xml.XMLConstants;
  69 import javax.xml.catalog.CatalogFeatures;
  70 import jdk.xml.internal.JdkXmlUtils;
  71 import jdk.xml.internal.SecuritySupport;
  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 indicating whether XML11 components have been initialized. */
 419     private boolean f11Initialized = false;
 420 
 421     /** Flag indicating whether the symbol table instance was specified during construction **/
 422     private boolean fSymbolTableProvided = false;
 423 
 424     /** Flag indicating if the symbol table was initialized and never used before that **/
 425     private boolean fSymbolTableJustInitialized = true;
 426 
 427     //
 428     // Constructors
 429     //
 430 
 431     /** Default constructor. */
 432     public XML11Configuration() {
 433         this(null, null, null);
 434     } // <init>()
 435 
 436     /**
 437      * Constructs a parser configuration using the specified symbol table.
 438      *
 439      * @param symbolTable The symbol table to use.
 440      */
 441     public XML11Configuration(SymbolTable symbolTable) {
 442         this(symbolTable, null, null);
 443     } // <init>(SymbolTable)
 444 
 445     /**
 446      * Constructs a parser configuration using the specified symbol table and
 447      * grammar pool.
 448      * <p>
 449      * <strong>REVISIT:</strong>
 450      * Grammar pool will be updated when the new validation engine is
 451      * implemented.
 452      *
 453      * @param symbolTable The symbol table to use.
 454      * @param grammarPool The grammar pool to use.
 455      */
 456     public XML11Configuration(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
 457         this(symbolTable, grammarPool, null);
 458     } // <init>(SymbolTable,XMLGrammarPool)
 459 
 460     /**
 461      * Constructs a parser configuration using the specified symbol table,
 462      * grammar pool, and parent settings.
 463      * <p>
 464      * <strong>REVISIT:</strong>
 465      * Grammar pool will be updated when the new validation engine is
 466      * implemented.
 467      *
 468      * @param symbolTable    The symbol table to use.
 469      * @param grammarPool    The grammar pool to use.
 470      * @param parentSettings The parent settings.
 471      */
 472     public XML11Configuration(
 473         SymbolTable symbolTable,
 474         XMLGrammarPool grammarPool,
 475         XMLComponentManager parentSettings) {
 476 
 477         super(parentSettings);
 478 
 479         // create a vector to hold all the components in use
 480         // XML 1.0 specialized components
 481         fComponents = new ArrayList<>();
 482         // XML 1.1 specialized components
 483         fXML11Components = new ArrayList<>();
 484         // Common components for XML 1.1. and XML 1.0
 485         fCommonComponents = new ArrayList<>();
 486 
 487         // add default recognized features
 488         final String[] recognizedFeatures =
 489         {
 490             CONTINUE_AFTER_FATAL_ERROR, LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl
 491             VALIDATION,
 492             NAMESPACES,
 493             NORMALIZE_DATA, SCHEMA_ELEMENT_DEFAULT, SCHEMA_AUGMENT_PSVI,
 494             GENERATE_SYNTHETIC_ANNOTATIONS, VALIDATE_ANNOTATIONS,
 495             HONOUR_ALL_SCHEMALOCATIONS, IGNORE_XSI_TYPE,
 496             ID_IDREF_CHECKING, IDENTITY_CONSTRAINT_CHECKING,
 497             UNPARSED_ENTITY_CHECKING,
 498             NAMESPACE_GROWTH, TOLERATE_DUPLICATES,
 499             USE_GRAMMAR_POOL_ONLY,
 500             // NOTE: These shouldn't really be here but since the XML Schema
 501             //       validator is constructed dynamically, its recognized
 502             //       features might not have been set and it would cause a
 503             //       not-recognized exception to be thrown. -Ac
 504             XMLSCHEMA_VALIDATION, XMLSCHEMA_FULL_CHECKING,
 505             EXTERNAL_GENERAL_ENTITIES,
 506             EXTERNAL_PARAMETER_ENTITIES,
 507             PARSER_SETTINGS,
 508             XMLConstants.FEATURE_SECURE_PROCESSING,
 509             XMLConstants.USE_CATALOG
 510         };
 511         addRecognizedFeatures(recognizedFeatures);
 512         // set state for default features
 513         fFeatures.put(VALIDATION, Boolean.FALSE);
 514         fFeatures.put(NAMESPACES, Boolean.TRUE);
 515         fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE);
 516         fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE);
 517         fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE);
 518         fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE);
 519         fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE);
 520         fFeatures.put(NORMALIZE_DATA, Boolean.TRUE);
 521         fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE);
 522         fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE);
 523         fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE);
 524         fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE);
 525         fFeatures.put(IGNORE_XSI_TYPE, Boolean.FALSE);
 526         fFeatures.put(ID_IDREF_CHECKING, Boolean.TRUE);
 527         fFeatures.put(IDENTITY_CONSTRAINT_CHECKING, Boolean.TRUE);
 528         fFeatures.put(UNPARSED_ENTITY_CHECKING, Boolean.TRUE);
 529         fFeatures.put(NAMESPACE_GROWTH, Boolean.FALSE);
 530         fFeatures.put(TOLERATE_DUPLICATES, Boolean.FALSE);
 531         fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE);
 532         fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
 533         fFeatures.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
 534         fFeatures.put(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT);
 535 
 536         // add default recognized properties
 537         final String[] recognizedProperties =
 538         {
 539             SYMBOL_TABLE,
 540             ERROR_HANDLER,
 541             ENTITY_RESOLVER,
 542             ERROR_REPORTER,
 543             ENTITY_MANAGER,
 544             DOCUMENT_SCANNER,
 545             DTD_SCANNER,
 546             DTD_PROCESSOR,
 547             DTD_VALIDATOR,
 548             DATATYPE_VALIDATOR_FACTORY,
 549             VALIDATION_MANAGER,
 550             SCHEMA_VALIDATOR,
 551             XML_STRING,
 552             XMLGRAMMAR_POOL,
 553             JAXP_SCHEMA_SOURCE,
 554             JAXP_SCHEMA_LANGUAGE,
 555             // NOTE: These shouldn't really be here but since the XML Schema
 556             //       validator is constructed dynamically, its recognized
 557             //       properties might not have been set and it would cause a
 558             //       not-recognized exception to be thrown. -Ac
 559             SCHEMA_LOCATION,
 560             SCHEMA_NONS_LOCATION,
 561             ROOT_TYPE_DEF,
 562             ROOT_ELEMENT_DECL,
 563             LOCALE,
 564             SCHEMA_DV_FACTORY,
 565             SECURITY_MANAGER,
 566             XML_SECURITY_PROPERTY_MANAGER,
 567             JdkXmlUtils.CATALOG_DEFER,
 568             JdkXmlUtils.CATALOG_FILES,
 569             JdkXmlUtils.CATALOG_PREFER,
 570             JdkXmlUtils.CATALOG_RESOLVE,
 571             JdkXmlUtils.CDATA_CHUNK_SIZE
 572         };
 573         addRecognizedProperties(recognizedProperties);
 574 
 575         // Remember if symbolTable was provided from outside
 576         fSymbolTableProvided = symbolTable != null;
 577         if (!fSymbolTableProvided) {
 578             fSymbolTable = new SymbolTable();
 579         } else {
 580             fSymbolTable = symbolTable;
 581         }
 582         fProperties.put(SYMBOL_TABLE, fSymbolTable);
 583 
 584         fGrammarPool = grammarPool;
 585         if (fGrammarPool != null) {
 586             fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
 587         }
 588 
 589         fEntityManager = new XMLEntityManager();
 590         fProperties.put(ENTITY_MANAGER, fEntityManager);
 591         addCommonComponent(fEntityManager);
 592 
 593         fErrorReporter = new XMLErrorReporter();
 594         fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
 595         fProperties.put(ERROR_REPORTER, fErrorReporter);
 596         addCommonComponent(fErrorReporter);
 597 
 598         fNamespaceScanner = new XMLNSDocumentScannerImpl();
 599         fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner);
 600         addComponent((XMLComponent) fNamespaceScanner);
 601 
 602         fDTDScanner = new XMLDTDScannerImpl();
 603         fProperties.put(DTD_SCANNER, fDTDScanner);
 604         addComponent((XMLComponent) fDTDScanner);
 605 
 606         fDTDProcessor = new XMLDTDProcessor();
 607         fProperties.put(DTD_PROCESSOR, fDTDProcessor);
 608         addComponent((XMLComponent) fDTDProcessor);
 609 
 610         fDTDValidator = new XMLNSDTDValidator();
 611         fProperties.put(DTD_VALIDATOR, fDTDValidator);
 612         addComponent(fDTDValidator);
 613 
 614         fDatatypeValidatorFactory = DTDDVFactory.getInstance();
 615         fProperties.put(DATATYPE_VALIDATOR_FACTORY, fDatatypeValidatorFactory);
 616 
 617         fValidationManager = new ValidationManager();
 618         fProperties.put(VALIDATION_MANAGER, fValidationManager);
 619 
 620         fVersionDetector = new XMLVersionDetector();
 621 
 622         // add message formatters
 623         if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
 624             XMLMessageFormatter xmft = new XMLMessageFormatter();
 625             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
 626             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
 627         }
 628 
 629         // set locale
 630         try {
 631             setLocale(Locale.getDefault());
 632         } catch (XNIException e) {
 633             // do nothing
 634             // REVISIT: What is the right thing to do? -Ac
 635         }
 636 
 637         // Initialize Catalog features
 638         for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
 639             fProperties.put(f.getPropertyName(), null);
 640         }
 641 
 642         setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
 643 
 644         fConfigUpdated = false;
 645     } // <init>(SymbolTable,XMLGrammarPool)
 646 
 647     //
 648     // Public methods
 649     //
 650     /**
 651      * Sets the input source for the document to parse.
 652      *
 653      * @param inputSource The document's input source.
 654      *
 655      * @exception XMLConfigurationException Thrown if there is a
 656      *                        configuration error when initializing the
 657      *                        parser.
 658      * @exception IOException Thrown on I/O error.
 659      *
 660      * @see #parse(boolean)
 661      */
 662     public void setInputSource(XMLInputSource inputSource)
 663         throws XMLConfigurationException, IOException {
 664 
 665         // REVISIT: this method used to reset all the components and
 666         //          construct the pipeline. Now reset() is called
 667         //          in parse (boolean) just before we parse the document
 668         //          Should this method still throw exceptions..?
 669 
 670         fInputSource = inputSource;
 671 
 672     } // setInputSource(XMLInputSource)
 673 
 674     /**
 675      * Set the locale to use for messages.
 676      *
 677      * @param locale The locale object to use for localization of messages.
 678      *
 679      * @exception XNIException Thrown if the parser does not support the
 680      *                         specified locale.
 681      */
 682     public void setLocale(Locale locale) throws XNIException {
 683         fLocale = locale;
 684         fErrorReporter.setLocale(locale);
 685     } // setLocale(Locale)
 686         /**
 687          * Sets the document handler on the last component in the pipeline
 688          * to receive information about the document.
 689          *
 690          * @param documentHandler   The document handler.
 691          */
 692         public void setDocumentHandler(XMLDocumentHandler documentHandler) {
 693                 fDocumentHandler = documentHandler;
 694                 if (fLastComponent != null) {
 695                         fLastComponent.setDocumentHandler(fDocumentHandler);
 696                         if (fDocumentHandler !=null){
 697                                 fDocumentHandler.setDocumentSource(fLastComponent);
 698                         }
 699                 }
 700         } // setDocumentHandler(XMLDocumentHandler)
 701 
 702         /** Returns the registered document handler. */
 703         public XMLDocumentHandler getDocumentHandler() {
 704                 return fDocumentHandler;
 705         } // getDocumentHandler():XMLDocumentHandler
 706 
 707         /**
 708          * Sets the DTD handler.
 709          *
 710          * @param dtdHandler The DTD handler.
 711          */
 712         public void setDTDHandler(XMLDTDHandler dtdHandler) {
 713                 fDTDHandler = dtdHandler;
 714         } // setDTDHandler(XMLDTDHandler)
 715 
 716         /** Returns the registered DTD handler. */
 717         public XMLDTDHandler getDTDHandler() {
 718                 return fDTDHandler;
 719         } // getDTDHandler():XMLDTDHandler
 720 
 721         /**
 722          * Sets the DTD content model handler.
 723          *
 724          * @param handler The DTD content model handler.
 725          */
 726         public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) {
 727                 fDTDContentModelHandler = handler;
 728         } // setDTDContentModelHandler(XMLDTDContentModelHandler)
 729 
 730         /** Returns the registered DTD content model handler. */
 731         public XMLDTDContentModelHandler getDTDContentModelHandler() {
 732                 return fDTDContentModelHandler;
 733         } // getDTDContentModelHandler():XMLDTDContentModelHandler
 734 
 735         /**
 736          * Sets the resolver used to resolve external entities. The EntityResolver
 737          * interface supports resolution of public and system identifiers.
 738          *
 739          * @param resolver The new entity resolver. Passing a null value will
 740          *                 uninstall the currently installed resolver.
 741          */
 742         public void setEntityResolver(XMLEntityResolver resolver) {
 743                 fProperties.put(ENTITY_RESOLVER, resolver);
 744         } // setEntityResolver(XMLEntityResolver)
 745 
 746         /**
 747          * Return the current entity resolver.
 748          *
 749          * @return The current entity resolver, or null if none
 750          *         has been registered.
 751          * @see #setEntityResolver
 752          */
 753         public XMLEntityResolver getEntityResolver() {
 754                 return (XMLEntityResolver)fProperties.get(ENTITY_RESOLVER);
 755         } // getEntityResolver():XMLEntityResolver
 756 
 757         /**
 758          * Allow an application to register an error event handler.
 759          *
 760          * <p>If the application does not register an error handler, all
 761          * error events reported by the SAX parser will be silently
 762          * ignored; however, normal processing may not continue.  It is
 763          * highly recommended that all SAX applications implement an
 764          * error handler to avoid unexpected bugs.</p>
 765          *
 766          * <p>Applications may register a new or different handler in the
 767          * middle of a parse, and the SAX parser must begin using the new
 768          * handler immediately.</p>
 769          *
 770          * @param errorHandler The error handler.
 771          * @exception java.lang.NullPointerException If the handler
 772          *            argument is null.
 773          * @see #getErrorHandler
 774          */
 775         public void setErrorHandler(XMLErrorHandler errorHandler) {
 776                 fProperties.put(ERROR_HANDLER, errorHandler);
 777         } // setErrorHandler(XMLErrorHandler)
 778 
 779         /**
 780          * Return the current error handler.
 781          *
 782          * @return The current error handler, or null if none
 783          *         has been registered.
 784          * @see #setErrorHandler
 785          */
 786         public XMLErrorHandler getErrorHandler() {
 787                 // REVISIT: Should this be a property?
 788                 return (XMLErrorHandler)fProperties.get(ERROR_HANDLER);
 789         } // getErrorHandler():XMLErrorHandler
 790 
 791 
 792     /**
 793      * If the application decides to terminate parsing before the xml document
 794      * is fully parsed, the application should call this method to free any
 795      * resource allocated during parsing. For example, close all opened streams.
 796      */
 797     public void cleanup() {
 798         fEntityManager.closeReaders();
 799     }
 800 
 801     /**
 802      * Parses the specified input source.
 803      *
 804      * @param source The input source.
 805      *
 806      * @exception XNIException Throws exception on XNI error.
 807      * @exception java.io.IOException Throws exception on i/o error.
 808      */
 809     public void parse(XMLInputSource source) throws XNIException, IOException {
 810 
 811         if (fParseInProgress) {
 812             // REVISIT - need to add new error message
 813             throw new XNIException("FWK005 parse may not be called while parsing.");
 814         }
 815         fParseInProgress = true;
 816 
 817         try {
 818             setInputSource(source);
 819             parse(true);
 820         } catch (XNIException ex) {
 821             if (PRINT_EXCEPTION_STACK_TRACE)
 822                 ex.printStackTrace();
 823             throw ex;
 824         } catch (IOException ex) {
 825             if (PRINT_EXCEPTION_STACK_TRACE)
 826                 ex.printStackTrace();
 827             throw ex;
 828         } catch (RuntimeException ex) {
 829             if (PRINT_EXCEPTION_STACK_TRACE)
 830                 ex.printStackTrace();
 831             throw ex;
 832         } catch (Exception ex) {
 833             if (PRINT_EXCEPTION_STACK_TRACE)
 834                 ex.printStackTrace();
 835             throw new XNIException(ex);
 836         } finally {
 837             fParseInProgress = false;
 838             // close all streams opened by xerces
 839             this.cleanup();
 840         }
 841 
 842     } // parse(InputSource)
 843 
 844     public boolean parse(boolean complete) throws XNIException, IOException {
 845         //
 846         // reset and configure pipeline and set InputSource.
 847         if (fInputSource != null) {
 848             try {
 849                 fValidationManager.reset();
 850                 fVersionDetector.reset(this);
 851                 fConfigUpdated = true;
 852                 resetSymbolTable();
 853                 resetCommon();
 854 
 855                 short version = fVersionDetector.determineDocVersion(fInputSource);
 856                 if (version == Constants.XML_VERSION_1_1) {
 857                     initXML11Components();
 858                     configureXML11Pipeline();
 859                     resetXML11();
 860                 } else {
 861                     configurePipeline();
 862                     reset();
 863                 }
 864 
 865                 // mark configuration as fixed
 866                 fConfigUpdated = false;
 867 
 868                 // resets and sets the pipeline.
 869                 fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version);
 870                 fInputSource = null;
 871             } catch (IOException | RuntimeException ex) {
 872                 if (PRINT_EXCEPTION_STACK_TRACE)
 873                     ex.printStackTrace();
 874                 throw ex;
 875             } catch (Exception ex) {
 876                 if (PRINT_EXCEPTION_STACK_TRACE)
 877                     ex.printStackTrace();
 878                 throw new XNIException(ex);
 879             }
 880         }
 881 
 882         try {
 883             return fCurrentScanner.scanDocument(complete);
 884         } catch (IOException | RuntimeException ex) {
 885             if (PRINT_EXCEPTION_STACK_TRACE)
 886                 ex.printStackTrace();
 887             throw ex;
 888         } catch (Exception ex) {
 889             if (PRINT_EXCEPTION_STACK_TRACE)
 890                 ex.printStackTrace();
 891             throw new XNIException(ex);
 892         }
 893 
 894     } // parse(boolean):boolean
 895 
 896         /**
 897          * Returns the state of a feature.
 898          *
 899          * @param featureId The feature identifier.
 900          * @return true if the feature is supported
 901          *
 902          * @throws XMLConfigurationException Thrown for configuration error.
 903          *                                   In general, components should
 904          *                                   only throw this exception if
 905          *                                   it is <strong>really</strong>
 906          *                                   a critical error.
 907          */
 908         public FeatureState getFeatureState(String featureId)
 909                 throws XMLConfigurationException {
 910                         // make this feature special
 911         if (featureId.equals(PARSER_SETTINGS)){
 912                 return FeatureState.is(fConfigUpdated);
 913         }
 914         return super.getFeatureState(featureId);
 915 
 916         } // getFeature(String):boolean
 917 
 918         /**
 919          * Set the state of a feature.
 920          *
 921          * Set the state of any feature in a SAX2 parser.  The parser
 922          * might not recognize the feature, and if it does recognize
 923          * it, it might not be able to fulfill the request.
 924          *
 925          * @param featureId The unique identifier (URI) of the feature.
 926          * @param state The requested state of the feature (true or false).
 927          *
 928          * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the
 929          *            requested feature is not known.
 930          */
 931         public void setFeature(String featureId, boolean state)
 932                 throws XMLConfigurationException {
 933                 fConfigUpdated = true;
 934                 // forward to every XML 1.0 component
 935                 int count = fComponents.size();
 936                 for (int i = 0; i < count; i++) {
 937                         XMLComponent c = fComponents.get(i);
 938                         c.setFeature(featureId, state);
 939                 }
 940                 // forward it to common components
 941                 count = fCommonComponents.size();
 942                 for (int i = 0; i < count; i++) {
 943                         XMLComponent c = fCommonComponents.get(i);
 944                         c.setFeature(featureId, state);
 945                 }
 946 
 947                 // forward to every XML 1.1 component
 948                 count = fXML11Components.size();
 949                 for (int i = 0; i < count; i++) {
 950                         XMLComponent c = fXML11Components.get(i);
 951                         try{
 952                                 c.setFeature(featureId, state);
 953                         }
 954                         catch (Exception e){
 955                                 // no op
 956                         }
 957                 }
 958                 // save state if noone "objects"
 959                 super.setFeature(featureId, state);
 960 
 961         } // setFeature(String,boolean)
 962 
 963     /**
 964      * Returns the value of a property.
 965      *
 966      * @param propertyId The property identifier.
 967      * @return the value of the property
 968      *
 969      * @throws XMLConfigurationException Thrown for configuration error.
 970      *                                   In general, components should
 971      *                                   only throw this exception if
 972      *                                   it is <strong>really</strong>
 973      *                                   a critical error.
 974      */
 975     public PropertyState getPropertyState(String propertyId)
 976         throws XMLConfigurationException {
 977         if (LOCALE.equals(propertyId)) {
 978             return PropertyState.is(getLocale());
 979         }
 980         return super.getPropertyState(propertyId);
 981     }
 982 
 983         /**
 984          * setProperty
 985          *
 986          * @param propertyId
 987          * @param value
 988          */
 989         public void setProperty(String propertyId, Object value)
 990                 throws XMLConfigurationException {
 991                 fConfigUpdated = true;
 992                 if (LOCALE.equals(propertyId)) {
 993                     setLocale((Locale) value);
 994                 }
 995                 // forward to every XML 1.0 component
 996                 int count = fComponents.size();
 997                 for (int i = 0; i < count; i++) {
 998                         XMLComponent c = fComponents.get(i);
 999                         c.setProperty(propertyId, value);
1000                 }
1001                 // forward it to every common Component
1002                 count = fCommonComponents.size();
1003                 for (int i = 0; i < count; i++) {
1004                         XMLComponent c = fCommonComponents.get(i);
1005                         c.setProperty(propertyId, value);
1006                 }
1007                 // forward it to every XML 1.1 component
1008                 count = fXML11Components.size();
1009                 for (int i = 0; i < count; i++) {
1010                         XMLComponent c = fXML11Components.get(i);
1011                         try{
1012                                 c.setProperty(propertyId, value);
1013                         }
1014                         catch (Exception e){
1015                                 // ignore it
1016                         }
1017                 }
1018 
1019                 // store value if noone "objects"
1020                 super.setProperty(propertyId, value);
1021 
1022         } // setProperty(String,Object)
1023 
1024 
1025         /** Returns the locale. */
1026         public Locale getLocale() {
1027                 return fLocale;
1028         } // getLocale():Locale
1029 
1030         /**
1031          * reset all XML 1.0 components before parsing and namespace context
1032          */
1033         protected void reset() throws XNIException {
1034                 int count = fComponents.size();
1035                 for (int i = 0; i < count; i++) {
1036                         XMLComponent c = fComponents.get(i);
1037                         c.reset(this);
1038                 }
1039 
1040         } // reset()
1041 
1042         /**
1043          * reset all common components before parsing
1044          */
1045         protected void resetCommon() throws XNIException {
1046                 // reset common components
1047                 int count = fCommonComponents.size();
1048                 for (int i = 0; i < count; i++) {
1049                         XMLComponent c = fCommonComponents.get(i);
1050                         c.reset(this);
1051                 }
1052 
1053         } // resetCommon()
1054 
1055 
1056         /**
1057          * reset all components before parsing and namespace context
1058          */
1059         protected void resetXML11() throws XNIException {
1060                 // reset every component
1061                 int count = fXML11Components.size();
1062                 for (int i = 0; i < count; i++) {
1063                         XMLComponent c = fXML11Components.get(i);
1064                         c.reset(this);
1065                 }
1066 
1067         } // resetXML11()
1068 
1069 
1070     /**
1071      *  Configures the XML 1.1 pipeline.
1072      *  Note: this method also resets the new XML11 components.
1073      */
1074     protected void configureXML11Pipeline() {
1075         if (fCurrentDVFactory != fXML11DatatypeFactory) {
1076             fCurrentDVFactory = fXML11DatatypeFactory;
1077             setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
1078         }
1079         if (fCurrentDTDScanner != fXML11DTDScanner) {
1080             fCurrentDTDScanner = fXML11DTDScanner;
1081             setProperty(DTD_SCANNER, fCurrentDTDScanner);
1082                         setProperty(DTD_PROCESSOR, fXML11DTDProcessor);
1083         }
1084 
1085         fXML11DTDScanner.setDTDHandler(fXML11DTDProcessor);
1086         fXML11DTDProcessor.setDTDSource(fXML11DTDScanner);
1087         fXML11DTDProcessor.setDTDHandler(fDTDHandler);
1088         if (fDTDHandler != null) {
1089             fDTDHandler.setDTDSource(fXML11DTDProcessor);
1090         }
1091 
1092         fXML11DTDScanner.setDTDContentModelHandler(fXML11DTDProcessor);
1093         fXML11DTDProcessor.setDTDContentModelSource(fXML11DTDScanner);
1094         fXML11DTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler);
1095         if (fDTDContentModelHandler != null) {
1096             fDTDContentModelHandler.setDTDContentModelSource(fXML11DTDProcessor);
1097         }
1098 
1099         // setup XML 1.1 document pipeline
1100         if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
1101             if (fCurrentScanner != fXML11NSDocScanner) {
1102                 fCurrentScanner = fXML11NSDocScanner;
1103                 setProperty(DOCUMENT_SCANNER, fXML11NSDocScanner);
1104                 setProperty(DTD_VALIDATOR, fXML11NSDTDValidator);
1105             }
1106 
1107             fXML11NSDocScanner.setDTDValidator(fXML11NSDTDValidator);
1108             fXML11NSDocScanner.setDocumentHandler(fXML11NSDTDValidator);
1109             fXML11NSDTDValidator.setDocumentSource(fXML11NSDocScanner);
1110             fXML11NSDTDValidator.setDocumentHandler(fDocumentHandler);
1111 
1112             if (fDocumentHandler != null) {
1113                 fDocumentHandler.setDocumentSource(fXML11NSDTDValidator);
1114             }
1115             fLastComponent = fXML11NSDTDValidator;
1116 
1117         } else {
1118                         // create components
1119                           if (fXML11DocScanner == null) {
1120                                         // non namespace document pipeline
1121                                         fXML11DocScanner = new XML11DocumentScannerImpl();
1122                                         addXML11Component(fXML11DocScanner);
1123                                         fXML11DTDValidator = new XML11DTDValidator();
1124                                         addXML11Component(fXML11DTDValidator);
1125                           }
1126             if (fCurrentScanner != fXML11DocScanner) {
1127                 fCurrentScanner = fXML11DocScanner;
1128                 setProperty(DOCUMENT_SCANNER, fXML11DocScanner);
1129                 setProperty(DTD_VALIDATOR, fXML11DTDValidator);
1130             }
1131             fXML11DocScanner.setDocumentHandler(fXML11DTDValidator);
1132             fXML11DTDValidator.setDocumentSource(fXML11DocScanner);
1133             fXML11DTDValidator.setDocumentHandler(fDocumentHandler);
1134 
1135             if (fDocumentHandler != null) {
1136                 fDocumentHandler.setDocumentSource(fXML11DTDValidator);
1137             }
1138             fLastComponent = fXML11DTDValidator;
1139         }
1140 
1141         // setup document pipeline
1142         if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
1143             // If schema validator was not in the pipeline insert it.
1144             if (fSchemaValidator == null) {
1145                 fSchemaValidator = new XMLSchemaValidator();
1146                 // add schema component
1147                 setProperty(SCHEMA_VALIDATOR, fSchemaValidator);
1148                                 addCommonComponent(fSchemaValidator);
1149                                 fSchemaValidator.reset(this);
1150                 // add schema message formatter
1151                 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
1152                     XSMessageFormatter xmft = new XSMessageFormatter();
1153                     fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft);
1154                 }
1155             }
1156 
1157             fLastComponent.setDocumentHandler(fSchemaValidator);
1158             fSchemaValidator.setDocumentSource(fLastComponent);
1159             fSchemaValidator.setDocumentHandler(fDocumentHandler);
1160             if (fDocumentHandler != null) {
1161                 fDocumentHandler.setDocumentSource(fSchemaValidator);
1162             }
1163             fLastComponent = fSchemaValidator;
1164         }
1165 
1166     } // configureXML11Pipeline()
1167 
1168     /** Configures the pipeline. */
1169     protected void configurePipeline() {
1170         if (fCurrentDVFactory != fDatatypeValidatorFactory) {
1171             fCurrentDVFactory = fDatatypeValidatorFactory;
1172             // use XML 1.0 datatype library
1173             setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
1174         }
1175 
1176         // setup DTD pipeline
1177         if (fCurrentDTDScanner != fDTDScanner) {
1178             fCurrentDTDScanner = fDTDScanner;
1179             setProperty(DTD_SCANNER, fCurrentDTDScanner);
1180             setProperty(DTD_PROCESSOR, fDTDProcessor);
1181         }
1182         fDTDScanner.setDTDHandler(fDTDProcessor);
1183         fDTDProcessor.setDTDSource(fDTDScanner);
1184         fDTDProcessor.setDTDHandler(fDTDHandler);
1185         if (fDTDHandler != null) {
1186             fDTDHandler.setDTDSource(fDTDProcessor);
1187         }
1188 
1189         fDTDScanner.setDTDContentModelHandler(fDTDProcessor);
1190         fDTDProcessor.setDTDContentModelSource(fDTDScanner);
1191         fDTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler);
1192         if (fDTDContentModelHandler != null) {
1193             fDTDContentModelHandler.setDTDContentModelSource(fDTDProcessor);
1194         }
1195 
1196         // setup document pipeline
1197         if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
1198             if (fCurrentScanner != fNamespaceScanner) {
1199                 fCurrentScanner = fNamespaceScanner;
1200                 setProperty(DOCUMENT_SCANNER, fNamespaceScanner);
1201                 setProperty(DTD_VALIDATOR, fDTDValidator);
1202             }
1203             fNamespaceScanner.setDTDValidator(fDTDValidator);
1204             fNamespaceScanner.setDocumentHandler(fDTDValidator);
1205             fDTDValidator.setDocumentSource(fNamespaceScanner);
1206             fDTDValidator.setDocumentHandler(fDocumentHandler);
1207             if (fDocumentHandler != null) {
1208                 fDocumentHandler.setDocumentSource(fDTDValidator);
1209             }
1210             fLastComponent = fDTDValidator;
1211         } else {
1212             // create components
1213             if (fNonNSScanner == null) {
1214                 fNonNSScanner = new XMLDocumentScannerImpl();
1215                 fNonNSDTDValidator = new XMLDTDValidator();
1216                 // add components
1217                 addComponent((XMLComponent) fNonNSScanner);
1218                 addComponent((XMLComponent) fNonNSDTDValidator);
1219             }
1220             if (fCurrentScanner != fNonNSScanner) {
1221                 fCurrentScanner = fNonNSScanner;
1222                 setProperty(DOCUMENT_SCANNER, fNonNSScanner);
1223                 setProperty(DTD_VALIDATOR, fNonNSDTDValidator);
1224             }
1225 
1226             fNonNSScanner.setDocumentHandler(fNonNSDTDValidator);
1227             fNonNSDTDValidator.setDocumentSource(fNonNSScanner);
1228             fNonNSDTDValidator.setDocumentHandler(fDocumentHandler);
1229             if (fDocumentHandler != null) {
1230                 fDocumentHandler.setDocumentSource(fNonNSDTDValidator);
1231             }
1232             fLastComponent = fNonNSDTDValidator;
1233         }
1234 
1235         // add XML Schema validator if needed
1236         if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
1237             // If schema validator was not in the pipeline insert it.
1238             if (fSchemaValidator == null) {
1239                 fSchemaValidator = new XMLSchemaValidator();
1240                 // add schema component
1241                 setProperty(SCHEMA_VALIDATOR, fSchemaValidator);
1242                 addCommonComponent(fSchemaValidator);
1243                 fSchemaValidator.reset(this);
1244                 // add schema message formatter
1245                 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
1246                     XSMessageFormatter xmft = new XSMessageFormatter();
1247                     fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft);
1248                 }
1249 
1250             }
1251             fLastComponent.setDocumentHandler(fSchemaValidator);
1252             fSchemaValidator.setDocumentSource(fLastComponent);
1253             fSchemaValidator.setDocumentHandler(fDocumentHandler);
1254             if (fDocumentHandler != null) {
1255                 fDocumentHandler.setDocumentSource(fSchemaValidator);
1256             }
1257             fLastComponent = fSchemaValidator;
1258         }
1259     } // configurePipeline()
1260 
1261 
1262     // features and properties
1263 
1264     /**
1265      * Check a feature. If feature is know and supported, this method simply
1266      * returns. Otherwise, the appropriate exception is thrown.
1267      *
1268      * @param featureId The unique identifier (URI) of the feature.
1269      *
1270      * @throws XMLConfigurationException Thrown for configuration error.
1271      *                                   In general, components should
1272      *                                   only throw this exception if
1273      *                                   it is <strong>really</strong>
1274      *                                   a critical error.
1275      */
1276     protected FeatureState checkFeature(String featureId) throws XMLConfigurationException {
1277 
1278         //
1279         // Xerces Features
1280         //
1281 
1282         if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
1283             final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
1284 
1285             //
1286             // http://apache.org/xml/features/validation/dynamic
1287             //   Allows the parser to validate a document only when it
1288             //   contains a grammar. Validation is turned on/off based
1289             //   on each document instance, automatically.
1290             //
1291             if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() &&
1292                 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
1293                 return FeatureState.RECOGNIZED;
1294             }
1295 
1296             //
1297             // http://apache.org/xml/features/validation/default-attribute-values
1298             //
1299             if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() &&
1300                 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
1301                 // REVISIT
1302                 return FeatureState.NOT_SUPPORTED;
1303             }
1304             //
1305             // http://apache.org/xml/features/validation/default-attribute-values
1306             //
1307             if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() &&
1308                 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
1309                 // REVISIT
1310                 return FeatureState.NOT_SUPPORTED;
1311             }
1312             //
1313             // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
1314             //
1315             if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() &&
1316                 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
1317                 return FeatureState.RECOGNIZED;
1318             }
1319             //
1320             // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
1321             //
1322             if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
1323                 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
1324                 return FeatureState.RECOGNIZED;
1325             }
1326 
1327             //
1328             // http://apache.org/xml/features/validation/default-attribute-values
1329             //
1330             if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() &&
1331                 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
1332                 return FeatureState.NOT_SUPPORTED;
1333             }
1334 
1335             //
1336             // http://apache.org/xml/features/validation/schema
1337             //   Lets the user turn Schema validation support on/off.
1338             //
1339             if (suffixLength == Constants.SCHEMA_VALIDATION_FEATURE.length() &&
1340                 featureId.endsWith(Constants.SCHEMA_VALIDATION_FEATURE)) {
1341                 return FeatureState.RECOGNIZED;
1342             }
1343             // activate full schema checking
1344             if (suffixLength == Constants.SCHEMA_FULL_CHECKING.length() &&
1345                 featureId.endsWith(Constants.SCHEMA_FULL_CHECKING)) {
1346                 return FeatureState.RECOGNIZED;
1347             }
1348             // Feature identifier: expose schema normalized value
1349             //  http://apache.org/xml/features/validation/schema/normalized-value
1350             if (suffixLength == Constants.SCHEMA_NORMALIZED_VALUE.length() &&
1351                 featureId.endsWith(Constants.SCHEMA_NORMALIZED_VALUE)) {
1352                 return FeatureState.RECOGNIZED;
1353             }
1354             // Feature identifier: send element default value via characters()
1355             // http://apache.org/xml/features/validation/schema/element-default
1356             if (suffixLength == Constants.SCHEMA_ELEMENT_DEFAULT.length() &&
1357                 featureId.endsWith(Constants.SCHEMA_ELEMENT_DEFAULT)) {
1358                 return FeatureState.RECOGNIZED;
1359             }
1360 
1361             // special performance feature: only component manager is allowed to set it.
1362             if (suffixLength == Constants.PARSER_SETTINGS.length() &&
1363                 featureId.endsWith(Constants.PARSER_SETTINGS)) {
1364                 return FeatureState.NOT_SUPPORTED;
1365             }
1366 
1367         }
1368 
1369         //
1370         // Not recognized
1371         //
1372 
1373         return super.checkFeature(featureId);
1374 
1375     } // checkFeature(String)
1376 
1377     /**
1378      * Check a property. If the property is know and supported, this method
1379      * simply returns. Otherwise, the appropriate exception is thrown.
1380      *
1381      * @param propertyId The unique identifier (URI) of the property
1382      *                   being set.
1383      *
1384      * @throws XMLConfigurationException Thrown for configuration error.
1385      *                                   In general, components should
1386      *                                   only throw this exception if
1387      *                                   it is <strong>really</strong>
1388      *                                   a critical error.
1389      */
1390     protected PropertyState checkProperty(String propertyId) throws XMLConfigurationException {
1391 
1392         //
1393         // Xerces Properties
1394         //
1395 
1396         if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
1397             final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
1398 
1399             if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
1400                 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
1401                 return PropertyState.RECOGNIZED;
1402             }
1403             if (suffixLength == Constants.SCHEMA_LOCATION.length() &&
1404                 propertyId.endsWith(Constants.SCHEMA_LOCATION)) {
1405                 return PropertyState.RECOGNIZED;
1406             }
1407             if (suffixLength == Constants.SCHEMA_NONS_LOCATION.length() &&
1408                 propertyId.endsWith(Constants.SCHEMA_NONS_LOCATION)) {
1409                 return PropertyState.RECOGNIZED;
1410             }
1411         }
1412 
1413         if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) {
1414             final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length();
1415 
1416             if (suffixLength == Constants.SCHEMA_SOURCE.length() &&
1417                 propertyId.endsWith(Constants.SCHEMA_SOURCE)) {
1418                 return PropertyState.RECOGNIZED;
1419             }
1420         }
1421 
1422         // special cases
1423         if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
1424             final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
1425 
1426             //
1427             // http://xml.org/sax/properties/xml-string
1428             // Value type: String
1429             // Access: read-only
1430             //   Get the literal string of characters associated with the
1431             //   current event.  If the parser recognises and supports this
1432             //   property but is not currently parsing text, it should return
1433             //   null (this is a good way to check for availability before the
1434             //   parse begins).
1435             //
1436             if (suffixLength == Constants.XML_STRING_PROPERTY.length() &&
1437                 propertyId.endsWith(Constants.XML_STRING_PROPERTY)) {
1438                 // REVISIT - we should probably ask xml-dev for a precise
1439                 // definition of what this is actually supposed to return, and
1440                 // in exactly which circumstances.
1441                 return PropertyState.NOT_SUPPORTED;
1442             }
1443         }
1444 
1445         //
1446         // Not recognized
1447         //
1448 
1449         return super.checkProperty(propertyId);
1450 
1451     } // checkProperty(String)
1452 
1453 
1454     /**
1455      * Adds a component to the parser configuration. This method will
1456      * also add all of the component's recognized features and properties
1457      * to the list of default recognized features and properties.
1458      *
1459      * @param component The component to add.
1460      */
1461     protected void addComponent(XMLComponent component) {
1462 
1463         // don't add a component more than once
1464         if (fComponents.contains(component)) {
1465             return;
1466         }
1467         fComponents.add(component);
1468         addRecognizedParamsAndSetDefaults(component);
1469 
1470     } // addComponent(XMLComponent)
1471 
1472     /**
1473      * Adds common component to the parser configuration. This method will
1474      * also add all of the component's recognized features and properties
1475      * to the list of default recognized features and properties.
1476      *
1477      * @param component The component to add.
1478      */
1479     protected void addCommonComponent(XMLComponent component) {
1480 
1481         // don't add a component more than once
1482         if (fCommonComponents.contains(component)) {
1483             return;
1484         }
1485         fCommonComponents.add(component);
1486         addRecognizedParamsAndSetDefaults(component);
1487 
1488     } // addCommonComponent(XMLComponent)
1489 
1490     /**
1491      * Adds an XML 1.1 component to the parser configuration. This method will
1492      * also add all of the component's recognized features and properties
1493      * to the list of default recognized features and properties.
1494      *
1495      * @param component The component to add.
1496      */
1497     protected void addXML11Component(XMLComponent component) {
1498 
1499         // don't add a component more than once
1500         if (fXML11Components.contains(component)) {
1501             return;
1502         }
1503         fXML11Components.add(component);
1504         addRecognizedParamsAndSetDefaults(component);
1505 
1506     } // addXML11Component(XMLComponent)
1507 
1508     /**
1509      * Adds all of the component's recognized features and properties
1510      * to the list of default recognized features and properties, and
1511      * sets default values on the configuration for features and
1512      * properties which were previously absent from the configuration.
1513      *
1514      * @param component The component whose recognized features
1515      * and properties will be added to the configuration
1516      */
1517     protected void addRecognizedParamsAndSetDefaults(XMLComponent component) {
1518 
1519         // register component's recognized features
1520         String[] recognizedFeatures = component.getRecognizedFeatures();
1521         addRecognizedFeatures(recognizedFeatures);
1522 
1523         // register component's recognized properties
1524         String[] recognizedProperties = component.getRecognizedProperties();
1525         addRecognizedProperties(recognizedProperties);
1526 
1527         // set default values
1528         if (recognizedFeatures != null) {
1529             for (int i = 0; i < recognizedFeatures.length; ++i) {
1530                 String featureId = recognizedFeatures[i];
1531                 Boolean state = component.getFeatureDefault(featureId);
1532                 if (state != null) {
1533                     // Do not overwrite values already set on the configuration.
1534                     if (!fFeatures.containsKey(featureId)) {
1535                         fFeatures.put(featureId, state);
1536                         // For newly added components who recognize this feature
1537                         // but did not offer a default value, we need to make
1538                         // sure these components will get an opportunity to read
1539                         // the value before parsing begins.
1540                         fConfigUpdated = true;
1541                     }
1542                 }
1543             }
1544         }
1545         if (recognizedProperties != null) {
1546             for (int i = 0; i < recognizedProperties.length; ++i) {
1547                 String propertyId = recognizedProperties[i];
1548                 Object value = component.getPropertyDefault(propertyId);
1549                 if (value != null) {
1550                     // Do not overwrite values already set on the configuration.
1551                     if (!fProperties.containsKey(propertyId)) {
1552                         fProperties.put(propertyId, value);
1553                         // For newly added components who recognize this property
1554                         // but did not offer a default value, we need to make
1555                         // sure these components will get an opportunity to read
1556                         // the value before parsing begins.
1557                         fConfigUpdated = true;
1558                     }
1559                 }
1560             }
1561         }
1562     }
1563 
1564     private void initXML11Components() {
1565         if (!f11Initialized) {
1566 
1567             // create datatype factory
1568             fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY);
1569 
1570             // setup XML 1.1 DTD pipeline
1571             fXML11DTDScanner = new XML11DTDScannerImpl();
1572             addXML11Component(fXML11DTDScanner);
1573             fXML11DTDProcessor = new XML11DTDProcessor();
1574             addXML11Component(fXML11DTDProcessor);
1575 
1576             // setup XML 1.1. document pipeline - namespace aware
1577             fXML11NSDocScanner = new XML11NSDocumentScannerImpl();
1578             addXML11Component(fXML11NSDocScanner);
1579             fXML11NSDTDValidator = new XML11NSDTDValidator();
1580             addXML11Component(fXML11NSDTDValidator);
1581 
1582             f11Initialized = true;
1583         }
1584     }
1585 
1586 
1587     /**
1588      * Reset the symbol table if it wasn't provided during construction
1589      * and its not the first time when parse is called after initialization
1590      */
1591     private void resetSymbolTable() {
1592         if (!fSymbolTableProvided) {
1593             if (fSymbolTableJustInitialized) {
1594                 // Skip symbol table reallocation for the first parsing process
1595                 fSymbolTableJustInitialized = false;
1596             } else {
1597                 fSymbolTable = new SymbolTable();
1598                 fProperties.put(SYMBOL_TABLE, fSymbolTable);
1599             }
1600         }
1601     }
1602 
1603     /**
1604      * Returns the state of a feature. This method calls getFeature()
1605      * on ParserConfigurationSettings, bypassing getFeature() on this
1606      * class.
1607      */
1608     FeatureState getFeatureState0(String featureId)
1609         throws XMLConfigurationException {
1610         return super.getFeatureState(featureId);
1611     }
1612 
1613 } // class XML11Configuration