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 2002,2004 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.utils;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  import java.security.AccessController;
  import java.security.PrivilegedAction;
  import java.security.PrivilegedActionException;
  import java.security.PrivilegedExceptionAction;
  import java.util.Locale;
  import java.util.MissingResourceException;
  import java.util.Properties;
  import java.util.PropertyResourceBundle;
  import java.util.ResourceBundle;
  
  /**
   * This class is duplicated for each subpackage so keep it in sync.
   * It is package private and therefore is not exposed as part of any API.
   *
   * @xerces.internal
   */
  public final class SecuritySupport {
  
      private static final SecuritySupport securitySupport = new SecuritySupport();
  
      /**
       * Return an instance of this class.
       */
      public static SecuritySupport getInstance() {
          return securitySupport;
      }
  
      static ClassLoader getContextClassLoader() {
          return (ClassLoader)
          AccessController.doPrivileged(new PrivilegedAction() {
              public Object run() {
                  ClassLoader cl = null;
                  try {
                      cl = Thread.currentThread().getContextClassLoader();
                  } catch (SecurityException ex) { }
                  return cl;
              }
          });
      }
  
      static ClassLoader getSystemClassLoader() {
          return (ClassLoader)
          AccessController.doPrivileged(new PrivilegedAction() {
              public Object run() {
                  ClassLoader cl = null;
                  try {
                      cl = ClassLoader.getSystemClassLoader();
                  } catch (SecurityException ex) {}
                  return cl;
              }
          });
      }
  
      static ClassLoader getParentClassLoader(final ClassLoader cl) {
          return (ClassLoader)
          AccessController.doPrivileged(new PrivilegedAction() {
              public Object run() {
                  ClassLoader parent = null;
                  try {
                      parent = cl.getParent();
                  } catch (SecurityException ex) {}
  
                  // eliminate loops in case of the boot
                  // ClassLoader returning itself as a parent
                  return (parent == cl) ? null : parent;
              }
          });
      }
  
      public static String getSystemProperty(final String propName) {
          return (String)
          AccessController.doPrivileged(new PrivilegedAction() {
              public Object run() {
                  return System.getProperty(propName);
              }
          });
      }
  
      static FileInputStream getFileInputStream(final File file)
      throws FileNotFoundException
      {
          try {
              return (FileInputStream)
              AccessController.doPrivileged(new PrivilegedExceptionAction() {
                  public Object run() throws FileNotFoundException {
                      return new FileInputStream(file);
                  }
              });
          } catch (PrivilegedActionException e) {
              throw (FileNotFoundException)e.getException();
          }
      }
      /**
       * Return resource using the same classloader for the ObjectFactory by default
       * or bootclassloader when Security Manager is in place
       */
      public static InputStream getResourceAsStream(final String name) {
          if (System.getSecurityManager()!=null) {
              return getResourceAsStream(null, name);
          } else {
              return getResourceAsStream(ObjectFactory.findClassLoader(), name);
          }
      }
  
      public static InputStream getResourceAsStream(final ClassLoader cl,
              final String name)
      {
          return (InputStream)
          AccessController.doPrivileged(new PrivilegedAction() {
              public Object run() {
                  InputStream ris;
                  if (cl == null) {
                      ris = Object.class.getResourceAsStream("/"+name);
                  } else {
                      ris = cl.getResourceAsStream(name);
                  }
                  return ris;
              }
          });
      }
  
      /**
       * Gets a resource bundle using the specified base name, the default locale, and the caller's class loader.
       * @param bundle the base name of the resource bundle, a fully qualified class name
       * @return a resource bundle for the given base name and the default locale
       */
      public static ResourceBundle getResourceBundle(String bundle) {
          return getResourceBundle(bundle, Locale.getDefault());
      }
  
      /**
       * Gets a resource bundle using the specified base name and locale, and the caller's class loader.
       * @param bundle the base name of the resource bundle, a fully qualified class name
       * @param locale the locale for which a resource bundle is desired
       * @return a resource bundle for the given base name and locale
       */
      public static ResourceBundle getResourceBundle(final String bundle, final Locale locale) {
          return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
              public ResourceBundle run() {
                  try {
                      return PropertyResourceBundle.getBundle(bundle, locale);
                  } catch (MissingResourceException e) {
                      try {
                          return PropertyResourceBundle.getBundle(bundle, new Locale("en", "US"));
                      } catch (MissingResourceException e2) {
                          throw new MissingResourceException(
                                  "Could not load any resource bundle by " + bundle, bundle, "");
                      }
                  }
              }
          });
      }
  
      static boolean getFileExists(final File f) {
          return ((Boolean)
                  AccessController.doPrivileged(new PrivilegedAction() {
                      public Object run() {
                          return f.exists() ? Boolean.TRUE : Boolean.FALSE;
                      }
                  })).booleanValue();
      }
  
      static long getLastModified(final File f) {
          return ((Long)
                  AccessController.doPrivileged(new PrivilegedAction() {
                      public Object run() {
                          return new Long(f.lastModified());
                      }
                  })).longValue();
      }
  
      /**
       * Strip off path from an URI
       *
       * @param uri an URI with full path
       * @return the file name only
       */
      public static String sanitizePath(String uri) {
          if (uri == null) {
              return "";
          }
          int i = uri.lastIndexOf("/");
          if (i > 0) {
              return uri.substring(i+1, uri.length());
          }
          return uri;
      }
  
      /**
       * Check the protocol used in the systemId against allowed protocols
       *
       * @param systemId the Id of the URI
       * @param allowedProtocols a list of allowed protocols separated by comma
       * @param accessAny keyword to indicate allowing any protocol
       * @return the name of the protocol if rejected, null otherwise
       */
      public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException {
          if (systemId == null || (allowedProtocols != null &&
                  allowedProtocols.equalsIgnoreCase(accessAny))) {
              return null;
          }
  
          String protocol;
          if (systemId.indexOf(":")==-1) {
              protocol = "file";
          } else {
              URL url = new URL(systemId);
              protocol = url.getProtocol();
              if (protocol.equalsIgnoreCase("jar")) {
                  String path = url.getPath();
                  protocol = path.substring(0, path.indexOf(":"));
              }
          }
  
          if (isProtocolAllowed(protocol, allowedProtocols)) {
              //access allowed
              return null;
          } else {
              return protocol;
          }
      }
  
      /**
       * Check if the protocol is in the allowed list of protocols. The check
       * is case-insensitive while ignoring whitespaces.
       *
       * @param protocol a protocol
       * @param allowedProtocols a list of allowed protocols
       * @return true if the protocol is in the list
       */
      private static boolean isProtocolAllowed(String protocol, String allowedProtocols) {
           if (allowedProtocols == null) {
               return false;
           }
           String temp[] = allowedProtocols.split(",");
           for (String t : temp) {
               t = t.trim();
               if (t.equalsIgnoreCase(protocol)) {
                   return true;
               }
           }
           return false;
       }
  
      /**
       * Read JAXP system property in this order: system property,
       * $java.home/lib/jaxp.properties if the system property is not specified
       *
       * @param propertyId the Id of the property
       * @return the value of the property
       */
      public static String getJAXPSystemProperty(String sysPropertyId) {
          String accessExternal = getSystemProperty(sysPropertyId);
          if (accessExternal == null) {
              accessExternal = readJAXPProperty(sysPropertyId);
          }
          return accessExternal;
      }
  
       /**
       * Read from $java.home/lib/jaxp.properties for the specified property
       * The program
       *
       * @param propertyId the Id of the property
       * @return the value of the property
       */
      static String readJAXPProperty(String propertyId) {
          String value = null;
          InputStream is = null;
          try {
              if (firstTime) {
                  synchronized (cacheProps) {
                      if (firstTime) {
                          String configFile = getSystemProperty("java.home") + File.separator +
                              "lib" + File.separator + "jaxp.properties";
                          File f = new File(configFile);
                          if (getFileExists(f)) {
                              is = getFileInputStream(f);
                              cacheProps.load(is);
                          }
                          firstTime = false;
                      }
                  }
              }
              value = cacheProps.getProperty(propertyId);
  
          }
          catch (Exception ex) {}
          finally {
              if (is != null) {
                  try {
                      is.close();
                  } catch (IOException ex) {}
              }
          }
  
          return value;
      }
  
     /**
       * Cache for properties in java.home/lib/jaxp.properties
       */
      static final Properties cacheProps = new Properties();
  
      /**
       * Flag indicating if the program has tried reading java.home/lib/jaxp.properties
       */
      static volatile boolean firstTime = true;
  
      private SecuritySupport () {}
  }
  