JAL-3253 Jalview2XML minor recoding; suggesting InvokeLater rather than
authorhansonr <hansonr@STO24954W.ad.stolaf.edu>
Tue, 2 Jul 2019 12:30:50 +0000 (14:30 +0200)
committerhansonr <hansonr@STO24954W.ad.stolaf.edu>
Tue, 2 Jul 2019 12:30:50 +0000 (14:30 +0200)
InvokeAndWait to allow some asynchronous updating

src/jalview/project/Jalview2XML.java

index 4ad61d9..22d7bfd 100644 (file)
@@ -28,6 +28,7 @@ import jalview.analysis.Conservation;
 import jalview.analysis.PCA;
 import jalview.analysis.scoremodels.ScoreModels;
 import jalview.analysis.scoremodels.SimilarityParams;
+import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureColourI;
 import jalview.api.ViewStyleI;
 import jalview.api.analysis.ScoreModelI;
@@ -162,7 +163,6 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.lang.reflect.InvocationTargetException;
 import java.math.BigInteger;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -623,13 +623,14 @@ public class Jalview2XML
    * core method for storing state for a set of AlignFrames.
    * 
    * @param frames
-   *          - frames involving all data to be exported (including containing
-   *          splitframes)
+   *          - frames involving all data to be exported (including those
+   *          contained in splitframes, though not the split frames themselves)
    * @param jout
    *          - project output stream
    */
   private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
   {
+
     Hashtable<String, AlignFrame> dsses = new Hashtable<>();
 
     /*
@@ -652,21 +653,22 @@ public class Jalview2XML
       for (int i = frames.size() - 1; i > -1; i--)
       {
         AlignFrame af = frames.get(i);
+        AlignViewport vp = af.getViewport();
         // skip ?
         if (skipList != null && skipList
-                .containsKey(af.getViewport().getSequenceSetId()))
+                .containsKey(vp.getSequenceSetId()))
         {
           continue;
         }
 
         String shortName = makeFilename(af, shortNames);
 
-        int apSize = af.getAlignPanels().size();
-
+        AlignmentI alignment = vp.getAlignment();
+        List<? extends AlignmentViewPanel> panels = af.getAlignPanels();
+        int apSize = panels.size();
         for (int ap = 0; ap < apSize; ap++)
-        {
-          AlignmentPanel apanel = (AlignmentPanel) af.getAlignPanels()
-                  .get(ap);
+          {
+          AlignmentPanel apanel = (AlignmentPanel) panels.get(ap);
           String fileName = apSize == 1 ? shortName : ap + shortName;
           if (!fileName.endsWith(".xml"))
           {
@@ -674,11 +676,17 @@ public class Jalview2XML
           }
 
           saveState(apanel, fileName, jout, viewIds);
-
-          String dssid = getDatasetIdRef(
-                  af.getViewport().getAlignment().getDataset());
+        }
+        if (apSize > 0)
+        {
+          // BH moved next bit out of inner loop, not that it really matters.
+          // so we are testing to make sure we actually have an alignment,
+          // apparently.
+          String dssid = getDatasetIdRef(alignment.getDataset());
           if (!dsses.containsKey(dssid))
           {
+            // We have not already covered this data by reference from another
+            // frame.
             dsses.put(dssid, af);
           }
         }
@@ -796,12 +804,21 @@ public class Jalview2XML
     }
   }
 
+  /**
+   * Each AlignFrame has a single data set associated with it. Note that none of
+   * these frames are split frames, because Desktop.getAlignFrames() collects
+   * top and bottom separately here.
+   * 
+   * @param dsses
+   * @param fileName
+   * @param jout
+   */
   private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
           String fileName, JarOutputStream jout)
   {
 
-    // BH: Question: What is this Dataset for, as it seems to
-    // duplicate the actual XML file data.
+    // Note that in saveAllFrames we have associated each specific dataset to
+    // ONE of its associated frames.
 
     for (String dssids : dsses.keySet())
     {
@@ -2757,7 +2774,8 @@ public class Jalview2XML
     {
       try
       {
-        SwingUtilities.invokeAndWait(new Runnable()
+         // BH 2019 -- can't wait
+        SwingUtilities.invokeLater(new Runnable()
         {
           @Override
           public void run()
@@ -2850,6 +2868,9 @@ public class Jalview2XML
       JarEntry jarentry = null;
       int entryCount = 1;
 
+      // Look for all the entry names ending with ".xml"
+      // This includes all panels and at least one frame.
+//      Platform.timeCheck(null, Platform.TIME_MARK);
       do
       {
         jin = jprovider.getJarInputStream();
@@ -2858,14 +2879,21 @@ public class Jalview2XML
           jarentry = jin.getNextJarEntry();
         }
         String name = (jarentry == null ? null : jarentry.getName());
-        if (name != null && name.endsWith(".xml")
-        // The question here is what to do with the two
-        // .xml files in the jvp file. They are identical?
-        // && name.indexOf(" Dataset for ") < 0 // BH 2019.05.21
-        // we need to talk about how to avoid the full duplication of
-        // reading these.
-        )
+        if (name != null && name.endsWith(".xml"))
         {
+
+          // The question here is what to do with the two
+          // .xml files in the jvp file.
+          // Some number of them, "...Dataset for...", will be the
+          // Only AlignPanels and will have Viewport.
+          // One or more will be the source data, with the DBRefs.
+          //
+          // JVP file writing (above) ensures tha the AlignPanels are written
+          // first, then all relevant datasets (which are
+          // Jalview.datamodel.Alignment).
+          //
+
+//          Platform.timeCheck("Jalview2XML JAXB " + name, Platform.TIME_MARK);
           JAXBContext jc = JAXBContext
                   .newInstance("jalview.xml.binding.jalview");
           XMLStreamReader streamReader = XMLInputFactory.newInstance()
@@ -2873,14 +2901,19 @@ public class Jalview2XML
           javax.xml.bind.Unmarshaller um = jc.createUnmarshaller();
           JAXBElement<JalviewModel> jbe = um
                   .unmarshal(streamReader, JalviewModel.class);
-          JalviewModel object = jbe.getValue();
+          JalviewModel model = jbe.getValue();
 
           if (true) // !skipViewport(object))
           {
-            _af = loadFromObject(object, file, true, jprovider);
-            if (_af != null && object.getViewport().size() > 0)
-            // getJalviewModelSequence().getViewportCount() > 0)
+            // Q: Do we have to load from the model, even if it
+            // does not have a viewport, could we discover that early on?
+            // Q: Do we need to load this object?
+            _af = loadFromObject(model, file, true, jprovider);
+//            Platform.timeCheck("Jalview2XML.loadFromObject",
+            // Platform.TIME_MARK);
+            if (_af != null && model.getViewport().size() > 0)
             {
+              // That is, this is one of the AlignmentPanel models
               if (af == null)
               {
                 // store a reference to the first view
@@ -2900,6 +2933,7 @@ public class Jalview2XML
                       af.getViewport().getAlignment().getDataset());
             }
           }
+//          Platform.timeCheck("JAXB " + name, Platform.TIME_MARK);
           entryCount++;
         }
         else if (jarentry != null)
@@ -2908,7 +2942,10 @@ public class Jalview2XML
           entryCount++;
         }
       } while (jarentry != null);
+//      Platform.timeCheck("JAXB loop exit", Platform.TIME_MARK);
       resolveFrefedSequences();
+//      Platform.timeCheck("JAXB resolveFrefed", Platform.TIME_MARK);
+
     } catch (IOException ex)
     {
       ex.printStackTrace();
@@ -3271,7 +3308,9 @@ public class Jalview2XML
   }
 
   /**
-   * Load alignment frame from jalview XML DOM object
+   * Load alignment frame from jalview XML DOM object. For a DOM object that
+   * includes one or more Viewport elements (one with a title that does NOT
+   * contain "Dataset for"), create the frame.
    * 
    * @param jalviewModel
    *          DOM
@@ -3286,9 +3325,13 @@ public class Jalview2XML
   AlignFrame loadFromObject(JalviewModel jalviewModel, String file,
           boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
   {
+
+//    Platform.timeCheck("Jalview2XML.loadFromObject0", Platform.TIME_MARK);
+
     SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet().get(0);
     List<Sequence> vamsasSeqs = vamsasSet.getSequence();
 
+
     // JalviewModelSequence jms = object.getJalviewModelSequence();
 
     // Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
@@ -3319,6 +3362,7 @@ public class Jalview2XML
               : view.getId() + uniqueSetSuffix);
     }
 
+//    Platform.timeCheck("Jalview2XML.loadFromObject1", Platform.TIME_MARK);
     // ////////////////////////////////
     // LOAD SEQUENCES
 
@@ -3339,6 +3383,7 @@ public class Jalview2XML
       SequenceI tmpSeq = seqRefIds.get(seqId);
       if (tmpSeq != null)
       {
+        //
         if (!incompleteSeqs.containsKey(seqId))
         {
           // may not need this check, but keep it for at least 2.9,1 release
@@ -3403,6 +3448,8 @@ public class Jalview2XML
       }
     }
 
+//    Platform.timeCheck("Jalview2XML.loadFromObject-seq",
+//            Platform.TIME_MARK);
     // /
     // Create the alignment object from the sequence set
     // ///////////////////////////////
@@ -3443,6 +3490,8 @@ public class Jalview2XML
       recoverDatasetFor(vamsasSet, al, isdsal, uniqueSeqSetId);
     }
 
+//    Platform.timeCheck("Jalview2XML.loadFromObject-align",
+//            Platform.TIME_MARK);
     if (referenceseqForView != null)
     {
       al.setSeqrep(referenceseqForView);
@@ -3455,6 +3504,8 @@ public class Jalview2XML
       al.setProperty(ssp.getKey(), ssp.getValue());
     }
 
+//    Platform.timeCheck("Jalview2XML.loadFromObject-setseqprop",
+//            Platform.TIME_MARK);
     // ///////////////////////////////
 
     Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
@@ -3596,6 +3647,8 @@ public class Jalview2XML
           }
         }
       }
+//      Platform.timeCheck("Jalview2XML.loadFromObject-endmultiview",
+//              Platform.TIME_MARK);
     } // end !multipleview
 
     // ///////////////////////////////
@@ -3637,6 +3690,8 @@ public class Jalview2XML
           al.addCodonFrame(cf);
         }
       }
+//      Platform.timeCheck("Jalview2XML.loadFromObject-seqmap",
+//              Platform.TIME_MARK);
     }
 
     // ////////////////////////////////
@@ -3697,6 +3752,9 @@ public class Jalview2XML
         }
         // Construct new annotation from model.
         List<AnnotationElement> ae = annotation.getAnnotationElement();
+//        System.err.println(
+//                "Jalview2XML processing " + ae.size() + " annotations");
+
         jalview.datamodel.Annotation[] anot = null;
         java.awt.Color firstColour = null;
         int anpos;
@@ -3732,6 +3790,7 @@ public class Jalview2XML
             }
           }
         }
+        // create the new AlignmentAnnotation
         jalview.datamodel.AlignmentAnnotation jaa = null;
 
         if (annotation.isGraph())
@@ -3768,6 +3827,7 @@ public class Jalview2XML
           jaa._linecolour = firstColour;
         }
         // register new annotation
+        // Annotation graphs such as Conservation will not have id.
         if (annotation.getId() != null)
         {
           annotationIds.put(annotation.getId(), jaa);
@@ -3856,6 +3916,8 @@ public class Jalview2XML
           al.addAnnotation(jaa);
         }
       }
+//      Platform.timeCheck("Jalview2XML.loadFromObject-annot",
+//              Platform.TIME_MARK);
     }
     // ///////////////////////
     // LOAD GROUPS
@@ -3970,6 +4032,8 @@ public class Jalview2XML
                   jGroup.getAnnotationColours(), null, al, jalviewModel, false));
         }
       }
+//      Platform.timeCheck("Jalview2XML.loadFromObject-groups",
+//              Platform.TIME_MARK);
     }
     if (view == null)
     {
@@ -3979,8 +4043,6 @@ public class Jalview2XML
     // ///////////////////////////////
     // LOAD VIEWPORT
 
-    AlignFrame af = null;
-    AlignViewport av = null;
     // now check to see if we really need to create a new viewport.
     if (multipleView && viewportsAdded.size() == 0)
     {
@@ -4011,6 +4073,8 @@ public class Jalview2XML
         }
 
       }
+//      Platform.timeCheck("Jalview2XML.loadFromObject-viewport",
+//              Platform.TIME_MARK);
     }
     /**
      * indicate that annotation colours are applied across all groups (pre
@@ -4019,8 +4083,9 @@ public class Jalview2XML
     boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan("2.8.1",
             jalviewModel.getVersion());
 
+    AlignFrame af = null;
     AlignmentPanel ap = null;
-    boolean isnewview = true;
+    AlignViewport av = null;
     if (viewId != null)
     {
       // Check to see if this alignment already has a view id == viewId
@@ -4030,25 +4095,27 @@ public class Jalview2XML
       {
         for (int v = 0; v < views.length; v++)
         {
-          if (views[v].av.getViewId().equalsIgnoreCase(viewId))
+          ap = views[v];
+          av = ap.av;
+          if (av.getViewId().equalsIgnoreCase(viewId))
           {
             // recover the existing alignpanel, alignframe, viewport
-            af = views[v].alignFrame;
-            av = views[v].av;
-            ap = views[v];
+            af = ap.alignFrame;
+            break;
             // TODO: could even skip resetting view settings if we don't want to
             // change the local settings from other jalview processes
-            isnewview = false;
           }
         }
       }
     }
 
-    if (isnewview)
+    if (af == null)
     {
       af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view,
               uniqueSeqSetId, viewId, autoAlan);
       av = af.getViewport();
+      // note that this only retrieves the most recently accessed
+      // tab of an AlignFrame.
       ap = af.alignPanel;
     }
 
@@ -4057,12 +4124,57 @@ public class Jalview2XML
      * 
      * Not done if flag is false (when this method is used for New View)
      */
+    final AlignFrame af0 = af;
+    final AlignViewport av0 = av;
+    final AlignmentPanel ap0 = ap;
+//    Platform.timeCheck("Jalview2XML.loadFromObject-beforetree",
+//            Platform.TIME_MARK);
     if (loadTreesAndStructures)
     {
-      loadTrees(jalviewModel, view, af, av, ap);
-      loadPCAViewers(jalviewModel, ap);
-      loadPDBStructures(jprovider, jseqs, af, ap);
-      loadRnaViewers(jprovider, jseqs, ap);
+      if (!jalviewModel.getTree().isEmpty())
+      {
+        SwingUtilities.invokeLater(new Runnable()
+        {
+          @Override
+          public void run()
+          {
+//            Platform.timeCheck(null, Platform.TIME_MARK);
+            loadTrees(jalviewModel, view, af0, av0, ap0);
+//            Platform.timeCheck("Jalview2XML.loadTrees", Platform.TIME_MARK);
+          }
+        });
+      }
+      if (!jalviewModel.getPcaViewer().isEmpty())
+      {
+        SwingUtilities.invokeLater(new Runnable()
+        {
+          @Override
+          public void run()
+          {
+//            Platform.timeCheck(null, Platform.TIME_MARK);
+            loadPCAViewers(jalviewModel, ap0);
+//            Platform.timeCheck("Jalview2XML.loadPCA", Platform.TIME_MARK);
+          }
+        });
+      }
+      SwingUtilities.invokeLater(new Runnable()
+      {
+        @Override
+        public void run()
+        {
+//          Platform.timeCheck(null, Platform.TIME_MARK);
+          loadPDBStructures(jprovider, jseqs, af0, ap0);
+//          Platform.timeCheck("Jalview2XML.loadPDB", Platform.TIME_MARK);
+        }
+      });
+      SwingUtilities.invokeLater(new Runnable()
+      {
+        @Override
+        public void run()
+        {
+          loadRnaViewers(jprovider, jseqs, ap0);
+        }
+      });
     }
     // and finally return.
     return af;
@@ -4081,7 +4193,7 @@ public class Jalview2XML
    * @param jseqs
    * @param ap
    */
-  private void loadRnaViewers(jarInputStreamProvider jprovider,
+  protected void loadRnaViewers(jarInputStreamProvider jprovider,
           List<JSeq> jseqs, AlignmentPanel ap)
   {
     /*
@@ -4619,9 +4731,9 @@ public class Jalview2XML
     final AlignFrame alf = af;
     final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
             svattrib.getWidth(), svattrib.getHeight());
-    try
-    {
-      javax.swing.SwingUtilities.invokeAndWait(new Runnable()
+    // try
+    // {
+      javax.swing.SwingUtilities.invokeLater(new Runnable()
       {
         @Override
         public void run()
@@ -4648,14 +4760,14 @@ public class Jalview2XML
           }
         }
       });
-    } catch (InvocationTargetException ex)
-    {
-      warn("Unexpected error when opening Jmol view.", ex);
-
-    } catch (InterruptedException e)
-    {
-      // e.printStackTrace();
-    }
+    // } catch (InvocationTargetException ex)
+    // {
+    // warn("Unexpected error when opening Jmol view.", ex);
+    //
+    // } catch (InterruptedException e)
+    // {
+    // // e.printStackTrace();
+    // }
 
   }