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