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