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 1999-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.
   */
  /*
   * $Id: SystemIDResolver.java,v 1.2.4.1 2005/09/15 08:15:58 suresh_emailid Exp $
   */
  package jaxp.sun.org.apache.xml.internal.utils;
  
  import java.io.File;
  
  import jaxp.xml.transform.TransformerException;
  
  /**
   * This class is used to resolve relative URIs and SystemID
   * strings into absolute URIs.
   *
   * <p>This is a generic utility for resolving URIs, other than the
   * fact that it's declared to throw TransformerException.  Please
   * see code comments for details on how resolution is performed.</p>
   * @xsl.usage internal
   */
  public class SystemIDResolver
  {
  
    /**
     * Get an absolute URI from a given relative URI (local path).
     *
     * <p>The relative URI is a local filesystem path. The path can be
     * absolute or relative. If it is a relative path, it is resolved relative
     * to the system property "user.dir" if it is available; if not (i.e. in an
     * Applet perhaps which throws SecurityException) then we just return the
     * relative path. The space and backslash characters are also replaced to
     * generate a good absolute URI.</p>
     *
     * @param localPath The relative URI to resolve
     *
     * @return Resolved absolute URI
     */
    public static String getAbsoluteURIFromRelative(String localPath)
    {
      if (localPath == null || localPath.length() == 0)
        return "";
  
      // If the local path is a relative path, then it is resolved against
      // the "user.dir" system property.
      String absolutePath = localPath;
      if (!isAbsolutePath(localPath))
      {
        try
        {
          absolutePath = getAbsolutePathFromRelativePath(localPath);
        }
        // user.dir not accessible from applet
        catch (SecurityException se)
        {
          return "file:" + localPath;
        }
      }
  
      String urlString;
      if (null != absolutePath)
      {
        if (absolutePath.startsWith(File.separator))
          urlString = "file://" + absolutePath;
        else
          urlString = "file:///" + absolutePath;
      }
      else
        urlString = "file:" + localPath;
  
      return replaceChars(urlString);
    }
  
    /**
     * Return an absolute path from a relative path.
     *
     * @param relativePath A relative path
     * @return The absolute path
     */
    private static String getAbsolutePathFromRelativePath(String relativePath)
    {
      return new File(relativePath).getAbsolutePath();
    }
  
    /**
     * Return true if the systemId denotes an absolute URI .
     *
     * @param systemId The systemId string
     * @return true if the systemId is an an absolute URI
     */
    public static boolean isAbsoluteURI(String systemId)
    {
       /** http://www.ietf.org/rfc/rfc2396.txt
        *   Authors should be aware that a path segment which contains a colon
        * character cannot be used as the first segment of a relative URI path
        * (e.g., "this:that"), because it would be mistaken for a scheme name.
       **/
       /**
        * %REVIEW% Can we assume here that systemId is a valid URI?
        * It looks like we cannot ( See discussion of this common problem in
        * Bugzilla Bug 22777 ).
       **/
       //"fix" for Bugzilla Bug 22777
      if(isWindowsAbsolutePath(systemId)){
          return false;
       }
  
      final int fragmentIndex = systemId.indexOf('#');
      final int queryIndex = systemId.indexOf('?');
      final int slashIndex = systemId.indexOf('/');
      final int colonIndex = systemId.indexOf(':');
  
      //finding substring  before '#', '?', and '/'
      int index = systemId.length() -1;
      if(fragmentIndex > 0)
          index = fragmentIndex;
      if((queryIndex > 0) && (queryIndex <index))
          index = queryIndex;
      if((slashIndex > 0) && (slashIndex <index))
          index = slashIndex;
      // return true if there is ':' before '#', '?', and '/'
      return ((colonIndex >0) && (colonIndex<index));
  
    }
  
    /**
     * Return true if the local path is an absolute path.
     *
     * @param systemId The path string
     * @return true if the path is absolute
     */
    public static boolean isAbsolutePath(String systemId)
    {
      if(systemId == null)
          return false;
      final File file = new File(systemId);
      return file.isAbsolute();
  
    }
  
     /**
     * Return true if the local path is a Windows absolute path.
     *
     * @param systemId The path string
     * @return true if the path is a Windows absolute path
     */
      private static boolean isWindowsAbsolutePath(String systemId)
    {
      if(!isAbsolutePath(systemId))
        return false;
      // On Windows, an absolute path starts with "[drive_letter]:\".
      if (systemId.length() > 2
          && systemId.charAt(1) == ':'
          && Character.isLetter(systemId.charAt(0))
          && (systemId.charAt(2) == '\\' || systemId.charAt(2) == '/'))
        return true;
      else
        return false;
    }
  
    /**
     * Replace spaces with "%20" and backslashes with forward slashes in
     * the input string to generate a well-formed URI string.
     *
     * @param str The input string
     * @return The string after conversion
     */
    private static String replaceChars(String str)
    {
      StringBuffer buf = new StringBuffer(str);
      int length = buf.length();
      for (int i = 0; i < length; i++)
      {
        char currentChar = buf.charAt(i);
        // Replace space with "%20"
        if (currentChar == ' ')
        {
          buf.setCharAt(i, '%');
          buf.insert(i+1, "20");
          length = length + 2;
          i = i + 2;
        }
        // Replace backslash with forward slash
        else if (currentChar == '\\')
        {
          buf.setCharAt(i, '/');
        }
      }
  
      return buf.toString();
    }
  
    /**
     * Take a SystemID string and try to turn it into a good absolute URI.
     *
     * @param systemId A URI string, which may be absolute or relative.
     *
     * @return The resolved absolute URI
     */
    public static String getAbsoluteURI(String systemId)
    {
      String absoluteURI = systemId;
      if (isAbsoluteURI(systemId))
      {
        // Only process the systemId if it starts with "file:".
        if (systemId.startsWith("file:"))
        {
          String str = systemId.substring(5);
  
          // Resolve the absolute path if the systemId starts with "file:///"
          // or "file:/". Don't do anything if it only starts with "file://".
          if (str != null && str.startsWith("/"))
          {
            if (str.startsWith("///") || !str.startsWith("//"))
            {
              // A Windows path containing a drive letter can be relative.
              // A Unix path starting with "file:/" is always absolute.
              int secondColonIndex = systemId.indexOf(':', 5);
              if (secondColonIndex > 0)
              {
                String localPath = systemId.substring(secondColonIndex-1);
                try {
                  if (!isAbsolutePath(localPath))
                    absoluteURI = systemId.substring(0, secondColonIndex-1) +
                                  getAbsolutePathFromRelativePath(localPath);
                }
                catch (SecurityException se) {
                  return systemId;
                }
              }
            }
          }
          else
          {
            return getAbsoluteURIFromRelative(systemId.substring(5));
          }
  
          return replaceChars(absoluteURI);
        }
        else
          return systemId;
      }
      else
        return getAbsoluteURIFromRelative(systemId);
  
    }
  
  
    /**
     * Take a SystemID string and try to turn it into a good absolute URI.
     *
     * @param urlString SystemID string
     * @param base The URI string used as the base for resolving the systemID
     *
     * @return The resolved absolute URI
     * @throws TransformerException thrown if the string can't be turned into a URI.
     */
    public static String getAbsoluteURI(String urlString, String base)
            throws TransformerException
    {
      if (base == null)
        return getAbsoluteURI(urlString);
  
      String absoluteBase = getAbsoluteURI(base);
      URI uri = null;
      try
      {
        URI baseURI = new URI(absoluteBase);
        uri = new URI(baseURI, urlString);
      }
      catch (URI.MalformedURIException mue)
      {
        throw new TransformerException(mue);
      }
  
      return replaceChars(uri.toString());
    }
  
  }
  