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. */ 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 */ 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 */ 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 */ 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 }; 309 addRecognizedFeatures(recognizedFeatures); 310 fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); 311 // set state for default features 312 fFeatures.put(WARN_ON_DUPLICATE_ATTDEF, Boolean.FALSE); 313 //setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false); 314 fFeatures.put(WARN_ON_UNDECLARED_ELEMDEF, Boolean.FALSE); 315 fFeatures.put(ALLOW_JAVA_ENCODINGS, Boolean.FALSE); 316 fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE); 317 fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE); 318 fFeatures.put(NOTIFY_BUILTIN_REFS, Boolean.FALSE); 319 fFeatures.put(NOTIFY_CHAR_REFS, Boolean.FALSE); 320 fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE); 321 fFeatures.put(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT); 322 323 // add default recognized properties 324 final String[] recognizedProperties = { 325 ERROR_REPORTER, 326 ENTITY_MANAGER, 327 DOCUMENT_SCANNER, 328 DTD_SCANNER, 329 DTD_VALIDATOR, 330 NAMESPACE_BINDER, 331 XMLGRAMMAR_POOL, 332 DATATYPE_VALIDATOR_FACTORY, 333 VALIDATION_MANAGER, 334 GENERATE_SYNTHETIC_ANNOTATIONS, 335 LOCALE, 336 JdkXmlUtils.CATALOG_DEFER, 337 JdkXmlUtils.CATALOG_FILES, 338 JdkXmlUtils.CATALOG_PREFER, 339 JdkXmlUtils.CATALOG_RESOLVE, 340 JdkXmlUtils.CDATA_CHUNK_SIZE 341 }; 342 addRecognizedProperties(recognizedProperties); 343 344 fGrammarPool = grammarPool; 345 if (fGrammarPool != null) { 346 setProperty(XMLGRAMMAR_POOL, fGrammarPool); 347 } 348 349 fEntityManager = new XMLEntityManager(); 350 fProperties.put(ENTITY_MANAGER, fEntityManager); 351 addComponent(fEntityManager); 352 353 fErrorReporter = new XMLErrorReporter(); 354 fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner()); 355 fProperties.put(ERROR_REPORTER, fErrorReporter); 356 addComponent(fErrorReporter); 357 358 fNamespaceScanner = new XMLNSDocumentScannerImpl(); 359 fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner); 360 addRecognizedParamsAndSetDefaults(fNamespaceScanner); 361 362 fDTDScanner = new XMLDTDScannerImpl(); 363 fProperties.put(DTD_SCANNER, fDTDScanner); 364 addRecognizedParamsAndSetDefaults(fDTDScanner); 365 366 fDatatypeValidatorFactory = DTDDVFactory.getInstance(); 367 fProperties.put(DATATYPE_VALIDATOR_FACTORY, 368 fDatatypeValidatorFactory); 369 370 fValidationManager = new ValidationManager(); 371 fProperties.put(VALIDATION_MANAGER, fValidationManager); 372 fProperties.put(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT); 373 374 fVersionDetector = new XMLVersionDetector(); 375 376 // add message formatters 377 if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { 378 XMLMessageFormatter xmft = new XMLMessageFormatter(); 379 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); 380 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); 381 } 382 383 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) { 384 XSMessageFormatter xmft = new XSMessageFormatter(); 385 fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft); 386 } 387 388 // set locale 389 try { 390 setLocale(Locale.getDefault()); 391 } 392 catch (XNIException e) { 393 // do nothing 394 // REVISIT: What is the right thing to do? -Ac 395 } 396 397 } // <init>(SymbolTable,XMLGrammarPool) 398 399 // 400 // Public methods 401 // 402 403 /** 404 * Returns the state of a feature. 405 * 406 * @param featureId The feature identifier. 407 * @return true if the feature is supported 408 * 409 * @throws XMLConfigurationException Thrown for configuration error. 410 * In general, components should 411 * only throw this exception if 412 * it is <strong>really</strong> 413 * a critical error. 414 */ 415 public FeatureState getFeatureState(String featureId) 416 throws XMLConfigurationException { 417 // make this feature special 418 if (featureId.equals(PARSER_SETTINGS)) { 419 return FeatureState.is(fConfigUpdated); 420 } 421 return super.getFeatureState(featureId); 422 423 } // getFeature(String):boolean 424 425 /** 426 * Set the state of a feature. 427 * 428 * Set the state of any feature in a SAX2 parser. The parser 429 * might not recognize the feature, and if it does recognize 430 * it, it might not be able to fulfill the request. 431 * 432 * @param featureId The unique identifier (URI) of the feature. 433 * @param state The requested state of the feature (true or false). 434 * 435 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 436 * requested feature is not known. 437 */ 438 public void setFeature(String featureId, boolean state) 439 throws XMLConfigurationException { 440 441 fConfigUpdated = true; 442 443 // forward to every XML 1.0 component 444 fNamespaceScanner.setFeature(featureId, state); 445 fDTDScanner.setFeature(featureId, state); 446 447 // forward to every XML 1.1 component 448 if (f11Initialized) { 449 try { 450 fXML11DTDScanner.setFeature(featureId, state); 451 } 452 // ignore the exception. 453 catch (Exception e) {} 454 try { 455 fXML11NSDocScanner.setFeature(featureId, state); 456 } 457 // ignore the exception 458 catch (Exception e) {} 459 } 460 461 // save state if noone "objects" 462 super.setFeature(featureId, state); 463 464 } // setFeature(String,boolean) 465 466 /** 467 * Returns the value of a property. 468 * 469 * @param propertyId The property identifier. 470 * @return the value of the property 471 * 472 * @throws XMLConfigurationException Thrown for configuration error. 473 * In general, components should 474 * only throw this exception if 475 * it is <strong>really</strong> 476 * a critical error. 477 */ 478 public PropertyState getPropertyState(String propertyId) 479 throws XMLConfigurationException { 480 if (LOCALE.equals(propertyId)) { 481 return PropertyState.is(getLocale()); 482 } 483 return super.getPropertyState(propertyId); 484 } 485 486 /** 487 * setProperty 488 * 489 * @param propertyId 490 * @param value 491 */ 492 public void setProperty(String propertyId, Object value) 493 throws XMLConfigurationException { 494 495 fConfigUpdated = true; 496 if (LOCALE.equals(propertyId)) { 497 setLocale((Locale) value); 498 } 499 500 // forward to every XML 1.0 component 501 fNamespaceScanner.setProperty(propertyId, value); 502 fDTDScanner.setProperty(propertyId, value); 503 504 // forward to every XML 1.1 component 505 if (f11Initialized) { 506 try { 507 fXML11DTDScanner.setProperty(propertyId, value); 508 } 509 // ignore the exception. 510 catch (Exception e) {} 511 try { 512 fXML11NSDocScanner.setProperty(propertyId, value); 513 } 514 // ignore the exception 515 catch (Exception e) {} 516 } 517 518 // store value if noone "objects" 519 super.setProperty(propertyId, value); 520 521 } // setProperty(String,Object) 522 523 /** 524 * Set the locale to use for messages. 525 * 526 * @param locale The locale object to use for localization of messages. 527 * 528 * @exception XNIException Thrown if the parser does not support the 529 * specified locale. 530 */ 531 public void setLocale(Locale locale) throws XNIException { 532 super.setLocale(locale); 533 fErrorReporter.setLocale(locale); 534 } // setLocale(Locale) 535 536 // 537 // XMLPullParserConfiguration methods 538 // 539 540 // parsing 541 542 /** 543 * Sets the input source for the document to parse. 544 * 545 * @param inputSource The document's input source. 546 * 547 * @exception XMLConfigurationException Thrown if there is a 548 * configuration error when initializing the 549 * parser. 550 * @exception IOException Thrown on I/O error. 551 * 552 * @see #parse(boolean) 553 */ 554 public void setInputSource(XMLInputSource inputSource) 555 throws XMLConfigurationException, IOException { 556 557 // REVISIT: this method used to reset all the components and 558 // construct the pipeline. Now reset() is called 559 // in parse (boolean) just before we parse the document 560 // Should this method still throw exceptions..? 561 562 fInputSource = inputSource; 563 564 } // setInputSource(XMLInputSource) 565 566 /** 567 * Parses the document in a pull parsing fashion. 568 * 569 * @param complete True if the pull parser should parse the 570 * remaining document completely. 571 * 572 * @return True if there is more document to parse. 573 * 574 * @exception XNIException Any XNI exception, possibly wrapping 575 * another exception. 576 * @exception IOException An IO exception from the parser, possibly 577 * from a byte stream or character stream 578 * supplied by the parser. 579 * 580 * @see #setInputSource 581 */ 582 public boolean parse(boolean complete) throws XNIException, IOException { 583 // 584 // reset and configure pipeline and set InputSource. 585 if (fInputSource != null) { 586 try { 587 fValidationManager.reset(); 588 fVersionDetector.reset(this); 589 reset(); 590 591 short version = fVersionDetector.determineDocVersion(fInputSource); 592 // XML 1.0 593 if (version == Constants.XML_VERSION_1_0) { 594 configurePipeline(); 595 resetXML10(); 596 } 597 // XML 1.1 598 else if (version == Constants.XML_VERSION_1_1) { 599 initXML11Components(); 600 configureXML11Pipeline(); 601 resetXML11(); 602 } 603 // Unrecoverable error reported during version detection 604 else { 605 return false; 606 } 607 608 // mark configuration as fixed 609 fConfigUpdated = false; 610 611 // resets and sets the pipeline. 612 fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version); 613 fInputSource = null; 614 } 615 catch (XNIException ex) { 616 if (PRINT_EXCEPTION_STACK_TRACE) 617 ex.printStackTrace(); 618 throw ex; 619 } 620 catch (IOException ex) { 621 if (PRINT_EXCEPTION_STACK_TRACE) 622 ex.printStackTrace(); 623 throw ex; 624 } 625 catch (RuntimeException ex) { 626 if (PRINT_EXCEPTION_STACK_TRACE) 627 ex.printStackTrace(); 628 throw ex; 629 } 630 catch (Exception ex) { 631 if (PRINT_EXCEPTION_STACK_TRACE) 632 ex.printStackTrace(); 633 throw new XNIException(ex); 634 } 635 } 636 637 try { 638 return fCurrentScanner.scanDocument(complete); 639 } 640 catch (XNIException ex) { 641 if (PRINT_EXCEPTION_STACK_TRACE) 642 ex.printStackTrace(); 643 throw ex; 644 } 645 catch (IOException ex) { 646 if (PRINT_EXCEPTION_STACK_TRACE) 647 ex.printStackTrace(); 648 throw ex; 649 } 650 catch (RuntimeException ex) { 651 if (PRINT_EXCEPTION_STACK_TRACE) 652 ex.printStackTrace(); 653 throw ex; 654 } 655 catch (Exception ex) { 656 if (PRINT_EXCEPTION_STACK_TRACE) 657 ex.printStackTrace(); 658 throw new XNIException(ex); 659 } 660 661 } // parse(boolean):boolean 662 663 /** 664 * If the application decides to terminate parsing before the xml document 665 * is fully parsed, the application should call this method to free any 666 * resource allocated during parsing. For example, close all opened streams. 667 */ 668 public void cleanup() { 669 fEntityManager.closeReaders(); 670 } 671 672 // 673 // XMLParserConfiguration methods 674 // 675 676 /** 677 * Parses the specified input source. 678 * 679 * @param source The input source. 680 * 681 * @exception XNIException Throws exception on XNI error. 682 * @exception java.io.IOException Throws exception on i/o error. 683 */ 684 public void parse(XMLInputSource source) throws XNIException, IOException { 685 686 if (fParseInProgress) { 687 // REVISIT - need to add new error message 688 throw new XNIException("FWK005 parse may not be called while parsing."); 689 } 690 fParseInProgress = true; 691 692 try { 693 setInputSource(source); 694 parse(true); 695 } 696 catch (XNIException ex) { 697 if (PRINT_EXCEPTION_STACK_TRACE) 698 ex.printStackTrace(); 699 throw ex; 700 } 701 catch (IOException ex) { 702 if (PRINT_EXCEPTION_STACK_TRACE) 703 ex.printStackTrace(); 704 throw ex; 705 } 706 catch (RuntimeException ex) { 707 if (PRINT_EXCEPTION_STACK_TRACE) 708 ex.printStackTrace(); 709 throw ex; 710 } 711 catch (Exception ex) { 712 if (PRINT_EXCEPTION_STACK_TRACE) 713 ex.printStackTrace(); 714 throw new XNIException(ex); 715 } 716 finally { 717 fParseInProgress = false; 718 // close all streams opened by xerces 719 this.cleanup(); 720 } 721 722 } // parse(InputSource) 723 724 // 725 // Protected methods 726 // 727 728 /** 729 * Reset all components before parsing. 730 * 731 * @throws XNIException Thrown if an error occurs during initialization. 732 */ 733 public void reset() throws XNIException { 734 735 // initialize the common components 736 super.reset(); 737 738 } // reset() 739 740 /** Configures the XML 1.0 pipeline. */ 741 protected void configurePipeline() { 742 743 if (fCurrentDVFactory != fDatatypeValidatorFactory) { 744 fCurrentDVFactory = fDatatypeValidatorFactory; 745 // use XML 1.0 datatype library 746 setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory); 747 } 748 749 // setup document pipeline 750 if (fCurrentScanner != fNamespaceScanner) { 751 fCurrentScanner = fNamespaceScanner; 752 setProperty(DOCUMENT_SCANNER, fCurrentScanner); 753 } 754 fNamespaceScanner.setDocumentHandler(fDocumentHandler); 755 if (fDocumentHandler != null) { 756 fDocumentHandler.setDocumentSource(fNamespaceScanner); 757 } 758 fLastComponent = fNamespaceScanner; 759 760 // setup dtd pipeline 761 if (fCurrentDTDScanner != fDTDScanner) { 762 fCurrentDTDScanner = fDTDScanner; 763 setProperty(DTD_SCANNER, fCurrentDTDScanner); 764 } 765 fDTDScanner.setDTDHandler(fDTDHandler); 766 if (fDTDHandler != null) { 767 fDTDHandler.setDTDSource(fDTDScanner); 768 } 769 fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); 770 if (fDTDContentModelHandler != null) { 771 fDTDContentModelHandler.setDTDContentModelSource(fDTDScanner); 772 } 773 774 } // configurePipeline() 775 776 /** Configures the XML 1.1 pipeline. */ 777 protected void configureXML11Pipeline() { 778 779 if (fCurrentDVFactory != fXML11DatatypeFactory) { 780 fCurrentDVFactory = fXML11DatatypeFactory; 781 // use XML 1.1 datatype library 782 setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory); 783 } 784 785 // setup document pipeline 786 if (fCurrentScanner != fXML11NSDocScanner) { 787 fCurrentScanner = fXML11NSDocScanner; 788 setProperty(DOCUMENT_SCANNER, fCurrentScanner); 789 } 790 fXML11NSDocScanner.setDocumentHandler(fDocumentHandler); 791 if (fDocumentHandler != null) { 792 fDocumentHandler.setDocumentSource(fXML11NSDocScanner); 793 } 794 fLastComponent = fXML11NSDocScanner; 795 796 // setup dtd pipeline 797 if (fCurrentDTDScanner != fXML11DTDScanner) { 798 fCurrentDTDScanner = fXML11DTDScanner; 799 setProperty(DTD_SCANNER, fCurrentDTDScanner); 800 } 801 fXML11DTDScanner.setDTDHandler(fDTDHandler); 802 if (fDTDHandler != null) { 803 fDTDHandler.setDTDSource(fXML11DTDScanner); 804 } 805 fXML11DTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); 806 if (fDTDContentModelHandler != null) { 807 fDTDContentModelHandler.setDTDContentModelSource(fXML11DTDScanner); 808 } 809 810 } // configureXML11Pipeline() 811 812 // features and properties 813 814 /** 815 * Check a feature. If feature is know and supported, this method simply 816 * returns. Otherwise, the appropriate exception is thrown. 817 * 818 * @param featureId The unique identifier (URI) of the feature. 819 * 820 * @throws XMLConfigurationException Thrown for configuration error. 821 * In general, components should 822 * only throw this exception if 823 * it is <strong>really</strong> 824 * a critical error. 825 */ 826 protected FeatureState checkFeature(String featureId) 827 throws XMLConfigurationException { 828 829 // 830 // Xerces Features 831 // 832 833 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 834 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 835 836 // 837 // http://apache.org/xml/features/validation/dynamic 838 // Allows the parser to validate a document only when it 839 // contains a grammar. Validation is turned on/off based 840 // on each document instance, automatically. 841 // 842 if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() && 843 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) { 844 return FeatureState.RECOGNIZED; 845 } 846 // 847 // http://apache.org/xml/features/validation/default-attribute-values 848 // 849 if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() && 850 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) { 851 // REVISIT 852 return FeatureState.NOT_SUPPORTED; 853 } 854 // 855 // http://apache.org/xml/features/validation/default-attribute-values 856 // 857 if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() && 858 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) { 859 // REVISIT 860 return FeatureState.NOT_SUPPORTED; 861 } 862 // 863 // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar 864 // 865 if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() && 866 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) { 867 return FeatureState.RECOGNIZED; 868 } 869 // 870 // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd 871 // 872 if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && 873 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) { 874 return FeatureState.RECOGNIZED; 875 } 876 877 // 878 // http://apache.org/xml/features/validation/default-attribute-values 879 // 880 if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() && 881 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) { 882 return FeatureState.NOT_SUPPORTED; 883 } 884 } 885 886 // 887 // Not recognized 888 // 889 890 return super.checkFeature(featureId); 891 892 } // checkFeature(String) 893 894 /** 895 * Check a property. If the property is know and supported, this method 896 * simply returns. Otherwise, the appropriate exception is thrown. 897 * 898 * @param propertyId The unique identifier (URI) of the property 899 * being set. 900 * 901 * @throws XMLConfigurationException Thrown for configuration error. 902 * In general, components should 903 * only throw this exception if 904 * it is <strong>really</strong> 905 * a critical error. 906 */ 907 protected PropertyState checkProperty(String propertyId) 908 throws XMLConfigurationException { 909 910 // 911 // Xerces Properties 912 // 913 914 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 915 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 916 917 if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && 918 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) { 919 return PropertyState.RECOGNIZED; 920 } 921 } 922 923 if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) { 924 final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length(); 925 926 if (suffixLength == Constants.SCHEMA_SOURCE.length() && 927 propertyId.endsWith(Constants.SCHEMA_SOURCE)) { 928 return PropertyState.RECOGNIZED; 929 } 930 } 931 932 // 933 // Not recognized 934 // 935 936 return super.checkProperty(propertyId); 937 938 } // checkProperty(String) 939 940 /** 941 * Adds all of the component's recognized features and properties 942 * to the list of default recognized features and properties, and 943 * sets default values on the configuration for features and 944 * properties which were previously absent from the configuration. 945 * 946 * @param component The component whose recognized features 947 * and properties will be added to the configuration 948 */ 949 private void addRecognizedParamsAndSetDefaults(XMLComponent component) { 950 951 // register component's recognized features 952 String[] recognizedFeatures = component.getRecognizedFeatures(); 953 addRecognizedFeatures(recognizedFeatures); 954 955 // register component's recognized properties 956 String[] recognizedProperties = component.getRecognizedProperties(); 957 addRecognizedProperties(recognizedProperties); 958 959 // set default values 960 if (recognizedFeatures != null) { 961 for (int i = 0; i < recognizedFeatures.length; ++i) { 962 String featureId = recognizedFeatures[i]; 963 Boolean state = component.getFeatureDefault(featureId); 964 if (state != null) { 965 // Do not overwrite values already set on the configuration. 966 if (!fFeatures.containsKey(featureId)) { 967 fFeatures.put(featureId, state); 968 // For newly added components who recognize this feature 969 // but did not offer a default value, we need to make 970 // sure these components will get an opportunity to read 971 // the value before parsing begins. 972 fConfigUpdated = true; 973 } 974 } 975 } 976 } 977 if (recognizedProperties != null) { 978 for (int i = 0; i < recognizedProperties.length; ++i) { 979 String propertyId = recognizedProperties[i]; 980 Object value = component.getPropertyDefault(propertyId); 981 if (value != null) { 982 // Do not overwrite values already set on the configuration. 983 if (!fProperties.containsKey(propertyId)) { 984 fProperties.put(propertyId, value); 985 // For newly added components who recognize this property 986 // but did not offer a default value, we need to make 987 // sure these components will get an opportunity to read 988 // the value before parsing begins. 989 fConfigUpdated = true; 990 } 991 } 992 } 993 } 994 } 995 996 /** 997 * Reset all XML 1.0 components before parsing 998 */ 999 protected final void resetXML10() throws XNIException { 1000 // Reset XML 1.0 components 1001 fNamespaceScanner.reset(this); 1002 fDTDScanner.reset(this); 1003 } // resetXML10() 1004 1005 /** 1006 * Reset all XML 1.1 components before parsing 1007 */ 1008 protected final void resetXML11() throws XNIException { 1009 // Reset XML 1.1 components 1010 fXML11NSDocScanner.reset(this); 1011 fXML11DTDScanner.reset(this); 1012 } // resetXML11() 1013 1014 // 1015 // other methods 1016 // 1017 1018 /** */ 1019 public void resetNodePool() { 1020 // REVISIT: to implement: introduce a node pool to reuse DTM nodes. 1021 // reset this pool here. 1022 } 1023 1024 private void initXML11Components() { 1025 if (!f11Initialized) { 1026 // create datatype factory 1027 fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY); 1028 1029 // setup XML 1.1 DTD pipeline 1030 fXML11DTDScanner = new XML11DTDScannerImpl(); 1031 addRecognizedParamsAndSetDefaults(fXML11DTDScanner); 1032 1033 // setup XML 1.1. document pipeline - namespace aware 1034 fXML11NSDocScanner = new XML11NSDocumentScannerImpl(); 1035 addRecognizedParamsAndSetDefaults(fXML11NSDocScanner); 1036 1037 f11Initialized = true; 1038 } 1039 } 1040 }