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