Fix -saveSourceOutput when target is a directory

The problem is actually that the one-arg version of
OutputFileSet.openForWrite() didn't work, but it is unused
except by SourceSaver.

Wrote javadoc explaining how these methods actually work.

(The OutputFileSet classes are quite messy, but it looks like
this code is intended to avoid touching files unnecessarily
to work well with a Makefile-style build where timestamps
are used to determine whether downstream build rules need
to run. It seems fragile, but I'm ignoring that issue and
just getting -saveSourceOutput to work.)

Change-Id: Iebbad400942115c0acb34fefb1fba502ba8256d8
diff --git a/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java b/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java
index d0de937..d6a0ec4 100644
--- a/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java
+++ b/dev/core/src/com/google/gwt/dev/util/OutputFileSet.java
@@ -24,6 +24,12 @@
  * An abstract set of files that a linker links into.
  */
 public abstract class OutputFileSet {
+
+  /**
+   * Indicates that the file should be overwritten.
+   */
+  public static final int TIMESTAMP_UNAVAILABLE = -1;
+
   private final String pathDescription;
   private final Set<String> pathsSeen = new HashSet<String>();
 
@@ -52,15 +58,28 @@
     return pathDescription;
   }
 
+  /**
+   * Opens a file for write. If writing to a zip file and the file already exists,
+   * this has no effect. Otherwise, overwrites any existing file.
+   * @return the output stream to write to, possibly a NullOutputStream
+   */
   public final OutputStream openForWrite(String path) throws IOException {
-    int lastModifiedTime = -1;
-    return openForWrite(path, lastModifiedTime);
+    return openForWrite(path, TIMESTAMP_UNAVAILABLE);
   }
 
-  public OutputStream openForWrite(String path, long lastModifiedTime)
+  /**
+   * Opens a file for write. If writing to a zip file and the file already
+   * exists, there will be no effect. If writing to a directory, the file
+   * exists, and the given timestamp is older or equal to the file's
+   * current timestamp, there will be no effect.
+   * @param timeStampMillis last modified time in milliseconds, or
+   * TIMESTAMP_UNAVAILABLE to force an overwrite.
+   * @return the output stream to write to, possibly a NullOutputStream
+   */
+  public OutputStream openForWrite(String path, long timeStampMillis)
       throws IOException {
     pathsSeen.add(path);
-    return createNewOutputStream(path, lastModifiedTime);
+    return createNewOutputStream(path, timeStampMillis);
   }
 
   protected abstract OutputStream createNewOutputStream(String path,
diff --git a/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnDirectory.java b/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnDirectory.java
index 10b58dd..7fbf183 100644
--- a/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnDirectory.java
+++ b/dev/core/src/com/google/gwt/dev/util/OutputFileSetOnDirectory.java
@@ -44,9 +44,10 @@
 
   @Override
   protected OutputStream createNewOutputStream(String path,
-      final long lastModifiedTime) throws IOException {
+      final long timeStampMillis) throws IOException {
     final File file = pathToFile(path);
-    if (file.exists() && file.lastModified() >= lastModifiedTime) {
+    if (file.exists() && timeStampMillis != TIMESTAMP_UNAVAILABLE &&
+        file.lastModified() >= timeStampMillis) {
       return new NullOutputStream();
     }
 
@@ -55,7 +56,9 @@
       @Override
       public void close() throws IOException {
         super.close();
-        file.setLastModified(lastModifiedTime);
+        if (timeStampMillis != TIMESTAMP_UNAVAILABLE) {
+          file.setLastModified(timeStampMillis);
+        }
       }
     };
   }