JAL-3672 debug=false means no debug output
[jalview.git] / src / ext / edu / ucsf / rbvi / strucviz2 / ChimeraManager.java
index a322f0b..375fa4a 100644 (file)
@@ -32,8 +32,6 @@
  */
 package ext.edu.ucsf.rbvi.strucviz2;
 
-import jalview.ws.HttpClientUtils;
-
 import java.awt.Color;
 import java.io.BufferedReader;
 import java.io.File;
@@ -54,6 +52,7 @@ import org.slf4j.LoggerFactory;
 
 import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
 import ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads;
+import jalview.ws.HttpClientUtils;
 
 /**
  * This object maintains the Chimera communication information.
@@ -334,7 +333,8 @@ public class ChimeraManager
 
   public void stopListening()
   {
-    sendChimeraCommand("listen stop models ; listen stop selection ", false);
+    String command = "listen stop models ; listen stop selection ";
+    sendChimeraCommand(command, false);
   }
 
   /**
@@ -344,9 +344,17 @@ public class ChimeraManager
    */
   public void startListening(String uri)
   {
-    sendChimeraCommand("listen start models url " + uri
-            + ";listen start select prefix SelectionChanged url " + uri,
-            false);
+    /*
+     * listen for model changes
+     */
+    String command = "listen start models url " + uri;
+    sendChimeraCommand(command, false);
+
+    /*
+     * listen for selection changes
+     */
+    command = "listen start select prefix SelectionChanged url " + uri;
+    sendChimeraCommand(command, false);
   }
 
   /**
@@ -420,19 +428,23 @@ public class ChimeraManager
   public List<String> getSelectedResidueSpecs()
   {
     List<String> selectedResidues = new ArrayList<>();
-    List<String> chimeraReply = sendChimeraCommand(
-            "list selection level residue", true);
+
+    String command = "list selection level residue";
+    List<String> chimeraReply = sendChimeraCommand(command, true);
     if (chimeraReply != null)
     {
       /*
-       * expect 0, 1 or more lines of the format
+       * expect 0, 1 or more lines of the format either
+       * Chimera:
        * residue id #0:43.A type GLY
-       * where we are only interested in the atomspec #0.43.A
+       * ChimeraX:
+       * residue id /A:89 name THR index 88
+       * We are only interested in the atomspec (third token of the reply)
        */
       for (String inputLine : chimeraReply)
       {
         String[] inputLineParts = inputLine.split("\\s+");
-        if (inputLineParts.length == 5)
+        if (inputLineParts.length >= 5)
         {
           selectedResidues.add(inputLineParts[2]);
         }
@@ -473,19 +485,24 @@ public class ChimeraManager
   public List<ChimeraModel> getModelList()
   {
     List<ChimeraModel> modelList = new ArrayList<>();
-    modelList.add(new ChimeraModel("4zhp", ModelType.PDB_MODEL, 1, 0));
-    return modelList; // ChimeraX doesn't have 'list models' command
-    // List<String> list = sendChimeraCommand("list models type molecule",
-    // true);
-    // if (list != null)
-    // {
-    // for (String modelLine : list)
-    // {
-    // ChimeraModel chimeraModel = new ChimeraModel(modelLine);
-    // modelList.add(chimeraModel);
-    // }
-    // }
-    // return modelList;
+    String command = "list models type "
+            + (isChimeraX() ? "AtomicStructure" : "molecule");
+    List<String> list = sendChimeraCommand(command, true);
+    if (list != null)
+    {
+      for (String modelLine : list)
+      {
+        try
+        {
+          ChimeraModel chimeraModel = new ChimeraModel(modelLine);
+          modelList.add(chimeraModel);
+        } catch (NullPointerException e)
+        {
+          // hack for now
+        }
+      }
+    }
+    return modelList;
   }
 
   /**
@@ -557,7 +574,6 @@ public class ChimeraManager
       {
         // ensure symbolic links are resolved
         chimeraPath = Paths.get(chimeraPath).toRealPath().toString();
-        isChimeraX = chimeraPath.toLowerCase().contains("chimerax");
         File path = new File(chimeraPath);
         // uncomment the next line to simulate Chimera not installed
         // path = new File(chimeraPath + "x");
@@ -570,16 +586,7 @@ public class ChimeraManager
         args.add(chimeraPath);
         // shows Chimera output window but suppresses REST responses:
         // args.add("--debug");
-        if (isChimeraX())
-        {
-          args.add("--cmd");
-          args.add("remote rest start");
-        }
-        else
-        {
-          args.add("--start");
-          args.add("RESTServer");
-        }
+        addLaunchArguments(args);
         ProcessBuilder pb = new ProcessBuilder(args);
         chimera = pb.start();
         error = "";
@@ -611,6 +618,18 @@ public class ChimeraManager
   }
 
   /**
+   * Adds command-line arguments to start the REST server
+   * <p>
+   * Method extracted for Jalview to allow override in ChimeraXManager
+   * @param args
+   */
+  protected void addLaunchArguments(List<String> args)
+  {
+    args.add("--start");
+    args.add("RESTServer");
+  }
+
+  /**
    * Read and return the port number returned in the reply to --start RESTServer
    */
   private int getPortNumber()
@@ -722,7 +741,8 @@ public class ChimeraManager
   public List<String> getAttrList()
   {
     List<String> attributes = new ArrayList<>();
-    final List<String> reply = sendChimeraCommand("list resattr", true);
+    String command = (isChimeraX() ? "info " : "list ") + "resattr";
+    final List<String> reply = sendChimeraCommand(command, true);
     if (reply != null)
     {
       for (String inputLine : reply)
@@ -781,8 +801,6 @@ public class ChimeraManager
 
   private volatile boolean busy = false;
 
-  private boolean isChimeraX;
-
   /**
    * Send a command to Chimera.
    * 
@@ -796,7 +814,9 @@ public class ChimeraManager
    */
   public List<String> sendChimeraCommand(String command, boolean reply)
   {
-    System.out.println("chimeradebug>> " + command);
+    if (debug) {
+      System.out.println("chimeradebug>> " + command);
+    }
     if (!isChimeraLaunched() || command == null
             || "".equals(command.trim()))
     {
@@ -843,24 +863,23 @@ public class ChimeraManager
   {
     String restUrl = "http://127.0.0.1:" + this.chimeraRestPort + "/run";
     List<NameValuePair> commands = new ArrayList<>(1);
-    String encoded = command.replace(" ", "+").replace("#", "%23")
-            .replace("|", "%7C").replace(";", "%3B");
-    commands.add(new BasicNameValuePair("command", encoded));
+    String method = getHttpRequestMethod();
+    if ("GET".equals(method))
+    {
+      command = command.replace(" ", "+").replace("#", "%23")
+              .replace("|", "%7C").replace(";", "%3B");
+    }
+    commands.add(new BasicNameValuePair("command", command));
 
     List<String> reply = new ArrayList<>();
     BufferedReader response = null;
     try
     {
-      if (isChimeraX())
-      {
-        response = HttpClientUtils.doHttpGet(restUrl, commands,
-                CONNECTION_TIMEOUT_MS, REST_REPLY_TIMEOUT_MS);
-      }
-      else
-      {
-        response = HttpClientUtils.doHttpUrlPost(restUrl, commands,
-                CONNECTION_TIMEOUT_MS, REST_REPLY_TIMEOUT_MS);
-      }
+      response = "GET".equals(method)
+              ? HttpClientUtils.doHttpGet(restUrl, commands,
+                      CONNECTION_TIMEOUT_MS, REST_REPLY_TIMEOUT_MS)
+              : HttpClientUtils.doHttpUrlPost(restUrl, commands,
+                      CONNECTION_TIMEOUT_MS, REST_REPLY_TIMEOUT_MS);
       String line = "";
       while ((line = response.readLine()) != null)
       {
@@ -885,6 +904,15 @@ public class ChimeraManager
   }
 
   /**
+   * Returns "POST" as the HTTP request method to use for REST service calls to Chimera
+   * @return
+   */
+  protected String getHttpRequestMethod()
+  {
+    return "POST";
+  }
+
+  /**
    * Send a command to stdin of Chimera process, and optionally read any
    * responses.
    * 
@@ -935,6 +963,6 @@ public class ChimeraManager
 
   public boolean isChimeraX()
   {
-    return isChimeraX;
+    return false;
   }
 }