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