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