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