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