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.parsers;
  
  import java.io.IOException;
  
  import jaxp.sun.org.apache.xerces.internal.impl.Constants;
  import jaxp.sun.org.apache.xerces.internal.util.EntityResolverWrapper;
  import jaxp.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper;
  import jaxp.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
  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.util.SymbolTable;
  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.XNIException;
  import jaxp.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
  import jaxp.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
  import org.w3c.dom.Node;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXNotRecognizedException;
  import org.xml.sax.SAXNotSupportedException;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.ext.EntityResolver2;
  import org.xml.sax.helpers.LocatorImpl;
  
  /**
   * This is the main Xerces DOM parser class. It uses the abstract DOM
   * parser with a document scanner, a dtd scanner, and a validator, as
   * well as a grammar pool.
   *
   * @author Arnaud  Le Hors, IBM
   * @author Andy Clark, IBM
   *
   * @version $Id: DOMParser.java,v 1.7 2010-11-01 04:40:09 joehw Exp $
   */
  public class DOMParser
      extends AbstractDOMParser {
  
      //
      // Constants
      //
  
      // features
  
      /** Feature identifier: EntityResolver2. */
      protected static final String USE_ENTITY_RESOLVER2 =
          Constants.SAX_FEATURE_PREFIX + Constants.USE_ENTITY_RESOLVER2_FEATURE;
  
      protected static final String REPORT_WHITESPACE =
              Constants.SUN_SCHEMA_FEATURE_PREFIX + Constants.SUN_REPORT_IGNORED_ELEMENT_CONTENT_WHITESPACE;
  
      /** Property identifier: Security property manager. */
      private static final String XML_SECURITY_PROPERTY_MANAGER =
              Constants.XML_SECURITY_PROPERTY_MANAGER;
  
      // recognized features:
      private static final String[] RECOGNIZED_FEATURES = {
          REPORT_WHITESPACE
      };
  
      // properties
  
      /** Property identifier: symbol table. */
      protected static final String SYMBOL_TABLE =
          Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
  
      /** Property identifier: XML grammar pool. */
      protected static final String XMLGRAMMAR_POOL =
          Constants.XERCES_PROPERTY_PREFIX+Constants.XMLGRAMMAR_POOL_PROPERTY;
  
      /** Recognized properties. */
      private static final String[] RECOGNIZED_PROPERTIES = {
          SYMBOL_TABLE,
          XMLGRAMMAR_POOL,
      };
  
      //
      // Data
      //
  
      // features
  
      /** Use EntityResolver2. */
      protected boolean fUseEntityResolver2 = true;
  
      //
      // Constructors
      //
  
      /**
       * Constructs a DOM parser using the specified parser configuration.
       */
      public DOMParser(XMLParserConfiguration config) {
          super(config);
      } // <init>(XMLParserConfiguration)
  
      /**
       * Constructs a DOM parser using the dtd/xml schema parser configuration.
       */
      public DOMParser() {
          this(null, null);
      } // <init>()
  
      /**
       * Constructs a DOM parser using the specified symbol table.
       */
      public DOMParser(SymbolTable symbolTable) {
          this(symbolTable, null);
      } // <init>(SymbolTable)
  
  
      /**
       * Constructs a DOM parser using the specified symbol table and
       * grammar pool.
       */
      public DOMParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
          super(new XIncludeAwareParserConfiguration());
  
          // set properties
          fConfiguration.addRecognizedProperties(RECOGNIZED_PROPERTIES);
          if (symbolTable != null) {
              fConfiguration.setProperty(SYMBOL_TABLE, symbolTable);
          }
          if (grammarPool != null) {
              fConfiguration.setProperty(XMLGRAMMAR_POOL, grammarPool);
          }
  
          fConfiguration.addRecognizedFeatures(RECOGNIZED_FEATURES);
  
      } // <init>(SymbolTable,XMLGrammarPool)
  
      //
      // XMLReader methods
      //
  
      /**
       * Parses the input source specified by the given system identifier.
       * <p>
       * This method is equivalent to the following:
       * <pre>
       *     parse(new InputSource(systemId));
       * </pre>
       *
       * @param systemId The system identifier (URI).
       *
       * @exception org.xml.sax.SAXException Throws exception on SAX error.
       * @exception java.io.IOException Throws exception on i/o error.
       */
      public void parse(String systemId) throws SAXException, IOException {
  
          // parse document
          XMLInputSource source = new XMLInputSource(null, systemId, null);
          try {
              parse(source);
          }
  
          // wrap XNI exceptions as SAX exceptions
          catch (XMLParseException e) {
              Exception ex = e.getException();
              if (ex == null) {
                  // must be a parser exception; mine it for locator info and throw
                  // a SAXParseException
                  LocatorImpl locatorImpl = new LocatorImpl();
                  locatorImpl.setPublicId(e.getPublicId());
                  locatorImpl.setSystemId(e.getExpandedSystemId());
                  locatorImpl.setLineNumber(e.getLineNumber());
                  locatorImpl.setColumnNumber(e.getColumnNumber());
                  throw new SAXParseException(e.getMessage(), locatorImpl);
              }
              if (ex instanceof SAXException) {
                  // why did we create an XMLParseException?
                  throw (SAXException)ex;
              }
              if (ex instanceof IOException) {
                  throw (IOException)ex;
              }
              throw new SAXException(ex);
          }
          catch (XNIException e) {
              e.printStackTrace();
              Exception ex = e.getException();
              if (ex == null) {
                  throw new SAXException(e.getMessage());
              }
              if (ex instanceof SAXException) {
                  throw (SAXException)ex;
              }
              if (ex instanceof IOException) {
                  throw (IOException)ex;
              }
              throw new SAXException(ex);
          }
  
      } // parse(String)
  
      /**
       * parse
       *
       * @param inputSource
       *
       * @exception org.xml.sax.SAXException
       * @exception java.io.IOException
       */
      public void parse(InputSource inputSource)
          throws SAXException, IOException {
  
          // parse document
          try {
              XMLInputSource xmlInputSource =
                  new XMLInputSource(inputSource.getPublicId(),
                                     inputSource.getSystemId(),
                                     null);
              xmlInputSource.setByteStream(inputSource.getByteStream());
              xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
              xmlInputSource.setEncoding(inputSource.getEncoding());
              parse(xmlInputSource);
          }
  
          // wrap XNI exceptions as SAX exceptions
          catch (XMLParseException e) {
              Exception ex = e.getException();
              if (ex == null) {
                  // must be a parser exception; mine it for locator info and throw
                  // a SAXParseException
                  LocatorImpl locatorImpl = new LocatorImpl();
                  locatorImpl.setPublicId(e.getPublicId());
                  locatorImpl.setSystemId(e.getExpandedSystemId());
                  locatorImpl.setLineNumber(e.getLineNumber());
                  locatorImpl.setColumnNumber(e.getColumnNumber());
                  throw new SAXParseException(e.getMessage(), locatorImpl);
              }
              if (ex instanceof SAXException) {
                  // why did we create an XMLParseException?
                  throw (SAXException)ex;
              }
              if (ex instanceof IOException) {
                  throw (IOException)ex;
              }
              throw new SAXException(ex);
          }
          catch (XNIException e) {
              Exception ex = e.getException();
              if (ex == null) {
                  throw new SAXException(e.getMessage());
              }
              if (ex instanceof SAXException) {
                  throw (SAXException)ex;
              }
              if (ex instanceof IOException) {
                  throw (IOException)ex;
              }
              throw new SAXException(ex);
          }
  
      } // parse(InputSource)
  
      /**
       * Sets the resolver used to resolve external entities. The EntityResolver
       * interface supports resolution of public and system identifiers.
       *
       * @param resolver The new entity resolver. Passing a null value will
       *                 uninstall the currently installed resolver.
       */
      public void setEntityResolver(EntityResolver resolver) {
  
          try {
              XMLEntityResolver xer = (XMLEntityResolver) fConfiguration.getProperty(ENTITY_RESOLVER);
              if (fUseEntityResolver2 && resolver instanceof EntityResolver2) {
                  if (xer instanceof EntityResolver2Wrapper) {
                      EntityResolver2Wrapper er2w = (EntityResolver2Wrapper) xer;
                      er2w.setEntityResolver((EntityResolver2) resolver);
                  }
                  else {
                      fConfiguration.setProperty(ENTITY_RESOLVER,
                              new EntityResolver2Wrapper((EntityResolver2) resolver));
                  }
              }
              else {
                  if (xer instanceof EntityResolverWrapper) {
                      EntityResolverWrapper erw = (EntityResolverWrapper) xer;
                      erw.setEntityResolver(resolver);
                  }
                  else {
                      fConfiguration.setProperty(ENTITY_RESOLVER,
                              new EntityResolverWrapper(resolver));
                  }
              }
          }
          catch (XMLConfigurationException e) {
              // do nothing
          }
  
      } // setEntityResolver(EntityResolver)
  
      /**
       * Return the current entity resolver.
       *
       * @return The current entity resolver, or null if none
       *         has been registered.
       * @see #setEntityResolver
       */
      public EntityResolver getEntityResolver() {
  
          EntityResolver entityResolver = null;
          try {
              XMLEntityResolver xmlEntityResolver =
                  (XMLEntityResolver)fConfiguration.getProperty(ENTITY_RESOLVER);
              if (xmlEntityResolver != null) {
                  if (xmlEntityResolver instanceof EntityResolverWrapper) {
                      entityResolver =
                          ((EntityResolverWrapper) xmlEntityResolver).getEntityResolver();
                  }
                  else if (xmlEntityResolver instanceof EntityResolver2Wrapper) {
                      entityResolver =
                          ((EntityResolver2Wrapper) xmlEntityResolver).getEntityResolver();
                  }
              }
          }
          catch (XMLConfigurationException e) {
              // do nothing
          }
          return entityResolver;
  
      } // getEntityResolver():EntityResolver
  
      /**
       * Allow an application to register an error event handler.
       *
       * <p>If the application does not register an error handler, all
       * error events reported by the SAX parser will be silently
       * ignored; however, normal processing may not continue.  It is
       * highly recommended that all SAX applications implement an
       * error handler to avoid unexpected bugs.</p>
       *
       * <p>Applications may register a new or different handler in the
       * middle of a parse, and the SAX parser must begin using the new
       * handler immediately.</p>
       *
       * @param errorHandler The error handler.
       * @exception java.lang.NullPointerException If the handler
       *            argument is null.
       * @see #getErrorHandler
       */
      public void setErrorHandler(ErrorHandler errorHandler) {
  
          try {
              XMLErrorHandler xeh = (XMLErrorHandler) fConfiguration.getProperty(ERROR_HANDLER);
              if (xeh instanceof ErrorHandlerWrapper) {
                  ErrorHandlerWrapper ehw = (ErrorHandlerWrapper) xeh;
                  ehw.setErrorHandler(errorHandler);
              }
              else {
                  fConfiguration.setProperty(ERROR_HANDLER,
                          new ErrorHandlerWrapper(errorHandler));
              }
          }
          catch (XMLConfigurationException e) {
              // do nothing
          }
  
      } // setErrorHandler(ErrorHandler)
  
      /**
       * Return the current error handler.
       *
       * @return The current error handler, or null if none
       *         has been registered.
       * @see #setErrorHandler
       */
      public ErrorHandler getErrorHandler() {
  
          ErrorHandler errorHandler = null;
          try {
              XMLErrorHandler xmlErrorHandler =
                  (XMLErrorHandler)fConfiguration.getProperty(ERROR_HANDLER);
              if (xmlErrorHandler != null &&
                  xmlErrorHandler instanceof ErrorHandlerWrapper) {
                  errorHandler = ((ErrorHandlerWrapper)xmlErrorHandler).getErrorHandler();
              }
          }
          catch (XMLConfigurationException e) {
              // do nothing
          }
          return errorHandler;
  
      } // getErrorHandler():ErrorHandler
  
      /**
       * Set the state of any feature in a SAX2 parser.  The parser
       * might not recognize the feature, and if it does recognize
       * it, it might not be able to fulfill the request.
       *
       * @param featureId The unique identifier (URI) of the feature.
       * @param state The requested state of the feature (true or false).
       *
       * @exception SAXNotRecognizedException If the
       *            requested feature is not known.
       * @exception SAXNotSupportedException If the
       *            requested feature is known, but the requested
       *            state is not supported.
       */
      public void setFeature(String featureId, boolean state)
          throws SAXNotRecognizedException, SAXNotSupportedException {
  
          try {
  
              // http://xml.org/sax/features/use-entity-resolver2
              //   controls whether the methods of an object implementing
              //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
              //
              if (featureId.equals(USE_ENTITY_RESOLVER2)) {
                  if (state != fUseEntityResolver2) {
                      fUseEntityResolver2 = state;
                      // Refresh EntityResolver wrapper.
                      setEntityResolver(getEntityResolver());
                  }
                  return;
              }
  
              //
              // Default handling
              //
  
              fConfiguration.setFeature(featureId, state);
          }
          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}));
              }
          }
  
      } // setFeature(String,boolean)
  
      /**
       * Query the state of a feature.
       *
       * Query the current state of any feature in a SAX2 parser.  The
       * parser might not recognize the feature.
       *
       * @param featureId The unique identifier (URI) of the feature
       *                  being set.
       * @return The current state of the feature.
       * @exception org.xml.sax.SAXNotRecognizedException If the
       *            requested feature is not known.
       * @exception SAXNotSupportedException If the
       *            requested feature is known but not supported.
       */
      public boolean getFeature(String featureId)
          throws SAXNotRecognizedException, SAXNotSupportedException {
  
          try {
  
              // http://xml.org/sax/features/use-entity-resolver2
              //   controls whether the methods of an object implementing
              //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
              //
              if (featureId.equals(USE_ENTITY_RESOLVER2)) {
                  return fUseEntityResolver2;
              }
  
              //
              // Default handling
              //
  
              return fConfiguration.getFeature(featureId);
          }
          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}));
              }
          }
  
      } // getFeature(String):boolean
  
      /**
       * Set the value of any property in a SAX2 parser.  The parser
       * might not recognize the property, and if it does recognize
       * it, it might not support the requested value.
       *
       * @param propertyId The unique identifier (URI) of the property
       *                   being set.
       * @param value The value to which the property is being set.
       *
       * @exception SAXNotRecognizedException If the
       *            requested property is not known.
       * @exception SAXNotSupportedException If the
       *            requested property is known, but the requested
       *            value is not supported.
       */
      public void setProperty(String propertyId, Object value)
          throws SAXNotRecognizedException, SAXNotSupportedException {
          /**
           * It's possible for users to set a security manager through the interface.
           * If it's the old SecurityManager, convert it to the new XMLSecurityManager
           */
          if (propertyId.equals(Constants.SECURITY_MANAGER)) {
              securityManager = XMLSecurityManager.convert(value, securityManager);
              setProperty0(Constants.SECURITY_MANAGER, securityManager);
              return;
          }
          if (propertyId.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) {
              if (value == null) {
                  securityPropertyManager = new XMLSecurityPropertyManager();
              } else {
                  securityPropertyManager = (XMLSecurityPropertyManager)value;
              }
              setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
              return;
          }
  
          if (securityManager == null) {
              securityManager = new XMLSecurityManager(true);
              setProperty0(Constants.SECURITY_MANAGER, securityManager);
          }
  
          if (securityPropertyManager == null) {
              securityPropertyManager = new XMLSecurityPropertyManager();
              setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
          }
          int index = securityPropertyManager.getIndex(propertyId);
  
          if (index > -1) {
              /**
               * this is a direct call to this parser, not a subclass since
               * internally the support of this property is done through
               * XMLSecurityPropertyManager
               */
              securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
          } else {
              //check if the property is managed by security manager
              if (!securityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) {
                  //fall back to the default configuration to handle the property
                  setProperty0(propertyId, value);
              }
          }
      }
  
      public void setProperty0(String propertyId, Object value)
          throws SAXNotRecognizedException, SAXNotSupportedException {
          try {
              fConfiguration.setProperty(propertyId, value);
          }
          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}));
              }
          }
  
      } // setProperty(String,Object)
  
      /**
       * Query the value of a property.
       *
       * Return the current value of a property in a SAX2 parser.
       * The parser might not recognize the property.
       *
       * @param propertyId The unique identifier (URI) of the property
       *                   being set.
       * @return The current value of the property.
       * @exception org.xml.sax.SAXNotRecognizedException If the
       *            requested property is not known.
       * @exception SAXNotSupportedException If the
       *            requested property is known but not supported.
       */
      public Object getProperty(String propertyId)
          throws SAXNotRecognizedException, SAXNotSupportedException {
  
         if (propertyId.equals(CURRENT_ELEMENT_NODE)) {
             boolean deferred = false;
             try {
                 deferred = getFeature(DEFER_NODE_EXPANSION);
             }
             catch (XMLConfigurationException e){
                 // ignore
             }
             if (deferred) {
                 throw new SAXNotSupportedException("Current element node cannot be queried when node expansion is deferred.");
             }
             return (fCurrentNode!=null &&
                     fCurrentNode.getNodeType() == Node.ELEMENT_NODE)? fCurrentNode:null;
         }
  
          try {
              XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)
                      fConfiguration.getProperty(XML_SECURITY_PROPERTY_MANAGER);
              int index = spm.getIndex(propertyId);
              if (index > -1) {
                  return spm.getValueByIndex(index);
              }
  
              return fConfiguration.getProperty(propertyId);
          }
          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}));
              }
          }
  
      } // getProperty(String):Object
  
      /**
       * Returns this parser's XMLParserConfiguration.
       */
      public XMLParserConfiguration getXMLParserConfiguration() {
          return fConfiguration;
      } // getXMLParserConfiguration():XMLParserConfiguration
  
  } // class DOMParser
  