1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 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.ArrayList; 25 import java.util.HashMap; 26 import java.util.Locale; 27 28 import com.sun.org.apache.xerces.internal.impl.Constants; 29 import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl; 30 import com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl; 31 import com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl; 32 import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl; 33 import com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl; 34 import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; 35 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; 36 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; 37 import com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl; 38 import com.sun.org.apache.xerces.internal.impl.XMLVersionDetector; 39 import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory; 40 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 41 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; 42 import com.sun.org.apache.xerces.internal.util.FeatureState; 43 import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; 44 import com.sun.org.apache.xerces.internal.util.PropertyState; 45 import com.sun.org.apache.xerces.internal.util.Status; 46 import com.sun.org.apache.xerces.internal.util.SymbolTable; 47 import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; 48 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; 49 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; 50 import com.sun.org.apache.xerces.internal.xni.XMLLocator; 51 import com.sun.org.apache.xerces.internal.xni.XNIException; 52 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; 53 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; 54 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 55 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 56 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner; 57 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner; 58 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; 59 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; 60 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; 61 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 62 import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration; 63 64 /** 65 * This class is the non vlaidating parser configuration 66 * used to parse XML 1.0 and XML 1.1 documents. 67 * 68 * Xerces parser that uses this configuration is <strong>not</strong> <a href="http://www.w3.org/TR/REC-xml#sec-conformance">conformant</a> 69 * non-validating XML processor, since conformant non-validating processor is required 70 * to process "all the declarations they read in the internal DTD subset ... must use the information in those declarations to normalize attribute values, 71 * include the replacement text of internal entities, and supply default attribute values". 72 73 * @author Elena Litani, IBM 74 * @author John Kim, IBM 75 * @author Michael Glavassevich, IBM 76 * 77 * @version $Id: XML11NonValidatingConfiguration.java,v 1.5 2010-11-01 04:40:10 joehw Exp $ 78 */ 79 public class XML11NonValidatingConfiguration extends ParserConfigurationSettings 80 implements XMLPullParserConfiguration, XML11Configurable { 81 82 // 83 // Constants 84 // 85 protected final static String XML11_DATATYPE_VALIDATOR_FACTORY = 86 "com.sun.org.apache.xerces.internal.impl.dv.dtd.XML11DTDDVFactoryImpl"; 87 88 // feature identifiers 89 90 /** Feature identifier: validation. */ 91 protected static final String VALIDATION = 92 Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE; 93 94 /** Feature identifier: namespaces. */ 95 protected static final String NAMESPACES = 96 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE; 97 98 /** Feature identifier: external general entities. */ 99 protected static final String EXTERNAL_GENERAL_ENTITIES = 100 Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE; 101 102 /** Feature identifier: external parameter entities. */ 103 protected static final String EXTERNAL_PARAMETER_ENTITIES = 104 Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE; 105 106 107 /** Feature identifier: continue after fatal error. */ 108 protected static final String CONTINUE_AFTER_FATAL_ERROR = 109 Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE; 110 111 112 // property identifiers 113 114 /** Property identifier: xml string. */ 115 protected static final String XML_STRING = 116 Constants.SAX_PROPERTY_PREFIX + Constants.XML_STRING_PROPERTY; 117 118 /** Property identifier: symbol table. */ 119 protected static final String SYMBOL_TABLE = 120 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; 121 122 /** Property identifier: error handler. */ 123 protected static final String ERROR_HANDLER = 124 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY; 125 126 /** Property identifier: entity resolver. */ 127 protected static final String ENTITY_RESOLVER = 128 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; 129 130 /** Property identifier: error reporter. */ 131 protected static final String ERROR_REPORTER = 132 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 133 134 /** Property identifier: entity manager. */ 135 protected static final String ENTITY_MANAGER = 136 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; 137 138 /** Property identifier document scanner: */ 139 protected static final String DOCUMENT_SCANNER = 140 Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY; 141 142 /** Property identifier: DTD scanner. */ 143 protected static final String DTD_SCANNER = 144 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY; 145 146 /** Property identifier: grammar pool. */ 147 protected static final String XMLGRAMMAR_POOL = 148 Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; 149 150 /** Property identifier: DTD validator. */ 151 protected static final String DTD_VALIDATOR = 152 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY; 153 154 /** Property identifier: namespace binder. */ 155 protected static final String NAMESPACE_BINDER = 156 Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY; 157 158 /** Property identifier: datatype validator factory. */ 159 protected static final String DATATYPE_VALIDATOR_FACTORY = 160 Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY; 161 162 protected static final String VALIDATION_MANAGER = 163 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 164 165 // debugging 166 167 /** Set to true and recompile to print exception stack trace. */ 168 protected static final boolean PRINT_EXCEPTION_STACK_TRACE = false; 169 170 // 171 // Data 172 // 173 protected SymbolTable fSymbolTable; 174 protected XMLInputSource fInputSource; 175 protected ValidationManager fValidationManager; 176 protected XMLVersionDetector fVersionDetector; 177 protected XMLLocator fLocator; 178 protected Locale fLocale; 179 180 /** XML 1.0 Components. */ 181 protected ArrayList fComponents; 182 183 /** XML 1.1. Components. */ 184 protected ArrayList fXML11Components = null; 185 186 /** Common components: XMLEntityManager, XMLErrorReporter */ 187 protected ArrayList fCommonComponents = null; 188 189 /** The document handler. */ 190 protected XMLDocumentHandler fDocumentHandler; 191 192 /** The DTD handler. */ 193 protected XMLDTDHandler fDTDHandler; 194 195 /** The DTD content model handler. */ 196 protected XMLDTDContentModelHandler fDTDContentModelHandler; 197 198 /** Last component in the document pipeline */ 199 protected XMLDocumentSource fLastComponent; 200 201 /** 202 * True if a parse is in progress. This state is needed because 203 * some features/properties cannot be set while parsing (e.g. 204 * namespaces). 205 */ 206 protected boolean fParseInProgress = false; 207 208 /** fConfigUpdated is set to true if there has been any change to the configuration settings, 209 * i.e a feature or a property was changed. 210 */ 211 protected boolean fConfigUpdated = false; 212 213 // 214 // XML 1.0 components 215 // 216 217 /** The XML 1.0 Datatype validator factory. */ 218 protected DTDDVFactory fDatatypeValidatorFactory; 219 220 /** The XML 1.0 Document scanner that does namespace binding. */ 221 protected XMLNSDocumentScannerImpl fNamespaceScanner; 222 223 /** The XML 1.0 Non-namespace implementation of scanner */ 224 protected XMLDocumentScannerImpl fNonNSScanner; 225 226 /** The XML 1.0 DTD scanner. */ 227 protected XMLDTDScanner fDTDScanner; 228 229 // 230 // XML 1.1 components 231 // 232 233 /** The XML 1.1 datatype factory. **/ 234 protected DTDDVFactory fXML11DatatypeFactory = null; 235 236 /** The XML 1.1 document scanner that does namespace binding. **/ 237 protected XML11NSDocumentScannerImpl fXML11NSDocScanner = null; 238 239 /** The XML 1.1 document scanner that does not do namespace binding. **/ 240 protected XML11DocumentScannerImpl fXML11DocScanner = null; 241 242 /** The XML 1.1 DTD scanner. **/ 243 protected XML11DTDScannerImpl fXML11DTDScanner = null; 244 245 // 246 // Common components 247 // 248 249 /** Grammar pool. */ 250 protected XMLGrammarPool fGrammarPool; 251 252 /** Error reporter. */ 253 protected XMLErrorReporter fErrorReporter; 254 255 /** Entity manager. */ 256 protected XMLEntityManager fEntityManager; 257 258 /** Current scanner */ 259 protected XMLDocumentScanner fCurrentScanner; 260 261 /** Current Datatype validator factory. */ 262 protected DTDDVFactory fCurrentDVFactory; 263 264 /** Current DTD scanner. */ 265 protected XMLDTDScanner fCurrentDTDScanner; 266 267 268 /** Flag indiciating whether XML11 components have been initialized. */ 269 private boolean f11Initialized = false; 270 271 // 272 // Constructors 273 // 274 275 /** Default constructor. */ 276 public XML11NonValidatingConfiguration() { 277 this(null, null, null); 278 } // <init>() 279 280 /** 281 * Constructs a parser configuration using the specified symbol table. 282 * 283 * @param symbolTable The symbol table to use. 284 */ 285 public XML11NonValidatingConfiguration(SymbolTable symbolTable) { 286 this(symbolTable, null, null); 287 } // <init>(SymbolTable) 288 289 /** 290 * Constructs a parser configuration using the specified symbol table and 291 * grammar pool. 292 * <p> 293 * <strong>REVISIT:</strong> 294 * Grammar pool will be updated when the new validation engine is 295 * implemented. 296 * 297 * @param symbolTable The symbol table to use. 298 * @param grammarPool The grammar pool to use. 299 */ 300 public XML11NonValidatingConfiguration(SymbolTable symbolTable, XMLGrammarPool grammarPool) { 301 this(symbolTable, grammarPool, null); 302 } // <init>(SymbolTable,XMLGrammarPool) 303 304 /** 305 * Constructs a parser configuration using the specified symbol table, 306 * grammar pool, and parent settings. 307 * <p> 308 * <strong>REVISIT:</strong> 309 * Grammar pool will be updated when the new validation engine is 310 * implemented. 311 * 312 * @param symbolTable The symbol table to use. 313 * @param grammarPool The grammar pool to use. 314 * @param parentSettings The parent settings. 315 */ 316 public XML11NonValidatingConfiguration( 317 SymbolTable symbolTable, 318 XMLGrammarPool grammarPool, 319 XMLComponentManager parentSettings) { 320 321 super(parentSettings); 322 323 // create a vector to hold all the components in use 324 // XML 1.0 specialized components 325 fComponents = new ArrayList(); 326 // XML 1.1 specialized components 327 fXML11Components = new ArrayList(); 328 // Common components for XML 1.1. and XML 1.0 329 fCommonComponents = new ArrayList(); 330 331 // create table for features and properties 332 fFeatures = new HashMap(); 333 fProperties = new HashMap(); 334 335 // add default recognized features 336 final String[] recognizedFeatures = 337 { 338 CONTINUE_AFTER_FATAL_ERROR, // from XMLDTDScannerImpl 339 VALIDATION, 340 NAMESPACES, 341 EXTERNAL_GENERAL_ENTITIES, 342 EXTERNAL_PARAMETER_ENTITIES, 343 PARSER_SETTINGS 344 }; 345 addRecognizedFeatures(recognizedFeatures); 346 347 // set state for default features 348 fFeatures.put(VALIDATION, Boolean.FALSE); 349 fFeatures.put(NAMESPACES, Boolean.TRUE); 350 fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE); 351 fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE); 352 fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE); 353 fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); 354 355 // add default recognized properties 356 final String[] recognizedProperties = 357 { 358 XML_STRING, 359 SYMBOL_TABLE, 360 ERROR_HANDLER, 361 ENTITY_RESOLVER, 362 ERROR_REPORTER, 363 ENTITY_MANAGER, 364 DOCUMENT_SCANNER, 365 DTD_SCANNER, 366 DTD_VALIDATOR, 367 DATATYPE_VALIDATOR_FACTORY, 368 VALIDATION_MANAGER, 369 XML_STRING, 370 XMLGRAMMAR_POOL, }; 371 addRecognizedProperties(recognizedProperties); 372 373 if (symbolTable == null) { 374 symbolTable = new SymbolTable(); 375 } 376 fSymbolTable = symbolTable; 377 fProperties.put(SYMBOL_TABLE, fSymbolTable); 378 379 fGrammarPool = grammarPool; 380 if (fGrammarPool != null) { 381 fProperties.put(XMLGRAMMAR_POOL, fGrammarPool); 382 } 383 384 fEntityManager = new XMLEntityManager(); 385 fProperties.put(ENTITY_MANAGER, fEntityManager); 386 addCommonComponent(fEntityManager); 387 388 fErrorReporter = new XMLErrorReporter(); 389 fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner()); 390 fProperties.put(ERROR_REPORTER, fErrorReporter); 391 addCommonComponent(fErrorReporter); 392 393 fNamespaceScanner = new XMLNSDocumentScannerImpl(); 394 fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner); 395 addComponent((XMLComponent) fNamespaceScanner); 396 397 fDTDScanner = new XMLDTDScannerImpl(); 398 fProperties.put(DTD_SCANNER, fDTDScanner); 399 addComponent((XMLComponent) fDTDScanner); 400 401 fDatatypeValidatorFactory = DTDDVFactory.getInstance(); 402 fProperties.put(DATATYPE_VALIDATOR_FACTORY, fDatatypeValidatorFactory); 403 404 fValidationManager = new ValidationManager(); 405 fProperties.put(VALIDATION_MANAGER, fValidationManager); 406 407 fVersionDetector = new XMLVersionDetector(); 408 409 // add message formatters 410 if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { 411 XMLMessageFormatter xmft = new XMLMessageFormatter(); 412 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); 413 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); 414 } 415 416 // set locale 417 try { 418 setLocale(Locale.getDefault()); 419 } catch (XNIException e) { 420 // do nothing 421 // REVISIT: What is the right thing to do? -Ac 422 } 423 424 fConfigUpdated = false; 425 426 } // <init>(SymbolTable,XMLGrammarPool) 427 428 /** 429 * Sets the input source for the document to parse. 430 * 431 * @param inputSource The document's input source. 432 * 433 * @exception XMLConfigurationException Thrown if there is a 434 * configuration error when initializing the 435 * parser. 436 * @exception IOException Thrown on I/O error. 437 * 438 * @see #parse(boolean) 439 */ 440 public void setInputSource(XMLInputSource inputSource) 441 throws XMLConfigurationException, IOException { 442 443 // REVISIT: this method used to reset all the components and 444 // construct the pipeline. Now reset() is called 445 // in parse (boolean) just before we parse the document 446 // Should this method still throw exceptions..? 447 448 fInputSource = inputSource; 449 450 } // setInputSource(XMLInputSource) 451 452 /** 453 * Set the locale to use for messages. 454 * 455 * @param locale The locale object to use for localization of messages. 456 * 457 * @exception XNIException Thrown if the parser does not support the 458 * specified locale. 459 */ 460 public void setLocale(Locale locale) throws XNIException { 461 fLocale = locale; 462 fErrorReporter.setLocale(locale); 463 } // setLocale(Locale) 464 465 /** 466 * Sets the document handler on the last component in the pipeline 467 * to receive information about the document. 468 * 469 * @param documentHandler The document handler. 470 */ 471 public void setDocumentHandler(XMLDocumentHandler documentHandler) { 472 fDocumentHandler = documentHandler; 473 if (fLastComponent != null) { 474 fLastComponent.setDocumentHandler(fDocumentHandler); 475 if (fDocumentHandler !=null){ 476 fDocumentHandler.setDocumentSource(fLastComponent); 477 } 478 } 479 } // setDocumentHandler(XMLDocumentHandler) 480 481 /** Returns the registered document handler. */ 482 public XMLDocumentHandler getDocumentHandler() { 483 return fDocumentHandler; 484 } // getDocumentHandler():XMLDocumentHandler 485 486 /** 487 * Sets the DTD handler. 488 * 489 * @param dtdHandler The DTD handler. 490 */ 491 public void setDTDHandler(XMLDTDHandler dtdHandler) { 492 fDTDHandler = dtdHandler; 493 } // setDTDHandler(XMLDTDHandler) 494 495 /** Returns the registered DTD handler. */ 496 public XMLDTDHandler getDTDHandler() { 497 return fDTDHandler; 498 } // getDTDHandler():XMLDTDHandler 499 500 /** 501 * Sets the DTD content model handler. 502 * 503 * @param handler The DTD content model handler. 504 */ 505 public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) { 506 fDTDContentModelHandler = handler; 507 } // setDTDContentModelHandler(XMLDTDContentModelHandler) 508 509 /** Returns the registered DTD content model handler. */ 510 public XMLDTDContentModelHandler getDTDContentModelHandler() { 511 return fDTDContentModelHandler; 512 } // getDTDContentModelHandler():XMLDTDContentModelHandler 513 514 /** 515 * Sets the resolver used to resolve external entities. The EntityResolver 516 * interface supports resolution of public and system identifiers. 517 * 518 * @param resolver The new entity resolver. Passing a null value will 519 * uninstall the currently installed resolver. 520 */ 521 public void setEntityResolver(XMLEntityResolver resolver) { 522 fProperties.put(ENTITY_RESOLVER, resolver); 523 } // setEntityResolver(XMLEntityResolver) 524 525 /** 526 * Return the current entity resolver. 527 * 528 * @return The current entity resolver, or null if none 529 * has been registered. 530 * @see #setEntityResolver 531 */ 532 public XMLEntityResolver getEntityResolver() { 533 return (XMLEntityResolver)fProperties.get(ENTITY_RESOLVER); 534 } // getEntityResolver():XMLEntityResolver 535 536 /** 537 * Allow an application to register an error event handler. 538 * 539 * <p>If the application does not register an error handler, all 540 * error events reported by the SAX parser will be silently 541 * ignored; however, normal processing may not continue. It is 542 * highly recommended that all SAX applications implement an 543 * error handler to avoid unexpected bugs.</p> 544 * 545 * <p>Applications may register a new or different handler in the 546 * middle of a parse, and the SAX parser must begin using the new 547 * handler immediately.</p> 548 * 549 * @param errorHandler The error handler. 550 * @exception java.lang.NullPointerException If the handler 551 * argument is null. 552 * @see #getErrorHandler 553 */ 554 public void setErrorHandler(XMLErrorHandler errorHandler) { 555 fProperties.put(ERROR_HANDLER, errorHandler); 556 } // setErrorHandler(XMLErrorHandler) 557 558 /** 559 * Return the current error handler. 560 * 561 * @return The current error handler, or null if none 562 * has been registered. 563 * @see #setErrorHandler 564 */ 565 public XMLErrorHandler getErrorHandler() { 566 // REVISIT: Should this be a property? 567 return (XMLErrorHandler)fProperties.get(ERROR_HANDLER); 568 } // getErrorHandler():XMLErrorHandler 569 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 * Parses the specified input source. 582 * 583 * @param source The input source. 584 * 585 * @exception XNIException Throws exception on XNI error. 586 * @exception java.io.IOException Throws exception on i/o error. 587 */ 588 public void parse(XMLInputSource source) throws XNIException, IOException { 589 590 if (fParseInProgress) { 591 // REVISIT - need to add new error message 592 throw new XNIException("FWK005 parse may not be called while parsing."); 593 } 594 fParseInProgress = true; 595 596 try { 597 setInputSource(source); 598 parse(true); 599 } catch (XNIException ex) { 600 if (PRINT_EXCEPTION_STACK_TRACE) 601 ex.printStackTrace(); 602 throw ex; 603 } catch (IOException ex) { 604 if (PRINT_EXCEPTION_STACK_TRACE) 605 ex.printStackTrace(); 606 throw ex; 607 } catch (RuntimeException ex) { 608 if (PRINT_EXCEPTION_STACK_TRACE) 609 ex.printStackTrace(); 610 throw ex; 611 } catch (Exception ex) { 612 if (PRINT_EXCEPTION_STACK_TRACE) 613 ex.printStackTrace(); 614 throw new XNIException(ex); 615 } finally { 616 fParseInProgress = false; 617 // close all streams opened by xerces 618 this.cleanup(); 619 } 620 621 } // parse(InputSource) 622 623 public boolean parse(boolean complete) throws XNIException, IOException { 624 // 625 // reset and configure pipeline and set InputSource. 626 if (fInputSource != null) { 627 try { 628 fValidationManager.reset(); 629 fVersionDetector.reset(this); 630 resetCommon(); 631 632 short version = fVersionDetector.determineDocVersion(fInputSource); 633 if (version == Constants.XML_VERSION_1_1) { 634 initXML11Components(); 635 configureXML11Pipeline(); 636 resetXML11(); 637 } else { 638 configurePipeline(); 639 reset(); 640 } 641 642 // mark configuration as fixed 643 fConfigUpdated = false; 644 645 // resets and sets the pipeline. 646 fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version); 647 fInputSource = null; 648 } catch (XNIException ex) { 649 if (PRINT_EXCEPTION_STACK_TRACE) 650 ex.printStackTrace(); 651 throw ex; 652 } catch (IOException ex) { 653 if (PRINT_EXCEPTION_STACK_TRACE) 654 ex.printStackTrace(); 655 throw ex; 656 } catch (RuntimeException ex) { 657 if (PRINT_EXCEPTION_STACK_TRACE) 658 ex.printStackTrace(); 659 throw ex; 660 } catch (Exception ex) { 661 if (PRINT_EXCEPTION_STACK_TRACE) 662 ex.printStackTrace(); 663 throw new XNIException(ex); 664 } 665 } 666 667 try { 668 return fCurrentScanner.scanDocument(complete); 669 } catch (XNIException ex) { 670 if (PRINT_EXCEPTION_STACK_TRACE) 671 ex.printStackTrace(); 672 throw ex; 673 } catch (IOException ex) { 674 if (PRINT_EXCEPTION_STACK_TRACE) 675 ex.printStackTrace(); 676 throw ex; 677 } catch (RuntimeException ex) { 678 if (PRINT_EXCEPTION_STACK_TRACE) 679 ex.printStackTrace(); 680 throw ex; 681 } catch (Exception ex) { 682 if (PRINT_EXCEPTION_STACK_TRACE) 683 ex.printStackTrace(); 684 throw new XNIException(ex); 685 } 686 687 } // parse(boolean):boolean 688 689 /** 690 * Returns the state of a feature. 691 * 692 * @param featureId The feature identifier. 693 * @return true if the feature is supported 694 * 695 * @throws XMLConfigurationException Thrown for configuration error. 696 * In general, components should 697 * only throw this exception if 698 * it is <strong>really</strong> 699 * a critical error. 700 */ 701 public FeatureState getFeatureState(String featureId) 702 throws XMLConfigurationException { 703 // make this feature special 704 if (featureId.equals(PARSER_SETTINGS)){ 705 return FeatureState.is(fConfigUpdated); 706 } 707 return super.getFeatureState(featureId); 708 709 } // getFeature(String):boolean 710 711 /** 712 * Set the state of a feature. 713 * 714 * Set the state of any feature in a SAX2 parser. The parser 715 * might not recognize the feature, and if it does recognize 716 * it, it might not be able to fulfill the request. 717 * 718 * @param featureId The unique identifier (URI) of the feature. 719 * @param state The requested state of the feature (true or false). 720 * 721 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 722 * requested feature is not known. 723 */ 724 public void setFeature(String featureId, boolean state) 725 throws XMLConfigurationException { 726 fConfigUpdated = true; 727 // forward to every XML 1.0 component 728 int count = fComponents.size(); 729 for (int i = 0; i < count; i++) { 730 XMLComponent c = (XMLComponent) fComponents.get(i); 731 c.setFeature(featureId, state); 732 } 733 // forward it to common components 734 count = fCommonComponents.size(); 735 for (int i = 0; i < count; i++) { 736 XMLComponent c = (XMLComponent) fCommonComponents.get(i); 737 c.setFeature(featureId, state); 738 } 739 740 // forward to every XML 1.1 component 741 count = fXML11Components.size(); 742 for (int i = 0; i < count; i++) { 743 XMLComponent c = (XMLComponent) fXML11Components.get(i); 744 try{ 745 c.setFeature(featureId, state); 746 } 747 catch (Exception e){ 748 // no op 749 } 750 } 751 // save state if noone "objects" 752 super.setFeature(featureId, state); 753 754 } // setFeature(String,boolean) 755 756 /** 757 * setProperty 758 * 759 * @param propertyId 760 * @param value 761 */ 762 public void setProperty(String propertyId, Object value) 763 throws XMLConfigurationException { 764 fConfigUpdated = true; 765 // forward to every XML 1.0 component 766 int count = fComponents.size(); 767 for (int i = 0; i < count; i++) { 768 XMLComponent c = (XMLComponent) fComponents.get(i); 769 c.setProperty(propertyId, value); 770 } 771 // forward it to every common Component 772 count = fCommonComponents.size(); 773 for (int i = 0; i < count; i++) { 774 XMLComponent c = (XMLComponent) fCommonComponents.get(i); 775 c.setProperty(propertyId, value); 776 } 777 // forward it to every XML 1.1 component 778 count = fXML11Components.size(); 779 for (int i = 0; i < count; i++) { 780 XMLComponent c = (XMLComponent) fXML11Components.get(i); 781 try{ 782 c.setProperty(propertyId, value); 783 } 784 catch (Exception e){ 785 // ignore it 786 } 787 } 788 789 // store value if noone "objects" 790 super.setProperty(propertyId, value); 791 792 } // setProperty(String,Object) 793 794 795 /** Returns the locale. */ 796 public Locale getLocale() { 797 return fLocale; 798 } // getLocale():Locale 799 800 /** 801 * reset all XML 1.0 components before parsing and namespace context 802 */ 803 protected void reset() throws XNIException { 804 int count = fComponents.size(); 805 for (int i = 0; i < count; i++) { 806 XMLComponent c = (XMLComponent) fComponents.get(i); 807 c.reset(this); 808 } 809 810 } // reset() 811 812 /** 813 * reset all common components before parsing 814 */ 815 protected void resetCommon() throws XNIException { 816 // reset common components 817 int count = fCommonComponents.size(); 818 for (int i = 0; i < count; i++) { 819 XMLComponent c = (XMLComponent) fCommonComponents.get(i); 820 c.reset(this); 821 } 822 823 } // resetCommon() 824 825 826 /** 827 * reset all components before parsing and namespace context 828 */ 829 protected void resetXML11() throws XNIException { 830 // reset every component 831 int count = fXML11Components.size(); 832 for (int i = 0; i < count; i++) { 833 XMLComponent c = (XMLComponent) fXML11Components.get(i); 834 c.reset(this); 835 } 836 837 } // resetXML11() 838 839 840 /** 841 * Configures the XML 1.1 pipeline. 842 * Note: this method also resets the new XML11 components. 843 */ 844 protected void configureXML11Pipeline() { 845 if (fCurrentDVFactory != fXML11DatatypeFactory) { 846 fCurrentDVFactory = fXML11DatatypeFactory; 847 setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory); 848 } 849 850 // setup DTD pipeline 851 if (fCurrentDTDScanner != fXML11DTDScanner) { 852 fCurrentDTDScanner = fXML11DTDScanner; 853 setProperty(DTD_SCANNER, fCurrentDTDScanner); 854 } 855 fXML11DTDScanner.setDTDHandler(fDTDHandler); 856 fXML11DTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); 857 858 // setup XML 1.1 document pipeline 859 if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { 860 if (fCurrentScanner != fXML11NSDocScanner) { 861 fCurrentScanner = fXML11NSDocScanner; 862 setProperty(DOCUMENT_SCANNER, fXML11NSDocScanner); 863 } 864 865 fXML11NSDocScanner.setDTDValidator(null); 866 fXML11NSDocScanner.setDocumentHandler(fDocumentHandler); 867 if (fDocumentHandler != null) { 868 fDocumentHandler.setDocumentSource(fXML11NSDocScanner); 869 } 870 fLastComponent = fXML11NSDocScanner; 871 872 } else { 873 // create components 874 if (fXML11DocScanner == null) { 875 // non namespace document pipeline 876 fXML11DocScanner = new XML11DocumentScannerImpl(); 877 addXML11Component(fXML11DocScanner); 878 } 879 if (fCurrentScanner != fXML11DocScanner) { 880 fCurrentScanner = fXML11DocScanner; 881 setProperty(DOCUMENT_SCANNER, fXML11DocScanner); 882 } 883 fXML11DocScanner.setDocumentHandler(fDocumentHandler); 884 885 if (fDocumentHandler != null) { 886 fDocumentHandler.setDocumentSource(fXML11DocScanner); 887 } 888 fLastComponent = fXML11DocScanner; 889 } 890 891 } // configureXML11Pipeline() 892 893 /** Configures the pipeline. */ 894 protected void configurePipeline() { 895 if (fCurrentDVFactory != fDatatypeValidatorFactory) { 896 fCurrentDVFactory = fDatatypeValidatorFactory; 897 // use XML 1.0 datatype library 898 setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory); 899 } 900 901 // setup DTD pipeline 902 if (fCurrentDTDScanner != fDTDScanner) { 903 fCurrentDTDScanner = fDTDScanner; 904 setProperty(DTD_SCANNER, fCurrentDTDScanner); 905 } 906 fDTDScanner.setDTDHandler(fDTDHandler); 907 fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); 908 909 // setup document pipeline 910 if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { 911 if (fCurrentScanner != fNamespaceScanner) { 912 fCurrentScanner = fNamespaceScanner; 913 setProperty(DOCUMENT_SCANNER, fNamespaceScanner); 914 } 915 fNamespaceScanner.setDTDValidator(null); 916 fNamespaceScanner.setDocumentHandler(fDocumentHandler); 917 if (fDocumentHandler != null) { 918 fDocumentHandler.setDocumentSource(fNamespaceScanner); 919 } 920 fLastComponent = fNamespaceScanner; 921 } else { 922 // create components 923 if (fNonNSScanner == null) { 924 fNonNSScanner = new XMLDocumentScannerImpl(); 925 // add components 926 addComponent((XMLComponent) fNonNSScanner); 927 928 } 929 if (fCurrentScanner != fNonNSScanner) { 930 fCurrentScanner = fNonNSScanner; 931 setProperty(DOCUMENT_SCANNER, fNonNSScanner); 932 933 } 934 935 fNonNSScanner.setDocumentHandler(fDocumentHandler); 936 if (fDocumentHandler != null) { 937 fDocumentHandler.setDocumentSource(fNonNSScanner); 938 } 939 fLastComponent = fNonNSScanner; 940 } 941 942 } // configurePipeline() 943 944 945 // features and properties 946 947 /** 948 * Check a feature. If feature is know and supported, this method simply 949 * returns. Otherwise, the appropriate exception is thrown. 950 * 951 * @param featureId The unique identifier (URI) of the feature. 952 * 953 * @throws XMLConfigurationException Thrown for configuration error. 954 * In general, components should 955 * only throw this exception if 956 * it is <strong>really</strong> 957 * a critical error. 958 */ 959 protected FeatureState checkFeature(String featureId) throws XMLConfigurationException { 960 961 // 962 // Xerces Features 963 // 964 965 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 966 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 967 968 // 969 // http://apache.org/xml/features/validation/dynamic 970 // Allows the parser to validate a document only when it 971 // contains a grammar. Validation is turned on/off based 972 // on each document instance, automatically. 973 // 974 if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() && 975 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) { 976 return FeatureState.RECOGNIZED; 977 } 978 979 // 980 // http://apache.org/xml/features/validation/default-attribute-values 981 // 982 if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() && 983 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) { 984 // REVISIT 985 return FeatureState.NOT_SUPPORTED; 986 } 987 // 988 // http://apache.org/xml/features/validation/default-attribute-values 989 // 990 if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() && 991 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) { 992 // REVISIT 993 return FeatureState.NOT_SUPPORTED; 994 } 995 // 996 // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar 997 // 998 if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() && 999 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) { 1000 return FeatureState.RECOGNIZED; 1001 } 1002 // 1003 // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd 1004 // 1005 if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && 1006 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) { 1007 return FeatureState.RECOGNIZED; 1008 } 1009 1010 // 1011 // http://apache.org/xml/features/validation/default-attribute-values 1012 // 1013 if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() && 1014 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) { 1015 return FeatureState.NOT_SUPPORTED; 1016 } 1017 1018 // special performance feature: only component manager is allowed to set it. 1019 if (suffixLength == Constants.PARSER_SETTINGS.length() && 1020 featureId.endsWith(Constants.PARSER_SETTINGS)) { 1021 return FeatureState.NOT_SUPPORTED; 1022 } 1023 } 1024 1025 // 1026 // Not recognized 1027 // 1028 1029 return super.checkFeature(featureId); 1030 1031 } // checkFeature(String) 1032 1033 /** 1034 * Check a property. If the property is know and supported, this method 1035 * simply returns. Otherwise, the appropriate exception is thrown. 1036 * 1037 * @param propertyId The unique identifier (URI) of the property 1038 * being set. 1039 * 1040 * @throws XMLConfigurationException Thrown for configuration error. 1041 * In general, components should 1042 * only throw this exception if 1043 * it is <strong>really</strong> 1044 * a critical error. 1045 */ 1046 protected PropertyState checkProperty(String propertyId) throws XMLConfigurationException { 1047 1048 // 1049 // Xerces Properties 1050 // 1051 1052 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 1053 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 1054 1055 if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && 1056 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) { 1057 return PropertyState.RECOGNIZED; 1058 } 1059 } 1060 1061 if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) { 1062 final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length(); 1063 1064 if (suffixLength == Constants.SCHEMA_SOURCE.length() && 1065 propertyId.endsWith(Constants.SCHEMA_SOURCE)) { 1066 return PropertyState.RECOGNIZED; 1067 } 1068 } 1069 1070 // special cases 1071 if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) { 1072 final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length(); 1073 1074 // 1075 // http://xml.org/sax/properties/xml-string 1076 // Value type: String 1077 // Access: read-only 1078 // Get the literal string of characters associated with the 1079 // current event. If the parser recognises and supports this 1080 // property but is not currently parsing text, it should return 1081 // null (this is a good way to check for availability before the 1082 // parse begins). 1083 // 1084 if (suffixLength == Constants.XML_STRING_PROPERTY.length() && 1085 propertyId.endsWith(Constants.XML_STRING_PROPERTY)) { 1086 // REVISIT - we should probably ask xml-dev for a precise 1087 // definition of what this is actually supposed to return, and 1088 // in exactly which circumstances. 1089 return PropertyState.NOT_SUPPORTED; 1090 } 1091 } 1092 1093 // 1094 // Not recognized 1095 // 1096 1097 return super.checkProperty(propertyId); 1098 1099 } // checkProperty(String) 1100 1101 1102 /** 1103 * Adds a component to the parser configuration. This method will 1104 * also add all of the component's recognized features and properties 1105 * to the list of default recognized features and properties. 1106 * 1107 * @param component The component to add. 1108 */ 1109 protected void addComponent(XMLComponent component) { 1110 1111 // don't add a component more than once 1112 if (fComponents.contains(component)) { 1113 return; 1114 } 1115 fComponents.add(component); 1116 addRecognizedParamsAndSetDefaults(component); 1117 1118 } // addComponent(XMLComponent) 1119 1120 /** 1121 * Adds common component to the parser configuration. This method will 1122 * also add all of the component's recognized features and properties 1123 * to the list of default recognized features and properties. 1124 * 1125 * @param component The component to add. 1126 */ 1127 protected void addCommonComponent(XMLComponent component) { 1128 1129 // don't add a component more than once 1130 if (fCommonComponents.contains(component)) { 1131 return; 1132 } 1133 fCommonComponents.add(component); 1134 addRecognizedParamsAndSetDefaults(component); 1135 1136 } // addCommonComponent(XMLComponent) 1137 1138 /** 1139 * Adds an XML 1.1 component to the parser configuration. This method will 1140 * also add all of the component's recognized features and properties 1141 * to the list of default recognized features and properties. 1142 * 1143 * @param component The component to add. 1144 */ 1145 protected void addXML11Component(XMLComponent component) { 1146 1147 // don't add a component more than once 1148 if (fXML11Components.contains(component)) { 1149 return; 1150 } 1151 fXML11Components.add(component); 1152 addRecognizedParamsAndSetDefaults(component); 1153 1154 } // addXML11Component(XMLComponent) 1155 1156 /** 1157 * Adds all of the component's recognized features and properties 1158 * to the list of default recognized features and properties, and 1159 * sets default values on the configuration for features and 1160 * properties which were previously absent from the configuration. 1161 * 1162 * @param component The component whose recognized features 1163 * and properties will be added to the configuration 1164 */ 1165 protected void addRecognizedParamsAndSetDefaults(XMLComponent component) { 1166 1167 // register component's recognized features 1168 String[] recognizedFeatures = component.getRecognizedFeatures(); 1169 addRecognizedFeatures(recognizedFeatures); 1170 1171 // register component's recognized properties 1172 String[] recognizedProperties = component.getRecognizedProperties(); 1173 addRecognizedProperties(recognizedProperties); 1174 1175 // set default values 1176 if (recognizedFeatures != null) { 1177 for (int i = 0; i < recognizedFeatures.length; ++i) { 1178 String featureId = recognizedFeatures[i]; 1179 Boolean state = component.getFeatureDefault(featureId); 1180 if (state != null) { 1181 // Do not overwrite values already set on the configuration. 1182 if (!fFeatures.containsKey(featureId)) { 1183 fFeatures.put(featureId, state); 1184 // For newly added components who recognize this feature 1185 // but did not offer a default value, we need to make 1186 // sure these components will get an opportunity to read 1187 // the value before parsing begins. 1188 fConfigUpdated = true; 1189 } 1190 } 1191 } 1192 } 1193 if (recognizedProperties != null) { 1194 for (int i = 0; i < recognizedProperties.length; ++i) { 1195 String propertyId = recognizedProperties[i]; 1196 Object value = component.getPropertyDefault(propertyId); 1197 if (value != null) { 1198 // Do not overwrite values already set on the configuration. 1199 if (!fProperties.containsKey(propertyId)) { 1200 fProperties.put(propertyId, value); 1201 // For newly added components who recognize this property 1202 // but did not offer a default value, we need to make 1203 // sure these components will get an opportunity to read 1204 // the value before parsing begins. 1205 fConfigUpdated = true; 1206 } 1207 } 1208 } 1209 } 1210 } 1211 1212 private void initXML11Components() { 1213 if (!f11Initialized) { 1214 1215 // create datatype factory 1216 fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY); 1217 1218 // setup XML 1.1 DTD pipeline 1219 fXML11DTDScanner = new XML11DTDScannerImpl(); 1220 addXML11Component(fXML11DTDScanner); 1221 1222 // setup XML 1.1. document pipeline - namespace aware 1223 fXML11NSDocScanner = new XML11NSDocumentScannerImpl(); 1224 addXML11Component(fXML11NSDocScanner); 1225 1226 f11Initialized = true; 1227 } 1228 } 1229 1230 } // class XML11NonValidatingConfiguration