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