JAL-3190 rough Proof of Concept of JalviewJS - Chimera feature/JAL-3190jalviewjsChimera
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 31 Jan 2019 16:42:28 +0000 (16:42 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 31 Jan 2019 16:42:28 +0000 (16:42 +0000)
src/ext/edu/ucsf/rbvi/strucviz2/ChimUtils.java
src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java
src/ext/edu/ucsf/rbvi/strucviz2/Logger.java [new file with mode: 0644]
src/ext/edu/ucsf/rbvi/strucviz2/StructureManager.java
src/ext/edu/ucsf/rbvi/strucviz2/port/ListenerThreads.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/Preferences.java
src/jalview/jbgui/GPreferences.java

index 1d57a31..819c83a 100644 (file)
@@ -38,15 +38,15 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
 
 import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
 
 public abstract class ChimUtils
 {
 
-  private static Logger logger = LoggerFactory.getLogger(ChimUtils.class);
+  private static Logger logger = new Logger();//LoggerFactory.getLogger(ChimUtils.class);
 
   static int MAX_SUB_MODELS = 1000;
 
index a910a5a..d23f41a 100644 (file)
@@ -32,6 +32,7 @@
  */
 package ext.edu.ucsf.rbvi.strucviz2;
 
+import jalview.util.Platform;
 import jalview.ws.HttpClientUtils;
 
 import java.awt.Color;
@@ -40,6 +41,9 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -47,10 +51,12 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.ws.rs.HttpMethod;
+
 import org.apache.http.NameValuePair;
 import org.apache.http.message.BasicNameValuePair;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
 
 import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
 import ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads;
@@ -66,6 +72,12 @@ public class ChimeraManager
 
   private static final boolean debug = false;
 
+  /*
+   * this has to be set to the port number of the REST server
+   * currently being run by Chimera
+   */
+  private int jsPortNo = 51940;
+  
   private int chimeraRestPort;
 
   private Process chimera;
@@ -74,8 +86,8 @@ public class ChimeraManager
 
   private Map<Integer, ChimeraModel> currentModelsMap;
 
-  private Logger logger = LoggerFactory
-          .getLogger(ext.edu.ucsf.rbvi.strucviz2.ChimeraManager.class);
+  private Logger logger = new Logger(); 
+                 //LoggerFactory.getLogger(ext.edu.ucsf.rbvi.strucviz2.ChimeraManager.class);
 
   private StructureManager structureManager;
 
@@ -213,26 +225,28 @@ public class ChimeraManager
   public List<ChimeraModel> openModel(String modelPath, String modelName,
           ModelType type)
   {
-    logger.info("chimera open " + modelPath);
+         String toOpen = Platform.isJS() ? "cifID:" + modelName : modelPath;
+         
+    logger.info("chimera open " + toOpen);
     // stopListening();
     List<ChimeraModel> modelList = getModelList();
     List<String> response = null;
     // TODO: [Optional] Handle modbase models
     if (type == ModelType.MODBASE_MODEL)
     {
-      response = sendChimeraCommand("open modbase:" + modelPath, true);
+      response = sendChimeraCommand("open modbase:" + toOpen, true);
       // } else if (type == ModelType.SMILES) {
       // response = sendChimeraCommand("open smiles:" + modelName, true);
       // modelName = "smiles:" + modelName;
     }
     else
     {
-      response = sendChimeraCommand("open " + modelPath, true);
+      response = sendChimeraCommand("open " + toOpen, true);
     }
     if (response == null)
     {
       // something went wrong
-      logger.warn("Could not open " + modelPath);
+      logger.warn("Could not open " + toOpen);
       return null;
     }
 
@@ -475,6 +489,10 @@ public class ChimeraManager
     List<ChimeraModel> modelList = new ArrayList<>();
     List<String> list = sendChimeraCommand("list models type molecule",
             true);
+    if (Platform.isJS()) 
+    {
+       list.add("model id #0 type Molecule name foo");
+    }
     if (list != null)
     {
       for (String modelLine : list)
@@ -513,6 +531,11 @@ public class ChimeraManager
 
   public boolean isChimeraLaunched()
   {
+         if (Platform.isJS())
+         {
+        this.chimeraRestPort = jsPortNo;
+           return true;
+         }
     boolean launched = false;
     if (chimera != null)
     {
@@ -539,12 +562,19 @@ public class ChimeraManager
    */
   public boolean launchChimera(List<String> chimeraPaths)
   {
+           if (Platform.isJS()) 
+           {
+               // Chimera: run Utilities | REST server
+               // and read port number off reply log, set as jsPortNo
+               this.chimeraRestPort = jsPortNo; 
+               return true;
+           }
     // Do nothing if Chimera is already launched
     if (isChimeraLaunched())
     {
       return true;
     }
-
+    
     // Try to launch Chimera (eventually using one of the possible paths)
     String error = "Error message: ";
     String workingPath = "";
@@ -820,6 +850,11 @@ public class ChimeraManager
    */
   protected List<String> sendRestCommand(String command)
   {
+         if (Platform.isJS()) 
+         {
+                 return sendRestCommandForJS(command);
+         }
+         
     String restUrl = "http://127.0.0.1:" + this.chimeraRestPort + "/run";
     List<NameValuePair> commands = new ArrayList<>(1);
     commands.add(new BasicNameValuePair("command", command));
@@ -854,6 +889,51 @@ public class ChimeraManager
   }
 
   /**
+   * Alternative that uses java.net not apache http client
+   * @param command
+   * @return
+   */
+  protected List<String> sendRestCommandForJS(String command) 
+  {
+    List<String> reply = new ArrayList<>();
+    BufferedReader response = null;
+    try
+       {
+       String encoded = URLEncoder.encode(command, "UTF-8");
+               URL url = new URL("http://127.0.0.1:" + this.chimeraRestPort + "/run?command="+encoded);
+               HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+               connection.setRequestMethod(HttpMethod.GET);
+               connection.setDoInput(true);
+               InputStream is = connection.getInputStream();
+               //      JalviewJS can't read response without access-control-allow-origin * header
+               if (!Platform.isJS())
+               {
+                       response = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+                       String line = "";
+                       while ((line = response.readLine()) != null) 
+                       {
+                                       reply.add(line);
+                       }
+               }
+       } catch (Exception e)
+    {
+      logger.error("REST call '" + command + "' failed: " + e.getMessage());
+    } finally
+    {
+      if (response != null)
+      {
+        try
+        {
+          response.close();
+        } catch (IOException e)
+        {
+        }
+      }
+    }
+    return reply;
+  }
+
+  /**
    * Send a command to stdin of Chimera process, and optionally read any
    * responses.
    * 
diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/Logger.java b/src/ext/edu/ucsf/rbvi/strucviz2/Logger.java
new file mode 100644 (file)
index 0000000..8c56064
--- /dev/null
@@ -0,0 +1,27 @@
+package ext.edu.ucsf.rbvi.strucviz2;
+
+import java.io.IOException;
+
+public class Logger {
+
+       public void error(String string, IOException ioe) {
+               System.out.println("Error: " + string + " " + ioe.toString());
+       }
+
+       public void warn(String string, Exception ex) {
+               System.out.println("Warn: " + string + " " + ex.toString());
+       }
+
+       public void info(String string) {
+               System.out.println("Info: " + string);
+       }
+
+       public void warn(String string) {
+               System.out.println("Warn: " + string);
+       }
+
+       public void error(String string) {
+               System.out.println("Error: " + string );
+       }
+
+}
index 09a9713..b71f6fa 100644 (file)
@@ -46,8 +46,8 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
 
 /**
  * This object maintains the relationship between Chimera objects and Cytoscape
@@ -89,8 +89,9 @@ public class StructureManager
 
   private File configurationDirectory = null;
 
-  private static Logger logger = LoggerFactory
-          .getLogger(ext.edu.ucsf.rbvi.strucviz2.StructureManager.class);
+  private static Logger logger = new Logger();
+//  = LoggerFactory
+//          .getLogger(ext.edu.ucsf.rbvi.strucviz2.StructureManager.class);
 
   public StructureManager(boolean haveGUI)
   {
index 379097c..b08a919 100644 (file)
@@ -41,8 +41,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import ext.edu.ucsf.rbvi.strucviz2.Logger;
+
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
 
 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
 
@@ -61,7 +63,7 @@ public class ListenerThreads extends Thread
 
   private Map<String, List<String>> replyLog = null;
 
-  private Logger logger;
+  private Logger logger = new Logger();
 
   private StructureManager structureManager = null;
 
@@ -83,8 +85,8 @@ public class ListenerThreads extends Thread
     // Get a line-oriented reader
     InputStream readChan = chimera.getInputStream();
     lineReader = new BufferedReader(new InputStreamReader(readChan));
-    logger = LoggerFactory
-            .getLogger(ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads.class);
+    logger =new Logger();
+    //LoggerFactory.getLogger(ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads.class);
   }
 
   /**
index 00446f2..12f3752 100644 (file)
@@ -40,6 +40,7 @@ import jalview.structure.StructureMappingcommandSet;
 import jalview.structure.StructureSelectionManager;
 import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 
 import java.awt.Color;
 import java.io.File;
@@ -599,7 +600,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
     boolean launched = viewer
             .launchChimera(StructureManager.getChimeraPaths());
-    if (launched)
+    if (launched && !Platform.isJS())
     {
       startChimeraProcessMonitor();
     }
index 9167c00..8392606 100644 (file)
@@ -354,7 +354,10 @@ public class ChimeraViewFrame extends StructureViewerBase
       }
     }
 
-    jmb.startChimeraListener();
+    if (!Platform.isJS())
+    {
+       jmb.startChimeraListener();
+    }
   }
 
   /**
index 35641f8..5b84594 100755 (executable)
@@ -1200,7 +1200,7 @@ public class Preferences extends GPreferences
   @Override
   protected void structureViewer_actionPerformed(String selectedItem)
   {
-    if (!selectedItem.equals(ViewerType.CHIMERA.name()))
+    if (!selectedItem.equals(ViewerType.CHIMERA.name()) || Platform.isJS())
     {
       return;
     }
index 1e01cc3..94698b9 100755 (executable)
@@ -1293,8 +1293,8 @@ public class GPreferences extends JPanel
     {
       pathLabel.setVisible(false);
       chimeraPath.setVisible(false);
-      viewerLabel.setVisible(false);
-      structViewer.setVisible(false);
+//      viewerLabel.setVisible(false);
+//      structViewer.setVisible(false);
     }
     
     return structureTab;