OSDN Git Service

2004-09-09 Jeroen Frijters <jeroen@frijters.net>
[pf3gnuchains/gcc-fork.git] / libjava / java / io / File.java
index 4872076..187558d 100644 (file)
@@ -1,5 +1,6 @@
 /* File.java -- Class representing a file on disk
-   Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004
+   Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -39,7 +40,10 @@ exception statement from your version. */
 package java.io;
 
 import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
+import gnu.classpath.Configuration;
 import gnu.gcj.runtime.FileDeleter;
 
 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
@@ -53,8 +57,8 @@ import gnu.gcj.runtime.FileDeleter;
  * 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>
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
  */
 public class File implements Serializable, Comparable
 {
@@ -87,6 +91,7 @@ public class File implements Serializable, Comparable
    * An example separator string would be "/" on the GNU system.
    */
   public static final String separator = System.getProperty("file.separator");
+  private static final String dupSeparator = separator + separator;
 
   /**
    * This is the first character of the file separator string.  On many
@@ -110,15 +115,18 @@ public class File implements Serializable, Comparable
    * is taken from the <code>path.separator</code> system property.
    */
   public static final char pathSeparatorChar = pathSeparator.charAt(0);
-  
 
   static final String tmpdir = System.getProperty("java.io.tmpdir");
   static int maxPathLen;
   static boolean caseSensitive;
-  static String dupSeparator = separator + separator;
   
   static
   {
+    if (Configuration.INIT_LOAD_LIBRARY)
+      {
+        System.loadLibrary("javaio");
+      }
+    
     init_native();
   }
   
@@ -134,7 +142,7 @@ public class File implements Serializable, Comparable
 
   // We keep a counter for use by createTempFile.  We choose the first
   // value randomly to try to avoid clashes with other VMs.
-  private static long counter = Double.doubleToLongBits (Math.random ());
+  private static long counter = Double.doubleToLongBits (Math.random());
 
   /**
    * This method tests whether or not the current thread is allowed to
@@ -149,7 +157,7 @@ public class File implements Serializable, Comparable
    * @exception SecurityException If the <code>SecurityManager</code> 
    * does not allow access to the file
    */
-  public boolean canRead ()
+  public boolean canRead()
   {
     checkRead();
     return _access (READ);
@@ -169,7 +177,7 @@ public class File implements Serializable, Comparable
    * @exception SecurityException If the <code>SecurityManager</code> 
    * does not allow access to the file
    */
-  public boolean canWrite ()
+  public boolean canWrite()
   {
     checkWrite();
     return _access (WRITE);
@@ -182,7 +190,7 @@ public class File implements Serializable, Comparable
    * the path of this <code>File</code> object if an only if that file
    * does not already exist.
    * <p>
-   * A <code>SecurityManager</code>checkWrite</code> check is done prior
+   * 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
@@ -203,7 +211,7 @@ public class File implements Serializable, Comparable
   /*
    * This native method handles the actual deleting of the file
    */
-  private native boolean performDelete ();
+  private native boolean performDelete();
 
   /**
    * This method deletes the file represented by this object.  If this file
@@ -214,14 +222,14 @@ public class File implements Serializable, Comparable
    *
    * @exception SecurityException If deleting of the file is not allowed
    */
-  public synchronized boolean delete ()
+  public synchronized boolean delete()
   {
-    SecurityManager s = System.getSecurityManager ();
+    SecurityManager s = System.getSecurityManager();
     
     if (s != null)
-      s.checkDelete (path);
+      s.checkDelete(path);
     
-    return performDelete ();
+    return performDelete();
   }
 
   /**
@@ -239,12 +247,13 @@ public class File implements Serializable, Comparable
    * @return <code>true</code> if the two objects are equal, 
    * <code>false</code> otherwise.
    */
-  public boolean equals (Object obj)
+  public boolean equals(Object obj)
   {
     if (! (obj instanceof File))
       return false;
     
     File other = (File) obj;
+
     if (caseSensitive)
       return path.equals(other.path);
     else
@@ -259,7 +268,7 @@ public class File implements Serializable, Comparable
    *
    * @exception SecurityException If reading of the file is not permitted
    */
-  public boolean exists ()
+  public boolean exists()
   {
     checkRead();
     return _access (EXISTS);
@@ -271,7 +280,7 @@ public class File implements Serializable, Comparable
    *
    * @param name The path name of the file
    */
-  public File (String name)
+  public File(String name)
   {
     path = normalizePath (name);
   }
@@ -282,7 +291,15 @@ public class File implements Serializable, Comparable
     // On Windows, convert any '/' to '\'.  This appears to be the same logic
     // that Sun's Win32 Java performs.
     if (separatorChar == '\\')
-      p = p.replace ('/', '\\');
+      {
+        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();
@@ -345,21 +362,44 @@ public class File implements Serializable, Comparable
    * name.  If the directory path name ends in the separator string, another
    * separator string will still be appended.
    *
-   * @param dirname The path to the directory the file resides in
+   * @param dirPath The path to the directory the file resides in
    * @param name The name of the file
    */
-  public File (String dirPath, String name)
+  public File(String dirPath, String name)
   {
     if (name == null)
-      throw new NullPointerException ();
-    if (dirPath != null && dirPath.length() > 0)
+      throw new NullPointerException();
+    if (dirPath != null)
       {
-       // Try to be smart about the number of separator characters.
-       if (dirPath.charAt(dirPath.length() - 1) == separatorChar
-           || name.length() == 0)
-         path = normalizePath(dirPath + name);
+       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
-         path = normalizePath(dirPath + separatorChar + name);
+         {
+           // 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);
@@ -375,12 +415,29 @@ public class File implements Serializable, Comparable
    * @param directory The directory this file resides in
    * @param name The name of the file
    */
-  public File (File directory, String name)
+  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.
+   */
+  public File(URI uri)
+  {
+    if (uri == null)
+       throw new NullPointerException("uri is null");
+
+    if (!uri.getScheme().equals("file"))
+       throw new IllegalArgumentException("invalid uri protocol");
+
+    path = normalizePath(uri.getPath());
+  }
+
+  /**
    * 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
@@ -389,12 +446,12 @@ public class File implements Serializable, Comparable
    *
    * @return The absolute path of this file
    */
-  public String getAbsolutePath ()
+  public String getAbsolutePath()
   {
-    if (isAbsolute ())
+    if (isAbsolute())
       return path;
     else if (separatorChar == '\\' 
-             && path.length () > 0 && path.charAt (0) == '\\')
+             && 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
@@ -402,7 +459,7 @@ public class File implements Serializable, Comparable
         return System.getProperty ("user.dir").substring (0, 2) + path;
       }
     else if (separatorChar == '\\' 
-             && path.length () > 1 && path.charAt (1) == ':'
+             && path.length() > 1 && path.charAt (1) == ':'
              && ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
                  || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
       {
@@ -413,7 +470,7 @@ public class File implements Serializable, Comparable
         String drvDir = null;
         try
           {
-            drvDir = new File (path.substring (0, 2)).getCanonicalPath ();
+            drvDir = new File (path.substring (0, 2)).getCanonicalPath();
           }
         catch (IOException e)
           {
@@ -423,8 +480,8 @@ public class File implements Serializable, Comparable
         // 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 ());
+        if (path.length() > 2)
+          return drvDir + '\\' + path.substring (2, path.length());
         else
           return drvDir;
       }
@@ -440,9 +497,9 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public File getAbsoluteFile ()
+  public File getAbsoluteFile()
   {
-    return new File (getAbsolutePath());
+    return new File(getAbsolutePath());
   }
 
   /**
@@ -458,7 +515,7 @@ public class File implements Serializable, Comparable
    *
    * @exception IOException If an error occurs
    */
-  public native String getCanonicalPath () throws IOException;
+  public native String getCanonicalPath() throws IOException;
 
   /**
    * This method returns a <code>File</code> object representing the
@@ -471,9 +528,9 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public File getCanonicalFile () throws IOException
+  public File getCanonicalFile() throws IOException
   {
-    return new File (getCanonicalPath());
+    return new File(getCanonicalPath());
   }
 
   /**
@@ -483,11 +540,11 @@ public class File implements Serializable, Comparable
    *
    * @return The file name
    */
-  public String getName ()
+  public String getName()
   {
     int nameSeqIndex = 0;
 
-    if (separatorChar == '\\' && path.length () > 1)
+    if (separatorChar == '\\' && path.length() > 1)
       {
         // On Windows, ignore the drive specifier or the leading '\\'
         // of a UNC network path, if any (a.k.a. the "prefix").
@@ -496,7 +553,7 @@ public class File implements Serializable, Comparable
                 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
                && path.charAt (1) == ':'))
          {
-           if (path.length () > 2)
+           if (path.length() > 2)
              nameSeqIndex = 2;
            else
              return "";
@@ -518,7 +575,7 @@ public class File implements Serializable, Comparable
    *
    * @return The parent directory of this file
    */
-  public String getParent ()
+  public String getParent()
   {
     String prefix = null;
     int nameSeqIndex = 0;
@@ -531,7 +588,7 @@ public class File implements Serializable, Comparable
         prefix = "/";
         nameSeqIndex = 1;
       }
-    else if (separatorChar == '\\' && path.length () > 1)
+    else if (separatorChar == '\\' && path.length() > 1)
       {
         if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
             || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
@@ -546,13 +603,13 @@ public class File implements Serializable, Comparable
     // 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 ())
+    if (nameSeqIndex < path.length())
       {
-        String nameSeq = path.substring (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))
+        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.
@@ -576,16 +633,16 @@ public class File implements Serializable, Comparable
    * This method returns a <code>File</code> object representing the parent
    * file of this one.
    *
-   * @param A <code>File</code> for the parent of this object.  
+   * @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 ()
+  public File getParentFile()
   {
-    String parent = getParent ();
-    return (parent == null ? null : new File (parent));
+    String parent = getParent();
+    return parent != null ? new File(parent) : null;
   }
 
   /**
@@ -594,7 +651,7 @@ public class File implements Serializable, Comparable
    *
    * @return The pathname of this file
    */
-  public String getPath ()
+  public String getPath()
   {
     return path;
   }
@@ -606,12 +663,12 @@ public class File implements Serializable, Comparable
    *
    * @return The hash code for this object
    */
-  public int hashCode ()
+  public int hashCode()
   {
     if (caseSensitive)
-      return (path.hashCode() ^ 1234321);
+      return path.hashCode() ^ 1234321;
     else
-      return (path.toLowerCase().hashCode() ^ 1234321);
+      return path.toLowerCase().hashCode() ^ 1234321;
   }
 
   /**
@@ -623,7 +680,7 @@ public class File implements Serializable, Comparable
    * @return <code>true</code> if this object represents an absolute 
    * file name, <code>false</code> otherwise.
    */
-  public native boolean isAbsolute ();
+  public native boolean isAbsolute();
 
   /**
    * This method tests whether or not the file represented by this object
@@ -635,7 +692,7 @@ public class File implements Serializable, Comparable
    *
    * @exception SecurityException If reading of the file is not permitted
    */
-  public boolean isDirectory ()
+  public boolean isDirectory()
   {
     checkRead();
     return _stat (DIRECTORY);
@@ -651,7 +708,7 @@ public class File implements Serializable, Comparable
    *
    * @exception SecurityException If reading of the file is not permitted
    */
-  public boolean isFile ()
+  public boolean isFile()
   {
     checkRead();
     return _stat (ISFILE);
@@ -668,7 +725,7 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public boolean isHidden ()
+  public boolean isHidden()
   {
     checkRead();
     return _stat (ISHIDDEN);
@@ -687,7 +744,7 @@ public class File implements Serializable, Comparable
    *
    * @exception SecurityException If reading of the file is not permitted
    */
-  public long lastModified ()
+  public long lastModified()
   {
     checkRead();
     return attr (MODIFIED);
@@ -701,7 +758,7 @@ public class File implements Serializable, Comparable
    *
    * @exception SecurityException If reading of the file is not permitted
    */
-  public long length ()
+  public long length()
   {
     checkRead();
     return attr (LENGTH);
@@ -711,7 +768,6 @@ public class File implements Serializable, Comparable
    * This native function actually produces the list of file in this
    * directory
    */
-    
   private final native Object[] performList (FilenameFilter filter,
                                             FileFilter fileFilter,
                                             Class result_type);
@@ -743,7 +799,7 @@ public class File implements Serializable, Comparable
    * @exception SecurityException If read access is not allowed to the 
    * directory by the <code>SecurityManager</code>
    */
-  public String[] list (FilenameFilter filter)
+  public String[] list(FilenameFilter filter)
   {
     checkRead();
     return (String[]) performList (filter, null, String.class);
@@ -767,7 +823,7 @@ public class File implements Serializable, Comparable
    * @exception SecurityException If read access is not allowed to the 
    * directory by the <code>SecurityManager</code>
    */
-  public String[] list ()
+  public String[] list()
   {
     checkRead();
     return (String[]) performList (null, null, String.class);
@@ -791,7 +847,7 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public File[] listFiles ()
+  public File[] listFiles()
   {
     checkRead();
     return (File[]) performList (null, null, File.class);
@@ -821,7 +877,7 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public File[] listFiles (FilenameFilter filter)
+  public File[] listFiles(FilenameFilter filter)
   {
     checkRead();
     return (File[]) performList (filter, null, File.class);
@@ -851,7 +907,7 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public File[] listFiles (FileFilter filter)
+  public File[] listFiles(FileFilter filter)
   {
     checkRead();
     return (File[]) performList (null, filter, File.class);
@@ -863,12 +919,33 @@ public class File implements Serializable, Comparable
    *
    * @return A <code>String</code> representation of this file
    */
-  public String toString ()
+  public String toString()
   {
     return path;
   }
 
   /**
+   * @return A <code>URI</code> for this object.
+   */
+  public URI toURI()
+  {
+    String abspath = getAbsolutePath();
+
+    if (isDirectory())
+      abspath = abspath + separator;
+        
+    try
+      {
+       return new URI("file", "", abspath.replace(separatorChar, '/'));
+      }
+    catch (URISyntaxException use)
+      {
+        // Can't happen.
+       throw new RuntimeException(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.
@@ -878,22 +955,22 @@ public class File implements Serializable, Comparable
    * @exception MalformedURLException If the URL cannot be created 
    * successfully.
    */
-  public URL toURL () throws MalformedURLException
+  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 ('\\', '/')
+      return new URL ("file:/" + getAbsolutePath().replace ('\\', '/')
                      + (isDirectory() ? "/" : ""));
     else
-      return new URL ("file:" + getAbsolutePath ()
+      return new URL ("file:" + getAbsolutePath()
                      + (isDirectory() ? "/" : ""));
   }
 
   /*
    * This native method actually creates the directory
    */
-  private final native boolean performMkdir ();
+  private final native boolean performMkdir();
 
   /**
    * This method creates a directory for the path represented by this object.
@@ -903,10 +980,10 @@ public class File implements Serializable, Comparable
    *
    * @exception SecurityException If write access is not allowed to this file
    */
-  public boolean mkdir ()
+  public boolean mkdir()
   {
     checkWrite();
-    return performMkdir ();
+    return performMkdir();
   }
 
   private static boolean mkdirs (File x)
@@ -934,15 +1011,15 @@ public class File implements Serializable, Comparable
    *
    * @exception SecurityException If write access is not allowed to this file
    */
-  public boolean mkdirs ()
+  public boolean mkdirs()
   {
     checkWrite();
-    if (isDirectory ())
+    if (isDirectory())
       return false;
     return mkdirs (new File (path));
   }
 
-  private static synchronized String nextValue ()
+  private static synchronized String nextValue()
   {
     return Long.toString(counter++, Character.MAX_RADIX);
   }
@@ -977,42 +1054,44 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public static File createTempFile (String prefix, String suffix,
-                                    File directory)
+  public static File createTempFile(String prefix, String suffix,
+                                   File directory)
     throws IOException
   {
     // Grab the system temp directory if necessary
     if (directory == null)
       {
-       String dirname = tmpdir;
-       if (dirname == null)
-         throw 
-           new IOException("Cannot determine system temporary directory"); 
+        String dirname = tmpdir;
+        if (dirname == null)
+          throw new IOException("Cannot determine system temporary directory"); 
        
-       directory = new File(dirname);
-       if (!directory.exists())
-         throw new IOException("System temporary directory " 
-                               + directory.getName() + " does not exist.");
-       if (!directory.isDirectory())
-         throw new IOException("System temporary directory " 
-                               + directory.getName() 
-                               + " is not really a directory.");
+        directory = new File(dirname);
+        if (!directory.exists())
+          throw new IOException("System temporary directory "
+                                + directory.getName() + " does not exist.");
+        if (!directory.isDirectory())
+          throw new IOException("System temporary directory "
+                                + directory.getName()
+                                + " is not really a directory.");
       }
 
-    if (prefix.length () < 3)
-      throw new IllegalArgumentException ("Prefix too short: " + prefix);
+    // 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";
 
     // Truncation rules.
     // `6' is the number of characters we generate.
-    if (prefix.length () + 6 + suffix.length () > maxPathLen)
+    if (prefix.length() + 6 + suffix.length() > maxPathLen)
       {
        int suf_len = 0;
        if (suffix.charAt(0) == '.')
          suf_len = 4;
        suffix = suffix.substring(0, suf_len);
-       if (prefix.length () + 6 + suf_len > maxPathLen)
+       if (prefix.length() + 6 + suf_len > maxPathLen)
          prefix = prefix.substring(0, maxPathLen - 6 - suf_len);
       }
 
@@ -1022,7 +1101,7 @@ public class File implements Serializable, Comparable
     for (int i = 0; i < 100; ++i)
       {
        // This is ugly.
-       String t = "ZZZZZZ" + nextValue ();
+       String t = "ZZZZZZ" + nextValue();
        String l = prefix + t.substring(t.length() - 6) + suffix;
        try
          {
@@ -1057,8 +1136,9 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public boolean setReadOnly ()
+  public boolean setReadOnly()
   {
+    // Do a security check before trying to do anything else.
     checkWrite();
     return performSetReadOnly();
   }
@@ -1076,7 +1156,7 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public static File[] listRoots ()
+  public static File[] listRoots()
   {
     File[] roots = performListRoots();
     
@@ -1089,7 +1169,7 @@ public class File implements Serializable, Comparable
          {
            try
              {
-               s.checkRead(roots[i].path);             
+               s.checkRead (roots[i].path);            
              }
            catch (SecurityException sx)
              {
@@ -1139,10 +1219,10 @@ public class File implements Serializable, Comparable
    * this operation
    * @exception IOException If an error occurs
    */
-  public static File createTempFile (String prefix, String suffix)
+  public static File createTempFile(String prefix, String suffix)
     throws IOException
   {
-    return createTempFile (prefix, suffix, null);
+    return createTempFile(prefix, suffix, null);
   }
 
   /**
@@ -1190,10 +1270,9 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public int compareTo(Object o)
+  public int compareTo(Object obj)
   {
-    File other = (File) o;
-    return compareTo (other);
+    return compareTo((File) obj);
   }
 
   /*
@@ -1213,15 +1292,15 @@ public class File implements Serializable, Comparable
    * @exception SecurityException If write access is not allowed to the 
    * file by the <code>SecurityMananger</code>.
    */
-  public synchronized boolean renameTo (File dest)
+  public synchronized boolean renameTo(File dest)
   {
     SecurityManager s = System.getSecurityManager();
     String sname = getName();
     String dname = dest.getName();
     if (s != null)
       {
-       s.checkWrite(sname);
-       s.checkWrite(dname);
+       s.checkWrite (sname);
+       s.checkWrite (dname);
       }
     return performRenameTo (dest);
   }
@@ -1247,64 +1326,72 @@ public class File implements Serializable, Comparable
    *
    * @since 1.2
    */
-  public boolean setLastModified (long time) 
+  public boolean setLastModified(long time) 
   {
+    if (time < 0)
+      throw new IllegalArgumentException("Negative modification time: " + time);
+
     checkWrite();
     return performSetLastModified(time);
   }
 
-  private void checkWrite ()
+  private void checkWrite()
   {
     // Check the SecurityManager
-    SecurityManager s = System.getSecurityManager ();
+    SecurityManager s = System.getSecurityManager();
     
     if (s != null)
-      s.checkWrite (path);
+      s.checkWrite(path);
   }
 
-  private void checkRead ()
+  private void checkRead()
   {
     // Check the SecurityManager
-    SecurityManager s = System.getSecurityManager ();
+    SecurityManager s = System.getSecurityManager();
     
     if (s != null)
-      s.checkRead (path);
+      s.checkRead(path);
   }
 
   /** 
-    * Add this File to the set of files to be deleted upon normal
-    * termination.
-    *
-    * @since 1.2 
-    */
+   * 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 
+   */
   // FIXME: This should use the ShutdownHook API once we implement that.
-  public void deleteOnExit ()
+  public void deleteOnExit()
   {
     // Check the SecurityManager
-    SecurityManager sm = System.getSecurityManager ();
+    SecurityManager sm = System.getSecurityManager();
     if (sm != null)
-      sm.checkDelete (getName ());
+      sm.checkDelete (getName());
 
     FileDeleter.add (this);
   }
 
-  private void writeObject (ObjectOutputStream oos) throws IOException
+  private void writeObject(ObjectOutputStream oos) throws IOException
   {
-    oos.defaultWriteObject ();
-    oos.writeChar (separatorChar);
+    oos.defaultWriteObject();
+    oos.writeChar(separatorChar);
   }
 
-  private void readObject (ObjectInputStream ois)
+  private void readObject(ObjectInputStream ois)
     throws ClassNotFoundException, IOException
   {
-    ois.defaultReadObject ();
+    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 ();
+    char oldSeparatorChar = ois.readChar();
     
     if (oldSeparatorChar != separatorChar)
-      path = path.replace (oldSeparatorChar, separatorChar);
+      path = path.replace(oldSeparatorChar, separatorChar);
   }
+  
 } // class File