1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xerces.internal.parsers;
  23 
  24 import java.io.IOException;
  25 
  26 import com.sun.org.apache.xerces.internal.impl.Constants;
  27 import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper;
  28 import com.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper;
  29 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
  30 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  31 import com.sun.org.apache.xerces.internal.util.Status;
  32 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  33 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
  34 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
  35 import com.sun.org.apache.xerces.internal.xni.XNIException;
  36 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  37 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  38 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  39 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  40 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  41 import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
  42 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
  43 import org.w3c.dom.Node;
  44 import org.xml.sax.EntityResolver;
  45 import org.xml.sax.ErrorHandler;
  46 import org.xml.sax.InputSource;
  47 import org.xml.sax.SAXException;
  48 import org.xml.sax.SAXNotRecognizedException;
  49 import org.xml.sax.SAXNotSupportedException;
  50 import org.xml.sax.SAXParseException;
  51 import org.xml.sax.ext.EntityResolver2;
  52 import org.xml.sax.helpers.LocatorImpl;
  53 
  54 /**
  55  * This is the main Xerces DOM parser class. It uses the abstract DOM
  56  * parser with a document scanner, a dtd scanner, and a validator, as
  57  * well as a grammar pool.
  58  *
  59  * @author Arnaud  Le Hors, IBM
  60  * @author Andy Clark, IBM
  61  *
  62  * @version $Id: DOMParser.java,v 1.7 2010-11-01 04:40:09 joehw Exp $
  63  */
  64 public class DOMParser
  65     extends AbstractDOMParser {
  66 
  67     //
  68     // Constants
  69     //
  70 
  71     // features
  72 
  73     /** Feature identifier: EntityResolver2. */
  74     protected static final String USE_ENTITY_RESOLVER2 =
  75         Constants.SAX_FEATURE_PREFIX + Constants.USE_ENTITY_RESOLVER2_FEATURE;
  76 
  77     protected static final String REPORT_WHITESPACE =
  78             Constants.SUN_SCHEMA_FEATURE_PREFIX + Constants.SUN_REPORT_IGNORED_ELEMENT_CONTENT_WHITESPACE;
  79 
  80     /** Property identifier: Security property manager. */
  81     private static final String XML_SECURITY_PROPERTY_MANAGER =
  82             Constants.XML_SECURITY_PROPERTY_MANAGER;
  83 
  84     // recognized features:
  85     private static final String[] RECOGNIZED_FEATURES = {
  86         REPORT_WHITESPACE
  87     };
  88 
  89     // properties
  90 
  91     /** Property identifier: symbol table. */
  92     protected static final String SYMBOL_TABLE =
  93         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
  94 
  95     /** Property identifier: XML grammar pool. */
  96     protected static final String XMLGRAMMAR_POOL =
  97         Constants.XERCES_PROPERTY_PREFIX+Constants.XMLGRAMMAR_POOL_PROPERTY;
  98 
  99     /** Recognized properties. */
 100     private static final String[] RECOGNIZED_PROPERTIES = {
 101         SYMBOL_TABLE,
 102         XMLGRAMMAR_POOL,
 103     };
 104 
 105     //
 106     // Data
 107     //
 108 
 109     // features
 110 
 111     /** Use EntityResolver2. */
 112     protected boolean fUseEntityResolver2 = true;
 113 
 114     //
 115     // Constructors
 116     //
 117 
 118     /**
 119      * Constructs a DOM parser using the specified parser configuration.
 120      */
 121     public DOMParser(XMLParserConfiguration config) {
 122         super(config);
 123     } // <init>(XMLParserConfiguration)
 124 
 125     /**
 126      * Constructs a DOM parser using the dtd/xml schema parser configuration.
 127      */
 128     public DOMParser() {
 129         this(null, null);
 130     } // <init>()
 131 
 132     /**
 133      * Constructs a DOM parser using the specified symbol table.
 134      */
 135     public DOMParser(SymbolTable symbolTable) {
 136         this(symbolTable, null);
 137     } // <init>(SymbolTable)
 138 
 139 
 140     /**
 141      * Constructs a DOM parser using the specified symbol table and
 142      * grammar pool.
 143      */
 144     public DOMParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
 145         super(new XIncludeAwareParserConfiguration());
 146 
 147         // set properties
 148         fConfiguration.addRecognizedProperties(RECOGNIZED_PROPERTIES);
 149         if (symbolTable != null) {
 150             fConfiguration.setProperty(SYMBOL_TABLE, symbolTable);
 151         }
 152         if (grammarPool != null) {
 153             fConfiguration.setProperty(XMLGRAMMAR_POOL, grammarPool);
 154         }
 155 
 156         fConfiguration.addRecognizedFeatures(RECOGNIZED_FEATURES);
 157 
 158     } // <init>(SymbolTable,XMLGrammarPool)
 159 
 160     //
 161     // XMLReader methods
 162     //
 163 
 164     /**
 165      * Parses the input source specified by the given system identifier.
 166      * <p>
 167      * This method is equivalent to the following:
 168      * <pre>
 169      *     parse(new InputSource(systemId));
 170      * </pre>
 171      *
 172      * @param systemId The system identifier (URI).
 173      *
 174      * @exception org.xml.sax.SAXException Throws exception on SAX error.
 175      * @exception java.io.IOException Throws exception on i/o error.
 176      */
 177     public void parse(String systemId) throws SAXException, IOException {
 178 
 179         // parse document
 180         XMLInputSource source = new XMLInputSource(null, systemId, null);
 181         try {
 182             parse(source);
 183         }
 184 
 185         // wrap XNI exceptions as SAX exceptions
 186         catch (XMLParseException e) {
 187             Exception ex = e.getException();
 188             if (ex == null) {
 189                 // must be a parser exception; mine it for locator info and throw
 190                 // a SAXParseException
 191                 LocatorImpl locatorImpl = new LocatorImpl();
 192                 locatorImpl.setPublicId(e.getPublicId());
 193                 locatorImpl.setSystemId(e.getExpandedSystemId());
 194                 locatorImpl.setLineNumber(e.getLineNumber());
 195                 locatorImpl.setColumnNumber(e.getColumnNumber());
 196                 throw new SAXParseException(e.getMessage(), locatorImpl);
 197             }
 198             if (ex instanceof SAXException) {
 199                 // why did we create an XMLParseException?
 200                 throw (SAXException)ex;
 201             }
 202             if (ex instanceof IOException) {
 203                 throw (IOException)ex;
 204             }
 205             throw new SAXException(ex);
 206         }
 207         catch (XNIException e) {
 208             e.printStackTrace();
 209             Exception ex = e.getException();
 210             if (ex == null) {
 211                 throw new SAXException(e.getMessage());
 212             }
 213             if (ex instanceof SAXException) {
 214                 throw (SAXException)ex;
 215             }
 216             if (ex instanceof IOException) {
 217                 throw (IOException)ex;
 218             }
 219             throw new SAXException(ex);
 220         }
 221 
 222     } // parse(String)
 223 
 224     /**
 225      * parse
 226      *
 227      * @param inputSource
 228      *
 229      * @exception org.xml.sax.SAXException
 230      * @exception java.io.IOException
 231      */
 232     public void parse(InputSource inputSource)
 233         throws SAXException, IOException {
 234 
 235         // parse document
 236         try {
 237             XMLInputSource xmlInputSource =
 238                 new XMLInputSource(inputSource.getPublicId(),
 239                                    inputSource.getSystemId(),
 240                                    null);
 241             xmlInputSource.setByteStream(inputSource.getByteStream());
 242             xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
 243             xmlInputSource.setEncoding(inputSource.getEncoding());
 244             parse(xmlInputSource);
 245         }
 246 
 247         // wrap XNI exceptions as SAX exceptions
 248         catch (XMLParseException e) {
 249             Exception ex = e.getException();
 250             if (ex == null) {
 251                 // must be a parser exception; mine it for locator info and throw
 252                 // a SAXParseException
 253                 LocatorImpl locatorImpl = new LocatorImpl();
 254                 locatorImpl.setPublicId(e.getPublicId());
 255                 locatorImpl.setSystemId(e.getExpandedSystemId());
 256                 locatorImpl.setLineNumber(e.getLineNumber());
 257                 locatorImpl.setColumnNumber(e.getColumnNumber());
 258                 throw new SAXParseException(e.getMessage(), locatorImpl);
 259             }
 260             if (ex instanceof SAXException) {
 261                 // why did we create an XMLParseException?
 262                 throw (SAXException)ex;
 263             }
 264             if (ex instanceof IOException) {
 265                 throw (IOException)ex;
 266             }
 267             throw new SAXException(ex);
 268         }
 269         catch (XNIException e) {
 270             Exception ex = e.getException();
 271             if (ex == null) {
 272                 throw new SAXException(e.getMessage());
 273             }
 274             if (ex instanceof SAXException) {
 275                 throw (SAXException)ex;
 276             }
 277             if (ex instanceof IOException) {
 278                 throw (IOException)ex;
 279             }
 280             throw new SAXException(ex);
 281         }
 282 
 283     } // parse(InputSource)
 284 
 285     /**
 286      * Sets the resolver used to resolve external entities. The EntityResolver
 287      * interface supports resolution of public and system identifiers.
 288      *
 289      * @param resolver The new entity resolver. Passing a null value will
 290      *                 uninstall the currently installed resolver.
 291      */
 292     public void setEntityResolver(EntityResolver resolver) {
 293 
 294         try {
 295             XMLEntityResolver xer = (XMLEntityResolver) fConfiguration.getProperty(ENTITY_RESOLVER);
 296             if (fUseEntityResolver2 && resolver instanceof EntityResolver2) {
 297                 if (xer instanceof EntityResolver2Wrapper) {
 298                     EntityResolver2Wrapper er2w = (EntityResolver2Wrapper) xer;
 299                     er2w.setEntityResolver((EntityResolver2) resolver);
 300                 }
 301                 else {
 302                     fConfiguration.setProperty(ENTITY_RESOLVER,
 303                             new EntityResolver2Wrapper((EntityResolver2) resolver));
 304                 }
 305             }
 306             else {
 307                 if (xer instanceof EntityResolverWrapper) {
 308                     EntityResolverWrapper erw = (EntityResolverWrapper) xer;
 309                     erw.setEntityResolver(resolver);
 310                 }
 311                 else {
 312                     fConfiguration.setProperty(ENTITY_RESOLVER,
 313                             new EntityResolverWrapper(resolver));
 314                 }
 315             }
 316         }
 317         catch (XMLConfigurationException e) {
 318             // do nothing
 319         }
 320 
 321     } // setEntityResolver(EntityResolver)
 322 
 323     /**
 324      * Return the current entity resolver.
 325      *
 326      * @return The current entity resolver, or null if none
 327      *         has been registered.
 328      * @see #setEntityResolver
 329      */
 330     public EntityResolver getEntityResolver() {
 331 
 332         EntityResolver entityResolver = null;
 333         try {
 334             XMLEntityResolver xmlEntityResolver =
 335                 (XMLEntityResolver)fConfiguration.getProperty(ENTITY_RESOLVER);
 336             if (xmlEntityResolver != null) {
 337                 if (xmlEntityResolver instanceof EntityResolverWrapper) {
 338                     entityResolver =
 339                         ((EntityResolverWrapper) xmlEntityResolver).getEntityResolver();
 340                 }
 341                 else if (xmlEntityResolver instanceof EntityResolver2Wrapper) {
 342                     entityResolver =
 343                         ((EntityResolver2Wrapper) xmlEntityResolver).getEntityResolver();
 344                 }
 345             }
 346         }
 347         catch (XMLConfigurationException e) {
 348             // do nothing
 349         }
 350         return entityResolver;
 351 
 352     } // getEntityResolver():EntityResolver
 353 
 354     /**
 355      * Allow an application to register an error event handler.
 356      *
 357      * <p>If the application does not register an error handler, all
 358      * error events reported by the SAX parser will be silently
 359      * ignored; however, normal processing may not continue.  It is
 360      * highly recommended that all SAX applications implement an
 361      * error handler to avoid unexpected bugs.</p>
 362      *
 363      * <p>Applications may register a new or different handler in the
 364      * middle of a parse, and the SAX parser must begin using the new
 365      * handler immediately.</p>
 366      *
 367      * @param errorHandler The error handler.
 368      * @exception java.lang.NullPointerException If the handler
 369      *            argument is null.
 370      * @see #getErrorHandler
 371      */
 372     public void setErrorHandler(ErrorHandler errorHandler) {
 373 
 374         try {
 375             XMLErrorHandler xeh = (XMLErrorHandler) fConfiguration.getProperty(ERROR_HANDLER);
 376             if (xeh instanceof ErrorHandlerWrapper) {
 377                 ErrorHandlerWrapper ehw = (ErrorHandlerWrapper) xeh;
 378                 ehw.setErrorHandler(errorHandler);
 379             }
 380             else {
 381                 fConfiguration.setProperty(ERROR_HANDLER,
 382                         new ErrorHandlerWrapper(errorHandler));
 383             }
 384         }
 385         catch (XMLConfigurationException e) {
 386             // do nothing
 387         }
 388 
 389     } // setErrorHandler(ErrorHandler)
 390 
 391     /**
 392      * Return the current error handler.
 393      *
 394      * @return The current error handler, or null if none
 395      *         has been registered.
 396      * @see #setErrorHandler
 397      */
 398     public ErrorHandler getErrorHandler() {
 399 
 400         ErrorHandler errorHandler = null;
 401         try {
 402             XMLErrorHandler xmlErrorHandler =
 403                 (XMLErrorHandler)fConfiguration.getProperty(ERROR_HANDLER);
 404             if (xmlErrorHandler != null &&
 405                 xmlErrorHandler instanceof ErrorHandlerWrapper) {
 406                 errorHandler = ((ErrorHandlerWrapper)xmlErrorHandler).getErrorHandler();
 407             }
 408         }
 409         catch (XMLConfigurationException e) {
 410             // do nothing
 411         }
 412         return errorHandler;
 413 
 414     } // getErrorHandler():ErrorHandler
 415 
 416     /**
 417      * Set the state of any feature in a SAX2 parser.  The parser
 418      * might not recognize the feature, and if it does recognize
 419      * it, it might not be able to fulfill the request.
 420      *
 421      * @param featureId The unique identifier (URI) of the feature.
 422      * @param state The requested state of the feature (true or false).
 423      *
 424      * @exception SAXNotRecognizedException If the
 425      *            requested feature is not known.
 426      * @exception SAXNotSupportedException If the
 427      *            requested feature is known, but the requested
 428      *            state is not supported.
 429      */
 430     public void setFeature(String featureId, boolean state)
 431         throws SAXNotRecognizedException, SAXNotSupportedException {
 432 
 433         try {
 434 
 435             // http://xml.org/sax/features/use-entity-resolver2
 436             //   controls whether the methods of an object implementing
 437             //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
 438             //
 439             if (featureId.equals(USE_ENTITY_RESOLVER2)) {
 440                 if (state != fUseEntityResolver2) {
 441                     fUseEntityResolver2 = state;
 442                     // Refresh EntityResolver wrapper.
 443                     setEntityResolver(getEntityResolver());
 444                 }
 445                 return;
 446             }
 447 
 448             //
 449             // Default handling
 450             //
 451 
 452             fConfiguration.setFeature(featureId, state);
 453         }
 454         catch (XMLConfigurationException e) {
 455             String identifier = e.getIdentifier();
 456             if (e.getType() == Status.NOT_RECOGNIZED) {
 457                 throw new SAXNotRecognizedException(
 458                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 459                     "feature-not-recognized", new Object [] {identifier}));
 460             }
 461             else {
 462                 throw new SAXNotSupportedException(
 463                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 464                     "feature-not-supported", new Object [] {identifier}));
 465             }
 466         }
 467 
 468     } // setFeature(String,boolean)
 469 
 470     /**
 471      * Query the state of a feature.
 472      *
 473      * Query the current state of any feature in a SAX2 parser.  The
 474      * parser might not recognize the feature.
 475      *
 476      * @param featureId The unique identifier (URI) of the feature
 477      *                  being set.
 478      * @return The current state of the feature.
 479      * @exception org.xml.sax.SAXNotRecognizedException If the
 480      *            requested feature is not known.
 481      * @exception SAXNotSupportedException If the
 482      *            requested feature is known but not supported.
 483      */
 484     public boolean getFeature(String featureId)
 485         throws SAXNotRecognizedException, SAXNotSupportedException {
 486 
 487         try {
 488 
 489             // http://xml.org/sax/features/use-entity-resolver2
 490             //   controls whether the methods of an object implementing
 491             //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
 492             //
 493             if (featureId.equals(USE_ENTITY_RESOLVER2)) {
 494                 return fUseEntityResolver2;
 495             }
 496 
 497             //
 498             // Default handling
 499             //
 500 
 501             return fConfiguration.getFeature(featureId);
 502         }
 503         catch (XMLConfigurationException e) {
 504             String identifier = e.getIdentifier();
 505             if (e.getType() == Status.NOT_RECOGNIZED) {
 506                 throw new SAXNotRecognizedException(
 507                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 508                     "feature-not-recognized", new Object [] {identifier}));
 509             }
 510             else {
 511                 throw new SAXNotSupportedException(
 512                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 513                     "feature-not-supported", new Object [] {identifier}));
 514             }
 515         }
 516 
 517     } // getFeature(String):boolean
 518 
 519     /**
 520      * Set the value of any property in a SAX2 parser.  The parser
 521      * might not recognize the property, and if it does recognize
 522      * it, it might not support the requested value.
 523      *
 524      * @param propertyId The unique identifier (URI) of the property
 525      *                   being set.
 526      * @param value The value to which the property is being set.
 527      *
 528      * @exception SAXNotRecognizedException If the
 529      *            requested property is not known.
 530      * @exception SAXNotSupportedException If the
 531      *            requested property is known, but the requested
 532      *            value is not supported.
 533      */
 534     public void setProperty(String propertyId, Object value)
 535         throws SAXNotRecognizedException, SAXNotSupportedException {
 536         /**
 537          * It's possible for users to set a security manager through the interface.
 538          * If it's the old SecurityManager, convert it to the new XMLSecurityManager
 539          */
 540         if (propertyId.equals(Constants.SECURITY_MANAGER)) {
 541             securityManager = XMLSecurityManager.convert(value, securityManager);
 542             setProperty0(Constants.SECURITY_MANAGER, securityManager);
 543             return;
 544         }
 545         if (propertyId.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) {
 546             if (value == null) {
 547                 securityPropertyManager = new XMLSecurityPropertyManager();
 548             } else {
 549                 securityPropertyManager = (XMLSecurityPropertyManager)value;
 550             }
 551             setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
 552             return;
 553         }
 554 
 555         if (securityManager == null) {
 556             securityManager = new XMLSecurityManager(true);
 557             setProperty0(Constants.SECURITY_MANAGER, securityManager);
 558         }
 559 
 560         if (securityPropertyManager == null) {
 561             securityPropertyManager = new XMLSecurityPropertyManager();
 562             setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
 563         }
 564         int index = securityPropertyManager.getIndex(propertyId);
 565 
 566         if (index > -1) {
 567             /**
 568              * this is a direct call to this parser, not a subclass since
 569              * internally the support of this property is done through
 570              * XMLSecurityPropertyManager
 571              */
 572             securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
 573         } else {
 574             //check if the property is managed by security manager
 575             if (!securityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) {
 576                 //fall back to the default configuration to handle the property
 577                 setProperty0(propertyId, value);
 578             }
 579         }
 580     }
 581 
 582     public void setProperty0(String propertyId, Object value)
 583         throws SAXNotRecognizedException, SAXNotSupportedException {
 584         try {
 585             fConfiguration.setProperty(propertyId, value);
 586         }
 587         catch (XMLConfigurationException e) {
 588             String identifier = e.getIdentifier();
 589             if (e.getType() == Status.NOT_RECOGNIZED) {
 590                 throw new SAXNotRecognizedException(
 591                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 592                     "property-not-recognized", new Object [] {identifier}));
 593             }
 594             else {
 595                 throw new SAXNotSupportedException(
 596                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 597                     "property-not-supported", new Object [] {identifier}));
 598             }
 599         }
 600 
 601     } // setProperty(String,Object)
 602 
 603     /**
 604      * Query the value of a property.
 605      *
 606      * Return the current value of a property in a SAX2 parser.
 607      * The parser might not recognize the property.
 608      *
 609      * @param propertyId The unique identifier (URI) of the property
 610      *                   being set.
 611      * @return The current value of the property.
 612      * @exception org.xml.sax.SAXNotRecognizedException If the
 613      *            requested property is not known.
 614      * @exception SAXNotSupportedException If the
 615      *            requested property is known but not supported.
 616      */
 617     public Object getProperty(String propertyId)
 618         throws SAXNotRecognizedException, SAXNotSupportedException {
 619 
 620        if (propertyId.equals(CURRENT_ELEMENT_NODE)) {
 621            boolean deferred = false;
 622            try {
 623                deferred = getFeature(DEFER_NODE_EXPANSION);
 624            }
 625            catch (XMLConfigurationException e){
 626                // ignore
 627            }
 628            if (deferred) {
 629                throw new SAXNotSupportedException("Current element node cannot be queried when node expansion is deferred.");
 630            }
 631            return (fCurrentNode!=null &&
 632                    fCurrentNode.getNodeType() == Node.ELEMENT_NODE)? fCurrentNode:null;
 633        }
 634 
 635         try {
 636             XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)
 637                     fConfiguration.getProperty(XML_SECURITY_PROPERTY_MANAGER);
 638             int index = spm.getIndex(propertyId);
 639             if (index > -1) {
 640                 return spm.getValueByIndex(index);
 641             }
 642 
 643             return fConfiguration.getProperty(propertyId);
 644         }
 645         catch (XMLConfigurationException e) {
 646             String identifier = e.getIdentifier();
 647             if (e.getType() == Status.NOT_RECOGNIZED) {
 648                 throw new SAXNotRecognizedException(
 649                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 650                     "property-not-recognized", new Object [] {identifier}));
 651             }
 652             else {
 653                 throw new SAXNotSupportedException(
 654                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 655                     "property-not-supported", new Object [] {identifier}));
 656             }
 657         }
 658 
 659     } // getProperty(String):Object
 660 
 661     /**
 662      * Returns this parser's XMLParserConfiguration.
 663      */
 664     public XMLParserConfiguration getXMLParserConfiguration() {
 665         return fConfiguration;
 666     } // getXMLParserConfiguration():XMLParserConfiguration
 667 
 668 } // class DOMParser