JAL-2213 corrected wait for files to load in Jmol; extract method
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 29 Sep 2016 12:15:53 +0000 (13:15 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 29 Sep 2016 12:15:53 +0000 (13:15 +0100)
refactoring of run()

src/jalview/gui/AppJmol.java

index 7929787..2299c26 100644 (file)
@@ -41,6 +41,7 @@ import jalview.schemes.ZappoColourScheme;
 import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.ws.dbsources.Pdb;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -70,6 +71,7 @@ import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JSplitPane;
+import javax.swing.SwingUtilities;
 import javax.swing.event.InternalFrameAdapter;
 import javax.swing.event.InternalFrameEvent;
 import javax.swing.event.MenuEvent;
@@ -77,6 +79,10 @@ import javax.swing.event.MenuListener;
 
 public class AppJmol extends StructureViewerBase
 {
+  private static final String SPACE = " ";
+
+  private static final String BACKSLASH = "\"";
+
   AppJmolBinding jmb;
 
   JPanel scriptWindow;
@@ -478,15 +484,163 @@ public class AppJmol extends StructureViewerBase
   public void run()
   {
     _started = true;
+    try
+    {
+      List<String> files = fetchPdbFiles();
+      if (files.size() > 0)
+      {
+        showFilesInViewer(files);
+      }
+    } finally
+    {
+      _started = false;
+      worker = null;
+    }
+  }
+
+  /**
+   * Either adds the given files to a structure viewer or opens a new viewer to
+   * show them
+   * 
+   * @param files
+   *          list of absolute paths to structure files
+   */
+  void showFilesInViewer(List<String> files)
+  {
+    long lastnotify = jmb.getLoadNotifiesHandled();
+    StringBuilder fileList = new StringBuilder();
+    for (String s : files)
+    {
+      fileList.append(SPACE).append(BACKSLASH).append(Platform.escapeString(s))
+              .append(BACKSLASH);
+    }
+    String filesString = fileList.toString();
+
+    if (!addingStructures)
+    {
+      try
+      {
+        initJmol("load FILES " + filesString);
+      } catch (OutOfMemoryError oomerror)
+      {
+        new OOMWarning("When trying to open the Jmol viewer!", oomerror);
+        Cache.log.debug("File locations are " + filesString);
+      } catch (Exception ex)
+      {
+        Cache.log.error("Couldn't open Jmol viewer!", ex);
+      }
+    }
+    else
+    {
+      StringBuilder cmd = new StringBuilder();
+      cmd.append("loadingJalviewdata=true\nload APPEND ");
+      cmd.append(filesString);
+      cmd.append("\nloadingJalviewdata=null");
+      final String command = cmd.toString();
+      lastnotify = jmb.getLoadNotifiesHandled();
+
+      try
+      {
+        jmb.evalStateCommand(command);
+      } catch (OutOfMemoryError oomerror)
+      {
+        new OOMWarning(
+                "When trying to add structures to the Jmol viewer!",
+                oomerror);
+        Cache.log.debug("File locations are " + filesString);
+      } catch (Exception ex)
+      {
+        Cache.log.error("Couldn't add files to Jmol viewer!", ex);
+      }
+    }
+
+    // need to wait around until script has finished
+    int waitMax = 5000; // give up after 5 seconds
+    int waitFor = 35;
+    int waitTotal = 0;
+    while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
+            : !(jmb.isFinishedInit() && jmb.getPdbFile() != null && jmb
+                    .getPdbFile().length == files.size()))
+    {
+      try
+      {
+        Cache.log.debug("Waiting around for jmb notify.");
+        Thread.sleep(waitFor);
+        waitTotal += waitFor;
+      } catch (Exception e)
+      {
+      }
+      if (waitTotal > waitMax)
+      {
+        System.err.println("Timed out waiting for Jmol to load files");
+        break;
+      }
+    }
+
+    // refresh the sequence colours for the new structure(s)
+    for (AlignmentPanel ap : _colourwith)
+    {
+      jmb.updateColours(ap);
+    }
+    // do superposition if asked to
+    if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
+    {
+      alignAddedStructures();
+    }
+    addingStructures = false;
+  }
+
+  /**
+   * Queues a thread to align structures with Jalview alignments
+   */
+  void alignAddedStructures()
+  {
+    javax.swing.SwingUtilities.invokeLater(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        if (jmb.viewer.isScriptExecuting())
+        {
+          SwingUtilities.invokeLater(this);
+          try
+          {
+            Thread.sleep(5);
+          } catch (InterruptedException q)
+          {
+          }
+          return;
+        }
+        else
+        {
+          alignStructs_withAllAlignPanels();
+        }
+      }
+    });
+    alignAddedStructures = false;
+  }
+
+  /**
+   * Retrieves and saves as file any modelled PDB entries for which we do not
+   * already have a file saved. Returns a list of absolute paths to structure
+   * files which were either retrieved, or already stored but not modelled in
+   * the structure viewer (i.e. files to add to the viewer display).
+   * 
+   * @return
+   */
+  List<String> fetchPdbFiles()
+  {
+    // todo - record which pdbids were successfully imported.
+    StringBuilder errormsgs = new StringBuilder();
+
+    List<String> files = new ArrayList<String>();
     String pdbid = "";
-    // todo - record which pdbids were successfuly imported.
-    StringBuffer errormsgs = new StringBuffer(), files = new StringBuffer();
     try
     {
-      String[] curfiles = jmb.getPdbFile(); // files currently in viewer
+      String[] filesInViewer = jmb.getPdbFile();
       // TODO: replace with reference fetching/transfer code (validate PDBentry
       // as a DBRef?)
-      jalview.ws.dbsources.Pdb pdbclient = new jalview.ws.dbsources.Pdb();
+      Pdb pdbclient = new Pdb();
       for (int pi = 0; pi < jmb.getPdbCount(); pi++)
       {
         String file = jmb.getPdbEntry(pi).getFile();
@@ -510,12 +664,15 @@ public class AppJmol extends StructureViewerBase
           } catch (Exception ex)
           {
             ex.printStackTrace();
-            errormsgs.append("'" + pdbid + "'");
-          }
-          if (progressBar != null)
+            errormsgs.append("'").append(pdbid).append("'");
+          } finally
           {
-            progressBar.setProgressBar(
-                    MessageManager.getString("label.state_completed"), hdl);
+            if (progressBar != null)
+            {
+              progressBar.setProgressBar(
+                      MessageManager.getString("label.state_completed"),
+                      hdl);
+            }
           }
           if (pdbseq != null)
           {
@@ -524,22 +681,21 @@ public class AppJmol extends StructureViewerBase
             file = new File(pdbseq.getSequenceAt(0).getAllPDBEntries()
                     .elementAt(0).getFile()).getAbsolutePath();
             jmb.getPdbEntry(pi).setFile(file);
-
-            files.append(" \"" + Platform.escapeString(file) + "\"");
+            files.add(file);
           }
           else
           {
-            errormsgs.append("'" + pdbid + "' ");
+            errormsgs.append("'").append(pdbid).append("' ");
           }
         }
         else
         {
-          if (curfiles != null && curfiles.length > 0)
+          if (filesInViewer != null && filesInViewer.length > 0)
           {
             addingStructures = true; // already files loaded.
-            for (int c = 0; c < curfiles.length; c++)
+            for (int c = 0; c < filesInViewer.length; c++)
             {
-              if (curfiles[c].equals(file))
+              if (filesInViewer[c].equals(file))
               {
                 file = null;
                 break;
@@ -548,7 +704,7 @@ public class AppJmol extends StructureViewerBase
           }
           if (file != null)
           {
-            files.append(" \"" + Platform.escapeString(file) + "\"");
+            files.add(file);
           }
         }
       }
@@ -558,114 +714,18 @@ public class AppJmol extends StructureViewerBase
     } catch (Exception ex)
     {
       ex.printStackTrace();
-      errormsgs.append("When retrieving pdbfiles : current was: '" + pdbid
-              + "'");
+      errormsgs.append("When retrieving pdbfiles : current was: '")
+              .append(pdbid).append("'");
     }
     if (errormsgs.length() > 0)
     {
-
       JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.pdb_entries_couldnt_be_retrieved",
                       new String[] { errormsgs.toString() }),
               MessageManager.getString("label.couldnt_load_file"),
               JOptionPane.ERROR_MESSAGE);
-
     }
-    long lastnotify = jmb.getLoadNotifiesHandled();
-    if (files.length() > 0)
-    {
-      if (!addingStructures)
-      {
-
-        try
-        {
-          initJmol("load FILES " + files.toString());
-        } catch (OutOfMemoryError oomerror)
-        {
-          new OOMWarning("When trying to open the Jmol viewer!", oomerror);
-          Cache.log.debug("File locations are " + files);
-        } catch (Exception ex)
-        {
-          Cache.log.error("Couldn't open Jmol viewer!", ex);
-        }
-      }
-      else
-      {
-        StringBuffer cmd = new StringBuffer();
-        cmd.append("loadingJalviewdata=true\nload APPEND ");
-        cmd.append(files.toString());
-        cmd.append("\nloadingJalviewdata=null");
-        final String command = cmd.toString();
-        cmd = null;
-        lastnotify = jmb.getLoadNotifiesHandled();
-
-        try
-        {
-          jmb.evalStateCommand(command);
-        } catch (OutOfMemoryError oomerror)
-        {
-          new OOMWarning(
-                  "When trying to add structures to the Jmol viewer!",
-                  oomerror);
-          Cache.log.debug("File locations are " + files);
-        } catch (Exception ex)
-        {
-          Cache.log.error("Couldn't add files to Jmol viewer!", ex);
-        }
-      }
-
-      // need to wait around until script has finished
-      while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
-              : (!jmb.isFinishedInit() && jmb.getPdbFile() != null && jmb
-                      .getPdbFile().length != jmb.getPdbCount()))
-      {
-        try
-        {
-          Cache.log.debug("Waiting around for jmb notify.");
-          Thread.sleep(35);
-        } catch (Exception e)
-        {
-        }
-      }
-
-      // refresh the sequence colours for the new structure(s)
-      for (AlignmentPanel ap : _colourwith)
-      {
-        jmb.updateColours(ap);
-      }
-      // do superposition if asked to
-      if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
-      {
-        javax.swing.SwingUtilities.invokeLater(new Runnable()
-        {
-          @Override
-          public void run()
-          {
-            if (jmb.viewer.isScriptExecuting())
-            {
-              javax.swing.SwingUtilities.invokeLater(this);
-              try
-              {
-                Thread.sleep(5);
-              } catch (InterruptedException q)
-              {
-              }
-              ;
-              return;
-            }
-            else
-            {
-              alignStructs_withAllAlignPanels();
-            }
-          }
-        });
-        alignAddedStructures = false;
-      }
-      addingStructures = false;
-
-    }
-    _started = false;
-    worker = null;
+    return files;
   }
 
   @Override