1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Copyright 2001-2004 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.Locale;
  24 
  25 import com.sun.org.apache.xerces.internal.impl.Constants;
  26 import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl;
  27 import com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl;
  28 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
  29 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
  30 import com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl;
  31 import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory;
  32 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
  33 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
  34 import com.sun.org.apache.xerces.internal.util.FeatureState;
  35 import com.sun.org.apache.xerces.internal.util.PropertyState;
  36 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  37 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
  38 import com.sun.org.apache.xerces.internal.xni.XMLLocator;
  39 import com.sun.org.apache.xerces.internal.xni.XNIException;
  40 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  41 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
  42 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  43 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  44 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
  45 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner;
  46 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  47 import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration;
  48 import jdk.xml.internal.JdkXmlUtils;
  49 
  50 /**
  51  * This is the non validating parser configuration. It extends the basic
  52  * configuration with the set of following parser components:
  53  * Document scanner, DTD scanner, namespace binder, document handler.
  54  * <p>
  55  * Xerces parser that uses this configuration is <strong>not</strong> <a href="http://www.w3.org/TR/REC-xml#sec-conformance">conformant</a>
  56  * non-validating XML processor, since conformant non-validating processor is required
  57  * to process "all the declarations they read in the internal DTD subset ... must use the information in those declarations to normalize attribute values,
  58  * include the replacement text of internal entities, and supply default attribute values".
  59  *
  60  * @author Elena Litani, IBM
  61  * @version $Id: NonValidatingConfiguration.java,v 1.7 2010-11-01 04:40:09 joehw Exp $
  62  */
  63 public class NonValidatingConfiguration
  64     extends BasicParserConfiguration
  65     implements XMLPullParserConfiguration {
  66 
  67     //
  68     // Constants
  69     //
  70 
  71     // feature identifiers
  72 
  73     /** Feature identifier: warn on duplicate attribute definition. */
  74     protected static final String WARN_ON_DUPLICATE_ATTDEF =
  75         Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
  76 
  77     /** Feature identifier: warn on duplicate entity definition. */
  78     protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
  79         Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
  80 
  81     /** Feature identifier: warn on undeclared element definition. */
  82     protected static final String WARN_ON_UNDECLARED_ELEMDEF =
  83         Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
  84 
  85     /** Feature identifier: allow Java encodings. */
  86     protected static final String ALLOW_JAVA_ENCODINGS =
  87         Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
  88 
  89     /** Feature identifier: continue after fatal error. */
  90     protected static final String CONTINUE_AFTER_FATAL_ERROR =
  91         Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
  92 
  93     /** Feature identifier: load external DTD. */
  94     protected static final String LOAD_EXTERNAL_DTD =
  95         Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
  96 
  97     /** Feature identifier: notify built-in refereces. */
  98     protected static final String NOTIFY_BUILTIN_REFS =
  99         Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE;
 100 
 101     /** Feature identifier: notify character refereces. */
 102     protected static final String NOTIFY_CHAR_REFS =
 103         Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE;
 104 
 105 
 106     /** Feature identifier: expose schema normalized value */
 107     protected static final String NORMALIZE_DATA =
 108     Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE;
 109 
 110 
 111     /** Feature identifier: send element default value via characters() */
 112     protected static final String SCHEMA_ELEMENT_DEFAULT =
 113     Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT;
 114 
 115     // property identifiers
 116 
 117     /** Property identifier: error reporter. */
 118     protected static final String ERROR_REPORTER =
 119         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
 120 
 121     /** Property identifier: entity manager. */
 122     protected static final String ENTITY_MANAGER =
 123         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
 124 
 125     /** Property identifier document scanner: */
 126     protected static final String DOCUMENT_SCANNER =
 127         Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY;
 128 
 129     /** Property identifier: DTD scanner. */
 130     protected static final String DTD_SCANNER =
 131         Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY;
 132 
 133     /** Property identifier: grammar pool. */
 134     protected static final String XMLGRAMMAR_POOL =
 135         Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
 136 
 137     /** Property identifier: DTD validator. */
 138     protected static final String DTD_VALIDATOR =
 139         Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
 140 
 141     /** Property identifier: namespace binder. */
 142     protected static final String NAMESPACE_BINDER =
 143         Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY;
 144 
 145     /** Property identifier: datatype validator factory. */
 146     protected static final String DATATYPE_VALIDATOR_FACTORY =
 147         Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
 148 
 149     protected static final String VALIDATION_MANAGER =
 150         Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
 151 
 152     /** Property identifier: XML Schema validator. */
 153     protected static final String SCHEMA_VALIDATOR =
 154         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
 155 
 156     /** Property identifier: locale. */
 157     protected static final String LOCALE =
 158         Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
 159 
 160       /** Property identifier: Security property manager. */
 161       protected static final String XML_SECURITY_PROPERTY_MANAGER =
 162               Constants.XML_SECURITY_PROPERTY_MANAGER;
 163 
 164      /** Property identifier: Security manager. */
 165      private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
 166 
 167     // debugging
 168 
 169     /** Set to true and recompile to print exception stack trace. */
 170     private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
 171 
 172     //
 173     // Data
 174     //
 175 
 176     // components (non-configurable)
 177 
 178     /** Grammar pool. */
 179     protected XMLGrammarPool fGrammarPool;
 180 
 181     /** Datatype validator factory. */
 182     protected DTDDVFactory fDatatypeValidatorFactory;
 183 
 184     // components (configurable)
 185 
 186     /** Error reporter. */
 187     protected XMLErrorReporter fErrorReporter;
 188 
 189     /** Entity manager. */
 190     protected XMLEntityManager fEntityManager;
 191 
 192     /** Document scanner. */
 193     protected XMLDocumentScanner fScanner;
 194 
 195     /** Input Source */
 196     protected XMLInputSource fInputSource;
 197 
 198     /** DTD scanner. */
 199     protected XMLDTDScanner fDTDScanner;
 200 
 201 
 202     protected ValidationManager fValidationManager;
 203 
 204     // private data
 205 
 206     /** Document scanner that does namespace binding. */
 207     private XMLNSDocumentScannerImpl fNamespaceScanner;
 208 
 209     /** Default Xerces implementation of scanner*/
 210     private XMLDocumentScannerImpl fNonNSScanner;
 211 
 212 
 213         /** fConfigUpdated is set to true if there has been any change to the configuration settings,
 214          * i.e a feature or a property was changed.
 215          */
 216         protected boolean fConfigUpdated = false;
 217 
 218 
 219     // state
 220 
 221     /** Locator */
 222     protected XMLLocator fLocator;
 223 
 224     /**
 225      * True if a parse is in progress. This state is needed because
 226      * some features/properties cannot be set while parsing (e.g.
 227      * validation and namespaces).
 228      */
 229     protected boolean fParseInProgress = false;
 230 
 231     //
 232     // Constructors
 233     //
 234 
 235     /** Default constructor. */
 236     public NonValidatingConfiguration() {
 237         this(null, null, null);
 238     } // <init>()
 239 
 240     /**
 241      * Constructs a parser configuration using the specified symbol table.
 242      *
 243      * @param symbolTable The symbol table to use.
 244      */
 245     public NonValidatingConfiguration(SymbolTable symbolTable) {
 246         this(symbolTable, null, null);
 247     } // <init>(SymbolTable)
 248 
 249     /**
 250      * Constructs a parser configuration using the specified symbol table and
 251      * grammar pool.
 252      * <p>
 253      * <strong>REVISIT:</strong>
 254      * Grammar pool will be updated when the new validation engine is
 255      * implemented.
 256      *
 257      * @param symbolTable The symbol table to use.
 258      * @param grammarPool The grammar pool to use.
 259      */
 260     public NonValidatingConfiguration(SymbolTable symbolTable,
 261                                        XMLGrammarPool grammarPool) {
 262         this(symbolTable, grammarPool, null);
 263     } // <init>(SymbolTable,XMLGrammarPool)
 264 
 265     /**
 266      * Constructs a parser configuration using the specified symbol table,
 267      * grammar pool, and parent settings.
 268      * <p>
 269      * <strong>REVISIT:</strong>
 270      * Grammar pool will be updated when the new validation engine is
 271      * implemented.
 272      *
 273      * @param symbolTable    The symbol table to use.
 274      * @param grammarPool    The grammar pool to use.
 275      * @param parentSettings The parent settings.
 276      */
 277     public NonValidatingConfiguration(SymbolTable symbolTable,
 278                                        XMLGrammarPool grammarPool,
 279                                        XMLComponentManager parentSettings) {
 280         super(symbolTable, parentSettings);
 281 
 282         // add default recognized features
 283         final String[] recognizedFeatures = {
 284                 PARSER_SETTINGS,
 285                         NAMESPACES,
 286             //WARN_ON_DUPLICATE_ATTDEF,     // from XMLDTDScannerImpl
 287             //WARN_ON_UNDECLARED_ELEMDEF,   // from XMLDTDScannerImpl
 288             //ALLOW_JAVA_ENCODINGS,         // from XMLEntityManager
 289             CONTINUE_AFTER_FATAL_ERROR,
 290             //LOAD_EXTERNAL_DTD,    // from XMLDTDScannerImpl
 291             //NOTIFY_BUILTIN_REFS,  // from XMLDocumentFragmentScannerImpl
 292             //NOTIFY_CHAR_REFS,         // from XMLDocumentFragmentScannerImpl
 293             //WARN_ON_DUPLICATE_ENTITYDEF   // from XMLEntityManager
 294             JdkXmlUtils.OVERRIDE_PARSER
 295         };
 296         addRecognizedFeatures(recognizedFeatures);
 297 
 298         // set state for default features
 299         //setFeature(WARN_ON_DUPLICATE_ATTDEF, false);  // from XMLDTDScannerImpl
 300         //setFeature(WARN_ON_UNDECLARED_ELEMDEF, false);    // from XMLDTDScannerImpl
 301         //setFeature(ALLOW_JAVA_ENCODINGS, false);      // from XMLEntityManager
 302         fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE);
 303                 fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
 304                 fFeatures.put(NAMESPACES, Boolean.TRUE);
 305         //setFeature(LOAD_EXTERNAL_DTD, true);      // from XMLDTDScannerImpl
 306         //setFeature(NOTIFY_BUILTIN_REFS, false);   // from XMLDocumentFragmentScannerImpl
 307         //setFeature(NOTIFY_CHAR_REFS, false);      // from XMLDocumentFragmentScannerImpl
 308         //setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false);   // from XMLEntityManager
 309         fFeatures.put(JdkXmlUtils.OVERRIDE_PARSER, JdkXmlUtils.OVERRIDE_PARSER_DEFAULT);
 310 
 311         // add default recognized properties
 312         final String[] recognizedProperties = {
 313             ERROR_REPORTER,
 314             ENTITY_MANAGER,
 315             DOCUMENT_SCANNER,
 316             DTD_SCANNER,
 317             DTD_VALIDATOR,
 318             NAMESPACE_BINDER,
 319             XMLGRAMMAR_POOL,
 320             DATATYPE_VALIDATOR_FACTORY,
 321             VALIDATION_MANAGER,
 322             LOCALE,
 323             SECURITY_MANAGER,
 324             XML_SECURITY_PROPERTY_MANAGER
 325         };
 326         addRecognizedProperties(recognizedProperties);
 327 
 328         fGrammarPool = grammarPool;
 329         if(fGrammarPool != null){
 330                         fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
 331         }
 332 
 333         fEntityManager = createEntityManager();
 334                 fProperties.put(ENTITY_MANAGER, fEntityManager);
 335         addComponent(fEntityManager);
 336 
 337         fErrorReporter = createErrorReporter();
 338         fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
 339                 fProperties.put(ERROR_REPORTER, fErrorReporter);
 340         addComponent(fErrorReporter);
 341 
 342         // this configuration delays creation of the scanner
 343         // till it is known if namespace processing should be performed
 344 
 345         fDTDScanner = createDTDScanner();
 346         if (fDTDScanner != null) {
 347                         fProperties.put(DTD_SCANNER, fDTDScanner);
 348             if (fDTDScanner instanceof XMLComponent) {
 349                 addComponent((XMLComponent)fDTDScanner);
 350             }
 351         }
 352 
 353         fDatatypeValidatorFactory = createDatatypeValidatorFactory();
 354         if (fDatatypeValidatorFactory != null) {
 355                         fProperties.put(DATATYPE_VALIDATOR_FACTORY,
 356                         fDatatypeValidatorFactory);
 357         }
 358         fValidationManager = createValidationManager();
 359 
 360         if (fValidationManager != null) {
 361                         fProperties.put(VALIDATION_MANAGER, fValidationManager);
 362         }
 363         // add message formatters
 364         if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
 365             XMLMessageFormatter xmft = new XMLMessageFormatter();
 366             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
 367             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
 368         }
 369 
 370                 fConfigUpdated = false;
 371 
 372         // set locale
 373         try {
 374             setLocale(Locale.getDefault());
 375         }
 376         catch (XNIException e) {
 377             // do nothing
 378             // REVISIT: What is the right thing to do? -Ac
 379         }
 380 
 381         setProperty(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager());
 382     } // <init>(SymbolTable,XMLGrammarPool)
 383 
 384     //
 385     // Public methods
 386     //
 387         public void setFeature(String featureId, boolean state)
 388                 throws XMLConfigurationException {
 389                 fConfigUpdated = true;
 390                 super.setFeature(featureId, state);
 391         }
 392 
 393         public PropertyState getPropertyState(String propertyId)
 394              throws XMLConfigurationException {
 395              if (LOCALE.equals(propertyId)) {
 396                  return PropertyState.is(getLocale());
 397              }
 398              return super.getPropertyState(propertyId);
 399          }
 400 
 401         public void setProperty(String propertyId, Object value)
 402              throws XMLConfigurationException {
 403              fConfigUpdated = true;
 404              if (LOCALE.equals(propertyId)) {
 405                  setLocale((Locale) value);
 406              }
 407              super.setProperty(propertyId, value);
 408          }
 409 
 410     /**
 411      * Set the locale to use for messages.
 412      *
 413      * @param locale The locale object to use for localization of messages.
 414      *
 415      * @exception XNIException Thrown if the parser does not support the
 416      *                         specified locale.
 417      */
 418     public void setLocale(Locale locale) throws XNIException {
 419         super.setLocale(locale);
 420         fErrorReporter.setLocale(locale);
 421     } // setLocale(Locale)
 422 
 423         public FeatureState getFeatureState(String featureId)
 424                 throws XMLConfigurationException {
 425                         // make this feature special
 426                 if (featureId.equals(PARSER_SETTINGS)){
 427                         return FeatureState.is(fConfigUpdated);
 428                 }
 429                 return super.getFeatureState(featureId);
 430 
 431         } // getFeature(String):boolean
 432     //
 433     // XMLPullParserConfiguration methods
 434     //
 435 
 436     // parsing
 437 
 438     /**
 439      * Sets the input source for the document to parse.
 440      *
 441      * @param inputSource The document's input source.
 442      *
 443      * @exception XMLConfigurationException Thrown if there is a
 444      *                        configuration error when initializing the
 445      *                        parser.
 446      * @exception IOException Thrown on I/O error.
 447      *
 448      * @see #parse(boolean)
 449      */
 450     public void setInputSource(XMLInputSource inputSource)
 451         throws XMLConfigurationException, IOException {
 452 
 453         // REVISIT: this method used to reset all the components and
 454         //          construct the pipeline. Now reset() is called
 455         //          in parse (boolean) just before we parse the document
 456         //          Should this method still throw exceptions..?
 457 
 458         fInputSource = inputSource;
 459 
 460     } // setInputSource(XMLInputSource)
 461 
 462     /**
 463      * Parses the document in a pull parsing fashion.
 464      *
 465      * @param complete True if the pull parser should parse the
 466      *                 remaining document completely.
 467      *
 468      * @return True if there is more document to parse.
 469      *
 470      * @exception XNIException Any XNI exception, possibly wrapping
 471      *                         another exception.
 472      * @exception IOException  An IO exception from the parser, possibly
 473      *                         from a byte stream or character stream
 474      *                         supplied by the parser.
 475      *
 476      * @see #setInputSource
 477      */
 478     public boolean parse(boolean complete) throws XNIException, IOException {
 479         //
 480         // reset and configure pipeline and set InputSource.
 481         if (fInputSource !=null) {
 482             try {
 483                 // resets and sets the pipeline.
 484                 reset();
 485                 fScanner.setInputSource(fInputSource);
 486                 fInputSource = null;
 487             }
 488             catch (XNIException ex) {
 489                 if (PRINT_EXCEPTION_STACK_TRACE)
 490                     ex.printStackTrace();
 491                 throw ex;
 492             }
 493             catch (IOException ex) {
 494                 if (PRINT_EXCEPTION_STACK_TRACE)
 495                     ex.printStackTrace();
 496                 throw ex;
 497             }
 498             catch (RuntimeException ex) {
 499                 if (PRINT_EXCEPTION_STACK_TRACE)
 500                     ex.printStackTrace();
 501                 throw ex;
 502             }
 503             catch (Exception ex) {
 504                 if (PRINT_EXCEPTION_STACK_TRACE)
 505                     ex.printStackTrace();
 506                 throw new XNIException(ex);
 507             }
 508         }
 509 
 510         try {
 511             return fScanner.scanDocument(complete);
 512         }
 513         catch (XNIException ex) {
 514             if (PRINT_EXCEPTION_STACK_TRACE)
 515                 ex.printStackTrace();
 516             throw ex;
 517         }
 518         catch (IOException ex) {
 519             if (PRINT_EXCEPTION_STACK_TRACE)
 520                 ex.printStackTrace();
 521             throw ex;
 522         }
 523         catch (RuntimeException ex) {
 524             if (PRINT_EXCEPTION_STACK_TRACE)
 525                 ex.printStackTrace();
 526             throw ex;
 527         }
 528         catch (Exception ex) {
 529             if (PRINT_EXCEPTION_STACK_TRACE)
 530                 ex.printStackTrace();
 531             throw new XNIException(ex);
 532         }
 533 
 534     } // parse(boolean):boolean
 535 
 536     /**
 537      * If the application decides to terminate parsing before the xml document
 538      * is fully parsed, the application should call this method to free any
 539      * resource allocated during parsing. For example, close all opened streams.
 540      */
 541     public void cleanup() {
 542         fEntityManager.closeReaders();
 543     }
 544 
 545     //
 546     // XMLParserConfiguration methods
 547     //
 548 
 549     /**
 550      * Parses the specified input source.
 551      *
 552      * @param source The input source.
 553      *
 554      * @exception XNIException Throws exception on XNI error.
 555      * @exception java.io.IOException Throws exception on i/o error.
 556      */
 557     public void parse(XMLInputSource source) throws XNIException, IOException {
 558 
 559         if (fParseInProgress) {
 560             // REVISIT - need to add new error message
 561             throw new XNIException("FWK005 parse may not be called while parsing.");
 562         }
 563         fParseInProgress = true;
 564 
 565         try {
 566             setInputSource(source);
 567             parse(true);
 568         }
 569         catch (XNIException ex) {
 570             if (PRINT_EXCEPTION_STACK_TRACE)
 571                 ex.printStackTrace();
 572             throw ex;
 573         }
 574         catch (IOException ex) {
 575             if (PRINT_EXCEPTION_STACK_TRACE)
 576                 ex.printStackTrace();
 577             throw ex;
 578         }
 579         catch (RuntimeException ex) {
 580             if (PRINT_EXCEPTION_STACK_TRACE)
 581                 ex.printStackTrace();
 582             throw ex;
 583         }
 584         catch (Exception ex) {
 585             if (PRINT_EXCEPTION_STACK_TRACE)
 586                 ex.printStackTrace();
 587             throw new XNIException(ex);
 588         }
 589         finally {
 590             fParseInProgress = false;
 591             // close all streams opened by xerces
 592             this.cleanup();
 593         }
 594 
 595     } // parse(InputSource)
 596 
 597     //
 598     // Protected methods
 599     //
 600 
 601     /**
 602      * Reset all components before parsing.
 603      *
 604      * @throws XNIException Thrown if an error occurs during initialization.
 605      */
 606     protected void reset() throws XNIException {
 607 
 608         if (fValidationManager != null)
 609             fValidationManager.reset();
 610         // configure the pipeline and initialize the components
 611         configurePipeline();
 612         super.reset();
 613 
 614     } // reset()
 615 
 616     /** Configures the pipeline. */
 617     protected void configurePipeline() {
 618         // create appropriate scanner
 619         // and register it as one of the components.
 620         if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
 621             if (fNamespaceScanner == null) {
 622                 fNamespaceScanner = new XMLNSDocumentScannerImpl();
 623                 addComponent((XMLComponent)fNamespaceScanner);
 624             }
 625             fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner);
 626             fNamespaceScanner.setDTDValidator(null);
 627             fScanner = fNamespaceScanner;
 628         }
 629         else {
 630             if (fNonNSScanner == null) {
 631                 fNonNSScanner = new XMLDocumentScannerImpl();
 632                 addComponent((XMLComponent)fNonNSScanner);
 633             }
 634             fProperties.put(DOCUMENT_SCANNER, fNonNSScanner);
 635             fScanner = fNonNSScanner;
 636         }
 637 
 638         fScanner.setDocumentHandler(fDocumentHandler);
 639         fLastComponent = fScanner;
 640         // setup dtd pipeline
 641         if (fDTDScanner != null) {
 642                 fDTDScanner.setDTDHandler(fDTDHandler);
 643                 fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler);
 644         }
 645 
 646 
 647     } // configurePipeline()
 648 
 649     // features and properties
 650 
 651     /**
 652      * Check a feature. If feature is know and supported, this method simply
 653      * returns. Otherwise, the appropriate exception is thrown.
 654      *
 655      * @param featureId The unique identifier (URI) of the feature.
 656      *
 657      * @throws XMLConfigurationException Thrown for configuration error.
 658      *                                   In general, components should
 659      *                                   only throw this exception if
 660      *                                   it is <strong>really</strong>
 661      *                                   a critical error.
 662      */
 663     protected FeatureState checkFeature(String featureId)
 664         throws XMLConfigurationException {
 665 
 666         //
 667         // Xerces Features
 668         //
 669 
 670         if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
 671             final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
 672 
 673             //
 674             // http://apache.org/xml/features/validation/dynamic
 675             //   Allows the parser to validate a document only when it
 676             //   contains a grammar. Validation is turned on/off based
 677             //   on each document instance, automatically.
 678             //
 679             if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() &&
 680                 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
 681                 return FeatureState.RECOGNIZED;
 682             }
 683             //
 684             // http://apache.org/xml/features/validation/default-attribute-values
 685             //
 686             if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() &&
 687                 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
 688                 // REVISIT
 689                 return FeatureState.NOT_SUPPORTED;
 690             }
 691             //
 692             // http://apache.org/xml/features/validation/default-attribute-values
 693             //
 694             if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() &&
 695                 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
 696                 // REVISIT
 697                 return FeatureState.NOT_SUPPORTED;
 698             }
 699             //
 700             // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
 701             //
 702             if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() &&
 703                 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
 704                 return FeatureState.RECOGNIZED;
 705             }
 706             //
 707             // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
 708             //
 709             if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
 710                 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
 711                 return FeatureState.RECOGNIZED;
 712             }
 713 
 714             //
 715             // http://apache.org/xml/features/validation/default-attribute-values
 716             //
 717             if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() &&
 718                 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
 719                 return FeatureState.NOT_SUPPORTED;
 720             }
 721         }
 722 
 723         //
 724         // Not recognized
 725         //
 726 
 727         return super.checkFeature(featureId);
 728 
 729     } // checkFeature(String)
 730 
 731     /**
 732      * Check a property. If the property is know and supported, this method
 733      * simply returns. Otherwise, the appropriate exception is thrown.
 734      *
 735      * @param propertyId The unique identifier (URI) of the property
 736      *                   being set.
 737      *
 738      * @throws XMLConfigurationException Thrown for configuration error.
 739      *                                   In general, components should
 740      *                                   only throw this exception if
 741      *                                   it is <strong>really</strong>
 742      *                                   a critical error.
 743      */
 744     protected PropertyState checkProperty(String propertyId)
 745         throws XMLConfigurationException {
 746 
 747         //
 748         // Xerces Properties
 749         //
 750 
 751         if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
 752             final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
 753 
 754             if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
 755                 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
 756                 return PropertyState.RECOGNIZED;
 757             }
 758         }
 759 
 760         if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) {
 761             final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length();
 762 
 763             if (suffixLength == Constants.SCHEMA_SOURCE.length() &&
 764                 propertyId.endsWith(Constants.SCHEMA_SOURCE)) {
 765                 return PropertyState.RECOGNIZED;
 766             }
 767         }
 768 
 769         //
 770         // Not recognized
 771         //
 772 
 773         return super.checkProperty(propertyId);
 774 
 775     } // checkProperty(String)
 776 
 777     // factory methods
 778 
 779     /** Creates an entity manager. */
 780     protected XMLEntityManager createEntityManager() {
 781         return new XMLEntityManager();
 782     } // createEntityManager():XMLEntityManager
 783 
 784     /** Creates an error reporter. */
 785     protected XMLErrorReporter createErrorReporter() {
 786         return new XMLErrorReporter();
 787     } // createErrorReporter():XMLErrorReporter
 788 
 789     /** Create a document scanner. */
 790     protected XMLDocumentScanner createDocumentScanner() {
 791         return null;
 792     } // createDocumentScanner():XMLDocumentScanner
 793 
 794     /** Create a DTD scanner. */
 795     protected XMLDTDScanner createDTDScanner() {
 796         return new XMLDTDScannerImpl();
 797     } // createDTDScanner():XMLDTDScanner
 798 
 799     /** Create a datatype validator factory. */
 800     protected DTDDVFactory createDatatypeValidatorFactory() {
 801         return DTDDVFactory.getInstance();
 802     } // createDatatypeValidatorFactory():DatatypeValidatorFactory
 803     protected ValidationManager createValidationManager(){
 804         return new ValidationManager();
 805     }
 806 
 807 } // class NonValidatingConfiguration