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