JAL-1988 JAL-3772 Non-blocking modal dialogs for unsaved changes and saving files...
[jalview.git] / src / jalview / io / BackupFiles.java
index 529e1b2..88524d1 100644 (file)
@@ -32,6 +32,11 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 
 import jalview.bin.Cache;
 import jalview.bin.Console;
@@ -106,8 +111,14 @@ public class BackupFiles
 
   private static final String oldTempFileSuffix = "_oldfile_tobedeleted";
 
+  // thread pool used for completablefutures
+  private static final ExecutorService executorService = Executors
+          .newFixedThreadPool(3);
+
   private static List<BackupFiles> savesInProgress = new ArrayList<>();
 
+  private CompletableFuture<Boolean> myFuture = null;
+
   private boolean addSaveInProgress()
   {
     if (savesInProgress.contains(this))
@@ -116,25 +127,41 @@ public class BackupFiles
     }
     else
     {
+      this.setMyFuture();
       savesInProgress.add(this);
       return true;
     }
   }
 
-  private boolean removeSaveInProgress()
+  private boolean removeSaveInProgress(boolean ret)
   {
     if (savesInProgress.contains(this))
     {
+      this.getMyFuture().complete(ret);
       // remove all occurrences
       while (savesInProgress.remove(this))
       {
       }
       return true;
     }
-    else
+    return false;
+  }
+
+  private static CompletableFuture<Boolean> getNewFuture()
+  {
+    return new CompletableFuture<Boolean>()
     {
-      return false;
-    }
+    };
+  }
+
+  private CompletableFuture<Boolean> getMyFuture()
+  {
+    return this.myFuture;
+  }
+
+  private void setMyFuture()
+  {
+    this.myFuture = getNewFuture();
   }
 
   public static boolean hasSavesInProgress()
@@ -152,6 +179,41 @@ public class BackupFiles
     return files;
   }
 
+  public static List<CompletableFuture<Boolean>> savesInProgressCompletableFutures()
+  {
+    List<CompletableFuture<Boolean>> cfs = new ArrayList<>();
+    for (BackupFiles bfile : savesInProgress)
+    {
+      cfs.add(bfile.getMyFuture());
+    }
+    return cfs;
+  }
+
+  public static Future<Boolean> allSaved()
+  {
+    CompletableFuture<Boolean> f = new CompletableFuture<>();
+
+    executorService.submit(() -> {
+      for (BackupFiles buf : savesInProgress)
+      {
+        boolean allSaved = true;
+        try
+        {
+          allSaved &= buf.getMyFuture().get();
+        } catch (InterruptedException e)
+        {
+          Console.debug("InterruptedException waiting for files to save",
+                  e);
+        } catch (ExecutionException e)
+        {
+          Console.debug("ExecutionException waiting for files to save", e);
+        }
+        f.complete(allSaved);
+      }
+    });
+    return f;
+  }
+
   public BackupFiles(String filename)
   {
     this(new File(filename));
@@ -871,7 +933,7 @@ public class BackupFiles
     }
 
     // remove this file from the save in progress stack
-    removeSaveInProgress();
+    removeSaveInProgress(rename);
 
     return rename;
   }