/* File.java -- Class representing a file on disk
   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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 2, or (at your option)
any later version.
 
GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.io;

import gnu.classpath.SystemProperties;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * Status:  Complete to version 1.3.
 */

/**
 * This class represents a file or directory on a local disk.  It provides
 * facilities for dealing with a variety of systems that use various
 * types of path separators ("/" versus "\", for example).  It also
 * contains method useful for creating and deleting files and directories.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Tom Tromey (tromey@cygnus.com)
 */
public class File implements Serializable, Comparable
{
  private static final long serialVersionUID = 301077366599181567L;

  /**
   * This is the path separator string for the current host. This field
   * contains the value of the <code>file.separator</code> system property.
   * An example separator string would be "/" on the GNU system.
   */
  public static final String separator = SystemProperties.getProperty("file.separator");
  private static final String dupSeparator = separator + separator;

  /**
   * This is the first character of the file separator string.  On many
   * hosts (for example, on the GNU system), this represents the entire 
   * separator string.  The complete separator string is obtained from the
   * <code>file.separator</code>system property.
   */
  public static final char separatorChar = separator.charAt(0);
  
  /**
   * This is the string that is used to separate the host name from the
   * path name in paths that include the host name.  It is the value of
   * the <code>path.separator</code> system property.
   */
  public static final String pathSeparator
    = SystemProperties.getProperty("path.separator");
  
  /**
   * This is the first character of the string used to separate the host name
   * from the path name in paths that include a host.  The separator string
   * is taken from the <code>path.separator</code> system property.
   */
  public static final char pathSeparatorChar = pathSeparator.charAt(0);

  /**
   * This is the path to the file set when the object is created.  It
   * may be an absolute or relative path name.
   */
  private String path;
  
  
  /**
   * The time (millisecond), when the last temporary file was created.
   */
  private static long last_tmp;
  
  /**
   * The number of files, created during the current millisecond.
   */
  private static int n_created;  

  /**
   * This method tests whether or not the current thread is allowed to
   * to read the file pointed to by this object.  This will be true if and
   * and only if 1) the file exists and 2) the <code>SecurityManager</code>
   * (if any) allows access to the file via it's <code>checkRead</code>
   * method 3) the file is readable.
   *
   * @return <code>true</code> if reading is allowed, 
   * <code>false</code> otherwise
   *
   * @exception SecurityException If the <code>SecurityManager</code> 
   * does not allow access to the file
   */
  public boolean canRead()
  {
    // Test for existence. This also does the SecurityManager check
    if (!exists())
      return false;

    return VMFile.canRead(path);
  }

  /**
   * This method test whether or not the current thread is allowed to
   * write to this object.  This will be true if and only if 1) The
   * <code>SecurityManager</code> (if any) allows write access to the
   * file and 2) The file exists and 3) The file is writable.  To determine
   * whether or not a non-existent file can be created, check the parent
   * directory for write access.
   *
   * @return <code>true</code> if writing is allowed, <code>false</code> 
   * otherwise
   *
   * @exception SecurityException If the <code>SecurityManager</code> 
   * does not allow access to the file
   */
  public boolean canWrite()
  {
    // First do a SecurityCheck before doing anything else.
    checkWrite();
     
    // Test for existence.  This is required by the spec
    if (! VMFile.exists(path))
      return false;

    if (VMFile.isDirectory(path))
      return VMFile.canWriteDirectory(this);
    else
      return VMFile.canWrite(path);
  }

  /**
   * This method creates a new file of zero length with the same name as
   * the path of this <code>File</code> object if an only if that file
   * does not already exist.
   * <p>
   * A <code>SecurityManager.checkWrite</code> check is done prior
   * to performing this action.
   *
   * @return <code>true</code> if the file was created, <code>false</code> if
   * the file alread existed.
   *
   * @exception IOException If an I/O error occurs
   * @exception SecurityException If the <code>SecurityManager</code> will
   * not allow this operation to be performed.
   *
   * @since 1.2
   */
  public boolean createNewFile() throws IOException
  {
    checkWrite();
    return VMFile.create(path);
  }
  /**
   * This method deletes the file represented by this object.  If this file
   * is a directory, it must be empty in order for the delete to succeed.
   *
   * @return <code>true</code> if the file was deleted, <code>false</code> 
   * otherwise
   *
   * @exception SecurityException If deleting of the file is not allowed
   */
  public synchronized boolean delete()
  {
    SecurityManager s = System.getSecurityManager();
    
    if (s != null)
      s.checkDelete(path);
    
    return VMFile.delete(path);
  }

  /**
   * This method tests two <code>File</code> objects for equality by 
   * comparing the path of the specified <code>File</code> against the path
   * of this object.  The two objects are equal if an only if 1) The
   * argument is not null 2) The argument is a <code>File</code> object and
   * 3) The path of the <code>File</code>argument is equal to the path
   * of this object.
   * <p>
   * The paths of the files are determined by calling the 
   * <code>getPath()</code>
   * method on each object.
   *
   * @return <code>true</code> if the two objects are equal, 
   * <code>false</code> otherwise.
   */
  public boolean equals(Object obj)
  {
    if (! (obj instanceof File))
      return false;
    
    File other = (File) obj;

    if (VMFile.IS_CASE_SENSITIVE)
      return path.equals(other.path);
    else
      return path.equalsIgnoreCase(other.path);
  }

  /**
   * This method tests whether or not the file represented by the object
   * actually exists on the filesystem.
   *
   * @return <code>true</code> if the file exists, <code>false</code>otherwise.
   *
   * @exception SecurityException If reading of the file is not permitted
   */
  public boolean exists()
  {
    checkRead();
    return VMFile.exists(path);
  }

  /**
   * This method initializes a new <code>File</code> object to represent
   * a file with the specified path.
   *
   * @param name The path name of the file
   */
  public File(String name)
  {
    path = normalizePath (name);
  }
 
  // Remove duplicate and redundant separator characters.
  private String normalizePath(String p)
  {
    // On Windows, convert any '/' to '\'.  This appears to be the same logic
    // that Sun's Win32 Java performs.
    if (separatorChar == '\\')
      {
        p = p.replace ('/', '\\');
	// We have to special case the "\c:" prefix.
	if (p.length() > 2 && p.charAt(0) == '\\' &&
	    ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') ||
	    (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) &&
	    p.charAt(2) == ':')
	  p = p.substring(1);
      }

    int dupIndex = p.indexOf(dupSeparator);
    int plen = p.length();

    // Special case: permit Windows UNC path prefix.
    if (dupSeparator.equals("\\\\") && dupIndex == 0)
      dupIndex = p.indexOf(dupSeparator, 1);

    if (dupIndex == -1)
      {
        // Ignore trailing separator (though on Windows "a:\", for
        // example, is a valid and minimal path).
        if (plen > 1 && p.charAt (plen - 1) == separatorChar)
	  {
	    if (! (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':'))
	      return p.substring (0, plen - 1);
	  }
	else
	  return p;
      }
    
    StringBuffer newpath = new StringBuffer(plen);
    int last = 0;
    while (dupIndex != -1)
      {
        newpath.append(p.substring(last, dupIndex));
	// Ignore the duplicate path characters.
	while (p.charAt(dupIndex) == separatorChar)
	  {
	    dupIndex++;
	    if (dupIndex == plen)
	      return newpath.toString();
	  }
	newpath.append(separatorChar);
	last = dupIndex;
	dupIndex = p.indexOf(dupSeparator, last);
      }
    
    // Again, ignore possible trailing separator (except special cases
    // like "a:\" on Windows).
    int end;
    if (plen > 1 && p.charAt (plen - 1) == separatorChar)
    {
      if (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':')
        end = plen;
      else
        end = plen - 1;
    }
    else
      end = plen;
    newpath.append(p.substring(last, end));
    
    return newpath.toString();
  }
 
  /**
   * This method initializes a new <code>File</code> object to represent
   * a file in the specified named directory.  The path name to the file
   * will be the directory name plus the separator string plus the file
   * name.  If the directory path name ends in the separator string, another
   * separator string will still be appended.
   *
   * @param dirPath The path to the directory the file resides in
   * @param name The name of the file
   */
  public File(String dirPath, String name)
  {
    if (name == null)
      throw new NullPointerException();
    if (dirPath != null)
      {
	if (dirPath.length() > 0)
	  {
	    // Try to be smart about the number of separator characters.
	    if (dirPath.charAt(dirPath.length() - 1) == separatorChar
		|| name.length() == 0)
	      path = normalizePath(dirPath + name);
	    else
	      path = normalizePath(dirPath + separatorChar + name);
	  }
	else
	  {
	    // If dirPath is empty, use a system dependant
	    // default prefix.
	    // Note that the leading separators in name have
	    // to be chopped off, to prevent them forming
	    // a UNC prefix on Windows.
	    if (separatorChar == '\\' /* TODO use ON_WINDOWS */)
	      {
		int skip = 0;
		while(name.length() > skip
		    && (name.charAt(skip) == separatorChar
		    || name.charAt(skip) == '/'))
		  {
		    skip++;
		  }
		name = name.substring(skip);
	      }
	    path = normalizePath(separatorChar + name);
	  }
      }
    else
      path = normalizePath(name);
  }

  /**
   * This method initializes a new <code>File</code> object to represent
   * a file in the specified directory.  If the <code>directory</code>
   * argument is <code>null</code>, the file is assumed to be in the
   * current directory as specified by the <code>user.dir</code> system
   * property
   *
   * @param directory The directory this file resides in
   * @param name The name of the file
   */
  public File(File directory, String name)
  {
    this (directory == null ? null : directory.path, name);
  }

  /**
   * This method initializes a new <code>File</code> object to represent
   * a file corresponding to the specified <code>file:</code> protocol URI.
   *
   * @param uri The URI
   * @throws IllegalArgumentException if the URI is not hierarchical
   */
  public File(URI uri)
  {
    if (uri == null)
	throw new NullPointerException("uri is null");

    if (!uri.getScheme().equals("file"))
	throw new IllegalArgumentException("invalid uri protocol");

    String name = uri.getPath();
    if (name == null)
      throw new IllegalArgumentException("URI \"" + uri
                     + "\" is not hierarchical");
    path = normalizePath(name);
  }

  /**
   * This method returns the path of this file as an absolute path name.
   * If the path name is already absolute, then it is returned.  Otherwise
   * the value returned is the current directory plus the separatory
   * string plus the path of the file.  The current directory is determined
   * from the <code>user.dir</code> system property.
   *
   * @return The absolute path of this file
   */
  public String getAbsolutePath()
  {
    if (isAbsolute())
      return path;
    else if (separatorChar == '\\' 
             && path.length() > 0 && path.charAt (0) == '\\')
      {
        // On Windows, even if the path starts with a '\\' it is not
        // really absolute until we prefix the drive specifier from
        // the current working directory to it.
        return System.getProperty ("user.dir").substring (0, 2) + path;
      }
    else if (separatorChar == '\\' 
             && path.length() > 1 && path.charAt (1) == ':'
             && ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
                 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
      {
        // On Windows, a process has a current working directory for
        // each drive and a path like "G:foo\bar" would mean the 
        // absolute path "G:\wombat\foo\bar" if "\wombat" is the 
        // working directory on the G drive.
        String drvDir = null;
        try
          {
            drvDir = new File (path.substring (0, 2)).getCanonicalPath();
          }
        catch (IOException e)
          {
            drvDir = path.substring (0, 2) + "\\";
          }
        
        // Note: this would return "C:\\." for the path "C:.", if "\"
        // is the working folder on the C drive, but this is 
        // consistent with what Sun's JRE 1.4.1.01 actually returns!
        if (path.length() > 2)
          return drvDir + '\\' + path.substring (2, path.length());
        else
          return drvDir;
      }
    else if (path.equals(""))
      return System.getProperty ("user.dir");
    else
      return System.getProperty ("user.dir") + separatorChar + path;
  }

  /**
   * This method returns a <code>File</code> object representing the
   * absolute path of this object.
   *
   * @return A <code>File</code> with the absolute path of the object.
   *
   * @since 1.2
   */
  public File getAbsoluteFile()
  {
    return new File(getAbsolutePath());
  }

  /**
   * This method returns a canonical representation of the pathname of
   * this file.  The actual form of the canonical representation is
   * system-dependent.  On the GNU system, conversion to canonical
   * form involves the removal of redundant separators, references to
   * "." and "..", and symbolic links.
   * <p>
   * Note that this method, unlike the other methods which return path
   * names, can throw an IOException.  This is because native method 
   * might be required in order to resolve the canonical path
   *
   * @exception IOException If an error occurs
   */
  public String getCanonicalPath() throws IOException
  {
    // On Windows, getAbsolutePath might end up calling us, so we
    // have to special case that call to avoid infinite recursion.
    if (separatorChar == '\\' && path.length() == 2 &&
	((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') ||
	 (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) &&
	path.charAt(1) == ':')
    {
	return VMFile.toCanonicalForm(path);
    }
    // Call getAbsolutePath first to make sure that we do the
    // current directory handling, because the native code
    // may have a different idea of the current directory.
    return VMFile.toCanonicalForm(getAbsolutePath());
  }

  /**
   * This method returns a <code>File</code> object representing the
   * canonical path of this object.
   *
   * @return A <code>File</code> instance representing the canonical path of
   * this object.
   *
   * @exception IOException If an error occurs.
   *
   * @since 1.2
   */
  public File getCanonicalFile() throws IOException
  {
    return new File(getCanonicalPath());
  }

  /**
   * This method returns the name of the file.  This is everything in the
   * complete path of the file after the last instance of the separator
   * string.
   *
   * @return The file name
   */
  public String getName()
  {
  	return VMFile.getName(path);
  }

  /**
   * This method returns a <code>String</code> the represents this file's
   * parent.  <code>null</code> is returned if the file has no parent.  The
   * parent is determined via a simple operation which removes the name
   * after the last file separator character, as determined by the platform.
   *
   * @return The parent directory of this file
   */
  public String getParent()
  {
    String prefix = null;
    int nameSeqIndex = 0;
    
    if (path.equals(""))
      return null;

    // The "prefix", if present, is the leading "/" on UNIX and 
    // either the drive specifier (e.g. "C:") or the leading "\\"
    // of a UNC network path on Windows.
    if (separatorChar == '/' && path.charAt (0) == '/')
      {
        prefix = "/";
        nameSeqIndex = 1;
      }
    else if (separatorChar == '\\' && path.length() > 1)
      {
        if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
            || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
                 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
                && path.charAt (1) == ':'))
          {
            prefix = path.substring (0, 2);
            nameSeqIndex = 2;
          }
      }

    // According to the JDK docs, the returned parent path is the 
    // portion of the name sequence before the last separator
    // character, if found, prefixed by the prefix, otherwise null.
    if (nameSeqIndex < path.length())
      {
        String nameSeq = path.substring (nameSeqIndex, path.length());
        int last = nameSeq.lastIndexOf (separatorChar);
        if (last == -1)
          return prefix;
        else if (last == (nameSeq.length() - 1))
          // Note: The path would not have a trailing separator
          // except for cases like "C:\" on Windows (see 
          // normalizePath( )), where Sun's JRE 1.4 returns null.
          return null;
        else if (last == 0)
          last++;

        if (prefix != null)
          return prefix + nameSeq.substring (0, last);
        else
          return nameSeq.substring (0, last);
      }
    else
      // Sun's JRE 1.4 returns null if the prefix is the only 
      // component of the path - so "/" gives null on UNIX and 
      // "C:", "\\", etc. return null on Windows.
      return null;
  }

  /**
   * This method returns a <code>File</code> object representing the parent
   * file of this one.
   *
   * @return a <code>File</code> for the parent of this object.  
   * <code>null</code>
   * will be returned if this object does not have a parent.
   *
   * @since 1.2
   */
  public File getParentFile()
  {
    String parent = getParent();
    return parent != null ? new File(parent) : null;
  }

  /**
   * Returns the path name that represents this file.  May be a relative
   * or an absolute path name
   *
   * @return The pathname of this file
   */
  public String getPath()
  {
    return path;
  }

  /**
   * This method returns a hash code representing this file.  It is the
   * hash code of the path of this file (as returned by <code>getPath()</code>)
   * exclusived or-ed with the value 1234321.
   *
   * @return The hash code for this object
   */
  public int hashCode()
  {
    if (VMFile.IS_CASE_SENSITIVE)
      return path.hashCode() ^ 1234321;
    else
      return path.toLowerCase().hashCode() ^ 1234321;
  }

  /**
   * This method returns true if this object represents an absolute file
   * path and false if it does not.  The definition of an absolute path varies
   * by system.  As an example, on GNU systems, a path is absolute if it starts
   * with a "/".
   *
   * @return <code>true</code> if this object represents an absolute 
   * file name, <code>false</code> otherwise.
   */
  public boolean isAbsolute()
  {
    if (separatorChar == '\\')
	return path.startsWith(dupSeparator) || 
	    (path.length() > 2 && 
	     ((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') ||
	      (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) &&
	     path.charAt(1) == ':' &&
	     path.charAt(2) == '\\');
    else
	return path.startsWith(separator);
  }

  /**
   * This method tests whether or not the file represented by this object
   * is a directory.  In order for this method to return <code>true</code>,
   * the file represented by this object must exist and be a directory.
   * 
   * @return <code>true</code> if this file is a directory, <code>false</code>
   * otherwise
   *
   * @exception SecurityException If reading of the file is not permitted
   */
  public boolean isDirectory()
  {
    checkRead();
    return VMFile.isDirectory(path); 
  }

  /**
   * This method tests whether or not the file represented by this object
   * is a "plain" file.  A file is a plain file if and only if it 1) Exists,
   * 2) Is not a directory or other type of special file.
   *
   * @return <code>true</code> if this is a plain file, <code>false</code> 
   * otherwise
   *
   * @exception SecurityException If reading of the file is not permitted
   */
  public boolean isFile()
  {
    checkRead();
    return VMFile.isFile(path);
  }

  /**
   * This method tests whether or not this file represents a "hidden" file.
   * On GNU systems, a file is hidden if its name begins with a "."
   * character.  Files with these names are traditionally not shown with
   * directory listing tools.
   *
   * @return <code>true</code> if the file is hidden, <code>false</code>
   * otherwise.
   *
   * @since 1.2
   */
  public boolean isHidden()
  {
    return VMFile.isHidden(path);
  }

  /**
   * This method returns the last modification time of this file.  The
   * time value returned is an abstract value that should not be interpreted
   * as a specified time value.  It is only useful for comparing to other
   * such time values returned on the same system.  In that case, the larger
   * value indicates a more recent modification time. 
   * <p>
   * If the file does not exist, then a value of 0 is returned.
   *
   * @return The last modification time of the file
   *
   * @exception SecurityException If reading of the file is not permitted
   */
  public long lastModified()
  {
    checkRead();
    return VMFile.lastModified(path);
  }

  /**
   * This method returns the length of the file represented by this object,
   * or 0 if the specified file does not exist.
   *
   * @return The length of the file
   *
   * @exception SecurityException If reading of the file is not permitted
   */
  public long length()
  {
    checkRead();
    return VMFile.length(path);
  }

  /**
   * This method returns a array of <code>String</code>'s representing the
   * list of files is then directory represented by this object.  If this
   * object represents a non-directory file or a non-existent file, then
   * <code>null</code> is returned.  The list of files will not contain
   * any names such as "." or ".." which indicate the current or parent
   * directory.  Also, the names are not guaranteed to be sorted.
   * <p>
   * In this form of the <code>list()</code> method, a filter is specified
   * that allows the caller to control which files are returned in the
   * list.  The <code>FilenameFilter</code> specified is called for each
   * file returned to determine whether or not that file should be included
   * in the list.
   * <p>
   * A <code>SecurityManager</code> check is made prior to reading the
   * directory.  If read access to the directory is denied, an exception
   * will be thrown.
   *
   * @param filter An object which will identify files to exclude from 
   * the directory listing.
   *
   * @return An array of files in the directory, or <code>null</code> 
   * if this object does not represent a valid directory.
   * 
   * @exception SecurityException If read access is not allowed to the 
   * directory by the <code>SecurityManager</code>
   */
  public String[] list(FilenameFilter filter)
  {
    checkRead();

    if (!exists() || !isDirectory())
      return null;
    
    // Get the list of files
    String files[] = VMFile.list(path);
    
    // Check if an error occured in listInternal().
    if (files == null)
      return null;

    if (filter == null)
      return files;
    
    // Apply the filter
    int count = 0;
    for (int i = 0; i < files.length; i++)
      {
        if (filter.accept(this, files[i]))
  	  ++count;
        else
  	  files[i] = null;
      }

    String[] retfiles = new String[count];
    count = 0;
    for (int i = 0; i < files.length; i++)
      if (files[i] != null)
        retfiles[count++] = files[i];

    return retfiles;
  }

  /**
   * This method returns a array of <code>String</code>'s representing the
   * list of files is then directory represented by this object.  If this
   * object represents a non-directory file or a non-existent file, then
   * <code>null</code> is returned.  The list of files will not contain
   * any names such as "." or ".." which indicate the current or parent
   * directory.  Also, the names are not guaranteed to be sorted.
   * <p>
   * A <code>SecurityManager</code> check is made prior to reading the
   * directory.  If read access to the directory is denied, an exception
   * will be thrown.
   *
   * @return An array of files in the directory, or <code>null</code> if 
   * this object does not represent a valid directory.
   * 
   * @exception SecurityException If read access is not allowed to the 
   * directory by the <code>SecurityManager</code>
   */
  public String[] list()
  {
    return list(null);
  }

  /**
   * This method returns an array of <code>File</code> objects representing
   * all the files in the directory represented by this object. If this
   * object does not represent a directory, <code>null</code> is returned.
   * Each of the returned <code>File</code> object is constructed with this
   * object as its parent.
   * <p>
   * A <code>SecurityManager</code> check is made prior to reading the
   * directory.  If read access to the directory is denied, an exception
   * will be thrown.
   *
   * @return An array of <code>File</code> objects for this directory.
   *
   * @exception SecurityException If the <code>SecurityManager</code> denies
   * access to this directory.
   *
   * @since 1.2
   */
  public File[] listFiles()
  {
    return listFiles((FilenameFilter) null);
  }
  
  /**
   * This method returns an array of <code>File</code> objects representing
   * all the files in the directory represented by this object. If this
   * object does not represent a directory, <code>null</code> is returned.
   * Each of the returned <code>File</code> object is constructed with this
   * object as its parent.
   * <p> 
   * In this form of the <code>listFiles()</code> method, a filter is specified
   * that allows the caller to control which files are returned in the
   * list.  The <code>FilenameFilter</code> specified is called for each
   * file returned to determine whether or not that file should be included
   * in the list.
   * <p>
   * A <code>SecurityManager</code> check is made prior to reading the
   * directory.  If read access to the directory is denied, an exception
   * will be thrown.
   *
   * @return An array of <code>File</code> objects for this directory.
   *
   * @exception SecurityException If the <code>SecurityManager</code> denies
   * access to this directory.
   *
   * @since 1.2
   */
  public File[] listFiles(FilenameFilter filter)
  {
    String[] filelist = list(filter);
    
    if (filelist == null)
      return null;

    File[] fobjlist = new File [filelist.length];

    for (int i = 0; i < filelist.length; i++)
      fobjlist [i] = new File(this, filelist [i]);

    return fobjlist;
  }

  /**
   * This method returns an array of <code>File</code> objects representing
   * all the files in the directory represented by this object. If this
   * object does not represent a directory, <code>null</code> is returned.
   * Each of the returned <code>File</code> object is constructed with this
   * object as its parent.
   * <p> 
   * In this form of the <code>listFiles()</code> method, a filter is specified
   * that allows the caller to control which files are returned in the
   * list.  The <code>FileFilter</code> specified is called for each
   * file returned to determine whether or not that file should be included
   * in the list.
   * <p>
   * A <code>SecurityManager</code> check is made prior to reading the
   * directory.  If read access to the directory is denied, an exception
   * will be thrown.
   *
   * @return An array of <code>File</code> objects for this directory.
   *
   * @exception SecurityException If the <code>SecurityManager</code> denies
   * access to this directory.
   *
   * @since 1.2
   */
  public File[] listFiles(FileFilter filter)
  {
    File[] fobjlist = listFiles((FilenameFilter) null);

    if (fobjlist == null)
      return null;

    if (filter == null)
      return fobjlist;

    int count = 0;
    for (int i = 0; i < fobjlist.length; i++)
      if (filter.accept(fobjlist[i]) == true)
        ++count;

    File[] final_list = new File[count];
    count = 0;
    for (int i = 0; i < fobjlist.length; i++)
      if (filter.accept(fobjlist[i]) == true)
        {
          final_list[count] = fobjlist[i];
          ++count;
        }

    return final_list;
  }

  /**
   * This method returns a <code>String</code> that is the path name of the
   * file as returned by <code>getPath</code>.
   *
   * @return A <code>String</code> representation of this file
   */
  public String toString()
  {
    return path;
  }

  /**
   * @return A <code>URI</code> for this object.
   */
  public URI toURI()
  {
    String abspath = getAbsolutePath();
       
    if (isDirectory() || path.equals(""))
      abspath = abspath + separatorChar;

    if (separatorChar == '\\')
      abspath = separatorChar + abspath;
        
    try
      {
        return new URI("file", null, null, -1,
                       abspath.replace(separatorChar, '/'),
                       null, null);
      }
    catch (URISyntaxException use)
      {
        // Can't happen.
        throw (InternalError) new InternalError("Unconvertible file: "
						+ this).initCause(use);
      }
  }

  /**
   * This method returns a <code>URL</code> with the <code>file:</code>
   * protocol that represents this file.  The exact form of this URL is
   * system dependent.
   *
   * @return A <code>URL</code> for this object.
   *
   * @exception MalformedURLException If the URL cannot be created 
   * successfully.
   */
  public URL toURL() throws MalformedURLException
  {
    // On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt",
    // while on UNIX, it returns URLs of the form "file:/foo/bar.txt". 
    if (separatorChar == '\\')
      return new URL ("file:/" + getAbsolutePath().replace ('\\', '/')
		      + (isDirectory() ? "/" : ""));
    else
      return new URL ("file:" + getAbsolutePath()
		      + (isDirectory() ? "/" : ""));
  }


  /**
   * This method creates a directory for the path represented by this object.
   *
   * @return <code>true</code> if the directory was created, 
   * <code>false</code> otherwise
   *
   * @exception SecurityException If write access is not allowed to this file
   */
  public boolean mkdir()
  {
    checkWrite();
    return VMFile.mkdir(path);
  }

  /**
   * This method creates a directory for the path represented by this file.
   * It will also create any intervening parent directories if necessary.
   *
   * @return <code>true</code> if the directory was created, 
   * <code>false</code> otherwise
   *
   * @exception SecurityException If write access is not allowed to this file
   */
  public boolean mkdirs()
  {
    String parent = getParent();
    if (parent == null)
      {
        return mkdir();
      }
      
    File f = new File(parent);
    if (!f.exists())
      {
        boolean rc = f.mkdirs();
        if (rc == false)
          return false;
      }

    return mkdir();
  }

  /**
   * This method creates a temporary file in the specified directory.  If 
   * the directory name is null, then this method uses the system temporary 
   * directory. The files created are guaranteed not to currently exist and 
   * the same file name will never be used twice in the same virtual 
   * machine instance.  
   * The system temporary directory is determined by examinging the 
   * <code>java.io.tmpdir</code> system property.
   * <p>
   * The <code>prefix</code> parameter is a sequence of at least three
   * characters that are used as the start of the generated filename.  The
   * <code>suffix</code> parameter is a sequence of characters that is used
   * to terminate the file name.  This parameter may be <code>null</code>
   * and if it is, the suffix defaults to ".tmp".
   * <p>
   * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
   * method is used to verify that this operation is permitted.
   *
   * @param prefix The character prefix to use in generating the path name.
   * @param suffix The character suffix to use in generating the path name.
   * @param directory The directory to create the file in, or 
   * <code>null</code> for the default temporary directory
   *
   * @exception IllegalArgumentException If the patterns is not valid
   * @exception SecurityException If there is no permission to perform 
   * this operation
   * @exception IOException If an error occurs
   *
   * @since 1.2
   */
  public static synchronized File createTempFile(String prefix, String suffix,
				    File directory)
    throws IOException
  {
    // Grab the system temp directory if necessary
    if (directory == null)
      {
        String dirname = System.getProperty("java.io.tmpdir");
        if (dirname == null)
          throw new IOException("Cannot determine system temporary directory"); 
	
        directory = new File(dirname);
        if (! VMFile.exists(directory.path))
          throw new IOException("System temporary directory "
                                + directory.getName() + " does not exist.");
        if (! VMFile.isDirectory(directory.path))
          throw new IOException("System temporary directory "
                                + directory.getName()
                                + " is not really a directory.");
      }

    // Check if prefix is at least 3 characters long
    if (prefix.length() < 3)
      throw new IllegalArgumentException("Prefix too short: " + prefix);

    // Set default value of suffix
    if (suffix == null)
      suffix = ".tmp";

    // Now identify a file name and make sure it doesn't exist.
    File file;
    if (!VMFile.IS_DOS_8_3)
      { 
        do
          {
            long now = System.currentTimeMillis();
            if (now > last_tmp)
              {
                // The last temporary file was created more than 1 ms ago.
                last_tmp = now;
                n_created = 0;
              }
            else
              n_created++;
            
            String name = Long.toHexString(now);
            if (n_created > 0)
              name += '_'+Integer.toHexString(n_created);
            String filename = prefix + name + suffix;
            file = new File(directory, filename);
          }
        while (VMFile.exists(file.path));
      }
    else
      {
        // make sure prefix is not longer than 7 characters
        if (prefix.length() >= 8)
          throw new IllegalArgumentException("Prefix too long: " + prefix + "(valid length 3..7)");

        long mask = 0x000000ffffFFFFL >> (prefix.length() * 4);
        do
          {
            int n = (int) (System.currentTimeMillis() & mask);
            String filename = prefix + java.lang.Integer.toHexString(n) + suffix;
            file = new File(directory, filename);
          }
        while (VMFile.exists(file.path));
      }

    // Verify that we are allowed to create this file
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkWrite(file.getAbsolutePath());

    // Now create the file and return our file object
    // XXX - FIXME race condition.
    VMFile.create(file.getAbsolutePath()); 
    return file;
  }

  /**
   * This method sets the file represented by this object to be read only.
   * A read only file or directory cannot be modified.  Please note that 
   * GNU systems allow read only files to be deleted if the directory it
   * is contained in is writable.
   *
   * @return <code>true</code> if the operation succeeded, <code>false</code>
   * otherwise.
   *
   * @exception SecurityException If the <code>SecurityManager</code> does
   * not allow this operation.
   *
   * @since 1.2
   */
  public boolean setReadOnly()
  {
    // Do a security check before trying to do anything else.
    checkWrite();

    // Test for existence.
    if (! VMFile.exists(path))
      return false;

    return VMFile.setReadOnly(path);
  }

  /**
   * This method returns an array of filesystem roots.  Some operating systems
   * have volume oriented filesystem.  This method provides a mechanism for
   * determining which volumes exist.  GNU systems use a single hierarchical
   * filesystem, so will have only one "/" filesystem root.
   *
   * @return An array of <code>File</code> objects for each filesystem root
   * available.
   *
   * @since 1.2
   */
  public static File[] listRoots()
  {
    File[] roots = VMFile.listRoots();
    
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      {
	// Only return roots to which the security manager permits read access.
	int count = roots.length;
	for (int i = 0; i < roots.length; i++)
	  {
	    try
	      {
        	s.checkRead (roots[i].path);		
	      }
	    catch (SecurityException sx)
	      {
	        roots[i] = null;
		count--;
	      }
	  }
	if (count != roots.length)
	  {
	    File[] newRoots = new File[count];
	    int k = 0;
	    for (int i = 0; i < roots.length; i++)
	      {
	        if (roots[i] != null)
		  newRoots[k++] = roots[i];
	      }
	    roots = newRoots;
	  }
      }
    return roots;
  }

  /**
   * This method creates a temporary file in the system temporary directory. 
   * The files created are guaranteed not to currently exist and the same file
   * name will never be used twice in the same virtual machine instance.  The
   * system temporary directory is determined by examinging the 
   * <code>java.io.tmpdir</code> system property.
   * <p>
   * The <code>prefix</code> parameter is a sequence of at least three
   * characters that are used as the start of the generated filename.  The
   * <code>suffix</code> parameter is a sequence of characters that is used
   * to terminate the file name.  This parameter may be <code>null</code>
   * and if it is, the suffix defaults to ".tmp".
   * <p>
   * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
   * method is used to verify that this operation is permitted.
   * <p>
   * This method is identical to calling 
   * <code>createTempFile(prefix, suffix, null)</code>.
   *
   * @param prefix The character prefix to use in generating the path name.
   * @param suffix The character suffix to use in generating the path name.
   *
   * @exception IllegalArgumentException If the prefix or suffix are not valid.
   * @exception SecurityException If there is no permission to perform 
   * this operation
   * @exception IOException If an error occurs
   */
  public static File createTempFile(String prefix, String suffix)
    throws IOException
  {
    return createTempFile(prefix, suffix, null);
  }

  /**
   * This method compares the specified <code>File</code> to this one
   * to test for equality.  It does this by comparing the canonical path names
   * of the files. 
   * <p>
   * The canonical paths of the files are determined by calling the
   * <code>getCanonicalPath</code> method on each object.
   * <p>
   * This method returns a 0 if the specified <code>Object</code> is equal
   * to this one, a negative value if it is less than this one 
   * a positive value if it is greater than this one.
   *
   * @return An integer as described above
   *
   * @since 1.2
   */
  public int compareTo(File other)
  {
    if (VMFile.IS_CASE_SENSITIVE)
      return path.compareTo (other.path);
    else
      return path.compareToIgnoreCase (other.path);
  }

  /**
   * This method compares the specified <code>Object</code> to this one
   * to test for equality.  It does this by comparing the canonical path names
   * of the files.  This method is identical to <code>compareTo(File)</code>
   * except that if the <code>Object</code> passed to it is not a 
   * <code>File</code>, it throws a <code>ClassCastException</code>
   * <p>
   * The canonical paths of the files are determined by calling the
   * <code>getCanonicalPath</code> method on each object.
   * <p>
   * This method returns a 0 if the specified <code>Object</code> is equal
   * to this one, a negative value if it is less than this one 
   * a positive value if it is greater than this one.
   *
   * @return An integer as described above
   *
   * @exception ClassCastException If the passed <code>Object</code> is 
   * not a <code>File</code>
   *
   * @since 1.2
   */
  public int compareTo(Object obj)
  {
    return compareTo((File) obj);
  }

  /**
   * This method renames the file represented by this object to the path
   * of the file represented by the argument <code>File</code>.
   *
   * @param dest The <code>File</code> object representing the target name
   *
   * @return <code>true</code> if the rename succeeds, <code>false</code> 
   * otherwise.
   *
   * @exception SecurityException If write access is not allowed to the 
   * file by the <code>SecurityMananger</code>.
   */
  public synchronized boolean renameTo(File dest)
  {
    checkWrite();
    dest.checkWrite();
    // Call our native rename method
    return VMFile.renameTo(path, dest.path);
  }

  /**
   * This method sets the modification time on the file to the specified
   * value.  This is specified as the number of seconds since midnight
   * on January 1, 1970 GMT.
   *
   * @param time The desired modification time.
   *
   * @return <code>true</code> if the operation succeeded, <code>false</code>
   * otherwise.
   *
   * @exception IllegalArgumentException If the specified time is negative.
   * @exception SecurityException If the <code>SecurityManager</code> will
   * not allow this operation.
   *
   * @since 1.2
   */
  public boolean setLastModified(long time) 
  {
    if (time < 0)
      throw new IllegalArgumentException("Negative modification time: " + time);

    checkWrite();
    return VMFile.setLastModified(path, time);
  }

  private void checkWrite()
  {
    // Check the SecurityManager
    SecurityManager s = System.getSecurityManager();
    
    if (s != null)
      s.checkWrite(path);
  }

  private void checkRead()
  {
    // Check the SecurityManager
    SecurityManager s = System.getSecurityManager();
    
    if (s != null)
      s.checkRead(path);
  }

  /** 
   * Calling this method requests that the file represented by this object
   * be deleted when the virtual machine exits.  Note that this request cannot
   * be cancelled.  Also, it will only be carried out if the virtual machine
   * exits normally.
   *
   * @exception SecurityException If deleting of the file is not allowed
   *
   * @since 1.2 
   */
  public void deleteOnExit()
  {
    // Check the SecurityManager
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkDelete(path);

    DeleteFileHelper.add(this);
  }

  private void writeObject(ObjectOutputStream oos) throws IOException
  {
    oos.defaultWriteObject();
    oos.writeChar(separatorChar);
  }

  private void readObject(ObjectInputStream ois)
    throws ClassNotFoundException, IOException
  {
    ois.defaultReadObject();

    // If the file was from an OS with a different dir separator,
    // fixup the path to use the separator on this OS.
    char oldSeparatorChar = ois.readChar();
    
    if (oldSeparatorChar != separatorChar)
      path = path.replace(oldSeparatorChar, separatorChar);
  }
  
} // class File

