1 /* 2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.parsers; 22 23 import java.io.IOException; 24 import java.util.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.XMLNamespaceBinder; 32 import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDProcessor; 33 import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator; 34 import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory; 35 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 36 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; 37 import com.sun.org.apache.xerces.internal.util.FeatureState; 38 import com.sun.org.apache.xerces.internal.util.PropertyState; 39 import com.sun.org.apache.xerces.internal.util.SymbolTable; 40 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; 41 import com.sun.org.apache.xerces.internal.xni.XMLLocator; 42 import com.sun.org.apache.xerces.internal.xni.XNIException; 43 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; 44 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; 45 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 46 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 47 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner; 48 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner; 49 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 50 import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration; 51 import javax.xml.XMLConstants; 52 import javax.xml.catalog.CatalogFeatures; 53 import jdk.xml.internal.JdkXmlUtils; 54 55 /** 56 * This is the DTD-only parser configuration. It extends the basic 57 * configuration with a standard set of parser components appropriate 58 * to DTD-centric validation. Since 59 * the Xerces2 reference implementation document and DTD scanner 60 * implementations are capable of acting as pull parsers, this 61 * configuration implements the 62 * <code>XMLPullParserConfiguration</code> interface. 63 * <p> 64 * In addition to the features and properties recognized by the base 65 * parser configuration, this class recognizes these additional 66 * features and properties: 67 * <ul> 68 * <li>Features 69 * <ul> 70 * <li>http://apache.org/xml/features/validation/warn-on-duplicate-attdef</li> 71 * <li>http://apache.org/xml/features/validation/warn-on-undeclared-elemdef</li> 72 * <li>http://apache.org/xml/features/allow-java-encodings</li> 73 * <li>http://apache.org/xml/features/continue-after-fatal-error</li> 74 * <li>http://apache.org/xml/features/load-external-dtd</li> 75 * </ul> 76 * <li>Properties 77 * <ul> 78 * <li>http://apache.org/xml/properties/internal/error-reporter</li> 79 * <li>http://apache.org/xml/properties/internal/entity-manager</li> 80 * <li>http://apache.org/xml/properties/internal/document-scanner</li> 81 * <li>http://apache.org/xml/properties/internal/dtd-scanner</li> 82 * <li>http://apache.org/xml/properties/internal/grammar-pool</li> 83 * <li>http://apache.org/xml/properties/internal/validator/dtd</li> 84 * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li> 85 * </ul> 86 * </ul> 87 * 88 * @author Arnaud Le Hors, IBM 89 * @author Andy Clark, IBM 90 * @author Neil Graham, IBM 91 * 92 */ 93 public class DTDConfiguration 94 extends BasicParserConfiguration 95 implements XMLPullParserConfiguration { 96 97 // 98 // Constants 99 // 100 101 // feature identifiers 102 103 /** Feature identifier: warn on duplicate attribute definition. */ 104 protected static final String WARN_ON_DUPLICATE_ATTDEF = 105 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE; 106 107 /** Feature identifier: warn on duplicate entity definition. */ 108 protected static final String WARN_ON_DUPLICATE_ENTITYDEF = 109 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE; 110 111 /** Feature identifier: warn on undeclared element definition. */ 112 protected static final String WARN_ON_UNDECLARED_ELEMDEF = 113 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE; 114 115 /** Feature identifier: allow Java encodings. */ 116 protected static final String ALLOW_JAVA_ENCODINGS = 117 Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE; 118 119 /** Feature identifier: continue after fatal error. */ 120 protected static final String CONTINUE_AFTER_FATAL_ERROR = 121 Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE; 122 123 /** Feature identifier: load external DTD. */ 124 protected static final String LOAD_EXTERNAL_DTD = 125 Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE; 126 127 /** Feature identifier: notify built-in refereces. */ 128 protected static final String NOTIFY_BUILTIN_REFS = 129 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE; 130 131 /** Feature identifier: notify character refereces. */ 132 protected static final String NOTIFY_CHAR_REFS = 133 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE; 134 135 136 // property identifiers 137 138 /** Property identifier: error reporter. */ 139 protected static final String ERROR_REPORTER = 140 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 141 142 /** Property identifier: entity manager. */ 143 protected static final String ENTITY_MANAGER = 144 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; 145 146 /** Property identifier document scanner: */ 147 protected static final String DOCUMENT_SCANNER = 148 Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY; 149 150 /** Property identifier: DTD scanner. */ 151 protected static final String DTD_SCANNER = 152 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY; 153 154 /** Property identifier: grammar pool. */ 155 protected static final String XMLGRAMMAR_POOL = 156 Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; 157 158 /** Property identifier: DTD loader. */ 159 protected static final String DTD_PROCESSOR = 160 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_PROCESSOR_PROPERTY; 161 162 /** Property identifier: DTD validator. */ 163 protected static final String DTD_VALIDATOR = 164 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY; 165 166 /** Property identifier: namespace binder. */ 167 protected static final String NAMESPACE_BINDER = 168 Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY; 169 170 /** Property identifier: datatype validator factory. */ 171 protected static final String DATATYPE_VALIDATOR_FACTORY = 172 Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY; 173 174 protected static final String VALIDATION_MANAGER = 175 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 176 177 /** Property identifier: JAXP schema language / DOM schema-type. */ 178 protected static final String JAXP_SCHEMA_LANGUAGE = 179 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE; 180 181 /** Property identifier: JAXP schema source/ DOM schema-location. */ 182 protected static final String JAXP_SCHEMA_SOURCE = 183 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE; 184 185 /** Property identifier: locale. */ 186 protected static final String LOCALE = 187 Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; 188 189 /** Property identifier: Security property manager. */ 190 protected static final String XML_SECURITY_PROPERTY_MANAGER = 191 Constants.XML_SECURITY_PROPERTY_MANAGER; 192 193 /** Property identifier: Security manager. */ 194 private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; 195 196 // debugging 197 198 /** Set to true and recompile to print exception stack trace. */ 199 protected static final boolean PRINT_EXCEPTION_STACK_TRACE = false; 200 201 // 202 // Data 203 // 204 205 // components (non-configurable) 206 207 /** Grammar pool. */ 208 protected XMLGrammarPool fGrammarPool; 209 210 /** Datatype validator factory. */ 211 protected DTDDVFactory fDatatypeValidatorFactory; 212 213 // components (configurable) 214 215 /** Error reporter. */ 216 protected XMLErrorReporter fErrorReporter; 217 218 /** Entity manager. */ 219 protected XMLEntityManager fEntityManager; 220 221 /** Document scanner. */ 222 protected XMLDocumentScanner fScanner; 223 224 /** Input Source */ 225 protected XMLInputSource fInputSource; 226 227 /** DTD scanner. */ 228 protected XMLDTDScanner fDTDScanner; 229 230 /** DTD Processor . */ 231 protected XMLDTDProcessor fDTDProcessor; 232 233 /** DTD Validator. */ 234 protected XMLDTDValidator fDTDValidator; 235 236 /** Namespace binder. */ 237 protected XMLNamespaceBinder fNamespaceBinder; 238 239 protected ValidationManager fValidationManager; 240 // state 241 242 /** Locator */ 243 protected XMLLocator fLocator; 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 // Constructors 254 // 255 256 /** Default constructor. */ 257 public DTDConfiguration() { 258 this(null, null, null); 259 } // <init>() 260 261 /** 262 * Constructs a parser configuration using the specified symbol table. 263 * 264 * @param symbolTable The symbol table to use. 265 */ 266 public DTDConfiguration(SymbolTable symbolTable) { 267 this(symbolTable, null, null); 268 } // <init>(SymbolTable) 269 270 /** 271 * Constructs a parser configuration using the specified symbol table and 272 * grammar pool. 273 * <p> 274 * <strong>REVISIT:</strong> 275 * Grammar pool will be updated when the new validation engine is 276 * implemented. 277 * 278 * @param symbolTable The symbol table to use. 279 * @param grammarPool The grammar pool to use. 280 */ 281 public DTDConfiguration(SymbolTable symbolTable, 282 XMLGrammarPool grammarPool) { 283 this(symbolTable, grammarPool, null); 284 } // <init>(SymbolTable,XMLGrammarPool) 285 286 /** 287 * Constructs a parser configuration using the specified symbol table, 288 * grammar pool, and parent settings. 289 * <p> 290 * <strong>REVISIT:</strong> 291 * Grammar pool will be updated when the new validation engine is 292 * implemented. 293 * 294 * @param symbolTable The symbol table to use. 295 * @param grammarPool The grammar pool to use. 296 * @param parentSettings The parent settings. 297 */ 298 public DTDConfiguration(SymbolTable symbolTable, 299 XMLGrammarPool grammarPool, 300 XMLComponentManager parentSettings) { 301 super(symbolTable, parentSettings); 302 303 // add default recognized features 304 final String[] recognizedFeatures = { 305 //WARN_ON_DUPLICATE_ATTDEF, // from XMLDTDScannerImpl 306 //WARN_ON_UNDECLARED_ELEMDEF, // from XMLDTDScannerImpl 307 //ALLOW_JAVA_ENCODINGS, // from XMLEntityManager 308 CONTINUE_AFTER_FATAL_ERROR, 309 LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl 310 //NOTIFY_BUILTIN_REFS, // from XMLDocumentFragmentScannerImpl 311 //NOTIFY_CHAR_REFS, // from XMLDocumentFragmentScannerImpl 312 //WARN_ON_DUPLICATE_ENTITYDEF, // from XMLEntityManager 313 XMLConstants.USE_CATALOG 314 }; 315 addRecognizedFeatures(recognizedFeatures); 316 317 // set state for default features 318 //setFeature(WARN_ON_DUPLICATE_ATTDEF, false); // from XMLDTDScannerImpl 319 //setFeature(WARN_ON_UNDECLARED_ELEMDEF, false); // from XMLDTDScannerImpl 320 //setFeature(ALLOW_JAVA_ENCODINGS, false); // from XMLEntityManager 321 setFeature(CONTINUE_AFTER_FATAL_ERROR, false); 322 setFeature(LOAD_EXTERNAL_DTD, true); // from XMLDTDScannerImpl 323 //setFeature(NOTIFY_BUILTIN_REFS, false); // from XMLDocumentFragmentScannerImpl 324 //setFeature(NOTIFY_CHAR_REFS, false); // from XMLDocumentFragmentScannerImpl 325 //setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false); // from XMLEntityManager 326 fFeatures.put(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT); 327 328 // add default recognized properties 329 final String[] recognizedProperties = { 330 ERROR_REPORTER, 331 ENTITY_MANAGER, 332 DOCUMENT_SCANNER, 333 DTD_SCANNER, 334 DTD_PROCESSOR, 335 DTD_VALIDATOR, 336 NAMESPACE_BINDER, 337 XMLGRAMMAR_POOL, 338 DATATYPE_VALIDATOR_FACTORY, 339 VALIDATION_MANAGER, 340 JAXP_SCHEMA_SOURCE, 341 JAXP_SCHEMA_LANGUAGE, 342 LOCALE, 343 SECURITY_MANAGER, 344 XML_SECURITY_PROPERTY_MANAGER, 345 JdkXmlUtils.CATALOG_DEFER, 346 JdkXmlUtils.CATALOG_FILES, 347 JdkXmlUtils.CATALOG_PREFER, 348 JdkXmlUtils.CATALOG_RESOLVE 349 }; 350 addRecognizedProperties(recognizedProperties); 351 352 fGrammarPool = grammarPool; 353 if(fGrammarPool != null){ 354 setProperty(XMLGRAMMAR_POOL, fGrammarPool); 355 } 356 357 fEntityManager = createEntityManager(); 358 setProperty(ENTITY_MANAGER, fEntityManager); 359 addComponent(fEntityManager); 360 361 fErrorReporter = createErrorReporter(); 362 fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner()); 363 setProperty(ERROR_REPORTER, fErrorReporter); 364 addComponent(fErrorReporter); 365 366 fScanner = createDocumentScanner(); 367 setProperty(DOCUMENT_SCANNER, fScanner); 368 if (fScanner instanceof XMLComponent) { 369 addComponent((XMLComponent)fScanner); 370 } 371 372 fDTDScanner = createDTDScanner(); 373 if (fDTDScanner != null) { 374 setProperty(DTD_SCANNER, fDTDScanner); 375 if (fDTDScanner instanceof XMLComponent) { 376 addComponent((XMLComponent)fDTDScanner); 377 } 378 } 379 380 fDTDProcessor = createDTDProcessor(); 381 if (fDTDProcessor != null) { 382 setProperty(DTD_PROCESSOR, fDTDProcessor); 383 if (fDTDProcessor instanceof XMLComponent) { 384 addComponent((XMLComponent)fDTDProcessor); 385 } 386 } 387 388 fDTDValidator = createDTDValidator(); 389 if (fDTDValidator != null) { 390 setProperty(DTD_VALIDATOR, fDTDValidator); 391 addComponent(fDTDValidator); 392 } 393 394 fNamespaceBinder = createNamespaceBinder(); 395 if (fNamespaceBinder != null) { 396 setProperty(NAMESPACE_BINDER, fNamespaceBinder); 397 addComponent(fNamespaceBinder); 398 } 399 400 fDatatypeValidatorFactory = createDatatypeValidatorFactory(); 401 if (fDatatypeValidatorFactory != null) { 402 setProperty(DATATYPE_VALIDATOR_FACTORY, 403 fDatatypeValidatorFactory); 404 } 405 fValidationManager = createValidationManager(); 406 407 if (fValidationManager != null) { 408 setProperty (VALIDATION_MANAGER, fValidationManager); 409 } 410 // add message formatters 411 if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { 412 XMLMessageFormatter xmft = new XMLMessageFormatter(); 413 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); 414 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); 415 } 416 417 // set locale 418 try { 419 setLocale(Locale.getDefault()); 420 } 421 catch (XNIException e) { 422 // do nothing 423 // REVISIT: What is the right thing to do? -Ac 424 } 425 426 setProperty(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); 427 428 // Initialize Catalog features 429 for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) { 430 setProperty(f.getPropertyName(), null); 431 } 432 } // <init>(SymbolTable,XMLGrammarPool) 433 434 // 435 // Public methods 436 // 437 438 public PropertyState getPropertyState(String propertyId) 439 throws XMLConfigurationException { 440 if (LOCALE.equals(propertyId)) { 441 return PropertyState.is(getLocale()); 442 } 443 return super.getPropertyState(propertyId); 444 } 445 446 public void setProperty(String propertyId, Object value) 447 throws XMLConfigurationException { 448 if (LOCALE.equals(propertyId)) { 449 setLocale((Locale) value); 450 } 451 super.setProperty(propertyId, value); 452 } 453 454 /** 455 * Set the locale to use for messages. 456 * 457 * @param locale The locale object to use for localization of messages. 458 * 459 * @exception XNIException Thrown if the parser does not support the 460 * specified locale. 461 */ 462 public void setLocale(Locale locale) throws XNIException { 463 super.setLocale(locale); 464 fErrorReporter.setLocale(locale); 465 } // setLocale(Locale) 466 467 // 468 // XMLPullParserConfiguration methods 469 // 470 471 // parsing 472 473 /** 474 * Sets the input source for the document to parse. 475 * 476 * @param inputSource The document's input source. 477 * 478 * @exception XMLConfigurationException Thrown if there is a 479 * configuration error when initializing the 480 * parser. 481 * @exception IOException Thrown on I/O error. 482 * 483 * @see #parse(boolean) 484 */ 485 public void setInputSource(XMLInputSource inputSource) 486 throws XMLConfigurationException, IOException { 487 488 // REVISIT: this method used to reset all the components and 489 // construct the pipeline. Now reset() is called 490 // in parse (boolean) just before we parse the document 491 // Should this method still throw exceptions..? 492 493 fInputSource = inputSource; 494 495 } // setInputSource(XMLInputSource) 496 497 /** 498 * Parses the document in a pull parsing fashion. 499 * 500 * @param complete True if the pull parser should parse the 501 * remaining document completely. 502 * 503 * @return True if there is more document to parse. 504 * 505 * @exception XNIException Any XNI exception, possibly wrapping 506 * another exception. 507 * @exception IOException An IO exception from the parser, possibly 508 * from a byte stream or character stream 509 * supplied by the parser. 510 * 511 * @see #setInputSource 512 */ 513 public boolean parse(boolean complete) throws XNIException, IOException { 514 // 515 // reset and configure pipeline and set InputSource. 516 if (fInputSource !=null) { 517 try { 518 // resets and sets the pipeline. 519 reset(); 520 fScanner.setInputSource(fInputSource); 521 fInputSource = null; 522 } 523 catch (XNIException ex) { 524 if (PRINT_EXCEPTION_STACK_TRACE) 525 ex.printStackTrace(); 526 throw ex; 527 } 528 catch (IOException ex) { 529 if (PRINT_EXCEPTION_STACK_TRACE) 530 ex.printStackTrace(); 531 throw ex; 532 } 533 catch (RuntimeException ex) { 534 if (PRINT_EXCEPTION_STACK_TRACE) 535 ex.printStackTrace(); 536 throw ex; 537 } 538 catch (Exception ex) { 539 if (PRINT_EXCEPTION_STACK_TRACE) 540 ex.printStackTrace(); 541 throw new XNIException(ex); 542 } 543 } 544 545 try { 546 return fScanner.scanDocument(complete); 547 } 548 catch (XNIException ex) { 549 if (PRINT_EXCEPTION_STACK_TRACE) 550 ex.printStackTrace(); 551 throw ex; 552 } 553 catch (IOException ex) { 554 if (PRINT_EXCEPTION_STACK_TRACE) 555 ex.printStackTrace(); 556 throw ex; 557 } 558 catch (RuntimeException ex) { 559 if (PRINT_EXCEPTION_STACK_TRACE) 560 ex.printStackTrace(); 561 throw ex; 562 } 563 catch (Exception ex) { 564 if (PRINT_EXCEPTION_STACK_TRACE) 565 ex.printStackTrace(); 566 throw new XNIException(ex); 567 } 568 569 } // parse(boolean):boolean 570 571 /** 572 * If the application decides to terminate parsing before the xml document 573 * is fully parsed, the application should call this method to free any 574 * resource allocated during parsing. For example, close all opened streams. 575 */ 576 public void cleanup() { 577 fEntityManager.closeReaders(); 578 } 579 580 // 581 // XMLParserConfiguration methods 582 // 583 584 /** 585 * Parses the specified input source. 586 * 587 * @param source The input source. 588 * 589 * @exception XNIException Throws exception on XNI error. 590 * @exception java.io.IOException Throws exception on i/o error. 591 */ 592 public void parse(XMLInputSource source) throws XNIException, IOException { 593 594 if (fParseInProgress) { 595 // REVISIT - need to add new error message 596 throw new XNIException("FWK005 parse may not be called while parsing."); 597 } 598 fParseInProgress = true; 599 600 try { 601 setInputSource(source); 602 parse(true); 603 } 604 catch (XNIException ex) { 605 if (PRINT_EXCEPTION_STACK_TRACE) 606 ex.printStackTrace(); 607 throw ex; 608 } 609 catch (IOException ex) { 610 if (PRINT_EXCEPTION_STACK_TRACE) 611 ex.printStackTrace(); 612 throw ex; 613 } 614 catch (RuntimeException ex) { 615 if (PRINT_EXCEPTION_STACK_TRACE) 616 ex.printStackTrace(); 617 throw ex; 618 } 619 catch (Exception ex) { 620 if (PRINT_EXCEPTION_STACK_TRACE) 621 ex.printStackTrace(); 622 throw new XNIException(ex); 623 } 624 finally { 625 fParseInProgress = false; 626 // close all streams opened by xerces 627 this.cleanup(); 628 } 629 630 } // parse(InputSource) 631 632 // 633 // Protected methods 634 // 635 636 /** 637 * Reset all components before parsing. 638 * 639 * @throws XNIException Thrown if an error occurs during initialization. 640 */ 641 protected void reset() throws XNIException { 642 643 if (fValidationManager != null) 644 fValidationManager.reset(); 645 // configure the pipeline and initialize the components 646 configurePipeline(); 647 super.reset(); 648 } // reset() 649 650 /** Configures the pipeline. */ 651 protected void configurePipeline() { 652 653 // REVISIT: This should be better designed. In other words, we 654 // need to figure out what is the best way for people to 655 // re-use *most* of the standard configuration but do 656 // things common things such as remove a component (e.g. 657 // the validator), insert a new component (e.g. XInclude), 658 // etc... -Ac 659 660 // setup document pipeline 661 if (fDTDValidator != null) { 662 fScanner.setDocumentHandler(fDTDValidator); 663 if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { 664 665 // filters 666 fDTDValidator.setDocumentHandler(fNamespaceBinder); 667 fDTDValidator.setDocumentSource(fScanner); 668 fNamespaceBinder.setDocumentHandler(fDocumentHandler); 669 fNamespaceBinder.setDocumentSource(fDTDValidator); 670 fLastComponent = fNamespaceBinder; 671 } 672 else { 673 fDTDValidator.setDocumentHandler(fDocumentHandler); 674 fDTDValidator.setDocumentSource(fScanner); 675 fLastComponent = fDTDValidator; 676 } 677 } 678 else { 679 if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { 680 fScanner.setDocumentHandler(fNamespaceBinder); 681 fNamespaceBinder.setDocumentHandler(fDocumentHandler); 682 fNamespaceBinder.setDocumentSource(fScanner); 683 fLastComponent = fNamespaceBinder; 684 } 685 else { 686 fScanner.setDocumentHandler(fDocumentHandler); 687 fLastComponent = fScanner; 688 } 689 } 690 691 configureDTDPipeline(); 692 } // configurePipeline() 693 694 protected void configureDTDPipeline (){ 695 696 // setup dtd pipeline 697 if (fDTDScanner != null) { 698 fProperties.put(DTD_SCANNER, fDTDScanner); 699 if (fDTDProcessor != null) { 700 fProperties.put(DTD_PROCESSOR, fDTDProcessor); 701 fDTDScanner.setDTDHandler(fDTDProcessor); 702 fDTDProcessor.setDTDSource(fDTDScanner); 703 fDTDProcessor.setDTDHandler(fDTDHandler); 704 if (fDTDHandler != null) { 705 fDTDHandler.setDTDSource(fDTDProcessor); 706 } 707 708 fDTDScanner.setDTDContentModelHandler(fDTDProcessor); 709 fDTDProcessor.setDTDContentModelSource(fDTDScanner); 710 fDTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler); 711 if (fDTDContentModelHandler != null) { 712 fDTDContentModelHandler.setDTDContentModelSource(fDTDProcessor); 713 } 714 } 715 else { 716 fDTDScanner.setDTDHandler(fDTDHandler); 717 if (fDTDHandler != null) { 718 fDTDHandler.setDTDSource(fDTDScanner); 719 } 720 fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); 721 if (fDTDContentModelHandler != null) { 722 fDTDContentModelHandler.setDTDContentModelSource(fDTDScanner); 723 } 724 } 725 } 726 727 728 } 729 730 // features and properties 731 732 /** 733 * Check a feature. If feature is know and supported, this method simply 734 * returns. Otherwise, the appropriate exception is thrown. 735 * 736 * @param featureId The unique identifier (URI) of the feature. 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 FeatureState checkFeature(String featureId) 745 throws XMLConfigurationException { 746 747 // 748 // Xerces Features 749 // 750 751 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 752 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 753 754 // 755 // http://apache.org/xml/features/validation/dynamic 756 // Allows the parser to validate a document only when it 757 // contains a grammar. Validation is turned on/off based 758 // on each document instance, automatically. 759 // 760 if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() && 761 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) { 762 return FeatureState.RECOGNIZED; 763 } 764 765 // 766 // http://apache.org/xml/features/validation/default-attribute-values 767 // 768 if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() && 769 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) { 770 // REVISIT 771 return FeatureState.NOT_SUPPORTED; 772 } 773 // 774 // http://apache.org/xml/features/validation/default-attribute-values 775 // 776 if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() && 777 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) { 778 // REVISIT 779 return FeatureState.NOT_SUPPORTED; 780 } 781 // 782 // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar 783 // 784 if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() && 785 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) { 786 return FeatureState.RECOGNIZED; 787 } 788 // 789 // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd 790 // 791 if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && 792 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) { 793 return FeatureState.RECOGNIZED; 794 } 795 796 // 797 // http://apache.org/xml/features/validation/default-attribute-values 798 // 799 if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() && 800 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) { 801 return FeatureState.NOT_SUPPORTED; 802 } 803 } 804 805 // 806 // Not recognized 807 // 808 809 return super.checkFeature(featureId); 810 811 } // checkFeature(String) 812 813 /** 814 * Check a property. If the property is know and supported, this method 815 * simply returns. Otherwise, the appropriate exception is thrown. 816 * 817 * @param propertyId The unique identifier (URI) of the property 818 * being set. 819 * 820 * @throws XMLConfigurationException Thrown for configuration error. 821 * In general, components should 822 * only throw this exception if 823 * it is <strong>really</strong> 824 * a critical error. 825 */ 826 protected PropertyState checkProperty(String propertyId) 827 throws XMLConfigurationException { 828 829 // 830 // Xerces Properties 831 // 832 833 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 834 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 835 836 if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && 837 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) { 838 return PropertyState.RECOGNIZED; 839 } 840 } 841 842 // 843 // Not recognized 844 // 845 846 return super.checkProperty(propertyId); 847 848 } // checkProperty(String) 849 850 // factory methods 851 852 /** Creates an entity manager. */ 853 protected XMLEntityManager createEntityManager() { 854 return new XMLEntityManager(); 855 } // createEntityManager():XMLEntityManager 856 857 /** Creates an error reporter. */ 858 protected XMLErrorReporter createErrorReporter() { 859 return new XMLErrorReporter(); 860 } // createErrorReporter():XMLErrorReporter 861 862 /** Create a document scanner. */ 863 protected XMLDocumentScanner createDocumentScanner() { 864 return new XMLDocumentScannerImpl(); 865 } // createDocumentScanner():XMLDocumentScanner 866 867 /** Create a DTD scanner. */ 868 protected XMLDTDScanner createDTDScanner() { 869 return new XMLDTDScannerImpl(); 870 } // createDTDScanner():XMLDTDScanner 871 872 /** Create a DTD loader . */ 873 protected XMLDTDProcessor createDTDProcessor() { 874 return new XMLDTDProcessor(); 875 } // createDTDProcessor():XMLDTDProcessor 876 877 /** Create a DTD validator. */ 878 protected XMLDTDValidator createDTDValidator() { 879 return new XMLDTDValidator(); 880 } // createDTDValidator():XMLDTDValidator 881 882 /** Create a namespace binder. */ 883 protected XMLNamespaceBinder createNamespaceBinder() { 884 return new XMLNamespaceBinder(); 885 } // createNamespaceBinder():XMLNamespaceBinder 886 887 /** Create a datatype validator factory. */ 888 protected DTDDVFactory createDatatypeValidatorFactory() { 889 return DTDDVFactory.getInstance(); 890 } // createDatatypeValidatorFactory():DatatypeValidatorFactory 891 protected ValidationManager createValidationManager(){ 892 return new ValidationManager(); 893 } 894 895 } // class DTDConfiguration