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