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