content: /*
   *  This file is part of AndroidIDE.
   *
   *  AndroidIDE is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation, either version 3 of the License, or
   *  (at your option) any later version.
   *
   *  AndroidIDE is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *   along with AndroidIDE.  If not, see <https://www.gnu.org/licenses/>.
   */
  
  /*
   * reserved comment block
   * DO NOT REMOVE OR ALTER!
   */
  /*
   * Copyright 2000-2005 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package jaxp.sun.org.apache.xerces.internal.jaxp;
  
  import jaxp.sun.org.apache.xerces.internal.impl.Constants;
  import jaxp.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
  import jaxp.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
  import jaxp.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer;
  
  import jaxp.sun.org.apache.xerces.internal.parsers.SAXParser;
  import jaxp.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  import jaxp.sun.org.apache.xerces.internal.util.Status;
  import jaxp.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
  import jaxp.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
  import jaxp.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
  import jaxp.sun.org.apache.xerces.internal.xs.AttributePSVI;
  import jaxp.sun.org.apache.xerces.internal.xs.ElementPSVI;
  import jaxp.sun.org.apache.xerces.internal.xs.PSVIProvider;
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.Locale;
  import java.util.Map;
  import jaxp.xml.XMLConstants;
  import jaxp.xml.validation.Schema;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.HandlerBase;
  import org.xml.sax.InputSource;
  import org.xml.sax.Parser;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXNotRecognizedException;
  import org.xml.sax.SAXNotSupportedException;
  import org.xml.sax.XMLReader;
  import org.xml.sax.helpers.DefaultHandler;
  
  /**
   * This is the implementation specific class for the
   * <code>javax.xml.parsers.SAXParser</code>.
   *
   * @author Rajiv Mordani
   * @author Edwin Goei
   *
   * @version $Id: SAXParserImpl.java,v 1.7 2010-11-01 04:40:06 joehw Exp $
   */
  public class SAXParserImpl extends jaxp.xml.parsers.SAXParser
      implements JAXPConstants, PSVIProvider {
  
      /** Feature identifier: namespaces. */
      private static final String NAMESPACES_FEATURE =
          Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
  
      /** Feature identifier: namespace prefixes. */
      private static final String NAMESPACE_PREFIXES_FEATURE =
          Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE;
  
      /** Feature identifier: validation. */
      private static final String VALIDATION_FEATURE =
          Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
  
      /** Feature identifier: XML Schema validation */
      private static final String XMLSCHEMA_VALIDATION_FEATURE =
          Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
  
      /** Feature identifier: XInclude processing */
      private static final String XINCLUDE_FEATURE =
          Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;
  
      /** Property identifier: security manager. */
      private static final String SECURITY_MANAGER =
          Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
  
      /** Property identifier: Security property manager. */
      private static final String XML_SECURITY_PROPERTY_MANAGER =
              Constants.XML_SECURITY_PROPERTY_MANAGER;
  
      private final JAXPSAXParser xmlReader;
      private String schemaLanguage = null;     // null means DTD
      private final Schema grammar;
  
      private final XMLComponent fSchemaValidator;
      private final XMLComponentManager fSchemaValidatorComponentManager;
      private final ValidationManager fSchemaValidationManager;
      private final UnparsedEntityHandler fUnparsedEntityHandler;
  
      /** Initial ErrorHandler */
      private final ErrorHandler fInitErrorHandler;
  
      /** Initial EntityResolver */
      private final EntityResolver fInitEntityResolver;
  
      private final XMLSecurityManager fSecurityManager;
      private final XMLSecurityPropertyManager fSecurityPropertyMgr;
  
      /**
       * Create a SAX parser with the associated features
       * @param features Hashtable of SAX features, may be null
       */
      SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features)
          throws SAXException {
          this(spf, features, false);
      }
  
      /**
       * Create a SAX parser with the associated features
       * @param features Hashtable of SAX features, may be null
       */
      SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing)
          throws SAXException
      {
          fSecurityManager = new XMLSecurityManager(secureProcessing);
          fSecurityPropertyMgr = new XMLSecurityPropertyManager();
          // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader
          xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr, fSecurityManager);
  
          // JAXP "namespaceAware" == SAX Namespaces feature
          // Note: there is a compatibility problem here with default values:
          // JAXP default is false while SAX 2 default is true!
          xmlReader.setFeature0(NAMESPACES_FEATURE, spf.isNamespaceAware());
  
          // SAX "namespaces" and "namespace-prefixes" features should not
          // both be false.  We make them opposite for backward compatibility
          // since JAXP 1.0 apps may want to receive xmlns* attributes.
          xmlReader.setFeature0(NAMESPACE_PREFIXES_FEATURE, !spf.isNamespaceAware());
  
          // Avoid setting the XInclude processing feature if the value is false.
          // This will keep the configuration from throwing an exception if it
          // does not support XInclude.
          if (spf.isXIncludeAware()) {
              xmlReader.setFeature0(XINCLUDE_FEATURE, true);
          }
  
          xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
  
          xmlReader.setProperty0(SECURITY_MANAGER, fSecurityManager);
  
          if (secureProcessing) {
              /**
               * By default, secure processing is set, no external access is allowed.
               * However, we need to check if it is actively set on the factory since we
               * allow the use of the System Property or jaxp.properties to override
               * the default value
               */
              if (features != null) {
  
                  Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
                  if (temp != null) {
                      boolean value = ((Boolean) temp).booleanValue();
                      if (value && Constants.IS_JDK8_OR_ABOVE) {
                          fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
                                  XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
                          fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA,
                                  XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
  
                      }
                  }
              }
          }
  
          // Set application's features, followed by validation features.
          setFeatures(features);
  
          // If validating, provide a default ErrorHandler that prints
          // validation errors with a warning telling the user to set an
          // ErrorHandler.
          if (spf.isValidating()) {
              fInitErrorHandler = new DefaultValidationErrorHandler(xmlReader.getLocale());
              xmlReader.setErrorHandler(fInitErrorHandler);
          }
          else {
              fInitErrorHandler = xmlReader.getErrorHandler();
          }
          xmlReader.setFeature0(VALIDATION_FEATURE, spf.isValidating());
  
          // Get the Schema object from the factory
          this.grammar = spf.getSchema();
          if (grammar != null) {
              XMLParserConfiguration config = xmlReader.getXMLParserConfiguration();
              XMLComponent validatorComponent = null;
              /** For Xerces grammars, use built-in schema validator. **/
              if (grammar instanceof XSGrammarPoolContainer) {
                  validatorComponent = new XMLSchemaValidator();
                  fSchemaValidationManager = new ValidationManager();
                  fUnparsedEntityHandler = new UnparsedEntityHandler(fSchemaValidationManager);
                  config.setDTDHandler(fUnparsedEntityHandler);
                  fUnparsedEntityHandler.setDTDHandler(xmlReader);
                  xmlReader.setDTDSource(fUnparsedEntityHandler);
                  fSchemaValidatorComponentManager = new SchemaValidatorConfiguration(config,
                          (XSGrammarPoolContainer) grammar, fSchemaValidationManager);
              }
              /** For third party grammars, use the JAXP validator component. **/
              else {
                  validatorComponent = new JAXPValidatorComponent(grammar.newValidatorHandler());
                  fSchemaValidationManager = null;
                  fUnparsedEntityHandler = null;
                  fSchemaValidatorComponentManager = config;
              }
              config.addRecognizedFeatures(validatorComponent.getRecognizedFeatures());
              config.addRecognizedProperties(validatorComponent.getRecognizedProperties());
              config.setDocumentHandler((XMLDocumentHandler) validatorComponent);
              ((XMLDocumentSource)validatorComponent).setDocumentHandler(xmlReader);
              xmlReader.setDocumentSource((XMLDocumentSource) validatorComponent);
              fSchemaValidator = validatorComponent;
          }
          else {
              fSchemaValidationManager = null;
              fUnparsedEntityHandler = null;
              fSchemaValidatorComponentManager = null;
              fSchemaValidator = null;
          }
  
          // Initial EntityResolver
          fInitEntityResolver = xmlReader.getEntityResolver();
      }
  
      /**
       * Set any features of our XMLReader based on any features set on the
       * SAXParserFactory.
       *
       * XXX Does not handle possible conflicts between SAX feature names and
       * JAXP specific feature names, eg. SAXParserFactory.isValidating()
       */
      private void setFeatures(Hashtable features)
          throws SAXNotSupportedException, SAXNotRecognizedException {
          if (features != null) {
              Iterator entries = features.entrySet().iterator();
              while (entries.hasNext()) {
                  Map.Entry entry = (Map.Entry) entries.next();
                  String feature = (String) entry.getKey();
                  boolean value = ((Boolean) entry.getValue()).booleanValue();
                  xmlReader.setFeature0(feature, value);
              }
          }
      }
  
      public Parser getParser() throws SAXException {
          // Xerces2 AbstractSAXParser implements SAX1 Parser
          // assert(xmlReader instanceof Parser);
          return (Parser) xmlReader;
      }
  
      /**
       * Returns the XMLReader that is encapsulated by the implementation of
       * this class.
       */
      public XMLReader getXMLReader() {
          return xmlReader;
      }
  
      public boolean isNamespaceAware() {
          try {
              return xmlReader.getFeature(NAMESPACES_FEATURE);
          }
          catch (SAXException x) {
              throw new IllegalStateException(x.getMessage());
          }
      }
  
      public boolean isValidating() {
          try {
              return xmlReader.getFeature(VALIDATION_FEATURE);
          }
          catch (SAXException x) {
              throw new IllegalStateException(x.getMessage());
          }
      }
  
      /**
       * Gets the XInclude processing mode for this parser
       * @return the state of XInclude processing mode
       */
      public boolean isXIncludeAware() {
          try {
              return xmlReader.getFeature(XINCLUDE_FEATURE);
          }
          catch (SAXException exc) {
              return false;
          }
      }
  
      /**
       * Sets the particular property in the underlying implementation of
       * org.xml.sax.XMLReader.
       */
      public void setProperty(String name, Object value)
          throws SAXNotRecognizedException, SAXNotSupportedException {
          xmlReader.setProperty(name, value);
      }
  
      /**
       * returns the particular property requested for in the underlying
       * implementation of org.xml.sax.XMLReader.
       */
      public Object getProperty(String name)
          throws SAXNotRecognizedException, SAXNotSupportedException {
          return xmlReader.getProperty(name);
      }
  
      public void parse(InputSource is, DefaultHandler dh)
          throws SAXException, IOException {
          if (is == null) {
              throw new IllegalArgumentException();
          }
          if (dh != null) {
              xmlReader.setContentHandler(dh);
              xmlReader.setEntityResolver(dh);
              xmlReader.setErrorHandler(dh);
              xmlReader.setDTDHandler(dh);
              xmlReader.setDocumentHandler(null);
          }
          xmlReader.parse(is);
      }
  
      public void parse(InputSource is, HandlerBase hb)
          throws SAXException, IOException {
          if (is == null) {
              throw new IllegalArgumentException();
          }
          if (hb != null) {
              xmlReader.setDocumentHandler(hb);
              xmlReader.setEntityResolver(hb);
              xmlReader.setErrorHandler(hb);
              xmlReader.setDTDHandler(hb);
              xmlReader.setContentHandler(null);
          }
          xmlReader.parse(is);
      }
  
      public Schema getSchema() {
          return grammar;
      }
  
      public void reset() {
          try {
              /** Restore initial values of features and properties. **/
              xmlReader.restoreInitState();
          }
          catch (SAXException exc) {
              // This should never happen. We only store recognized
              // features and properties in the hash maps. For now
              // just ignore it.
          }
          /** Restore various handlers. **/
          xmlReader.setContentHandler(null);
          xmlReader.setDTDHandler(null);
          if (xmlReader.getErrorHandler() != fInitErrorHandler) {
              xmlReader.setErrorHandler(fInitErrorHandler);
          }
          if (xmlReader.getEntityResolver() != fInitEntityResolver) {
              xmlReader.setEntityResolver(fInitEntityResolver);
          }
      }
  
      /*
       * PSVIProvider methods
       */
  
      public ElementPSVI getElementPSVI() {
          return ((PSVIProvider)xmlReader).getElementPSVI();
      }
  
      public AttributePSVI getAttributePSVI(int index) {
          return ((PSVIProvider)xmlReader).getAttributePSVI(index);
      }
  
      public AttributePSVI getAttributePSVIByName(String uri, String localname) {
          return ((PSVIProvider)xmlReader).getAttributePSVIByName(uri, localname);
      }
  
      /**
       * Extension of SAXParser. This class tracks changes to
       * features and properties to allow the parser to be reset to
       * its initial state.
       */
      public static class JAXPSAXParser extends SAXParser {
  
          private final HashMap fInitFeatures = new HashMap();
          private final HashMap fInitProperties = new HashMap();
          private final SAXParserImpl fSAXParser;
          private XMLSecurityManager fSecurityManager;
          private XMLSecurityPropertyManager fSecurityPropertyMgr;
  
  
          public JAXPSAXParser() {
              this(null, null, null);
          }
  
          JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager securityPropertyMgr,
                  XMLSecurityManager securityManager) {
              super();
              fSAXParser = saxParser;
              fSecurityManager = securityManager;
              fSecurityPropertyMgr = securityPropertyMgr;
              /**
               * This class may be used directly. So initialize the security manager if
               * it is null.
               */
              if (fSecurityManager == null) {
                  fSecurityManager = new XMLSecurityManager(true);
                  try {
                      super.setProperty(SECURITY_MANAGER, fSecurityManager);
                  } catch (SAXException e) {
                      throw new UnsupportedOperationException(
                      SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
                      "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
                  }
              }
              if (fSecurityPropertyMgr == null) {
                  fSecurityPropertyMgr = new XMLSecurityPropertyManager();
                  try {
                      super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
                  } catch (SAXException e) {
                      throw new UnsupportedOperationException(
                      SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
                      "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
                  }
              }
          }
  
          /**
           * Override SAXParser's setFeature method to track the initial state
           * of features. This keeps us from affecting the performance of the
           * SAXParser when it is created with XMLReaderFactory.
           */
          public synchronized void setFeature(String name, boolean value)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              if (name == null) {
                  // TODO: Add localized error message.
                  throw new NullPointerException();
              }
              if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
                  try {
                      fSecurityManager.setSecureProcessing(value);
                      setProperty(SECURITY_MANAGER, fSecurityManager);
                  }
                  catch (SAXNotRecognizedException exc) {
                      // If the property is not supported
                      // re-throw the exception if the value is true.
                      if (value) {
                          throw exc;
                      }
                  }
                  catch (SAXNotSupportedException exc) {
                      // If the property is not supported
                      // re-throw the exception if the value is true.
                      if (value) {
                          throw exc;
                      }
                  }
                  return;
              }
              if (!fInitFeatures.containsKey(name)) {
                  boolean current = super.getFeature(name);
                  fInitFeatures.put(name, current ? Boolean.TRUE : Boolean.FALSE);
              }
              /** Forward feature to the schema validator if there is one. **/
              if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
                  setSchemaValidatorFeature(name, value);
              }
              super.setFeature(name, value);
          }
  
          public synchronized boolean getFeature(String name)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              if (name == null) {
                  // TODO: Add localized error message.
                  throw new NullPointerException();
              }
              if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
                  return fSecurityManager.isSecureProcessing();
              }
              return super.getFeature(name);
          }
  
          /**
           * Override SAXParser's setProperty method to track the initial state
           * of properties. This keeps us from affecting the performance of the
           * SAXParser when it is created with XMLReaderFactory.
           */
          public synchronized void setProperty(String name, Object value)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              if (name == null) {
                  // TODO: Add localized error message.
                  throw new NullPointerException();
              }
              if (fSAXParser != null) {
                  // JAXP 1.2 support
                  if (JAXP_SCHEMA_LANGUAGE.equals(name)) {
                      // The spec says if a schema is given via SAXParserFactory
                      // the JAXP 1.2 properties shouldn't be allowed.
                      if (fSAXParser.grammar != null) {
                          throw new SAXNotSupportedException(
                                  SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
                      }
                      if ( W3C_XML_SCHEMA.equals(value) ) {
                          //None of the properties will take effect till the setValidating(true) has been called
                          if( fSAXParser.isValidating() ) {
                              fSAXParser.schemaLanguage = W3C_XML_SCHEMA;
                              setFeature(XMLSCHEMA_VALIDATION_FEATURE, true);
                              // this will allow the parser not to emit DTD-related
                              // errors, as the spec demands
                              if (!fInitProperties.containsKey(JAXP_SCHEMA_LANGUAGE)) {
                                  fInitProperties.put(JAXP_SCHEMA_LANGUAGE, super.getProperty(JAXP_SCHEMA_LANGUAGE));
                              }
                              super.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
                          }
  
                      }
                      else if (value == null) {
                          fSAXParser.schemaLanguage = null;
                          setFeature(XMLSCHEMA_VALIDATION_FEATURE, false);
                      }
                      else {
                          // REVISIT: It would be nice if we could format this message
                          // using a user specified locale as we do in the underlying
                          // XMLReader -- mrglavas
                          throw new SAXNotSupportedException(
                              SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-not-supported", null));
                      }
                      return;
                  }
                  else if (JAXP_SCHEMA_SOURCE.equals(name)) {
                      // The spec says if a schema is given via SAXParserFactory
                      // the JAXP 1.2 properties shouldn't be allowed.
                      if (fSAXParser.grammar != null) {
                          throw new SAXNotSupportedException(
                                  SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
                      }
                      String val = (String)getProperty(JAXP_SCHEMA_LANGUAGE);
                      if ( val != null && W3C_XML_SCHEMA.equals(val) ) {
                          if (!fInitProperties.containsKey(JAXP_SCHEMA_SOURCE)) {
                              fInitProperties.put(JAXP_SCHEMA_SOURCE, super.getProperty(JAXP_SCHEMA_SOURCE));
                          }
                          super.setProperty(name, value);
                      }
                      else {
                          throw new SAXNotSupportedException(
                              SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
                              "jaxp-order-not-supported",
                              new Object[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE}));
                      }
                      return;
                  }
              }
              /** Forward property to the schema validator if there is one. **/
              if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
                  setSchemaValidatorProperty(name, value);
              }
  
              //check if the property is managed by security manager
              if (fSecurityManager == null ||
                      !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) {
                  //check if the property is managed by security property manager
                  if (fSecurityPropertyMgr == null ||
                          !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
                      //fall back to the existing property manager
                      if (!fInitProperties.containsKey(name)) {
                          fInitProperties.put(name, super.getProperty(name));
                      }
                      super.setProperty(name, value);
                  }
              }
  
          }
  
          public synchronized Object getProperty(String name)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              if (name == null) {
                  // TODO: Add localized error message.
                  throw new NullPointerException();
              }
              if (fSAXParser != null && JAXP_SCHEMA_LANGUAGE.equals(name)) {
                  // JAXP 1.2 support
                  return fSAXParser.schemaLanguage;
              }
  
              /** Check to see if the property is managed by the security manager **/
              String propertyValue = (fSecurityManager != null) ?
                      fSecurityManager.getLimitAsString(name) : null;
              if (propertyValue != null) {
                  return propertyValue;
              } else {
                  propertyValue = (fSecurityPropertyMgr != null) ?
                      fSecurityPropertyMgr.getValue(name) : null;
                  if (propertyValue != null) {
                      return propertyValue;
                  }
              }
  
              return super.getProperty(name);
          }
  
          synchronized void restoreInitState()
              throws SAXNotRecognizedException, SAXNotSupportedException {
              Iterator iter;
              if (!fInitFeatures.isEmpty()) {
                  iter = fInitFeatures.entrySet().iterator();
                  while (iter.hasNext()) {
                      Map.Entry entry = (Map.Entry) iter.next();
                      String name = (String) entry.getKey();
                      boolean value = ((Boolean) entry.getValue()).booleanValue();
                      super.setFeature(name, value);
                  }
                  fInitFeatures.clear();
              }
              if (!fInitProperties.isEmpty()) {
                  iter = fInitProperties.entrySet().iterator();
                  while (iter.hasNext()) {
                      Map.Entry entry = (Map.Entry) iter.next();
                      String name = (String) entry.getKey();
                      Object value = entry.getValue();
                      super.setProperty(name, value);
                  }
                  fInitProperties.clear();
              }
          }
  
          public void parse(InputSource inputSource)
              throws SAXException, IOException {
              if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
                  if (fSAXParser.fSchemaValidationManager != null) {
                      fSAXParser.fSchemaValidationManager.reset();
                      fSAXParser.fUnparsedEntityHandler.reset();
                  }
                  resetSchemaValidator();
              }
              super.parse(inputSource);
          }
  
          public void parse(String systemId)
              throws SAXException, IOException {
              if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
                  if (fSAXParser.fSchemaValidationManager != null) {
                      fSAXParser.fSchemaValidationManager.reset();
                      fSAXParser.fUnparsedEntityHandler.reset();
                  }
                  resetSchemaValidator();
              }
              super.parse(systemId);
          }
  
          XMLParserConfiguration getXMLParserConfiguration() {
              return fConfiguration;
          }
  
          void setFeature0(String name, boolean value)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              super.setFeature(name, value);
          }
  
          boolean getFeature0(String name)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              return super.getFeature(name);
          }
  
          void setProperty0(String name, Object value)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              super.setProperty(name, value);
          }
  
          Object getProperty0(String name)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              return super.getProperty(name);
          }
  
          Locale getLocale() {
              return fConfiguration.getLocale();
          }
  
          private void setSchemaValidatorFeature(String name, boolean value)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              try {
                  fSAXParser.fSchemaValidator.setFeature(name, value);
              }
              // This should never be thrown from the schema validator.
              catch (XMLConfigurationException e) {
                  String identifier = e.getIdentifier();
                  if (e.getType() == Status.NOT_RECOGNIZED) {
                      throw new SAXNotRecognizedException(
                          SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
                          "feature-not-recognized", new Object [] {identifier}));
                  }
                  else {
                      throw new SAXNotSupportedException(
                          SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
                          "feature-not-supported", new Object [] {identifier}));
                  }
              }
          }
  
          private void setSchemaValidatorProperty(String name, Object value)
              throws SAXNotRecognizedException, SAXNotSupportedException {
              try {
                  fSAXParser.fSchemaValidator.setProperty(name, value);
              }
              // This should never be thrown from the schema validator.
              catch (XMLConfigurationException e) {
                  String identifier = e.getIdentifier();
                  if (e.getType() == Status.NOT_RECOGNIZED) {
                      throw new SAXNotRecognizedException(
                          SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
                          "property-not-recognized", new Object [] {identifier}));
                  }
                  else {
                      throw new SAXNotSupportedException(
                          SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
                          "property-not-supported", new Object [] {identifier}));
                  }
              }
          }
  
          private void resetSchemaValidator() throws SAXException {
              try {
                  fSAXParser.fSchemaValidator.reset(fSAXParser.fSchemaValidatorComponentManager);
              }
              // This should never be thrown from the schema validator.
              catch (XMLConfigurationException e) {
                  throw new SAXException(e);
              }
          }
      }
  }
  