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.dom; 21 22 import com.sun.org.apache.xerces.internal.impl.Constants; 23 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; 24 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; 25 import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory; 26 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 27 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; 28 import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper; 29 import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper; 30 import com.sun.org.apache.xerces.internal.util.MessageFormatter; 31 import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; 32 import com.sun.org.apache.xerces.internal.util.PropertyState; 33 import com.sun.org.apache.xerces.internal.util.SymbolTable; 34 import com.sun.org.apache.xerces.internal.utils.ObjectFactory; 35 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; 36 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; 37 import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; 38 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; 39 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; 40 import com.sun.org.apache.xerces.internal.xni.XNIException; 41 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; 42 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; 43 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 44 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 45 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; 46 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; 47 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 48 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; 49 import java.io.IOException; 50 import java.util.ArrayList; 51 import java.util.HashMap; 52 import java.util.Locale; 53 import java.util.Vector; 54 import jdk.xml.internal.JdkXmlUtils; 55 import org.w3c.dom.DOMConfiguration; 56 import org.w3c.dom.DOMErrorHandler; 57 import org.w3c.dom.DOMException; 58 import org.w3c.dom.DOMStringList; 59 import org.w3c.dom.ls.LSResourceResolver; 60 61 62 63 /** 64 * Xerces implementation of DOMConfiguration that maintains a table of recognized parameters. 65 * 66 * @xerces.internal 67 * 68 * @author Elena Litani, IBM 69 * @author Neeraj Bajaj, Sun Microsystems. 70 */ 71 public class DOMConfigurationImpl extends ParserConfigurationSettings 72 implements XMLParserConfiguration, DOMConfiguration { 73 74 // 75 // Constants 76 // 77 78 // feature identifiers 79 80 /** Feature identifier: validation. */ 81 protected static final String XERCES_VALIDATION = 82 Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE; 83 84 /** Feature identifier: namespaces. */ 85 protected static final String XERCES_NAMESPACES = 86 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE; 87 88 protected static final String SCHEMA = 89 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE; 90 91 protected static final String SCHEMA_FULL_CHECKING = 92 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING; 93 94 protected static final String DYNAMIC_VALIDATION = 95 Constants.XERCES_FEATURE_PREFIX + Constants.DYNAMIC_VALIDATION_FEATURE; 96 97 protected static final String NORMALIZE_DATA = 98 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE; 99 100 /** sending psvi in the pipeline */ 101 protected static final String SEND_PSVI = 102 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI; 103 104 protected final static String DTD_VALIDATOR_FACTORY_PROPERTY = 105 Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY; 106 107 /** Feature identifier: namespace growth */ 108 protected static final String NAMESPACE_GROWTH = 109 Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACE_GROWTH_FEATURE; 110 111 protected static final String TOLERATE_DUPLICATES = 112 Constants.XERCES_FEATURE_PREFIX + Constants.TOLERATE_DUPLICATES_FEATURE; 113 114 // property identifiers 115 116 /** Property identifier: entity manager. */ 117 protected static final String ENTITY_MANAGER = 118 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; 119 120 /** Property identifier: error reporter. */ 121 protected static final String ERROR_REPORTER = 122 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 123 124 /** Property identifier: xml string. */ 125 protected static final String XML_STRING = 126 Constants.SAX_PROPERTY_PREFIX + Constants.XML_STRING_PROPERTY; 127 128 /** Property identifier: symbol table. */ 129 protected static final String SYMBOL_TABLE = 130 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; 131 132 /** Property id: Grammar pool*/ 133 protected static final String GRAMMAR_POOL = 134 Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; 135 136 /** Property identifier: error handler. */ 137 protected static final String ERROR_HANDLER = 138 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY; 139 140 /** Property identifier: entity resolver. */ 141 protected static final String ENTITY_RESOLVER = 142 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; 143 144 /** Property identifier: JAXP schema language / DOM schema-type. */ 145 protected static final String JAXP_SCHEMA_LANGUAGE = 146 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE; 147 148 /** Property identifier: JAXP schema source/ DOM schema-location. */ 149 protected static final String JAXP_SCHEMA_SOURCE = 150 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE; 151 152 protected static final String VALIDATION_MANAGER = 153 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 154 155 /** Property identifier: Schema DV Factory */ 156 protected static final String SCHEMA_DV_FACTORY = 157 Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; 158 159 /** Property identifier: Security manager. */ 160 private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; 161 162 /** Property identifier: Security property manager. */ 163 private static final String XML_SECURITY_PROPERTY_MANAGER = 164 Constants.XML_SECURITY_PROPERTY_MANAGER; 165 166 // 167 // Data 168 // 169 XMLDocumentHandler fDocumentHandler; 170 171 /** Normalization features*/ 172 protected short features = 0; 173 174 protected final static short NAMESPACES = 0x1<<0; 175 protected final static short DTNORMALIZATION = 0x1<<1; 176 protected final static short ENTITIES = 0x1<<2; 177 protected final static short CDATA = 0x1<<3; 178 protected final static short SPLITCDATA = 0x1<<4; 179 protected final static short COMMENTS = 0x1<<5; 180 protected final static short VALIDATE = 0x1<<6; 181 protected final static short PSVI = 0x1<<7; 182 protected final static short WELLFORMED = 0x1<<8; 183 protected final static short NSDECL = 0x1<<9; 184 185 protected final static short INFOSET_TRUE_PARAMS = NAMESPACES | COMMENTS | WELLFORMED | NSDECL; 186 protected final static short INFOSET_FALSE_PARAMS = ENTITIES | DTNORMALIZATION | CDATA; 187 protected final static short INFOSET_MASK = INFOSET_TRUE_PARAMS | INFOSET_FALSE_PARAMS; 188 189 // components 190 191 /** Symbol table. */ 192 protected SymbolTable fSymbolTable; 193 194 /** Components. */ 195 protected ArrayList fComponents; 196 197 protected ValidationManager fValidationManager; 198 199 /** Locale. */ 200 protected Locale fLocale; 201 202 /** Error reporter */ 203 protected XMLErrorReporter fErrorReporter; 204 205 protected final DOMErrorHandlerWrapper fErrorHandlerWrapper = 206 new DOMErrorHandlerWrapper(); 207 208 // private data 209 210 private DOMStringList fRecognizedParameters; 211 212 213 // 214 // Constructors 215 // 216 217 /** Default Constructor. */ 218 protected DOMConfigurationImpl() { 219 this(null, null); 220 } // <init>() 221 222 /** 223 * Constructs a parser configuration using the specified symbol table. 224 * 225 * @param symbolTable The symbol table to use. 226 */ 227 protected DOMConfigurationImpl(SymbolTable symbolTable) { 228 this(symbolTable, null); 229 } // <init>(SymbolTable) 230 231 /** 232 * Constructs a parser configuration using the specified symbol table 233 * and parent settings. 234 * 235 * @param symbolTable The symbol table to use. 236 * @param parentSettings The parent settings. 237 */ 238 protected DOMConfigurationImpl(SymbolTable symbolTable, 239 XMLComponentManager parentSettings) { 240 super(parentSettings); 241 242 243 // create table for features and properties 244 fFeatures = new HashMap(); 245 fProperties = new HashMap(); 246 247 // add default recognized features 248 final String[] recognizedFeatures = { 249 XERCES_VALIDATION, 250 XERCES_NAMESPACES, 251 SCHEMA, 252 SCHEMA_FULL_CHECKING, 253 DYNAMIC_VALIDATION, 254 NORMALIZE_DATA, 255 SEND_PSVI, 256 NAMESPACE_GROWTH, 257 TOLERATE_DUPLICATES, 258 JdkXmlUtils.OVERRIDE_PARSER 259 }; 260 addRecognizedFeatures(recognizedFeatures); 261 262 // set state for default features 263 setFeature(XERCES_VALIDATION, false); 264 setFeature(SCHEMA, false); 265 setFeature(SCHEMA_FULL_CHECKING, false); 266 setFeature(DYNAMIC_VALIDATION, false); 267 setFeature(NORMALIZE_DATA, false); 268 setFeature(XERCES_NAMESPACES, true); 269 setFeature(SEND_PSVI, true); 270 setFeature(NAMESPACE_GROWTH, false); 271 setFeature(JdkXmlUtils.OVERRIDE_PARSER, JdkXmlUtils.OVERRIDE_PARSER_DEFAULT); 272 273 // add default recognized properties 274 final String[] recognizedProperties = { 275 XML_STRING, 276 SYMBOL_TABLE, 277 ERROR_HANDLER, 278 ENTITY_RESOLVER, 279 ERROR_REPORTER, 280 ENTITY_MANAGER, 281 VALIDATION_MANAGER, 282 GRAMMAR_POOL, 283 JAXP_SCHEMA_SOURCE, 284 JAXP_SCHEMA_LANGUAGE, 285 DTD_VALIDATOR_FACTORY_PROPERTY, 286 SCHEMA_DV_FACTORY, 287 SECURITY_MANAGER, 288 XML_SECURITY_PROPERTY_MANAGER 289 }; 290 addRecognizedProperties(recognizedProperties); 291 292 // set default values for normalization features 293 features |= NAMESPACES; 294 features |= ENTITIES; 295 features |= COMMENTS; 296 features |= CDATA; 297 features |= SPLITCDATA; 298 features |= WELLFORMED; 299 features |= NSDECL; 300 301 if (symbolTable == null) { 302 symbolTable = new SymbolTable(); 303 } 304 fSymbolTable = symbolTable; 305 306 fComponents = new ArrayList(); 307 308 setProperty(SYMBOL_TABLE, fSymbolTable); 309 fErrorReporter = new XMLErrorReporter(); 310 setProperty(ERROR_REPORTER, fErrorReporter); 311 addComponent(fErrorReporter); 312 313 setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, DTDDVFactory.getInstance()); 314 315 XMLEntityManager manager = new XMLEntityManager(); 316 setProperty(ENTITY_MANAGER, manager); 317 addComponent(manager); 318 319 fValidationManager = createValidationManager(); 320 setProperty(VALIDATION_MANAGER, fValidationManager); 321 322 setProperty(SECURITY_MANAGER, new XMLSecurityManager(true)); 323 324 setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, 325 new XMLSecurityPropertyManager()); 326 327 // add message formatters 328 if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { 329 XMLMessageFormatter xmft = new XMLMessageFormatter(); 330 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); 331 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); 332 } 333 334 // REVISIT: try to include XML Schema formatter. 335 // This is a hack to allow DTD configuration to be build. 336 // 337 if (fErrorReporter.getMessageFormatter("http://www.w3.org/TR/xml-schema-1") == null) { 338 MessageFormatter xmft = null; 339 try { 340 xmft = (MessageFormatter)( 341 ObjectFactory.newInstance("com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter", true)); 342 } catch (Exception exception){ 343 } 344 345 if (xmft != null) { 346 fErrorReporter.putMessageFormatter("http://www.w3.org/TR/xml-schema-1", xmft); 347 } 348 } 349 350 351 // set locale 352 try { 353 setLocale(Locale.getDefault()); 354 } 355 catch (XNIException e) { 356 // do nothing 357 // REVISIT: What is the right thing to do? -Ac 358 } 359 360 361 } // <init>(SymbolTable) 362 363 364 // 365 // XMLParserConfiguration methods 366 // 367 368 /** 369 * Parse an XML document. 370 * <p> 371 * The parser can use this method to instruct this configuration 372 * to begin parsing an XML document from any valid input source 373 * (a character stream, a byte stream, or a URI). 374 * <p> 375 * Parsers may not invoke this method while a parse is in progress. 376 * Once a parse is complete, the parser may then parse another XML 377 * document. 378 * <p> 379 * This method is synchronous: it will not return until parsing 380 * has ended. If a client application wants to terminate 381 * parsing early, it should throw an exception. 382 * 383 * @param source The input source for the top-level of the 384 * XML document. 385 * 386 * @exception XNIException Any XNI exception, possibly wrapping 387 * another exception. 388 * @exception IOException An IO exception from the parser, possibly 389 * from a byte stream or character stream 390 * supplied by the parser. 391 */ 392 public void parse(XMLInputSource inputSource) 393 throws XNIException, IOException{ 394 // no-op 395 } 396 397 /** 398 * Sets the document handler on the last component in the pipeline 399 * to receive information about the document. 400 * 401 * @param documentHandler The document handler. 402 */ 403 public void setDocumentHandler(XMLDocumentHandler documentHandler) { 404 fDocumentHandler = documentHandler; 405 } // setDocumentHandler(XMLDocumentHandler) 406 407 /** Returns the registered document handler. */ 408 public XMLDocumentHandler getDocumentHandler() { 409 return fDocumentHandler; 410 } // getDocumentHandler():XMLDocumentHandler 411 412 /** 413 * Sets the DTD handler. 414 * 415 * @param dtdHandler The DTD handler. 416 */ 417 public void setDTDHandler(XMLDTDHandler dtdHandler) { 418 //no-op 419 } // setDTDHandler(XMLDTDHandler) 420 421 /** Returns the registered DTD handler. */ 422 public XMLDTDHandler getDTDHandler() { 423 return null; 424 } // getDTDHandler():XMLDTDHandler 425 426 /** 427 * Sets the DTD content model handler. 428 * 429 * @param handler The DTD content model handler. 430 */ 431 public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) { 432 //no-op 433 434 } // setDTDContentModelHandler(XMLDTDContentModelHandler) 435 436 /** Returns the registered DTD content model handler. */ 437 public XMLDTDContentModelHandler getDTDContentModelHandler() { 438 return null; 439 } // getDTDContentModelHandler():XMLDTDContentModelHandler 440 441 /** 442 * Sets the resolver used to resolve external entities. The EntityResolver 443 * interface supports resolution of public and system identifiers. 444 * 445 * @param resolver The new entity resolver. Passing a null value will 446 * uninstall the currently installed resolver. 447 */ 448 public void setEntityResolver(XMLEntityResolver resolver) { 449 if (resolver !=null) { 450 fProperties.put(ENTITY_RESOLVER, resolver); 451 } 452 } // setEntityResolver(XMLEntityResolver) 453 454 /** 455 * Return the current entity resolver. 456 * 457 * @return The current entity resolver, or null if none 458 * has been registered. 459 * @see #setEntityResolver 460 */ 461 public XMLEntityResolver getEntityResolver() { 462 return (XMLEntityResolver)fProperties.get(ENTITY_RESOLVER); 463 } // getEntityResolver():XMLEntityResolver 464 465 /** 466 * Allow an application to register an error event handler. 467 * 468 * <p>If the application does not register an error handler, all 469 * error events reported by the SAX parser will be silently 470 * ignored; however, normal processing may not continue. It is 471 * highly recommended that all SAX applications implement an 472 * error handler to avoid unexpected bugs.</p> 473 * 474 * <p>Applications may register a new or different handler in the 475 * middle of a parse, and the SAX parser must begin using the new 476 * handler immediately.</p> 477 * 478 * @param errorHandler The error handler. 479 * @exception java.lang.NullPointerException If the handler 480 * argument is null. 481 * @see #getErrorHandler 482 */ 483 public void setErrorHandler(XMLErrorHandler errorHandler) { 484 if (errorHandler != null) { 485 fProperties.put(ERROR_HANDLER, errorHandler); 486 } 487 } // setErrorHandler(XMLErrorHandler) 488 489 /** 490 * Return the current error handler. 491 * 492 * @return The current error handler, or null if none 493 * has been registered. 494 * @see #setErrorHandler 495 */ 496 public XMLErrorHandler getErrorHandler() { 497 return (XMLErrorHandler)fProperties.get(ERROR_HANDLER); 498 } // getErrorHandler():XMLErrorHandler 499 500 /** 501 * Set the state of a feature. 502 * 503 * Set the state of any feature in a SAX2 parser. The parser 504 * might not recognize the feature, and if it does recognize 505 * it, it might not be able to fulfill the request. 506 * 507 * @param featureId The unique identifier (URI) of the feature. 508 * @param state The requested state of the feature (true or false). 509 * 510 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 511 * requested feature is not known. 512 */ 513 public void setFeature(String featureId, boolean state) 514 throws XMLConfigurationException { 515 516 // save state if noone "objects" 517 super.setFeature(featureId, state); 518 519 } // setFeature(String,boolean) 520 521 /** 522 * setProperty 523 * 524 * @param propertyId 525 * @param value 526 */ 527 public void setProperty(String propertyId, Object value) 528 throws XMLConfigurationException { 529 530 // store value if noone "objects" 531 super.setProperty(propertyId, value); 532 533 } // setProperty(String,Object) 534 535 /** 536 * Set the locale to use for messages. 537 * 538 * @param locale The locale object to use for localization of messages. 539 * 540 * @exception XNIException Thrown if the parser does not support the 541 * specified locale. 542 */ 543 public void setLocale(Locale locale) throws XNIException { 544 fLocale = locale; 545 fErrorReporter.setLocale(locale); 546 547 } // setLocale(Locale) 548 549 /** Returns the locale. */ 550 public Locale getLocale() { 551 return fLocale; 552 } // getLocale():Locale 553 554 /** 555 * DOM Level 3 WD - Experimental. 556 * setParameter 557 */ 558 public void setParameter(String name, Object value) throws DOMException { 559 boolean found = true; 560 561 // REVISIT: Recognizes DOM L3 default features only. 562 // Does not yet recognize Xerces features. 563 if(value instanceof Boolean){ 564 boolean state = ((Boolean)value).booleanValue(); 565 566 if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) { 567 features = (short) (state ? features | COMMENTS : features & ~COMMENTS); 568 } 569 else if (name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) { 570 setFeature(NORMALIZE_DATA, state); 571 features = 572 (short) (state ? features | DTNORMALIZATION : features & ~DTNORMALIZATION); 573 if (state) { 574 features = (short) (features | VALIDATE); 575 } 576 } 577 else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) { 578 features = (short) (state ? features | NAMESPACES : features & ~NAMESPACES); 579 } 580 else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) { 581 features = (short) (state ? features | CDATA : features & ~CDATA); 582 } 583 else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) { 584 features = (short) (state ? features | ENTITIES : features & ~ENTITIES); 585 } 586 else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) { 587 features = (short) (state ? features | SPLITCDATA : features & ~SPLITCDATA); 588 } 589 else if (name.equalsIgnoreCase(Constants.DOM_VALIDATE)) { 590 features = (short) (state ? features | VALIDATE : features & ~VALIDATE); 591 } 592 else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) { 593 features = (short) (state ? features | WELLFORMED : features & ~WELLFORMED ); 594 } 595 else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) { 596 features = (short) (state ? features | NSDECL : features & ~NSDECL); 597 } 598 else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) { 599 // Setting to false has no effect. 600 if (state) { 601 features = (short) (features | INFOSET_TRUE_PARAMS); 602 features = (short) (features & ~INFOSET_FALSE_PARAMS); 603 setFeature(NORMALIZE_DATA, false); 604 } 605 } 606 else if (name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS) 607 || name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 608 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 609 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 610 ) { 611 if (state) { // true is not supported 612 String msg = 613 DOMMessageFormatter.formatMessage( 614 DOMMessageFormatter.DOM_DOMAIN, 615 "FEATURE_NOT_SUPPORTED", 616 new Object[] { name }); 617 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 618 } 619 } 620 else if ( name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)) { 621 if (!state) { // false is not supported 622 String msg = 623 DOMMessageFormatter.formatMessage( 624 DOMMessageFormatter.DOM_DOMAIN, 625 "FEATURE_NOT_SUPPORTED", 626 new Object[] { name }); 627 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 628 } 629 } 630 else if (name.equalsIgnoreCase(SEND_PSVI) ){ 631 // REVISIT: turning augmentation of PSVI is not support, 632 // because in this case we won't be able to retrieve element 633 // default value. 634 if (!state) { // false is not supported 635 String msg = 636 DOMMessageFormatter.formatMessage( 637 DOMMessageFormatter.DOM_DOMAIN, 638 "FEATURE_NOT_SUPPORTED", 639 new Object[] { name }); 640 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 641 } 642 } 643 else if (name.equalsIgnoreCase(Constants.DOM_PSVI)){ 644 features = (short) (state ? features | PSVI : features & ~PSVI); 645 } 646 else { 647 found = false; 648 /* 649 String msg = 650 DOMMessageFormatter.formatMessage( 651 DOMMessageFormatter.DOM_DOMAIN, 652 "FEATURE_NOT_FOUND", 653 new Object[] { name }); 654 throw new DOMException(DOMException.NOT_FOUND_ERR, msg); 655 */ 656 } 657 658 } 659 660 if (!found || !(value instanceof Boolean)) { // set properties 661 found = true; 662 663 if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) { 664 if (value instanceof DOMErrorHandler || value == null) { 665 fErrorHandlerWrapper.setErrorHandler((DOMErrorHandler)value); 666 setErrorHandler(fErrorHandlerWrapper); 667 } 668 669 else { 670 // REVISIT: type mismatch 671 String msg = 672 DOMMessageFormatter.formatMessage( 673 DOMMessageFormatter.DOM_DOMAIN, 674 "TYPE_MISMATCH_ERR", 675 new Object[] { name }); 676 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); 677 } 678 } 679 else if (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)) { 680 if (value instanceof LSResourceResolver || value == null) { 681 try { 682 setEntityResolver(new DOMEntityResolverWrapper((LSResourceResolver) value)); 683 } 684 catch (XMLConfigurationException e) {} 685 } 686 else { 687 // REVISIT: type mismatch 688 String msg = 689 DOMMessageFormatter.formatMessage( 690 DOMMessageFormatter.DOM_DOMAIN, 691 "TYPE_MISMATCH_ERR", 692 new Object[] { name }); 693 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); 694 } 695 696 } 697 else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) { 698 if (value instanceof String || value == null) { 699 try { 700 // map DOM schema-location to JAXP schemaSource property 701 setProperty( 702 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE, 703 value); 704 } 705 catch (XMLConfigurationException e) {} 706 } 707 else { 708 // REVISIT: type mismatch 709 String msg = 710 DOMMessageFormatter.formatMessage( 711 DOMMessageFormatter.DOM_DOMAIN, 712 "TYPE_MISMATCH_ERR", 713 new Object[] { name }); 714 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); 715 } 716 717 } 718 else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) { 719 if (value instanceof String || value == null) { 720 try { 721 if (value == null) { 722 setProperty( 723 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE, 724 null); 725 } 726 else if (value.equals(Constants.NS_XMLSCHEMA)) { 727 // REVISIT: when add support to DTD validation 728 setProperty( 729 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE, 730 Constants.NS_XMLSCHEMA); 731 } 732 else if (value.equals(Constants.NS_DTD)) { 733 // Added support for revalidation against DTDs 734 setProperty(Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE, 735 Constants.NS_DTD); 736 } 737 } 738 catch (XMLConfigurationException e) {} 739 } 740 else { 741 String msg = 742 DOMMessageFormatter.formatMessage( 743 DOMMessageFormatter.DOM_DOMAIN, 744 "TYPE_MISMATCH_ERR", 745 new Object[] { name }); 746 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); 747 } 748 749 } 750 else if (name.equalsIgnoreCase(SYMBOL_TABLE)){ 751 // Xerces Symbol Table 752 if (value instanceof SymbolTable){ 753 setProperty(SYMBOL_TABLE, value); 754 } 755 else { 756 // REVISIT: type mismatch 757 String msg = 758 DOMMessageFormatter.formatMessage( 759 DOMMessageFormatter.DOM_DOMAIN, 760 "TYPE_MISMATCH_ERR", 761 new Object[] { name }); 762 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); 763 } 764 } 765 else if (name.equalsIgnoreCase (GRAMMAR_POOL)){ 766 if (value instanceof XMLGrammarPool){ 767 setProperty(GRAMMAR_POOL, value); 768 } 769 else { 770 // REVISIT: type mismatch 771 String msg = 772 DOMMessageFormatter.formatMessage( 773 DOMMessageFormatter.DOM_DOMAIN, 774 "TYPE_MISMATCH_ERR", 775 new Object[] { name }); 776 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); 777 } 778 779 } 780 else { 781 // REVISIT: check if this is a boolean parameter -- type mismatch should be thrown. 782 //parameter is not recognized 783 String msg = 784 DOMMessageFormatter.formatMessage( 785 DOMMessageFormatter.DOM_DOMAIN, 786 "FEATURE_NOT_FOUND", 787 new Object[] { name }); 788 throw new DOMException(DOMException.NOT_FOUND_ERR, msg); 789 } 790 } 791 792 } 793 794 795 /** 796 * DOM Level 3 WD - Experimental. 797 * getParameter 798 */ 799 public Object getParameter(String name) throws DOMException { 800 801 // REVISIT: Recognizes DOM L3 default features only. 802 // Does not yet recognize Xerces features. 803 804 if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) { 805 return ((features & COMMENTS) != 0) ? Boolean.TRUE : Boolean.FALSE; 806 } 807 else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) { 808 return (features & NAMESPACES) != 0 ? Boolean.TRUE : Boolean.FALSE; 809 } 810 else if (name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) { 811 // REVISIT: datatype-normalization only takes effect if validation is on 812 return (features & DTNORMALIZATION) != 0 ? Boolean.TRUE : Boolean.FALSE; 813 } 814 else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) { 815 return (features & CDATA) != 0 ? Boolean.TRUE : Boolean.FALSE; 816 } 817 else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) { 818 return (features & ENTITIES) != 0 ? Boolean.TRUE : Boolean.FALSE; 819 } 820 else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) { 821 return (features & SPLITCDATA) != 0 ? Boolean.TRUE : Boolean.FALSE; 822 } 823 else if (name.equalsIgnoreCase(Constants.DOM_VALIDATE)) { 824 return (features & VALIDATE) != 0 ? Boolean.TRUE : Boolean.FALSE; 825 } 826 else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) { 827 return (features & WELLFORMED) != 0 ? Boolean.TRUE : Boolean.FALSE; 828 } 829 else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) { 830 return (features & NSDECL) != 0 ? Boolean.TRUE : Boolean.FALSE; 831 } 832 else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) { 833 return (features & INFOSET_MASK) == INFOSET_TRUE_PARAMS ? Boolean.TRUE : Boolean.FALSE; 834 } 835 else if (name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS) 836 || name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 837 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 838 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 839 ) { 840 return Boolean.FALSE; 841 } 842 else if (name.equalsIgnoreCase(SEND_PSVI)) { 843 return Boolean.TRUE; 844 } 845 else if (name.equalsIgnoreCase(Constants.DOM_PSVI)) { 846 return (features & PSVI) != 0 ? Boolean.TRUE : Boolean.FALSE; 847 } 848 else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)) { 849 return Boolean.TRUE; 850 } 851 else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) { 852 return fErrorHandlerWrapper.getErrorHandler(); 853 } 854 else if (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)) { 855 XMLEntityResolver entityResolver = getEntityResolver(); 856 if (entityResolver != null && entityResolver instanceof DOMEntityResolverWrapper) { 857 return ((DOMEntityResolverWrapper) entityResolver).getEntityResolver(); 858 } 859 return null; 860 } 861 else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) { 862 return getProperty(Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE); 863 } 864 else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) { 865 return getProperty(Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE); 866 } 867 else if (name.equalsIgnoreCase(SYMBOL_TABLE)){ 868 return getProperty(SYMBOL_TABLE); 869 } 870 else if (name.equalsIgnoreCase(GRAMMAR_POOL)){ 871 return getProperty(GRAMMAR_POOL); 872 } 873 else { 874 String msg = 875 DOMMessageFormatter.formatMessage( 876 DOMMessageFormatter.DOM_DOMAIN, 877 "FEATURE_NOT_FOUND", 878 new Object[] { name }); 879 throw new DOMException(DOMException.NOT_FOUND_ERR, msg); 880 } 881 882 } 883 884 /** 885 * DOM Level 3 WD - Experimental. 886 * Check if setting a parameter to a specific value is supported. 887 * 888 * @param name The name of the parameter to check. 889 * 890 * @param value An object. if null, the returned value is true. 891 * 892 * @return true if the parameter could be successfully set to the 893 * specified value, or false if the parameter is not recognized or 894 * the requested value is not supported. This does not change the 895 * current value of the parameter itself. 896 */ 897 public boolean canSetParameter(String name, Object value) { 898 899 if (value == null){ 900 //if null, the returned value is true. 901 //REVISIT: I dont like this --- even for unrecognized parameter it would 902 //return 'true'. I think it should return false in that case. 903 // Application will be surprised to find that setParameter throws not 904 //recognized exception when canSetParameter returns 'true' Then what is the use 905 //of having canSetParameter ??? - nb. 906 return true ; 907 } 908 if( value instanceof Boolean ){ 909 //features whose parameter value can be set either 'true' or 'false' 910 // or they accept any boolean value -- so we just need to check that 911 // its a boolean value.. 912 if (name.equalsIgnoreCase(Constants.DOM_COMMENTS) 913 || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION) 914 || name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS) 915 || name.equalsIgnoreCase(Constants.DOM_ENTITIES) 916 || name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA) 917 || name.equalsIgnoreCase(Constants.DOM_NAMESPACES) 918 || name.equalsIgnoreCase(Constants.DOM_VALIDATE) 919 || name.equalsIgnoreCase(Constants.DOM_WELLFORMED) 920 || name.equalsIgnoreCase(Constants.DOM_INFOSET) 921 || name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS) 922 ) { 923 return true; 924 }//features whose parameter value can not be set to 'true' 925 else if ( 926 name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS) 927 || name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 928 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 929 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 930 ) { 931 return (value.equals(Boolean.TRUE)) ? false : true; 932 }//features whose parameter value can not be set to 'false' 933 else if( name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) 934 || name.equalsIgnoreCase(SEND_PSVI) 935 ) { 936 return (value.equals(Boolean.TRUE)) ? true : false; 937 }// if name is not among the above listed above -- its not recognized. return false 938 else { 939 return false ; 940 } 941 } 942 else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) { 943 return (value instanceof DOMErrorHandler) ? true : false ; 944 } 945 else if (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)) { 946 return (value instanceof LSResourceResolver) ? true : false ; 947 } 948 else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) { 949 return (value instanceof String) ? true : false ; 950 } 951 else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) { 952 // REVISIT: should null value be supported? 953 //as of now we are only supporting W3C XML Schema 954 return ( (value instanceof String) && value.equals(Constants.NS_XMLSCHEMA) ) ? true : false ; 955 } 956 else if (name.equalsIgnoreCase(SYMBOL_TABLE)){ 957 // Xerces Symbol Table 958 return (value instanceof SymbolTable) ? true : false ; 959 } 960 else if (name.equalsIgnoreCase (GRAMMAR_POOL)){ 961 return (value instanceof XMLGrammarPool) ? true : false ; 962 } 963 else { 964 //false if the parameter is not recognized or the requested value is not supported. 965 return false ; 966 } 967 968 } //canSetParameter 969 970 /** 971 * DOM Level 3 CR - Experimental. 972 * 973 * The list of the parameters supported by this 974 * <code>DOMConfiguration</code> object and for which at least one value 975 * can be set by the application. Note that this list can also contain 976 * parameter names defined outside this specification. 977 */ 978 public DOMStringList getParameterNames() { 979 if (fRecognizedParameters == null){ 980 Vector parameters = new Vector(); 981 982 //Add DOM recognized parameters 983 //REVISIT: Would have been nice to have a list of 984 //recognized paramters. 985 parameters.add(Constants.DOM_COMMENTS); 986 parameters.add(Constants.DOM_DATATYPE_NORMALIZATION); 987 parameters.add(Constants.DOM_CDATA_SECTIONS); 988 parameters.add(Constants.DOM_ENTITIES); 989 parameters.add(Constants.DOM_SPLIT_CDATA); 990 parameters.add(Constants.DOM_NAMESPACES); 991 parameters.add(Constants.DOM_VALIDATE); 992 993 parameters.add(Constants.DOM_INFOSET); 994 parameters.add(Constants.DOM_NORMALIZE_CHARACTERS); 995 parameters.add(Constants.DOM_CANONICAL_FORM); 996 parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA); 997 parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION); 998 parameters.add(Constants.DOM_WELLFORMED); 999 1000 parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS); 1001 parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE); 1002 1003 parameters.add(Constants.DOM_ERROR_HANDLER); 1004 parameters.add(Constants.DOM_SCHEMA_TYPE); 1005 parameters.add(Constants.DOM_SCHEMA_LOCATION); 1006 parameters.add(Constants.DOM_RESOURCE_RESOLVER); 1007 1008 //Add recognized xerces features and properties 1009 parameters.add(GRAMMAR_POOL); 1010 parameters.add(SYMBOL_TABLE); 1011 parameters.add(SEND_PSVI); 1012 1013 fRecognizedParameters = new DOMStringListImpl(parameters); 1014 1015 } 1016 1017 return fRecognizedParameters; 1018 }//getParameterNames 1019 1020 // 1021 // Protected methods 1022 // 1023 1024 /** 1025 * reset all components before parsing 1026 */ 1027 protected void reset() throws XNIException { 1028 1029 if (fValidationManager != null) 1030 fValidationManager.reset(); 1031 1032 int count = fComponents.size(); 1033 for (int i = 0; i < count; i++) { 1034 XMLComponent c = (XMLComponent) fComponents.get(i); 1035 c.reset(this); 1036 } 1037 1038 } // reset() 1039 1040 /** 1041 * Check a property. If the property is known and supported, this method 1042 * simply returns. Otherwise, the appropriate exception is thrown. 1043 * 1044 * @param propertyId The unique identifier (URI) of the property 1045 * being set. 1046 * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the 1047 * requested feature is not known or supported. 1048 */ 1049 protected PropertyState checkProperty(String propertyId) 1050 throws XMLConfigurationException { 1051 1052 // special cases 1053 if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) { 1054 final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length(); 1055 1056 // 1057 // http://xml.org/sax/properties/xml-string 1058 // Value type: String 1059 // Access: read-only 1060 // Get the literal string of characters associated with the 1061 // current event. If the parser recognises and supports this 1062 // property but is not currently parsing text, it should return 1063 // null (this is a good way to check for availability before the 1064 // parse begins). 1065 // 1066 if (suffixLength == Constants.XML_STRING_PROPERTY.length() && 1067 propertyId.endsWith(Constants.XML_STRING_PROPERTY)) { 1068 // REVISIT - we should probably ask xml-dev for a precise 1069 // definition of what this is actually supposed to return, and 1070 // in exactly which circumstances. 1071 return PropertyState.NOT_SUPPORTED; 1072 } 1073 } 1074 1075 // check property 1076 return super.checkProperty(propertyId); 1077 1078 } // checkProperty(String) 1079 1080 1081 protected void addComponent(XMLComponent component) { 1082 1083 // don't add a component more than once 1084 if (fComponents.contains(component)) { 1085 return; 1086 } 1087 fComponents.add(component); 1088 1089 // register component's recognized features 1090 String[] recognizedFeatures = component.getRecognizedFeatures(); 1091 addRecognizedFeatures(recognizedFeatures); 1092 1093 // register component's recognized properties 1094 String[] recognizedProperties = component.getRecognizedProperties(); 1095 addRecognizedProperties(recognizedProperties); 1096 1097 } // addComponent(XMLComponent) 1098 1099 protected ValidationManager createValidationManager(){ 1100 return new ValidationManager(); 1101 } 1102 1103 } // class XMLParser