1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2000-2005 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.jaxp;
  22 
  23 import java.io.IOException;
  24 import java.util.HashMap;
  25 import java.util.Hashtable;
  26 import java.util.Iterator;
  27 import java.util.Map;
  28 
  29 import javax.xml.XMLConstants;
  30 import javax.xml.validation.Schema;
  31 
  32 import com.sun.org.apache.xerces.internal.impl.Constants;
  33 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
  34 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
  35 import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer;
  36 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  37 import com.sun.org.apache.xerces.internal.util.SecurityManager;
  38 import com.sun.org.apache.xerces.internal.util.Status;
  39 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
  40 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
  41 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
  42 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  43 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  44 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
  45 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
  46 import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
  47 import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
  48 import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
  49 import org.xml.sax.EntityResolver;
  50 import org.xml.sax.ErrorHandler;
  51 import org.xml.sax.HandlerBase;
  52 import org.xml.sax.InputSource;
  53 import org.xml.sax.Parser;
  54 import org.xml.sax.SAXException;
  55 import org.xml.sax.SAXNotRecognizedException;
  56 import org.xml.sax.SAXNotSupportedException;
  57 import org.xml.sax.XMLReader;
  58 import org.xml.sax.helpers.DefaultHandler;
  59 
  60 /**
  61  * This is the implementation specific class for the
  62  * <code>javax.xml.parsers.SAXParser</code>.
  63  *
  64  * @author Rajiv Mordani
  65  * @author Edwin Goei
  66  *
  67  * @version $Id: SAXParserImpl.java,v 1.7 2010-11-01 04:40:06 joehw Exp $
  68  */
  69 public class SAXParserImpl extends javax.xml.parsers.SAXParser
  70     implements JAXPConstants, PSVIProvider {
  71 
  72     /** Feature identifier: namespaces. */
  73     private static final String NAMESPACES_FEATURE =
  74         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
  75 
  76     /** Feature identifier: namespace prefixes. */
  77     private static final String NAMESPACE_PREFIXES_FEATURE =
  78         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE;
  79 
  80     /** Feature identifier: validation. */
  81     private static final String VALIDATION_FEATURE =
  82         Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
  83 
  84     /** Feature identifier: XML Schema validation */
  85     private static final String XMLSCHEMA_VALIDATION_FEATURE =
  86         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
  87 
  88     /** Feature identifier: XInclude processing */
  89     private static final String XINCLUDE_FEATURE =
  90         Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;
  91 
  92     /** Property identifier: security manager. */
  93     private static final String SECURITY_MANAGER =
  94         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
  95 
  96     /** Property identifier: Security property manager. */
  97     private static final String XML_SECURITY_PROPERTY_MANAGER =
  98             Constants.XML_SECURITY_PROPERTY_MANAGER;
  99 
 100     private final JAXPSAXParser xmlReader;
 101     private String schemaLanguage = null;     // null means DTD
 102     private final Schema grammar;
 103 
 104     private final XMLComponent fSchemaValidator;
 105     private final XMLComponentManager fSchemaValidatorComponentManager;
 106     private final ValidationManager fSchemaValidationManager;
 107     private final UnparsedEntityHandler fUnparsedEntityHandler;
 108 
 109     /** Initial ErrorHandler */
 110     private final ErrorHandler fInitErrorHandler;
 111 
 112     /** Initial EntityResolver */
 113     private final EntityResolver fInitEntityResolver;
 114 
 115     private final XMLSecurityPropertyManager fSecurityPropertyMgr;
 116 
 117     /**
 118      * Create a SAX parser with the associated features
 119      * @param features Hashtable of SAX features, may be null
 120      */
 121     SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features)
 122         throws SAXException {
 123         this(spf, features, false);
 124     }
 125 
 126     /**
 127      * Create a SAX parser with the associated features
 128      * @param features Hashtable of SAX features, may be null
 129      */
 130     SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing)
 131         throws SAXException
 132     {
 133         fSecurityPropertyMgr = new XMLSecurityPropertyManager();
 134 
 135         // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader
 136         xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr);
 137 
 138         // JAXP "namespaceAware" == SAX Namespaces feature
 139         // Note: there is a compatibility problem here with default values:
 140         // JAXP default is false while SAX 2 default is true!
 141         xmlReader.setFeature0(NAMESPACES_FEATURE, spf.isNamespaceAware());
 142 
 143         // SAX "namespaces" and "namespace-prefixes" features should not
 144         // both be false.  We make them opposite for backward compatibility
 145         // since JAXP 1.0 apps may want to receive xmlns* attributes.
 146         xmlReader.setFeature0(NAMESPACE_PREFIXES_FEATURE, !spf.isNamespaceAware());
 147 
 148         // Avoid setting the XInclude processing feature if the value is false.
 149         // This will keep the configuration from throwing an exception if it
 150         // does not support XInclude.
 151         if (spf.isXIncludeAware()) {
 152             xmlReader.setFeature0(XINCLUDE_FEATURE, true);
 153         }
 154 
 155         xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
 156 
 157         // If the secure processing feature is on set a security manager.
 158         if (secureProcessing) {
 159             xmlReader.setProperty0(SECURITY_MANAGER, new SecurityManager());
 160             /**
 161              * By default, secure processing is set, no external access is allowed.
 162              * However, we need to check if it is actively set on the factory since we
 163              * allow the use of the System Property or jaxp.properties to override
 164              * the default value
 165              */
 166             if (features != null) {
 167                 Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
 168                 if (temp != null) {
 169                     boolean value = ((Boolean) temp).booleanValue();
 170                     if (value && Constants.IS_JDK8_OR_ABOVE) {
 171                         fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
 172                                 XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
 173                         fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA,
 174                                 XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
 175 
 176                     }
 177                 }
 178             }
 179         }
 180 
 181         // Set application's features, followed by validation features.
 182         setFeatures(features);
 183 
 184         // If validating, provide a default ErrorHandler that prints
 185         // validation errors with a warning telling the user to set an
 186         // ErrorHandler.
 187         if (spf.isValidating()) {
 188             fInitErrorHandler = new DefaultValidationErrorHandler();
 189             xmlReader.setErrorHandler(fInitErrorHandler);
 190         }
 191         else {
 192             fInitErrorHandler = xmlReader.getErrorHandler();
 193         }
 194         xmlReader.setFeature0(VALIDATION_FEATURE, spf.isValidating());
 195 
 196         // Get the Schema object from the factory
 197         this.grammar = spf.getSchema();
 198         if (grammar != null) {
 199             XMLParserConfiguration config = xmlReader.getXMLParserConfiguration();
 200             XMLComponent validatorComponent = null;
 201             /** For Xerces grammars, use built-in schema validator. **/
 202             if (grammar instanceof XSGrammarPoolContainer) {
 203                 validatorComponent = new XMLSchemaValidator();
 204                 fSchemaValidationManager = new ValidationManager();
 205                 fUnparsedEntityHandler = new UnparsedEntityHandler(fSchemaValidationManager);
 206                 config.setDTDHandler(fUnparsedEntityHandler);
 207                 fUnparsedEntityHandler.setDTDHandler(xmlReader);
 208                 xmlReader.setDTDSource(fUnparsedEntityHandler);
 209                 fSchemaValidatorComponentManager = new SchemaValidatorConfiguration(config,
 210                         (XSGrammarPoolContainer) grammar, fSchemaValidationManager);
 211             }
 212             /** For third party grammars, use the JAXP validator component. **/
 213             else {
 214                 validatorComponent = new JAXPValidatorComponent(grammar.newValidatorHandler());
 215                 fSchemaValidationManager = null;
 216                 fUnparsedEntityHandler = null;
 217                 fSchemaValidatorComponentManager = config;
 218             }
 219             config.addRecognizedFeatures(validatorComponent.getRecognizedFeatures());
 220             config.addRecognizedProperties(validatorComponent.getRecognizedProperties());
 221             config.setDocumentHandler((XMLDocumentHandler) validatorComponent);
 222             ((XMLDocumentSource)validatorComponent).setDocumentHandler(xmlReader);
 223             xmlReader.setDocumentSource((XMLDocumentSource) validatorComponent);
 224             fSchemaValidator = validatorComponent;
 225         }
 226         else {
 227             fSchemaValidationManager = null;
 228             fUnparsedEntityHandler = null;
 229             fSchemaValidatorComponentManager = null;
 230             fSchemaValidator = null;
 231         }
 232 
 233         // Initial EntityResolver
 234         fInitEntityResolver = xmlReader.getEntityResolver();
 235     }
 236 
 237     /**
 238      * Set any features of our XMLReader based on any features set on the
 239      * SAXParserFactory.
 240      *
 241      * XXX Does not handle possible conflicts between SAX feature names and
 242      * JAXP specific feature names, eg. SAXParserFactory.isValidating()
 243      */
 244     private void setFeatures(Hashtable features)
 245         throws SAXNotSupportedException, SAXNotRecognizedException {
 246         if (features != null) {
 247             Iterator entries = features.entrySet().iterator();
 248             while (entries.hasNext()) {
 249                 Map.Entry entry = (Map.Entry) entries.next();
 250                 String feature = (String) entry.getKey();
 251                 boolean value = ((Boolean) entry.getValue()).booleanValue();
 252                 xmlReader.setFeature0(feature, value);
 253             }
 254         }
 255     }
 256 
 257     public Parser getParser() throws SAXException {
 258         // Xerces2 AbstractSAXParser implements SAX1 Parser
 259         // assert(xmlReader instanceof Parser);
 260         return (Parser) xmlReader;
 261     }
 262 
 263     /**
 264      * Returns the XMLReader that is encapsulated by the implementation of
 265      * this class.
 266      */
 267     public XMLReader getXMLReader() {
 268         return xmlReader;
 269     }
 270 
 271     public boolean isNamespaceAware() {
 272         try {
 273             return xmlReader.getFeature(NAMESPACES_FEATURE);
 274         }
 275         catch (SAXException x) {
 276             throw new IllegalStateException(x.getMessage());
 277         }
 278     }
 279 
 280     public boolean isValidating() {
 281         try {
 282             return xmlReader.getFeature(VALIDATION_FEATURE);
 283         }
 284         catch (SAXException x) {
 285             throw new IllegalStateException(x.getMessage());
 286         }
 287     }
 288 
 289     /**
 290      * Gets the XInclude processing mode for this parser
 291      * @return the state of XInclude processing mode
 292      */
 293     public boolean isXIncludeAware() {
 294         try {
 295             return xmlReader.getFeature(XINCLUDE_FEATURE);
 296         }
 297         catch (SAXException exc) {
 298             return false;
 299         }
 300     }
 301 
 302     /**
 303      * Sets the particular property in the underlying implementation of
 304      * org.xml.sax.XMLReader.
 305      */
 306     public void setProperty(String name, Object value)
 307         throws SAXNotRecognizedException, SAXNotSupportedException {
 308         xmlReader.setProperty(name, value);
 309     }
 310 
 311     /**
 312      * returns the particular property requested for in the underlying
 313      * implementation of org.xml.sax.XMLReader.
 314      */
 315     public Object getProperty(String name)
 316         throws SAXNotRecognizedException, SAXNotSupportedException {
 317         return xmlReader.getProperty(name);
 318     }
 319 
 320     public void parse(InputSource is, DefaultHandler dh)
 321         throws SAXException, IOException {
 322         if (is == null) {
 323             throw new IllegalArgumentException();
 324         }
 325         if (dh != null) {
 326             xmlReader.setContentHandler(dh);
 327             xmlReader.setEntityResolver(dh);
 328             xmlReader.setErrorHandler(dh);
 329             xmlReader.setDTDHandler(dh);
 330             xmlReader.setDocumentHandler(null);
 331         }
 332         xmlReader.parse(is);
 333     }
 334 
 335     public void parse(InputSource is, HandlerBase hb)
 336         throws SAXException, IOException {
 337         if (is == null) {
 338             throw new IllegalArgumentException();
 339         }
 340         if (hb != null) {
 341             xmlReader.setDocumentHandler(hb);
 342             xmlReader.setEntityResolver(hb);
 343             xmlReader.setErrorHandler(hb);
 344             xmlReader.setDTDHandler(hb);
 345             xmlReader.setContentHandler(null);
 346         }
 347         xmlReader.parse(is);
 348     }
 349 
 350     public Schema getSchema() {
 351         return grammar;
 352     }
 353 
 354     public void reset() {
 355         try {
 356             /** Restore initial values of features and properties. **/
 357             xmlReader.restoreInitState();
 358         }
 359         catch (SAXException exc) {
 360             // This should never happen. We only store recognized
 361             // features and properties in the hash maps. For now
 362             // just ignore it.
 363         }
 364         /** Restore various handlers. **/
 365         xmlReader.setContentHandler(null);
 366         xmlReader.setDTDHandler(null);
 367         if (xmlReader.getErrorHandler() != fInitErrorHandler) {
 368             xmlReader.setErrorHandler(fInitErrorHandler);
 369         }
 370         if (xmlReader.getEntityResolver() != fInitEntityResolver) {
 371             xmlReader.setEntityResolver(fInitEntityResolver);
 372         }
 373     }
 374 
 375     /*
 376      * PSVIProvider methods
 377      */
 378 
 379     public ElementPSVI getElementPSVI() {
 380         return ((PSVIProvider)xmlReader).getElementPSVI();
 381     }
 382 
 383     public AttributePSVI getAttributePSVI(int index) {
 384         return ((PSVIProvider)xmlReader).getAttributePSVI(index);
 385     }
 386 
 387     public AttributePSVI getAttributePSVIByName(String uri, String localname) {
 388         return ((PSVIProvider)xmlReader).getAttributePSVIByName(uri, localname);
 389     }
 390 
 391     /**
 392      * Extension of SAXParser. This class tracks changes to
 393      * features and properties to allow the parser to be reset to
 394      * its initial state.
 395      */
 396     public static class JAXPSAXParser extends com.sun.org.apache.xerces.internal.parsers.SAXParser {
 397 
 398         private final HashMap fInitFeatures = new HashMap();
 399         private final HashMap fInitProperties = new HashMap();
 400         private final SAXParserImpl fSAXParser;
 401         private XMLSecurityPropertyManager fSecurityPropertyMgr;
 402 
 403 
 404         public JAXPSAXParser() {
 405             this(null, null);
 406         }
 407 
 408         JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager spm) {
 409             super();
 410             fSAXParser = saxParser;
 411             fSecurityPropertyMgr = spm;
 412 
 413             /**
 414              * This class may be used directly. So initialize the security manager if
 415              * it is null.
 416              */
 417             if (fSecurityPropertyMgr == null) {
 418                 fSecurityPropertyMgr = new XMLSecurityPropertyManager();
 419                 try {
 420                     super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
 421                 } catch (SAXException e) {
 422                     throw new UnsupportedOperationException(
 423                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 424                         "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
 425                 }
 426             }
 427         }
 428 
 429         /**
 430          * Override SAXParser's setFeature method to track the initial state
 431          * of features. This keeps us from affecting the performance of the
 432          * SAXParser when it is created with XMLReaderFactory.
 433          */
 434         public synchronized void setFeature(String name, boolean value)
 435             throws SAXNotRecognizedException, SAXNotSupportedException {
 436             if (name == null) {
 437                 // TODO: Add localized error message.
 438                 throw new NullPointerException();
 439             }
 440             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 441                 try {
 442                     setProperty(SECURITY_MANAGER, value ? new SecurityManager() : null);
 443                 }
 444                 catch (SAXNotRecognizedException exc) {
 445                     // If the property is not supported
 446                     // re-throw the exception if the value is true.
 447                     if (value) {
 448                         throw exc;
 449                     }
 450                 }
 451                 catch (SAXNotSupportedException exc) {
 452                     // If the property is not supported
 453                     // re-throw the exception if the value is true.
 454                     if (value) {
 455                         throw exc;
 456                     }
 457                 }
 458                 return;
 459             }
 460             if (!fInitFeatures.containsKey(name)) {
 461                 boolean current = super.getFeature(name);
 462                 fInitFeatures.put(name, current ? Boolean.TRUE : Boolean.FALSE);
 463             }
 464             /** Forward feature to the schema validator if there is one. **/
 465             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 466                 setSchemaValidatorFeature(name, value);
 467             }
 468             super.setFeature(name, value);
 469         }
 470 
 471         public synchronized boolean getFeature(String name)
 472             throws SAXNotRecognizedException, SAXNotSupportedException {
 473             if (name == null) {
 474                 // TODO: Add localized error message.
 475                 throw new NullPointerException();
 476             }
 477             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 478                 try {
 479                     return (super.getProperty(SECURITY_MANAGER) != null);
 480                 }
 481                 // If the property is not supported the value must be false.
 482                 catch (SAXException exc) {
 483                     return false;
 484                 }
 485             }
 486             return super.getFeature(name);
 487         }
 488 
 489         /**
 490          * Override SAXParser's setProperty method to track the initial state
 491          * of properties. This keeps us from affecting the performance of the
 492          * SAXParser when it is created with XMLReaderFactory.
 493          */
 494         public synchronized void setProperty(String name, Object value)
 495             throws SAXNotRecognizedException, SAXNotSupportedException {
 496             if (name == null) {
 497                 // TODO: Add localized error message.
 498                 throw new NullPointerException();
 499             }
 500             if (fSAXParser != null) {
 501                 // JAXP 1.2 support
 502                 if (JAXP_SCHEMA_LANGUAGE.equals(name)) {
 503                     // The spec says if a schema is given via SAXParserFactory
 504                     // the JAXP 1.2 properties shouldn't be allowed.
 505                     if (fSAXParser.grammar != null) {
 506                         throw new SAXNotSupportedException(
 507                                 SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
 508                     }
 509                     if ( W3C_XML_SCHEMA.equals(value) ) {
 510                         //None of the properties will take effect till the setValidating(true) has been called
 511                         if( fSAXParser.isValidating() ) {
 512                             fSAXParser.schemaLanguage = W3C_XML_SCHEMA;
 513                             setFeature(XMLSCHEMA_VALIDATION_FEATURE, true);
 514                             // this will allow the parser not to emit DTD-related
 515                             // errors, as the spec demands
 516                             if (!fInitProperties.containsKey(JAXP_SCHEMA_LANGUAGE)) {
 517                                 fInitProperties.put(JAXP_SCHEMA_LANGUAGE, super.getProperty(JAXP_SCHEMA_LANGUAGE));
 518                             }
 519                             super.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
 520                         }
 521 
 522                     }
 523                     else if (value == null) {
 524                         fSAXParser.schemaLanguage = null;
 525                         setFeature(XMLSCHEMA_VALIDATION_FEATURE, false);
 526                     }
 527                     else {
 528                         // REVISIT: It would be nice if we could format this message
 529                         // using a user specified locale as we do in the underlying
 530                         // XMLReader -- mrglavas
 531                         throw new SAXNotSupportedException(
 532                             SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-not-supported", null));
 533                     }
 534                     return;
 535                 }
 536                 else if (JAXP_SCHEMA_SOURCE.equals(name)) {
 537                     // The spec says if a schema is given via SAXParserFactory
 538                     // the JAXP 1.2 properties shouldn't be allowed.
 539                     if (fSAXParser.grammar != null) {
 540                         throw new SAXNotSupportedException(
 541                                 SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
 542                     }
 543                     String val = (String)getProperty(JAXP_SCHEMA_LANGUAGE);
 544                     if ( val != null && W3C_XML_SCHEMA.equals(val) ) {
 545                         if (!fInitProperties.containsKey(JAXP_SCHEMA_SOURCE)) {
 546                             fInitProperties.put(JAXP_SCHEMA_SOURCE, super.getProperty(JAXP_SCHEMA_SOURCE));
 547                         }
 548                         super.setProperty(name, value);
 549                     }
 550                     else {
 551                         throw new SAXNotSupportedException(
 552                             SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 553                             "jaxp-order-not-supported",
 554                             new Object[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE}));
 555                     }
 556                     return;
 557                 }
 558             }
 559             /** Forward property to the schema validator if there is one. **/
 560             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 561                 setSchemaValidatorProperty(name, value);
 562             }
 563             /** Check to see if the property is managed by the property manager **/
 564             int index = (fSecurityPropertyMgr != null) ? fSecurityPropertyMgr.getIndex(name) : -1;
 565             if (index > -1) {
 566                 fSecurityPropertyMgr.setValue(index,
 567                         XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
 568             } else {
 569                 if (!fInitProperties.containsKey(name)) {
 570                     fInitProperties.put(name, super.getProperty(name));
 571                 }
 572                 super.setProperty(name, value);
 573             }
 574         }
 575 
 576         public synchronized Object getProperty(String name)
 577             throws SAXNotRecognizedException, SAXNotSupportedException {
 578             if (name == null) {
 579                 // TODO: Add localized error message.
 580                 throw new NullPointerException();
 581             }
 582             if (fSAXParser != null && JAXP_SCHEMA_LANGUAGE.equals(name)) {
 583                 // JAXP 1.2 support
 584                 return fSAXParser.schemaLanguage;
 585             }
 586             int index = (fSecurityPropertyMgr != null) ? fSecurityPropertyMgr.getIndex(name) : -1;
 587             if (index > -1) {
 588                 return fSecurityPropertyMgr.getValueByIndex(index);
 589             }
 590 
 591             return super.getProperty(name);
 592         }
 593 
 594         synchronized void restoreInitState()
 595             throws SAXNotRecognizedException, SAXNotSupportedException {
 596             Iterator iter;
 597             if (!fInitFeatures.isEmpty()) {
 598                 iter = fInitFeatures.entrySet().iterator();
 599                 while (iter.hasNext()) {
 600                     Map.Entry entry = (Map.Entry) iter.next();
 601                     String name = (String) entry.getKey();
 602                     boolean value = ((Boolean) entry.getValue()).booleanValue();
 603                     super.setFeature(name, value);
 604                 }
 605                 fInitFeatures.clear();
 606             }
 607             if (!fInitProperties.isEmpty()) {
 608                 iter = fInitProperties.entrySet().iterator();
 609                 while (iter.hasNext()) {
 610                     Map.Entry entry = (Map.Entry) iter.next();
 611                     String name = (String) entry.getKey();
 612                     Object value = entry.getValue();
 613                     super.setProperty(name, value);
 614                 }
 615                 fInitProperties.clear();
 616             }
 617         }
 618 
 619         public void parse(InputSource inputSource)
 620             throws SAXException, IOException {
 621             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 622                 if (fSAXParser.fSchemaValidationManager != null) {
 623                     fSAXParser.fSchemaValidationManager.reset();
 624                     fSAXParser.fUnparsedEntityHandler.reset();
 625                 }
 626                 resetSchemaValidator();
 627             }
 628             super.parse(inputSource);
 629         }
 630 
 631         public void parse(String systemId)
 632             throws SAXException, IOException {
 633             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 634                 if (fSAXParser.fSchemaValidationManager != null) {
 635                     fSAXParser.fSchemaValidationManager.reset();
 636                     fSAXParser.fUnparsedEntityHandler.reset();
 637                 }
 638                 resetSchemaValidator();
 639             }
 640             super.parse(systemId);
 641         }
 642 
 643         XMLParserConfiguration getXMLParserConfiguration() {
 644             return fConfiguration;
 645         }
 646 
 647         void setFeature0(String name, boolean value)
 648             throws SAXNotRecognizedException, SAXNotSupportedException {
 649             super.setFeature(name, value);
 650         }
 651 
 652         boolean getFeature0(String name)
 653             throws SAXNotRecognizedException, SAXNotSupportedException {
 654             return super.getFeature(name);
 655         }
 656 
 657         void setProperty0(String name, Object value)
 658             throws SAXNotRecognizedException, SAXNotSupportedException {
 659             super.setProperty(name, value);
 660         }
 661 
 662         Object getProperty0(String name)
 663             throws SAXNotRecognizedException, SAXNotSupportedException {
 664             return super.getProperty(name);
 665         }
 666 
 667         private void setSchemaValidatorFeature(String name, boolean value)
 668             throws SAXNotRecognizedException, SAXNotSupportedException {
 669             try {
 670                 fSAXParser.fSchemaValidator.setFeature(name, value);
 671             }
 672             // This should never be thrown from the schema validator.
 673             catch (XMLConfigurationException e) {
 674                 String identifier = e.getIdentifier();
 675                 if (e.getType() == Status.NOT_RECOGNIZED) {
 676                     throw new SAXNotRecognizedException(
 677                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 678                         "feature-not-recognized", new Object [] {identifier}));
 679                 }
 680                 else {
 681                     throw new SAXNotSupportedException(
 682                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 683                         "feature-not-supported", new Object [] {identifier}));
 684                 }
 685             }
 686         }
 687 
 688         private void setSchemaValidatorProperty(String name, Object value)
 689             throws SAXNotRecognizedException, SAXNotSupportedException {
 690             try {
 691                 fSAXParser.fSchemaValidator.setProperty(name, value);
 692             }
 693             // This should never be thrown from the schema validator.
 694             catch (XMLConfigurationException e) {
 695                 String identifier = e.getIdentifier();
 696                 if (e.getType() == Status.NOT_RECOGNIZED) {
 697                     throw new SAXNotRecognizedException(
 698                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 699                         "property-not-recognized", new Object [] {identifier}));
 700                 }
 701                 else {
 702                     throw new SAXNotSupportedException(
 703                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 704                         "property-not-supported", new Object [] {identifier}));
 705                 }
 706             }
 707         }
 708 
 709         private void resetSchemaValidator() throws SAXException {
 710             try {
 711                 fSAXParser.fSchemaValidator.reset(fSAXParser.fSchemaValidatorComponentManager);
 712             }
 713             // This should never be thrown from the schema validator.
 714             catch (XMLConfigurationException e) {
 715                 throw new SAXException(e);
 716             }
 717         }
 718     }
 719 }