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