JAL-2422 fixed stopProgressBar (broken in pull up refactoring)
[jalview.git] / src / ext / edu / ucsf / rbvi / strucviz2 / ChimeraManager.java
index a910a5a..78103af 100644 (file)
@@ -254,7 +254,7 @@ public class ChimeraManager
     for (ChimeraModel chimeraModel : modelList)
     {
       // get model color
-      Color modelColor = getModelColor(chimeraModel);
+      Color modelColor = isChimeraX() ? null : getModelColor(chimeraModel);
       if (modelColor != null)
       {
         chimeraModel.setModelColor(modelColor);
@@ -265,7 +265,7 @@ public class ChimeraManager
       // chimeraSend("repr stick "+newModel.toSpec());
 
       // Create the information we need for the navigator
-      if (type != ModelType.SMILES)
+      if (type != ModelType.SMILES && !isChimeraX())
       {
         addResidues(chimeraModel);
       }
@@ -334,7 +334,11 @@ public class ChimeraManager
 
   public void stopListening()
   {
-    sendChimeraCommand("listen stop models ; listen stop selection ", false);
+    // TODO send this command when viewer connection is closed in Jalview
+    String command = isChimeraX
+            ? "info notify stop models jalview; info notify stop selection jalview"
+            : "listen stop models ; listen stop selection ";
+    sendChimeraCommand(command, false);
   }
 
   /**
@@ -344,9 +348,23 @@ 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 = isChimeraX
+            ? ("info notify start models prefix ModelChanged jalview url "
+                    + uri)
+            : ("listen start models url " + uri);
+    sendChimeraCommand(command, false);
+
+    /*
+     * listen for selection changes
+     */
+    command = isChimeraX
+            ? ("info notify start selection jalview prefix SelectionChanged url "
+                    + uri)
+            : ("listen start select prefix SelectionChanged url " + uri);
+    sendChimeraCommand(command, false);
   }
 
   /**
@@ -420,19 +438,34 @@ public class ChimeraManager
   public List<String> getSelectedResidueSpecs()
   {
     List<String> selectedResidues = new ArrayList<>();
-    List<String> chimeraReply = sendChimeraCommand(
-            "list selection level residue", true);
+
+    /*
+     * skip for now if ChimeraX - request times out
+     */
+    if (isChimeraX)
+    {
+      // return selectedResidues;
+    }
+
+    // in fact 'listinfo' (undocumented) works in ChimeraX
+    String command = (isChimeraX
+            ? "wait 1; view" /*"info selection level residue" */
+            : "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,14 +506,21 @@ public class ChimeraManager
   public List<ChimeraModel> getModelList()
   {
     List<ChimeraModel> modelList = new ArrayList<>();
-    List<String> list = sendChimeraCommand("list models type molecule",
-            true);
+    String command = "list models type "
+            + (isChimeraX ? "AtomicStructure" : "molecule");
+    List<String> list = sendChimeraCommand(command, true);
     if (list != null)
     {
       for (String modelLine : list)
       {
-        ChimeraModel chimeraModel = new ChimeraModel(modelLine);
-        modelList.add(chimeraModel);
+        try
+        {
+          ChimeraModel chimeraModel = new ChimeraModel(modelLine);
+          modelList.add(chimeraModel);
+        } catch (NullPointerException e)
+        {
+          // hack for now
+        }
       }
     }
     return modelList;
@@ -555,6 +595,7 @@ 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");
@@ -567,8 +608,16 @@ public class ChimeraManager
         args.add(chimeraPath);
         // shows Chimera output window but suppresses REST responses:
         // args.add("--debug");
-        args.add("--start");
-        args.add("RESTServer");
+        if (isChimeraX())
+        {
+          args.add("--cmd");
+          args.add("remote rest start");
+        }
+        else
+        {
+          args.add("--start");
+          args.add("RESTServer");
+        }
         ProcessBuilder pb = new ProcessBuilder(args);
         chimera = pb.start();
         error = "";
@@ -616,15 +665,23 @@ public class ChimeraManager
       {
         responses.append("\n" + response);
         // expect: REST server on host 127.0.0.1 port port_number
+        // ChimeraX is the same except "REST server started on host..."
         if (response.startsWith("REST server"))
         {
           String[] tokens = response.split(" ");
-          if (tokens.length == 7 && "port".equals(tokens[5]))
+          for (int i = 0; i < tokens.length - 1; i++)
           {
-            port = Integer.parseInt(tokens[6]);
-            break;
+            if ("port".equals(tokens[i]))
+            {
+              port = Integer.parseInt(tokens[i + 1]);
+              break;
+            }
           }
         }
+        if (port > 0)
+        {
+          break; // hack for hanging readLine()
+        }
         response = lineReader.readLine();
       }
     } catch (Exception e)
@@ -703,7 +760,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)
@@ -762,6 +820,8 @@ public class ChimeraManager
 
   private volatile boolean busy = false;
 
+  private boolean isChimeraX;
+
   /**
    * Send a command to Chimera.
    * 
@@ -775,7 +835,7 @@ public class ChimeraManager
    */
   public List<String> sendChimeraCommand(String command, boolean reply)
   {
-   // System.out.println("chimeradebug>> " + command);
+    System.out.println("chimeradebug>> " + command);
     if (!isChimeraLaunched() || command == null
             || "".equals(command.trim()))
     {
@@ -822,14 +882,23 @@ public class ChimeraManager
   {
     String restUrl = "http://127.0.0.1:" + this.chimeraRestPort + "/run";
     List<NameValuePair> commands = new ArrayList<>(1);
+    String method = isChimeraX() ? "GET" : "POST";
+    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
     {
-      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)
       {
@@ -901,4 +970,14 @@ public class ChimeraManager
   {
     return chimera;
   }
+
+  public boolean isChimeraX()
+  {
+    return isChimeraX;
+  }
+
+  public void setChimeraX(boolean b)
+  {
+    isChimeraX = b;
+  }
 }