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