1 /* 2 * Copyright (c) 2011, 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.impl.xs.opti; 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.XML11NSDocumentScannerImpl; 26 import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl; 27 import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; 28 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; 29 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; 30 import com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl; 31 import com.sun.org.apache.xerces.internal.impl.XMLVersionDetector; 32 import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory; 33 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 34 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; 35 import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; 36 import com.sun.org.apache.xerces.internal.parsers.BasicParserConfiguration; 37 import com.sun.org.apache.xerces.internal.util.FeatureState; 38 import com.sun.org.apache.xerces.internal.util.PropertyState; 39 import com.sun.org.apache.xerces.internal.util.SymbolTable; 40 import com.sun.org.apache.xerces.internal.xni.XMLLocator; 41 import com.sun.org.apache.xerces.internal.xni.XNIException; 42 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; 43 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; 44 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 45 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 46 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner; 47 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner; 48 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 49 import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration; 50 import java.io.IOException; 51 import java.util.Locale; 52 import javax.xml.XMLConstants; 53 import jdk.xml.internal.JdkXmlUtils; 54 import jdk.xml.internal.SecuritySupport; 55 56 /** 57 * @xerces.internal 58 * 59 * @author Rahul Srivastava, Sun Microsystems Inc. 60 * 61 * @LastModified: Sep 2017 62 */ 63 public class SchemaParsingConfig extends BasicParserConfiguration 64 implements XMLPullParserConfiguration { 65 66 // 67 // Constants 68 // 69 70 protected final static String XML11_DATATYPE_VALIDATOR_FACTORY = 71 "com.sun.org.apache.xerces.internal.impl.dv.dtd.XML11DTDDVFactoryImpl"; 72 73 // feature identifiers 74 75 /** Feature identifier: warn on duplicate attribute definition. */ 76 protected static final String WARN_ON_DUPLICATE_ATTDEF = 77 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE; 78 79 /** Feature identifier: warn on duplicate entity definition. */ 80 // protected static final String WARN_ON_DUPLICATE_ENTITYDEF = Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE; 81 82 /** Feature identifier: warn on undeclared element definition. */ 83 protected static final String WARN_ON_UNDECLARED_ELEMDEF = 84 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE; 85 86 /** Feature identifier: allow Java encodings. */ 87 protected static final String ALLOW_JAVA_ENCODINGS = 88 Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE; 89 90 /** Feature identifier: continue after fatal error. */ 91 protected static final String CONTINUE_AFTER_FATAL_ERROR = 92 Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE; 93 94 /** Feature identifier: load external DTD. */ 95 protected static final String LOAD_EXTERNAL_DTD = 96 Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE; 97 98 /** Feature identifier: notify built-in refereces. */ 99 protected static final String NOTIFY_BUILTIN_REFS = 100 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE; 101 102 /** Feature identifier: notify character refereces. */ 103 protected static final String NOTIFY_CHAR_REFS = 104 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE; 105 106 /** Feature identifier: expose schema normalized value */ 107 protected static final String NORMALIZE_DATA = 108 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE; 109 110 /** Feature identifier: send element default value via characters() */ 111 protected static final String SCHEMA_ELEMENT_DEFAULT = 112 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT; 113 114 /** Feature identifier: generate synthetic annotations. */ 115 protected static final String GENERATE_SYNTHETIC_ANNOTATIONS = 116 Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE; 117 118 119 // property identifiers 120 121 /** Property identifier: error reporter. */ 122 protected static final String ERROR_REPORTER = 123 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 124 125 /** Property identifier: entity manager. */ 126 protected static final String ENTITY_MANAGER = 127 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; 128 129 /** Property identifier document scanner: */ 130 protected static final String DOCUMENT_SCANNER = 131 Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY; 132 133 /** Property identifier: DTD scanner. */ 134 protected static final String DTD_SCANNER = 135 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY; 136 137 /** Property identifier: grammar pool. */ 138 protected static final String XMLGRAMMAR_POOL = 139 Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; 140 141 /** Property identifier: DTD validator. */ 142 protected static final String DTD_VALIDATOR = 143 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY; 144 145 /** Property identifier: namespace binder. */ 146 protected static final String NAMESPACE_BINDER = 147 Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY; 148 149 /** Property identifier: datatype validator factory. */ 150 protected static final String DATATYPE_VALIDATOR_FACTORY = 151 Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY; 152 153 protected static final String VALIDATION_MANAGER = 154 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 155 156 /** Property identifier: XML Schema validator. */ 157 protected static final String SCHEMA_VALIDATOR = 158 Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY; 159 160 /** Property identifier: locale. */ 161 protected static final String LOCALE = 162 Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; 163 164 165 // debugging 166 167 /** Set to true and recompile to print exception stack trace. */ 168 private static final boolean PRINT_EXCEPTION_STACK_TRACE = false; 169 170 // 171 // Data 172 // 173 174 // 175 // XML 1.0 components 176 // 177 178 /** The XML 1.0 Datatype validator factory. */ 179 protected final DTDDVFactory fDatatypeValidatorFactory; 180 181 /** The XML 1.0 Document scanner. */ 182 protected final XMLNSDocumentScannerImpl fNamespaceScanner; 183 184 /** The XML 1.0 DTD scanner. */ 185 protected final XMLDTDScannerImpl fDTDScanner; 186 187 // 188 // XML 1.1 components 189 // 190 191 /** The XML 1.1 Datatype validator factory. */ 192 protected DTDDVFactory fXML11DatatypeFactory = null; 193 194 /** The XML 1.1 Document scanner. */ 195 protected XML11NSDocumentScannerImpl fXML11NSDocScanner = null; 196 197 /** The XML 1.1 DTD scanner. **/ 198 protected XML11DTDScannerImpl fXML11DTDScanner = null; 199 200 // common components (non-configurable) 201 202 /** Current Datatype validator factory. */ 203 protected DTDDVFactory fCurrentDVFactory; 204 205 /** Current scanner */ 206 protected XMLDocumentScanner fCurrentScanner; 207 208 /** Current DTD scanner. */ 209 protected XMLDTDScanner fCurrentDTDScanner; 210 211 /** Grammar pool. */ 212 protected XMLGrammarPool fGrammarPool; 213 214 /** XML version detector. */ 215 protected final XMLVersionDetector fVersionDetector; 216 217 // common components (configurable) 218 219 /** Error reporter. */ 220 protected final XMLErrorReporter fErrorReporter; 221 222 /** Entity manager. */ 223 protected final XMLEntityManager fEntityManager; 224 225 /** Input Source */ 226 protected XMLInputSource fInputSource; 227 228 protected final ValidationManager fValidationManager; 229 // state 230 231 /** Locator */ 232 protected XMLLocator fLocator; 233 234 /** 235 * True if a parse is in progress. This state is needed because 236 * some features/properties cannot be set while parsing (e.g. 237 * validation and namespaces). 238 */ 239 protected boolean fParseInProgress = false; 240 241 /** 242 * fConfigUpdated is set to true if there has been any change to the configuration settings, 243 * i.e a feature or a property was changed. 244 */ 245 protected boolean fConfigUpdated = false; 246 247 /** Flag indiciating whether XML11 components have been initialized. */ 248 private boolean f11Initialized = false; 249 250 // 251 // Constructors 252 // 253 254 /** Default constructor. */ SchemaParsingConfig()255 public SchemaParsingConfig() { 256 this(null, null, null); 257 } // <init>() 258 259 /** 260 * Constructs a parser configuration using the specified symbol table. 261 * 262 * @param symbolTable The symbol table to use. 263 */ SchemaParsingConfig(SymbolTable symbolTable)264 public SchemaParsingConfig(SymbolTable symbolTable) { 265 this(symbolTable, null, null); 266 } // <init>(SymbolTable) 267 268 /** 269 * Constructs a parser configuration using the specified symbol table and 270 * grammar pool. 271 * <p> 272 * <strong>REVISIT:</strong> 273 * Grammar pool will be updated when the new validation engine is 274 * implemented. 275 * 276 * @param symbolTable The symbol table to use. 277 * @param grammarPool The grammar pool to use. 278 */ SchemaParsingConfig(SymbolTable symbolTable, XMLGrammarPool grammarPool)279 public SchemaParsingConfig(SymbolTable symbolTable, 280 XMLGrammarPool grammarPool) { 281 this(symbolTable, grammarPool, null); 282 } // <init>(SymbolTable,XMLGrammarPool) 283 284 /** 285 * Constructs a parser configuration using the specified symbol table, 286 * grammar pool, and parent settings. 287 * <p> 288 * <strong>REVISIT:</strong> 289 * Grammar pool will be updated when the new validation engine is 290 * implemented. 291 * 292 * @param symbolTable The symbol table to use. 293 * @param grammarPool The grammar pool to use. 294 * @param parentSettings The parent settings. 295 */ SchemaParsingConfig(SymbolTable symbolTable, XMLGrammarPool grammarPool, XMLComponentManager parentSettings)296 public SchemaParsingConfig(SymbolTable symbolTable, 297 XMLGrammarPool grammarPool, 298 XMLComponentManager parentSettings) { 299 super(symbolTable, parentSettings); 300 301 // add default recognized features 302 final String[] recognizedFeatures = { 303 PARSER_SETTINGS, WARN_ON_DUPLICATE_ATTDEF, WARN_ON_UNDECLARED_ELEMDEF, 304 ALLOW_JAVA_ENCODINGS, CONTINUE_AFTER_FATAL_ERROR, 305 LOAD_EXTERNAL_DTD, NOTIFY_BUILTIN_REFS, 306 NOTIFY_CHAR_REFS, GENERATE_SYNTHETIC_ANNOTATIONS, 307 XMLConstants.USE_CATALOG, 308 JdkXmlUtils.OVERRIDE_PARSER 309 }; 310 addRecognizedFeatures(recognizedFeatures); 311 fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); 312 // set state for default features 313 fFeatures.put(WARN_ON_DUPLICATE_ATTDEF, Boolean.FALSE); 314 //setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false); 315 fFeatures.put(WARN_ON_UNDECLARED_ELEMDEF, Boolean.FALSE); 316 fFeatures.put(ALLOW_JAVA_ENCODINGS, Boolean.FALSE); 317 fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE); 318 fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE); 319 fFeatures.put(NOTIFY_BUILTIN_REFS, Boolean.FALSE); 320 fFeatures.put(NOTIFY_CHAR_REFS, Boolean.FALSE); 321 fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE); 322 fFeatures.put(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT); 323 fFeatures.put(JdkXmlUtils.OVERRIDE_PARSER, JdkXmlUtils.OVERRIDE_PARSER_DEFAULT); 324 325 // add default recognized properties 326 final String[] recognizedProperties = { 327 ERROR_REPORTER, 328 ENTITY_MANAGER, 329 DOCUMENT_SCANNER, 330 DTD_SCANNER, 331 DTD_VALIDATOR, 332 NAMESPACE_BINDER, 333 XMLGRAMMAR_POOL, 334 DATATYPE_VALIDATOR_FACTORY, 335 VALIDATION_MANAGER, 336 GENERATE_SYNTHETIC_ANNOTATIONS, 337 LOCALE, 338 JdkXmlUtils.CATALOG_DEFER, 339 JdkXmlUtils.CATALOG_FILES, 340 JdkXmlUtils.CATALOG_PREFER, 341 JdkXmlUtils.CATALOG_RESOLVE, 342 JdkXmlUtils.CDATA_CHUNK_SIZE 343 }; 344 addRecognizedProperties(recognizedProperties); 345 346 fGrammarPool = grammarPool; 347 if (fGrammarPool != null) { 348 setProperty(XMLGRAMMAR_POOL, fGrammarPool); 349 } 350 351 fEntityManager = new XMLEntityManager(); 352 fProperties.put(ENTITY_MANAGER, fEntityManager); 353 addComponent(fEntityManager); 354 355 fErrorReporter = new XMLErrorReporter(); 356 fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner()); 357 fProperties.put(ERROR_REPORTER, fErrorReporter); 358 addComponent(fErrorReporter); 359 360 fNamespaceScanner = new XMLNSDocumentScannerImpl(); 361 fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner); 362 addRecognizedParamsAndSetDefaults(fNamespaceScanner); 363 364 fDTDScanner = new XMLDTDScannerImpl(); 365 fProperties.put(DTD_SCANNER, fDTDScanner); 366 addRecognizedParamsAndSetDefaults(fDTDScanner); 367 368 fDatatypeValidatorFactory = DTDDVFactory.getInstance(); 369 fProperties.put(DATATYPE_VALIDATOR_FACTORY, 370 fDatatypeValidatorFactory); 371 372 fValidationManager = new ValidationManager(); 373 fProperties.put(VALIDATION_MANAGER, fValidationManager); 374 fProperties.put(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT); 375 376 fVersionDetector = new XMLVersionDetector(); 377 378 // add message formatters 379 if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { 380 XMLMessageFormatter xmft = new XMLMessageFormatter(); 381 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); 382 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); 383 } 384 385 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) { 386 XSMessageFormatter xmft = new XSMessageFormatter(); 387 fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft); 388 } 389 390 // set locale 391 try { 392 setLocale(Locale.getDefault()); 393 } 394 catch (XNIException e) { 395 // do nothing 396 // REVISIT: What is the right thing to do? -Ac 397 } 398 399 } // <init>(SymbolTable,XMLGrammarPool) 400 401 // 402 // Public methods 403 // 404 405 /** 406 * Returns the state of a feature. 407 * 408 * @param featureId The feature identifier. 409 * @return true if the feature is supported 410 * 411 * @throws XMLConfigurationException Thrown for configuration error. 412 * In general, components should 413 * only throw this exception if 414 * it is <strong>really</strong> 415 * a critical error. 416 */ getFeatureState(String featureId)417 public FeatureState getFeatureState(String featureId) 418 throws XMLConfigurationException { 419 // make this feature special 420 if (featureId.equals(PARSER_SETTINGS)) { 421 return FeatureState.is(fConfigUpdated); 422 } 423 return super.getFeatureState(featureId); 424 425 } // getFeature(String):boolean 426 427 /** 428 * Set the state of a feature. 429 * 430 * Set the state of any feature in a SAX2 parser. The parser 431 * might not recognize the feature, and if it does recognize 432 * it, it might not be able to fulfill the request. 433 * 434 * @param featureId The unique identifier (URI) of the feature. 435 * @param state The requested state of the feature (true or false). 436 * 437 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 438 * requested feature is not known. 439 */ setFeature(String featureId, boolean state)440 public void setFeature(String featureId, boolean state) 441 throws XMLConfigurationException { 442 443 fConfigUpdated = true; 444 445 // forward to every XML 1.0 component 446 fNamespaceScanner.setFeature(featureId, state); 447 fDTDScanner.setFeature(featureId, state); 448 449 // forward to every XML 1.1 component 450 if (f11Initialized) { 451 try { 452 fXML11DTDScanner.setFeature(featureId, state); 453 } 454 // ignore the exception. 455 catch (Exception e) {} 456 try { 457 fXML11NSDocScanner.setFeature(featureId, state); 458 } 459 // ignore the exception 460 catch (Exception e) {} 461 } 462 463 // save state if noone "objects" 464 super.setFeature(featureId, state); 465 466 } // setFeature(String,boolean) 467 468 /** 469 * Returns the value of a property. 470 * 471 * @param propertyId The property identifier. 472 * @return the value of the property 473 * 474 * @throws XMLConfigurationException Thrown for configuration error. 475 * In general, components should 476 * only throw this exception if 477 * it is <strong>really</strong> 478 * a critical error. 479 */ getPropertyState(String propertyId)480 public PropertyState getPropertyState(String propertyId) 481 throws XMLConfigurationException { 482 if (LOCALE.equals(propertyId)) { 483 return PropertyState.is(getLocale()); 484 } 485 return super.getPropertyState(propertyId); 486 } 487 488 /** 489 * setProperty 490 * 491 * @param propertyId 492 * @param value 493 */ setProperty(String propertyId, Object value)494 public void setProperty(String propertyId, Object value) 495 throws XMLConfigurationException { 496 497 fConfigUpdated = true; 498 if (LOCALE.equals(propertyId)) { 499 setLocale((Locale) value); 500 } 501 502 // forward to every XML 1.0 component 503 fNamespaceScanner.setProperty(propertyId, value); 504 fDTDScanner.setProperty(propertyId, value); 505 506 // forward to every XML 1.1 component 507 if (f11Initialized) { 508 try { 509 fXML11DTDScanner.setProperty(propertyId, value); 510 } 511 // ignore the exception. 512 catch (Exception e) {} 513 try { 514 fXML11NSDocScanner.setProperty(propertyId, value); 515 } 516 // ignore the exception 517 catch (Exception e) {} 518 } 519 520 // store value if noone "objects" 521 super.setProperty(propertyId, value); 522 523 } // setProperty(String,Object) 524 525 /** 526 * Set the locale to use for messages. 527 * 528 * @param locale The locale object to use for localization of messages. 529 * 530 * @exception XNIException Thrown if the parser does not support the 531 * specified locale. 532 */ setLocale(Locale locale)533 public void setLocale(Locale locale) throws XNIException { 534 super.setLocale(locale); 535 fErrorReporter.setLocale(locale); 536 } // setLocale(Locale) 537 538 // 539 // XMLPullParserConfiguration methods 540 // 541 542 // parsing 543 544 /** 545 * Sets the input source for the document to parse. 546 * 547 * @param inputSource The document's input source. 548 * 549 * @exception XMLConfigurationException Thrown if there is a 550 * configuration error when initializing the 551 * parser. 552 * @exception IOException Thrown on I/O error. 553 * 554 * @see #parse(boolean) 555 */ setInputSource(XMLInputSource inputSource)556 public void setInputSource(XMLInputSource inputSource) 557 throws XMLConfigurationException, IOException { 558 559 // REVISIT: this method used to reset all the components and 560 // construct the pipeline. Now reset() is called 561 // in parse (boolean) just before we parse the document 562 // Should this method still throw exceptions..? 563 564 fInputSource = inputSource; 565 566 } // setInputSource(XMLInputSource) 567 568 /** 569 * Parses the document in a pull parsing fashion. 570 * 571 * @param complete True if the pull parser should parse the 572 * remaining document completely. 573 * 574 * @return True if there is more document to parse. 575 * 576 * @exception XNIException Any XNI exception, possibly wrapping 577 * another exception. 578 * @exception IOException An IO exception from the parser, possibly 579 * from a byte stream or character stream 580 * supplied by the parser. 581 * 582 * @see #setInputSource 583 */ parse(boolean complete)584 public boolean parse(boolean complete) throws XNIException, IOException { 585 // 586 // reset and configure pipeline and set InputSource. 587 if (fInputSource != null) { 588 try { 589 fValidationManager.reset(); 590 fVersionDetector.reset(this); 591 reset(); 592 593 short version = fVersionDetector.determineDocVersion(fInputSource); 594 // XML 1.0 595 if (version == Constants.XML_VERSION_1_0) { 596 configurePipeline(); 597 resetXML10(); 598 } 599 // XML 1.1 600 else if (version == Constants.XML_VERSION_1_1) { 601 initXML11Components(); 602 configureXML11Pipeline(); 603 resetXML11(); 604 } 605 // Unrecoverable error reported during version detection 606 else { 607 return false; 608 } 609 610 // mark configuration as fixed 611 fConfigUpdated = false; 612 613 // resets and sets the pipeline. 614 fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version); 615 fInputSource = null; 616 } 617 catch (XNIException ex) { 618 if (PRINT_EXCEPTION_STACK_TRACE) 619 ex.printStackTrace(); 620 throw ex; 621 } 622 catch (IOException ex) { 623 if (PRINT_EXCEPTION_STACK_TRACE) 624 ex.printStackTrace(); 625 throw ex; 626 } 627 catch (RuntimeException ex) { 628 if (PRINT_EXCEPTION_STACK_TRACE) 629 ex.printStackTrace(); 630 throw ex; 631 } 632 catch (Exception ex) { 633 if (PRINT_EXCEPTION_STACK_TRACE) 634 ex.printStackTrace(); 635 throw new XNIException(ex); 636 } 637 } 638 639 try { 640 return fCurrentScanner.scanDocument(complete); 641 } 642 catch (XNIException ex) { 643 if (PRINT_EXCEPTION_STACK_TRACE) 644 ex.printStackTrace(); 645 throw ex; 646 } 647 catch (IOException ex) { 648 if (PRINT_EXCEPTION_STACK_TRACE) 649 ex.printStackTrace(); 650 throw ex; 651 } 652 catch (RuntimeException ex) { 653 if (PRINT_EXCEPTION_STACK_TRACE) 654 ex.printStackTrace(); 655 throw ex; 656 } 657 catch (Exception ex) { 658 if (PRINT_EXCEPTION_STACK_TRACE) 659 ex.printStackTrace(); 660 throw new XNIException(ex); 661 } 662 663 } // parse(boolean):boolean 664 665 /** 666 * If the application decides to terminate parsing before the xml document 667 * is fully parsed, the application should call this method to free any 668 * resource allocated during parsing. For example, close all opened streams. 669 */ cleanup()670 public void cleanup() { 671 fEntityManager.closeReaders(); 672 } 673 674 // 675 // XMLParserConfiguration methods 676 // 677 678 /** 679 * Parses the specified input source. 680 * 681 * @param source The input source. 682 * 683 * @exception XNIException Throws exception on XNI error. 684 * @exception java.io.IOException Throws exception on i/o error. 685 */ parse(XMLInputSource source)686 public void parse(XMLInputSource source) throws XNIException, IOException { 687 688 if (fParseInProgress) { 689 // REVISIT - need to add new error message 690 throw new XNIException("FWK005 parse may not be called while parsing."); 691 } 692 fParseInProgress = true; 693 694 try { 695 setInputSource(source); 696 parse(true); 697 } 698 catch (XNIException ex) { 699 if (PRINT_EXCEPTION_STACK_TRACE) 700 ex.printStackTrace(); 701 throw ex; 702 } 703 catch (IOException ex) { 704 if (PRINT_EXCEPTION_STACK_TRACE) 705 ex.printStackTrace(); 706 throw ex; 707 } 708 catch (RuntimeException ex) { 709 if (PRINT_EXCEPTION_STACK_TRACE) 710 ex.printStackTrace(); 711 throw ex; 712 } 713 catch (Exception ex) { 714 if (PRINT_EXCEPTION_STACK_TRACE) 715 ex.printStackTrace(); 716 throw new XNIException(ex); 717 } 718 finally { 719 fParseInProgress = false; 720 // close all streams opened by xerces 721 this.cleanup(); 722 } 723 724 } // parse(InputSource) 725 726 // 727 // Protected methods 728 // 729 730 /** 731 * Reset all components before parsing. 732 * 733 * @throws XNIException Thrown if an error occurs during initialization. 734 */ reset()735 public void reset() throws XNIException { 736 737 // initialize the common components 738 super.reset(); 739 740 } // reset() 741 742 /** Configures the XML 1.0 pipeline. */ configurePipeline()743 protected void configurePipeline() { 744 745 if (fCurrentDVFactory != fDatatypeValidatorFactory) { 746 fCurrentDVFactory = fDatatypeValidatorFactory; 747 // use XML 1.0 datatype library 748 setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory); 749 } 750 751 // setup document pipeline 752 if (fCurrentScanner != fNamespaceScanner) { 753 fCurrentScanner = fNamespaceScanner; 754 setProperty(DOCUMENT_SCANNER, fCurrentScanner); 755 } 756 fNamespaceScanner.setDocumentHandler(fDocumentHandler); 757 if (fDocumentHandler != null) { 758 fDocumentHandler.setDocumentSource(fNamespaceScanner); 759 } 760 fLastComponent = fNamespaceScanner; 761 762 // setup dtd pipeline 763 if (fCurrentDTDScanner != fDTDScanner) { 764 fCurrentDTDScanner = fDTDScanner; 765 setProperty(DTD_SCANNER, fCurrentDTDScanner); 766 } 767 fDTDScanner.setDTDHandler(fDTDHandler); 768 if (fDTDHandler != null) { 769 fDTDHandler.setDTDSource(fDTDScanner); 770 } 771 fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); 772 if (fDTDContentModelHandler != null) { 773 fDTDContentModelHandler.setDTDContentModelSource(fDTDScanner); 774 } 775 776 } // configurePipeline() 777 778 /** Configures the XML 1.1 pipeline. */ configureXML11Pipeline()779 protected void configureXML11Pipeline() { 780 781 if (fCurrentDVFactory != fXML11DatatypeFactory) { 782 fCurrentDVFactory = fXML11DatatypeFactory; 783 // use XML 1.1 datatype library 784 setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory); 785 } 786 787 // setup document pipeline 788 if (fCurrentScanner != fXML11NSDocScanner) { 789 fCurrentScanner = fXML11NSDocScanner; 790 setProperty(DOCUMENT_SCANNER, fCurrentScanner); 791 } 792 fXML11NSDocScanner.setDocumentHandler(fDocumentHandler); 793 if (fDocumentHandler != null) { 794 fDocumentHandler.setDocumentSource(fXML11NSDocScanner); 795 } 796 fLastComponent = fXML11NSDocScanner; 797 798 // setup dtd pipeline 799 if (fCurrentDTDScanner != fXML11DTDScanner) { 800 fCurrentDTDScanner = fXML11DTDScanner; 801 setProperty(DTD_SCANNER, fCurrentDTDScanner); 802 } 803 fXML11DTDScanner.setDTDHandler(fDTDHandler); 804 if (fDTDHandler != null) { 805 fDTDHandler.setDTDSource(fXML11DTDScanner); 806 } 807 fXML11DTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); 808 if (fDTDContentModelHandler != null) { 809 fDTDContentModelHandler.setDTDContentModelSource(fXML11DTDScanner); 810 } 811 812 } // configureXML11Pipeline() 813 814 // features and properties 815 816 /** 817 * Check a feature. If feature is know and supported, this method simply 818 * returns. Otherwise, the appropriate exception is thrown. 819 * 820 * @param featureId The unique identifier (URI) of the feature. 821 * 822 * @throws XMLConfigurationException Thrown for configuration error. 823 * In general, components should 824 * only throw this exception if 825 * it is <strong>really</strong> 826 * a critical error. 827 */ checkFeature(String featureId)828 protected FeatureState checkFeature(String featureId) 829 throws XMLConfigurationException { 830 831 // 832 // Xerces Features 833 // 834 835 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 836 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 837 838 // 839 // http://apache.org/xml/features/validation/dynamic 840 // Allows the parser to validate a document only when it 841 // contains a grammar. Validation is turned on/off based 842 // on each document instance, automatically. 843 // 844 if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() && 845 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) { 846 return FeatureState.RECOGNIZED; 847 } 848 // 849 // http://apache.org/xml/features/validation/default-attribute-values 850 // 851 if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() && 852 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) { 853 // REVISIT 854 return FeatureState.NOT_SUPPORTED; 855 } 856 // 857 // http://apache.org/xml/features/validation/default-attribute-values 858 // 859 if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() && 860 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) { 861 // REVISIT 862 return FeatureState.NOT_SUPPORTED; 863 } 864 // 865 // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar 866 // 867 if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() && 868 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) { 869 return FeatureState.RECOGNIZED; 870 } 871 // 872 // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd 873 // 874 if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && 875 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) { 876 return FeatureState.RECOGNIZED; 877 } 878 879 // 880 // http://apache.org/xml/features/validation/default-attribute-values 881 // 882 if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() && 883 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) { 884 return FeatureState.NOT_SUPPORTED; 885 } 886 } 887 888 // 889 // Not recognized 890 // 891 892 return super.checkFeature(featureId); 893 894 } // checkFeature(String) 895 896 /** 897 * Check a property. If the property is know and supported, this method 898 * simply returns. Otherwise, the appropriate exception is thrown. 899 * 900 * @param propertyId The unique identifier (URI) of the property 901 * being set. 902 * 903 * @throws XMLConfigurationException Thrown for configuration error. 904 * In general, components should 905 * only throw this exception if 906 * it is <strong>really</strong> 907 * a critical error. 908 */ checkProperty(String propertyId)909 protected PropertyState checkProperty(String propertyId) 910 throws XMLConfigurationException { 911 912 // 913 // Xerces Properties 914 // 915 916 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 917 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 918 919 if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && 920 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) { 921 return PropertyState.RECOGNIZED; 922 } 923 } 924 925 if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) { 926 final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length(); 927 928 if (suffixLength == Constants.SCHEMA_SOURCE.length() && 929 propertyId.endsWith(Constants.SCHEMA_SOURCE)) { 930 return PropertyState.RECOGNIZED; 931 } 932 } 933 934 // 935 // Not recognized 936 // 937 938 return super.checkProperty(propertyId); 939 940 } // checkProperty(String) 941 942 /** 943 * Adds all of the component's recognized features and properties 944 * to the list of default recognized features and properties, and 945 * sets default values on the configuration for features and 946 * properties which were previously absent from the configuration. 947 * 948 * @param component The component whose recognized features 949 * and properties will be added to the configuration 950 */ addRecognizedParamsAndSetDefaults(XMLComponent component)951 private void addRecognizedParamsAndSetDefaults(XMLComponent component) { 952 953 // register component's recognized features 954 String[] recognizedFeatures = component.getRecognizedFeatures(); 955 addRecognizedFeatures(recognizedFeatures); 956 957 // register component's recognized properties 958 String[] recognizedProperties = component.getRecognizedProperties(); 959 addRecognizedProperties(recognizedProperties); 960 961 // set default values 962 if (recognizedFeatures != null) { 963 for (int i = 0; i < recognizedFeatures.length; ++i) { 964 String featureId = recognizedFeatures[i]; 965 Boolean state = component.getFeatureDefault(featureId); 966 if (state != null) { 967 // Do not overwrite values already set on the configuration. 968 if (!fFeatures.containsKey(featureId)) { 969 fFeatures.put(featureId, state); 970 // For newly added components who recognize this feature 971 // but did not offer a default value, we need to make 972 // sure these components will get an opportunity to read 973 // the value before parsing begins. 974 fConfigUpdated = true; 975 } 976 } 977 } 978 } 979 if (recognizedProperties != null) { 980 for (int i = 0; i < recognizedProperties.length; ++i) { 981 String propertyId = recognizedProperties[i]; 982 Object value = component.getPropertyDefault(propertyId); 983 if (value != null) { 984 // Do not overwrite values already set on the configuration. 985 if (!fProperties.containsKey(propertyId)) { 986 fProperties.put(propertyId, value); 987 // For newly added components who recognize this property 988 // but did not offer a default value, we need to make 989 // sure these components will get an opportunity to read 990 // the value before parsing begins. 991 fConfigUpdated = true; 992 } 993 } 994 } 995 } 996 } 997 998 /** 999 * Reset all XML 1.0 components before parsing 1000 */ resetXML10()1001 protected final void resetXML10() throws XNIException { 1002 // Reset XML 1.0 components 1003 fNamespaceScanner.reset(this); 1004 fDTDScanner.reset(this); 1005 } // resetXML10() 1006 1007 /** 1008 * Reset all XML 1.1 components before parsing 1009 */ resetXML11()1010 protected final void resetXML11() throws XNIException { 1011 // Reset XML 1.1 components 1012 fXML11NSDocScanner.reset(this); 1013 fXML11DTDScanner.reset(this); 1014 } // resetXML11() 1015 1016 // 1017 // other methods 1018 // 1019 1020 /** */ resetNodePool()1021 public void resetNodePool() { 1022 // REVISIT: to implement: introduce a node pool to reuse DTM nodes. 1023 // reset this pool here. 1024 } 1025 initXML11Components()1026 private void initXML11Components() { 1027 if (!f11Initialized) { 1028 // create datatype factory 1029 fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY); 1030 1031 // setup XML 1.1 DTD pipeline 1032 fXML11DTDScanner = new XML11DTDScannerImpl(); 1033 addRecognizedParamsAndSetDefaults(fXML11DTDScanner); 1034 1035 // setup XML 1.1. document pipeline - namespace aware 1036 fXML11NSDocScanner = new XML11NSDocumentScannerImpl(); 1037 addRecognizedParamsAndSetDefaults(fXML11NSDocScanner); 1038 1039 f11Initialized = true; 1040 } 1041 } 1042 } 1043