JAL-1713 update from Jalview 2.11.3 develop
[jalview.git] / src / jalview / project / Jalview2XML.java
index e9a2a52..4b9c348 100644 (file)
@@ -84,6 +84,7 @@ import jalview.api.analysis.ScoreModelI;
 import jalview.api.analysis.SimilarityParamsI;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
+import jalview.bin.Console;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
@@ -230,6 +231,11 @@ public class Jalview2XML
   private static final String UTF_8 = "UTF-8";
 
   /**
+   * used in decision if quit confirmation should be issued
+   */
+  private static boolean stateSavedUpToDate = false;
+
+  /**
    * prefix for recovering datasets for alignments with multiple views where
    * non-existent dataset IDs were written for some views
    */
@@ -578,7 +584,7 @@ public class Jalview2XML
 
     } catch (Exception e)
     {
-      Cache.log.error("Couln't write Jalview state to " + statefile, e);
+      Console.error("Couln't write Jalview state to " + statefile, e);
       // TODO: inform user of the problem - they need to know if their data was
       // not saved !
       if (errorMessage == null)
@@ -617,6 +623,27 @@ public class Jalview2XML
   {
     AlignFrame[] frames = Desktop.getAlignFrames();
 
+    setStateSavedUpToDate(true);
+
+    if (Cache.getDefault("DEBUG_DELAY_SAVE", false))
+    {
+      int n = debugDelaySave;
+      int i = 0;
+      while (i < n)
+      {
+        Console.debug("***** debugging save sleep " + i + "/" + n);
+        try
+        {
+          Thread.sleep(1000);
+        } catch (InterruptedException e)
+        {
+          // TODO Auto-generated catch block
+          e.printStackTrace();
+        }
+        i++;
+      }
+    }
+
     if (frames == null)
     {
       return;
@@ -764,6 +791,25 @@ public class Jalview2XML
       FileOutputStream fos = new FileOutputStream(
               doBackup ? backupfiles.getTempFilePath() : jarFile);
 
+      if (Cache.getDefault("DEBUG_DELAY_SAVE", false))
+      {
+        int n = debugDelaySave;
+        int i = 0;
+        while (i < n)
+        {
+          Console.debug("***** debugging save sleep " + i + "/" + n);
+          try
+          {
+            Thread.sleep(1000);
+          } catch (InterruptedException e)
+          {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+          }
+          i++;
+        }
+      }
+
       JarOutputStream jout = new JarOutputStream(fos);
       List<AlignFrame> frames = new ArrayList<>();
 
@@ -883,8 +929,7 @@ public class Jalview2XML
     {
       System.err.println("error writing date: " + e.toString());
     }
-    object.setVersion(
-            jalview.bin.Cache.getDefault("VERSION", "Development Build"));
+    object.setVersion(Cache.getDefault("VERSION", "Development Build"));
 
     /**
      * rjal is full height alignment, jal is actual alignment with full metadata
@@ -1111,7 +1156,7 @@ public class Jalview2XML
                 }
                 else
                 {
-                  Cache.log.error(
+                  Console.error(
                           "Failed to save viewer state for " + viewerType);
                 }
               }
@@ -1651,7 +1696,8 @@ public class Jalview2XML
                 .getHiddenColumns();
         if (hidden == null)
         {
-          warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
+          Console.warn(
+                  "REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
         }
         else
         {
@@ -1820,7 +1866,7 @@ public class Jalview2XML
       object.getPcaViewer().add(viewer);
     } catch (Throwable t)
     {
-      Cache.log.error("Error saving PCA: " + t.getMessage());
+      Console.error("Error saving PCA: " + t.getMessage());
     }
   }
 
@@ -2110,7 +2156,7 @@ public class Jalview2XML
       }
       else if (!matchedFile.equals(pdbentry.getFile()))
       {
-        Cache.log.warn(
+        Console.warn(
                 "Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
                         + pdbentry.getFile());
       }
@@ -2408,7 +2454,7 @@ public class Jalview2XML
                   calcIdParam.getParameters().replace("|\\n|", "\n"));
         } catch (IOException x)
         {
-          warn("Couldn't parse parameter data for "
+          Console.warn("Couldn't parse parameter data for "
                   + calcIdParam.getCalcId(), x);
           return false;
         }
@@ -2436,7 +2482,8 @@ public class Jalview2XML
       }
       else
       {
-        warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
+        Console.warn(
+                "Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
         return false;
       }
     }
@@ -2480,7 +2527,8 @@ public class Jalview2XML
         return id.toString();
       }
       // give up and warn that something has gone wrong
-      warn("Cannot find ID for object in external mapping : " + jvobj);
+      Console.warn(
+              "Cannot find ID for object in external mapping : " + jvobj);
     }
     return altCode;
   }
@@ -2617,12 +2665,12 @@ public class Jalview2XML
         mp.setDseqFor(jmpid);
         if (!seqRefIds.containsKey(jmpid))
         {
-          jalview.bin.Cache.log.debug("creatign new DseqFor ID");
+          Console.debug("creatign new DseqFor ID");
           seqRefIds.put(jmpid, ps);
         }
         else
         {
-          jalview.bin.Cache.log.debug("reusing DseqFor ID");
+          Console.debug("reusing DseqFor ID");
         }
 
         // mp.setMappingChoice(mpc);
@@ -3248,7 +3296,8 @@ public class Jalview2XML
       }
       else
       {
-        warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
+        Console.warn(
+                "Couldn't find entry in Jalview Jar for " + jarEntryName);
       }
     } catch (Exception ex)
     {
@@ -4255,8 +4304,9 @@ public class Jalview2XML
         tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews());
         if (tp == null)
         {
-          warn("There was a problem recovering stored Newick tree: \n"
-                  + tree.getNewick());
+          Console.warn(
+                  "There was a problem recovering stored Newick tree: \n"
+                          + tree.getNewick());
           continue;
         }
 
@@ -4417,7 +4467,7 @@ public class Jalview2XML
             else
             {
               errorMessage = ("The Jmol views in this project were imported\nfrom an older version of Jalview.\nPlease review the sequence colour associations\nin the Colour by section of the Jmol View menu.\n\nIn the case of problems, see note at\nhttp://issues.jalview.org/browse/JAL-747");
-              warn(errorMessage);
+              Console.warn(errorMessage);
             }
           }
         }
@@ -4472,7 +4522,7 @@ public class Jalview2XML
     } catch (IllegalArgumentException | NullPointerException e)
     {
       // TODO JAL-3619 show error dialog / offer an alternative viewer
-      Cache.log.error("Invalid structure viewer type: " + type);
+      Console.error("Invalid structure viewer type: " + type);
     }
   }
 
@@ -5004,7 +5054,7 @@ public class Jalview2XML
           }
           else
           {
-            warn("Couldn't recover parameters for "
+            Console.warn("Couldn't recover parameters for "
                     + calcIdParam.getCalcId());
           }
         }
@@ -5281,10 +5331,7 @@ public class Jalview2XML
     String id = object.getViewport().get(0).getSequenceSetId();
     if (skipList.containsKey(id))
     {
-      if (Cache.log != null && Cache.log.isDebugEnabled())
-      {
-        Cache.log.debug("Skipping seuqence set id " + id);
-      }
+      Console.debug("Skipping seuqence set id " + id);
       return true;
     }
     return false;
@@ -5336,14 +5383,16 @@ public class Jalview2XML
       {
         if (ds != null && ds != seqSetDS)
         {
-          warn("JAL-3171 regression: Overwriting a dataset reference for an alignment"
-                  + " - CDS/Protein crossreference data may be lost");
+          Console.warn(
+                  "JAL-3171 regression: Overwriting a dataset reference for an alignment"
+                          + " - CDS/Protein crossreference data may be lost");
           if (xtant_ds != null)
           {
             // This can only happen if the unique sequence set ID was bound to a
             // dataset that did not contain any of the sequences in the view
             // currently being restored.
-            warn("JAL-3171 SERIOUS!  TOTAL CONFUSION - please consider contacting the Jalview Development team so they can investigate why your project caused this message to be displayed.");
+            Console.warn(
+                    "JAL-3171 SERIOUS!  TOTAL CONFUSION - please consider contacting the Jalview Development team so they can investigate why your project caused this message to be displayed.");
           }
         }
         ds = seqSetDS;
@@ -5368,7 +5417,7 @@ public class Jalview2XML
       SequenceI[] dsseqs = new SequenceI[dseqs.size()];
       dseqs.copyInto(dsseqs);
       ds = new jalview.datamodel.Alignment(dsseqs);
-      debug("Created new dataset " + vamsasSet.getDatasetId()
+      Console.debug("Created new dataset " + vamsasSet.getDatasetId()
               + " for alignment " + System.identityHashCode(al));
       addDatasetRef(vamsasSet.getDatasetId(), ds);
     }
@@ -5421,7 +5470,7 @@ public class Jalview2XML
       AlignmentI prevDS = seqToDataset.put(restoredSeq.getDsseqid(), ds);
       if (prevDS != null && prevDS != ds)
       {
-        warn("Dataset sequence appears in many datasets: "
+        Console.warn("Dataset sequence appears in many datasets: "
                 + restoredSeq.getDsseqid());
         // TODO: try to merge!
       }
@@ -5627,7 +5676,8 @@ public class Jalview2XML
   {
     if (dataset.getDataset() != null)
     {
-      warn("Serious issue!  Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
+      Console.warn(
+              "Serious issue!  Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
     }
     String datasetId = makeHashCode(dataset, null);
     if (datasetId == null)
@@ -5763,7 +5813,7 @@ public class Jalview2XML
         seqRefIds.put(sqid, djs);
 
       }
-      jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
+      Console.debug("about to recurse on addDBRefs.");
       addDBRefs(djs, ms);
 
     }
@@ -5816,62 +5866,6 @@ public class Jalview2XML
 
   private Hashtable jvids2vobj;
 
-  private void warn(String msg)
-  {
-    warn(msg, null);
-  }
-
-  private void warn(String msg, Exception e)
-  {
-    if (Cache.log != null)
-    {
-      if (e != null)
-      {
-        Cache.log.warn(msg, e);
-      }
-      else
-      {
-        Cache.log.warn(msg);
-      }
-    }
-    else
-    {
-      System.err.println("Warning: " + msg);
-      if (e != null)
-      {
-        e.printStackTrace();
-      }
-    }
-  }
-
-  private void debug(String string)
-  {
-    debug(string, null);
-  }
-
-  private void debug(String msg, Exception e)
-  {
-    if (Cache.log != null)
-    {
-      if (e != null)
-      {
-        Cache.log.debug(msg, e);
-      }
-      else
-      {
-        Cache.log.debug(msg);
-      }
-    }
-    else
-    {
-      System.err.println("Warning: " + msg);
-      if (e != null)
-      {
-        e.printStackTrace();
-      }
-    }
-  }
-
   /**
    * set the object to ID mapping tables used to write/recover objects and XML
    * ID strings for the jalview project. If external tables are provided then
@@ -5930,7 +5924,7 @@ public class Jalview2XML
         if (!jvann.annotationId.equals(anid))
         {
           // TODO verify that this is the correct behaviour
-          this.warn("Overriding Annotation ID for " + anid
+          Console.warn("Overriding Annotation ID for " + anid
                   + " from different id : " + jvann.annotationId);
           jvann.annotationId = anid;
         }
@@ -5945,7 +5939,7 @@ public class Jalview2XML
       }
       else
       {
-        Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
+        Console.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
       }
     }
   }
@@ -6015,7 +6009,8 @@ public class Jalview2XML
       }
       else
       {
-        warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
+        Console.warn(
+                "Couldn't find entry in Jalview Jar for " + jarEntryName);
       }
     } catch (Exception ex)
     {
@@ -6165,7 +6160,7 @@ public class Jalview2XML
       }
     } catch (Exception ex)
     {
-      Cache.log.error("Error loading PCA: " + ex.toString());
+      Console.error("Error loading PCA: " + ex.toString());
     }
   }
 
@@ -6225,7 +6220,7 @@ public class Jalview2XML
       });
     } catch (InvocationTargetException | InterruptedException ex)
     {
-      warn("Unexpected error when opening " + viewerType
+      Console.warn("Unexpected error when opening " + viewerType
               + " structure viewer", ex);
     }
   }
@@ -6332,7 +6327,7 @@ public class Jalview2XML
       }
     } catch (IOException e)
     {
-      Cache.log.error("Error restoring Jmol session: " + e.toString());
+      Console.error("Error restoring Jmol session: " + e.toString());
     }
     return null;
   }
@@ -6585,7 +6580,7 @@ public class Jalview2XML
         maxcol = new Color(Integer.parseInt(colourModel.getRGB(), 16));
       } catch (Exception e)
       {
-        Cache.log.warn("Couldn't parse out graduated feature color.", e);
+        Console.warn("Couldn't parse out graduated feature color.", e);
       }
 
       NoValueColour noCol = colourModel.getNoValueColour();
@@ -6639,4 +6634,44 @@ public class Jalview2XML
 
     return colour;
   }
+
+  public static void setStateSavedUpToDate(boolean s)
+  {
+    Console.debug("Setting overall stateSavedUpToDate to " + s);
+    stateSavedUpToDate = s;
+  }
+
+  public static boolean stateSavedUpToDate()
+  {
+    Console.debug("Returning overall stateSavedUpToDate value: "
+            + stateSavedUpToDate);
+    return stateSavedUpToDate;
+  }
+
+  public static boolean allSavedUpToDate()
+  {
+    if (stateSavedUpToDate()) // nothing happened since last project save
+      return true;
+
+    AlignFrame[] frames = Desktop.getAlignFrames();
+    if (frames != null)
+    {
+      for (int i = 0; i < frames.length; i++)
+      {
+        if (frames[i] == null)
+          continue;
+        if (!frames[i].getViewport().savedUpToDate())
+          return false; // at least one alignment is not individually saved
+      }
+    }
+    return true;
+  }
+
+  // used for debugging and tests
+  private static int debugDelaySave = 20;
+
+  public static void setDebugDelaySave(int n)
+  {
+    debugDelaySave = n;
+  }
 }