// File.java - File name

/* Copyright (C) 1998, 1999  Cygnus Solutions

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.io;

/**
 * @author Tom Tromey <tromey@cygnus.com>
 * @date September 24, 1998 
 */

/* 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.1; 1.2 functionality missing.
 * A known bug: most calls to the security manager can generate
 * IOException since we use the canonical path.
 */

public class File implements Serializable
{
  public boolean canRead ()
  {
    return access (checkRead (), READ);
  }

  public boolean canWrite ()
  {
    SecurityManager s = System.getSecurityManager();
    String p = safeCanonicalPath ();
    // FIXME: it isn't entirely clear what to do if we can't find the
    // canonical path.
    if (p == null)
      return false;
    if (s != null)
      s.checkWrite(p);
    return access (p, WRITE);
  }

  private final native boolean performDelete (String canon);
  public boolean delete ()
  {
    SecurityManager s = System.getSecurityManager();
    String p = safeCanonicalPath ();
    // FIXME: what is right?
    if (p == null)
      return false;
    if (s != null)
      s.checkDelete(p);
    return performDelete (p);
  }

  public boolean equals (Object obj)
  {
    if (! (obj instanceof File))
      return false;
    File other = (File) obj;
    return path.compareTo(other.path) == 0;
  }

  public boolean exists ()
  {
    return access (checkRead (), EXISTS);
  }

  public File (String p)
  {
    if (p == null)
      throw new NullPointerException ();
    path = p;
  }

  public File (String dirPath, String name)
  {
    if (name == null)
      throw new NullPointerException ();
    if (dirPath != null)
      {
	// Try to be smart about the number of separator characters.
	if (dirPath.charAt(dirPath.length() - 1) == separatorChar)
	  path = dirPath + name;
	else
	  path = dirPath + separatorChar + name;
      }
    else
      path = name;
  }

  public File (File dir, String name)
  {
    this (dir == null ? null : dir.path, name);
  }

  public String getAbsolutePath ()
  {
    if (isAbsolute ())
      return path;
    return System.getProperty("user.dir") + separatorChar + path;
  }

  public native String getCanonicalPath () throws IOException;

  public String getName ()
  {
    int last = path.lastIndexOf(separatorChar);
    if (last == -1)
      last = 0;
    return path.substring(last);
  }

  public String getParent ()
  {
    int last = path.lastIndexOf(separatorChar);
    if (last == -1)
      return null;
    return path.substring(0, last);
  }

  public String getPath ()
  {
    return path;
  }

  public int hashCode ()
  {
    // FIXME: test.
    return path.hashCode();
  }

  public native boolean isAbsolute ();

  public boolean isDirectory ()
  {
    return stat (checkRead (), DIRECTORY);
  }

  public boolean isFile ()
  {
    return stat (checkRead (), ISFILE);
  }

  public long lastModified ()
  {
    return attr (checkRead (), MODIFIED);
  }

  public long length ()
  {
    return attr (checkRead (), LENGTH);
  }

  private final native String[] performList (String canon,
					     FilenameFilter filter);
  public String[] list (FilenameFilter filter)
  {
    return performList (checkRead (), filter);
  }

  public String[] list ()
  {
    return performList (checkRead (), null);
  }

  public String toString ()
  {
    return path;
  }

  private final native boolean performMkdir ();
  public boolean mkdir ()
  {
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      {
	// NOTE: in theory we should use the canonical path.  In
	// practice, we can't compute the canonical path until we've
	// made this completely.  Lame.
	s.checkWrite(path);
      }
    return performMkdir ();
  }

  private static boolean mkdirs (File x)
  {
    if (x.isDirectory())
      return true;
    String p = x.getPath();
    String parent = x.getParent();
    if (parent != null)
      {
	x.setPath(parent);
	if (! mkdirs (x))
	  return false;
	x.setPath(p);
      }
    return x.mkdir();
  }

  public boolean mkdirs ()
  {
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      {
	// NOTE: in theory we should use the canonical path.  In
	// practice, we can't compute the canonical path until we've
	// made this completely.  Lame.
	s.checkWrite(path);
      }

    if (isDirectory ())
      return false;
    return mkdirs (new File (path));
  }

  private final native boolean performRenameTo (File dest);
  public boolean renameTo (File dest)
  {
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      {
	// FIXME: JCL doesn't specify which path to check.  We check the
	// source since we can canonicalize it.
	s.checkWrite(safeCanonicalPath());
      }
    return performRenameTo (dest);
  }

  public static final String pathSeparator
    = System.getProperty("path.separator");
  public static final char pathSeparatorChar = pathSeparator.charAt(0);
  public static final String separator = System.getProperty("file.separator");
  public static final char separatorChar = separator.charAt(0);


  // The path.
  private String path;

  // mkdirs() uses this to avoid repeated allocations.
  private final void setPath (String n)
  {
    path = n;
  }


  private final String checkRead ()
  {
    SecurityManager s = System.getSecurityManager();
    String p = safeCanonicalPath ();
    if (p == null)
      return null;
    if (s != null)
      s.checkRead(p);
    return p;
  }

  // Return canonical path, or null.
  private final String safeCanonicalPath ()
  {
    String p = null;
    try
      {
	p = getCanonicalPath ();
      }
    catch (IOException x)
      {
	// Nothing.
      }
    return p;
  }

  // QUERY arguments to access function.
  private final static int READ = 0;
  private final static int WRITE = 1;
  private final static int EXISTS = 2;

  // QUERY arguments to stat function.
  private final static int DIRECTORY = 0;
  private final static int ISFILE = 1;

  // QUERY arguments to attr function.
  private final static int MODIFIED = 0;
  private final static int LENGTH = 1;

  private final native long attr (String p, int query);
  private final native boolean access (String p, int query);
  private final native boolean stat (String p, int query);
}
