(JAL-1016) noted position where race condition occurs
[jalview.git] / src / jalview / ext / jmol / JalviewJmolBinding.java
index 8e1ede4..a625fd7 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)\r
- * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
+ * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
  * \r
  * This file is part of Jalview.\r
  * \r
  */\r
 package jalview.ext.jmol;\r
 \r
-import java.io.File;\r
-import java.net.URL;\r
-import java.util.*;\r
-import java.applet.Applet;\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import javax.swing.JPanel;\r
-\r
 import jalview.api.AlignmentViewPanel;\r
 import jalview.api.FeatureRenderer;\r
 import jalview.api.SequenceRenderer;\r
 import jalview.api.SequenceStructureBinding;\r
-import jalview.datamodel.*;\r
-import jalview.structure.*;\r
-import jalview.io.*;\r
+import jalview.api.StructureSelectionManagerProvider;\r
+import jalview.datamodel.AlignmentI;\r
+import jalview.datamodel.ColumnSelection;\r
+import jalview.datamodel.PDBEntry;\r
+import jalview.datamodel.SequenceI;\r
+import jalview.io.AppletFormatAdapter;\r
+import jalview.schemes.ColourSchemeI;\r
+import jalview.schemes.ResidueProperties;\r
+import jalview.structure.StructureListener;\r
+import jalview.structure.StructureMapping;\r
+import jalview.structure.StructureSelectionManager;\r
+\r
+import java.awt.Color;\r
+import java.awt.Container;\r
+import java.awt.event.ComponentEvent;\r
+import java.awt.event.ComponentListener;\r
+import java.io.File;\r
+import java.net.URL;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Map;\r
+import java.util.Vector;\r
 \r
-import org.jmol.api.*;\r
 import org.jmol.adapter.smarter.SmarterJmolAdapter;\r
-\r
-import org.jmol.popup.*;\r
-import org.jmol.viewer.JmolConstants;\r
-import org.jmol.viewer.Viewer;\r
-\r
-import jalview.schemes.*;\r
+import org.jmol.api.JmolAppConsoleInterface;\r
+import org.jmol.api.JmolSelectionListener;\r
+import org.jmol.api.JmolStatusListener;\r
+import org.jmol.api.JmolViewer;\r
+import org.jmol.constant.EnumCallback;\r
+import org.jmol.popup.JmolPopup;\r
 \r
 public abstract class JalviewJmolBinding implements StructureListener,\r
         JmolStatusListener, SequenceStructureBinding,\r
-        JmolSelectionListener, ComponentListener\r
+        JmolSelectionListener, ComponentListener, StructureSelectionManagerProvider\r
 \r
 {\r
   /**\r
@@ -128,13 +137,14 @@ public abstract class JalviewJmolBinding implements StructureListener,
    */\r
   public SequenceI[][] sequence;\r
 \r
-  StructureSelectionManager ssm;\r
+  public StructureSelectionManager ssm;\r
 \r
   public JmolViewer viewer;\r
 \r
-  public JalviewJmolBinding(PDBEntry[] pdbentry, SequenceI[][] sequenceIs,\r
+  public JalviewJmolBinding(StructureSelectionManager ssm, PDBEntry[] pdbentry, SequenceI[][] sequenceIs,\r
           String[][] chains, String protocol)\r
   {\r
+    this.ssm = ssm;\r
     this.sequence = sequenceIs;\r
     this.chains = chains;\r
     this.pdbentry = pdbentry;\r
@@ -152,8 +162,9 @@ public abstract class JalviewJmolBinding implements StructureListener,
      */\r
   }\r
 \r
-  public JalviewJmolBinding(JmolViewer viewer2)\r
+  public JalviewJmolBinding(StructureSelectionManager ssm, JmolViewer viewer2)\r
   {\r
+    this.ssm = ssm;\r
     viewer = viewer2;\r
     viewer.setJmolStatusListener(this);\r
     viewer.addSelectionListener(this);\r
@@ -227,8 +238,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
   {\r
     viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE);\r
     // remove listeners for all structures in viewer\r
-    StructureSelectionManager.getStructureSelectionManager()\r
-            .removeStructureViewerListener(this, this.getPdbFile());\r
+    ssm.removeStructureViewerListener(this, this.getPdbFile());\r
     // and shut down jmol\r
     viewer.evalStringQuiet("zap");\r
     viewer.setJmolStatusListener(null);\r
@@ -347,7 +357,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
       for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)\r
       {\r
         StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);\r
-\r
+        // RACE CONDITION - getMapping only returns Jmol loaded filenames once Jmol callback has completed. \r
         if (mapping == null || mapping.length < 1)\r
           continue;\r
 \r
@@ -568,7 +578,8 @@ public abstract class JalviewJmolBinding implements StructureListener,
     }\r
     AlignmentI alignment = alignmentv.getAlignment();\r
 \r
-    for (String cbyseq : JmolCommands.getColourBySequenceCommand(ssm, files, sequence, sr, fr, alignment)) {\r
+    for (jalview.structure.StructureMappingcommandSet cpdbbyseq: JmolCommands.getColourBySequenceCommand(ssm, files, sequence, sr, fr, alignment))\r
+      for (String cbyseq : cpdbbyseq.commands) {\r
       evalStateCommand(cbyseq);\r
     }\r
   }\r
@@ -679,10 +690,17 @@ public abstract class JalviewJmolBinding implements StructureListener,
       String mset[] = new String[viewer.getModelCount()];\r
       _modelFileNameMap = new int[mset.length];\r
       int j = 1;\r
-      mset[0] = viewer.getModelFileName(0);\r
+      String m=viewer.getModelFileName(0);\r
+      if (m!=null)\r
+      {\r
+        mset[0] = new File(m).getAbsolutePath();\r
+      }\r
       for (int i = 1; i < mset.length; i++)\r
       {\r
-        mset[j] = viewer.getModelFileName(i);\r
+        m=viewer.getModelFileName(i);\r
+        if (m!=null) {\r
+          mset[j] = new File(m).getAbsolutePath();\r
+        }\r
         _modelFileNameMap[j] = i; // record the model index for the filename\r
         // skip any additional models in the same file (NMR structures)\r
         if ((mset[j] == null ? mset[j] != mset[j - 1]\r
@@ -858,8 +876,17 @@ public abstract class JalviewJmolBinding implements StructureListener,
       try\r
       {\r
         // recover PDB filename for the model hovered over.\r
-        pdbfilename = viewer\r
-                .getModelFileName(new Integer(mdlId).intValue() - 1);\r
+        int _mp=_modelFileNameMap.length-1,\r
+                mnumber=new Integer(mdlId).intValue() - 1;\r
+        while(mnumber<_modelFileNameMap[_mp])\r
+        {\r
+          _mp--;\r
+        }\r
+        pdbfilename = modelFileNames[_mp];\r
+        if (pdbfilename==null) {pdbfilename=new File(viewer\r
+                .getModelFileName(mnumber)).getAbsolutePath();\r
+        }\r
+        \r
       } catch (Exception e)\r
       {\r
       }\r
@@ -937,47 +964,48 @@ public abstract class JalviewJmolBinding implements StructureListener,
 \r
   }\r
 \r
-  public void notifyCallback(int type, Object[] data)\r
+  @Override\r
+  public void notifyCallback(EnumCallback type, Object[] data)\r
   {\r
     try\r
     {\r
       switch (type)\r
       {\r
-      case JmolConstants.CALLBACK_LOADSTRUCT:\r
+      case LOADSTRUCT:\r
         notifyFileLoaded((String) data[1], (String) data[2],\r
                 (String) data[3], (String) data[4],\r
                 ((Integer) data[5]).intValue());\r
 \r
         break;\r
-      case JmolConstants.CALLBACK_PICK:\r
+      case PICK:\r
         notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],\r
                 (String) data[0]);\r
         // also highlight in alignment\r
-      case JmolConstants.CALLBACK_HOVER:\r
+      case HOVER:\r
         notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],\r
                 (String) data[0]);\r
         break;\r
-      case JmolConstants.CALLBACK_SCRIPT:\r
+      case SCRIPT:\r
         notifyScriptTermination((String) data[2],\r
                 ((Integer) data[3]).intValue());\r
         break;\r
-      case JmolConstants.CALLBACK_ECHO:\r
+      case ECHO:\r
         sendConsoleEcho((String) data[1]);\r
         break;\r
-      case JmolConstants.CALLBACK_MESSAGE:\r
+      case MESSAGE:\r
         sendConsoleMessage((data == null) ? ((String) null)\r
                 : (String) data[1]);\r
         break;\r
-      case JmolConstants.CALLBACK_ERROR:\r
+      case ERROR:\r
         // System.err.println("Ignoring error callback.");\r
         break;\r
-      case JmolConstants.CALLBACK_SYNC:\r
-      case JmolConstants.CALLBACK_RESIZE:\r
+      case SYNC:\r
+      case RESIZE:\r
         refreshGUI();\r
         break;\r
-      case JmolConstants.CALLBACK_MEASURE:\r
+      case MEASURE:\r
 \r
-      case JmolConstants.CALLBACK_CLICK:\r
+      case CLICK:\r
       default:\r
         System.err.println("Unhandled callback " + type + " "\r
                 + data[1].toString());\r
@@ -990,24 +1018,25 @@ public abstract class JalviewJmolBinding implements StructureListener,
     }\r
   }\r
 \r
-  public boolean notifyEnabled(int callbackPick)\r
+  @Override\r
+  public boolean notifyEnabled(EnumCallback callbackPick)\r
   {\r
     switch (callbackPick)\r
     {\r
-    case JmolConstants.CALLBACK_ECHO:\r
-    case JmolConstants.CALLBACK_LOADSTRUCT:\r
-    case JmolConstants.CALLBACK_MEASURE:\r
-    case JmolConstants.CALLBACK_MESSAGE:\r
-    case JmolConstants.CALLBACK_PICK:\r
-    case JmolConstants.CALLBACK_SCRIPT:\r
-    case JmolConstants.CALLBACK_HOVER:\r
-    case JmolConstants.CALLBACK_ERROR:\r
+    case ECHO:\r
+    case LOADSTRUCT:\r
+    case MEASURE:\r
+    case MESSAGE:\r
+    case PICK:\r
+    case SCRIPT:\r
+    case HOVER:\r
+    case ERROR:\r
       return true;\r
-    case JmolConstants.CALLBACK_RESIZE:\r
-    case JmolConstants.CALLBACK_SYNC:\r
-    case JmolConstants.CALLBACK_CLICK:\r
-    case JmolConstants.CALLBACK_ANIMFRAME:\r
-    case JmolConstants.CALLBACK_MINIMIZATION:\r
+    case RESIZE:\r
+    case SYNC:\r
+    case CLICK:\r
+    case ANIMFRAME:\r
+    case MINIMIZATION:\r
     }\r
     return false;\r
   }\r
@@ -1044,7 +1073,6 @@ public abstract class JalviewJmolBinding implements StructureListener,
     chainFile = new Hashtable();\r
     boolean notifyLoaded = false;\r
     String[] modelfilenames = getPdbFile();\r
-    ssm = StructureSelectionManager.getStructureSelectionManager();\r
     // first check if we've lost any structures\r
     if (oldmodels != null && oldmodels.length > 0)\r
     {\r
@@ -1118,7 +1146,8 @@ public abstract class JalviewJmolBinding implements StructureListener,
           }\r
           else\r
           {\r
-            if (matches = pdbentry[pe].getFile().equals(fileName))\r
+            File fl;\r
+            if (matches = (fl=new File(pdbentry[pe].getFile())).equals(new File(fileName)))\r
             {\r
               foundEntry = true;\r
               // TODO: Jmol can in principle retrieve from CLASSLOADER but\r
@@ -1129,7 +1158,6 @@ public abstract class JalviewJmolBinding implements StructureListener,
               String protocol = AppletFormatAdapter.URL;\r
               try\r
               {\r
-                File fl = new java.io.File(pdbentry[pe].getFile());\r
                 if (fl.exists())\r
                 {\r
                   protocol = AppletFormatAdapter.FILE;\r
@@ -1139,21 +1167,21 @@ public abstract class JalviewJmolBinding implements StructureListener,
               } catch (Error e)\r
               {\r
               }\r
-              ;\r
+              //Explicitly map to the filename used by Jmol ;\r
               pdb = ssm.setMapping(sequence[pe], chains[pe],\r
-                      pdbentry[pe].getFile(), protocol);\r
+                      fileName, protocol);\r
+                      //pdbentry[pe].getFile(), protocol);\r
 \r
             }\r
           }\r
           if (matches)\r
           {\r
-            pdbentry[pe].setId(pdb.id);\r
             // add an entry for every chain in the model\r
             for (int i = 0; i < pdb.chains.size(); i++)\r
             {\r
               String chid = new String(pdb.id + ":"\r
                       + ((MCview.PDBChain) pdb.chains.elementAt(i)).id);\r
-              chainFile.put(chid, pdbentry[pe].getFile());\r
+              chainFile.put(chid, fileName);\r
               chainNames.addElement(chid);\r
             }\r
             notifyLoaded = true;\r
@@ -1532,4 +1560,19 @@ public abstract class JalviewJmolBinding implements StructureListener,
       chains[pe] = null;\r
     }\r
   }\r
+  /**\r
+   * \r
+   * @param pdbfile\r
+   * @return text report of alignment between pdbfile and any associated alignment sequences\r
+   */\r
+  public String printMapping(String pdbfile)\r
+  {\r
+    return ssm.printMapping(pdbfile);\r
+  }\r
+  @Override\r
+  public void resizeInnerPanel(String data)\r
+  {\r
+    // Jalview doesn't honour resize panel requests\r
+    \r
+  }\r
 }\r