From 4f87eb03990d981d8abb3fc60e04f4b459ebe3dc Mon Sep 17 00:00:00 2001
From: kenneth_suter <kenneth_suter@localhost>
Date: Thu, 24 May 2007 19:24:49 +0000
Subject: [PATCH] issue 1628: fix for upgrader leaving files in the tmp directory

---
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java |   11 +++--
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java  |   53 +++++++++++++++++++++-----
 2 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
index 1ef0942..c9e96c5 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -1426,12 +1426,13 @@
       stagingDir = getStageDirectory();
       FileManager fm = new FileManager();
 
-      // Doing this seems to work better than just plain
-      // old delete.  Note that on Windows there are file
-      // locking issues to we mark files for deletion after
-      // this JVM exits
+      // On Linux at least the deleteOnExit seems not to work very well
+      // for directories that contain files, even if they have been marked
+      // for deletion upon exit as well.  Note that on Windows there are
+      // file locking issues so we mark files for deletion after this JVM exits.
       if (stagingDir.exists()) {
-        fm.deleteRecursively(stagingDir, null, /*onExit=*/true);
+        fm.deleteRecursively(stagingDir, null,
+                FileManager.DeletionPolicy.DELETE_ON_EXIT_IF_UNSUCCESSFUL);
       }
 
     } catch (IOException e) {
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java
index d684b47..10d5275 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java
@@ -41,6 +41,30 @@
  */
 public class FileManager {
 
+  /**
+   * Describes the approach taken to deleting a file or directory.
+   */
+  public enum DeletionPolicy {
+
+    /**
+     * Delete the file or directory immediately.
+     */
+    DELETE_IMMEDIATELY,
+
+    /**
+     * Mark the file or directory for deletion after the JVM has exited.
+     */
+    DELETE_ON_EXIT,
+
+    /**
+     * First try to delete the file immediately.  If the deletion was
+     * unsuccessful mark the file for deleteion when the JVM has
+     * existed.
+     */
+    DELETE_ON_EXIT_IF_UNSUCCESSFUL
+
+  }
+
   static private final Logger LOG =
           Logger.getLogger(FileManager.class.getName());
 
@@ -90,7 +114,7 @@
           throws ApplicationException
   {
     if (filter == null || filter.accept(object)) {
-      new DeleteOperation(object, false).apply();
+      new DeleteOperation(object, DeletionPolicy.DELETE_IMMEDIATELY).apply();
     }
   }
 
@@ -101,7 +125,8 @@
    * @throws org.opends.quicksetup.ApplicationException if something goes wrong.
    */
   public void deleteRecursively(File file) throws ApplicationException {
-    deleteRecursively(file, null, false);
+    deleteRecursively(file, null,
+            FileManager.DeletionPolicy.DELETE_IMMEDIATELY);
   }
 
   /**
@@ -110,13 +135,14 @@
    * @param file   the path to be deleted.
    * @param filter the filter of the files to know if the file can be deleted
    *               directly or not.
-   * @param onExit when true just marks the files for deletion after the
+   * @param deletePolicy describes how deletions are to be made
    *        JVM exits rather than deleting the files immediately.
    * @throws ApplicationException if something goes wrong.
    */
-  public void deleteRecursively(File file, FileFilter filter, boolean onExit)
+  public void deleteRecursively(File file, FileFilter filter,
+                                DeletionPolicy deletePolicy)
           throws ApplicationException {
-    operateRecursively(new DeleteOperation(file, onExit), filter);
+    operateRecursively(new DeleteOperation(file, deletePolicy), filter);
   }
 
   /**
@@ -382,25 +408,25 @@
    */
   private class DeleteOperation extends FileOperation {
 
-    private boolean afterExit;
+    private DeletionPolicy deletionPolicy;
 
     /**
      * Creates a delete operation.
      * @param objectFile to delete
-     * @param afterExit boolean indicates that the actual delete
+     * @param deletionPolicy describing how files will be deleted
      * is to take place after this program exists.  This is useful
      * for cleaning up files that are currently in use.
      */
-    public DeleteOperation(File objectFile, boolean afterExit) {
+    public DeleteOperation(File objectFile, DeletionPolicy deletionPolicy) {
       super(objectFile);
-      this.afterExit = afterExit;
+      this.deletionPolicy = deletionPolicy;
     }
 
     /**
      * {@inheritDoc}
      */
     public FileOperation copyForChild(File child) {
-      return new DeleteOperation(child, afterExit);
+      return new DeleteOperation(child, deletionPolicy);
     }
 
     /**
@@ -432,11 +458,16 @@
        */
       int nTries = 5;
       for (int i = 0; i < nTries && !delete; i++) {
-        if (afterExit) {
+        if (DeletionPolicy.DELETE_ON_EXIT.equals(deletionPolicy)) {
           file.deleteOnExit();
           delete = true;
         } else {
           delete = file.delete();
+          if (!delete && DeletionPolicy.DELETE_ON_EXIT_IF_UNSUCCESSFUL.
+                  equals(deletionPolicy)) {
+            file.deleteOnExit();
+            delete = true;
+          }
         }
         if (!delete) {
           try {

--
Gitblit v1.10.0