X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fext%2Fedu%2Fucsf%2Frbvi%2Fstrucviz2%2FChimeraManager.java;h=668039bb55da8d604f53f7225218657b0c563984;hb=HEAD;hp=78103af26222ec609eac42577a83c7e14ada22cb;hpb=48144232e86777008fb78dd1233ebb0eb3cc34cb;p=jalview.git diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java index 78103af..668039b 100644 --- a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java +++ b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java @@ -32,14 +32,15 @@ */ package ext.edu.ucsf.rbvi.strucviz2; -import jalview.ws.HttpClientUtils; - import java.awt.Color; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; @@ -54,6 +55,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. @@ -175,10 +177,11 @@ public class ChimeraManager return hasChimeraModel(modelNubmer, 0); } - public boolean hasChimeraModel(Integer modelNubmer, Integer subModelNumber) + public boolean hasChimeraModel(Integer modelNubmer, + Integer subModelNumber) { - return currentModelsMap.containsKey(ChimUtils.makeModelKey(modelNubmer, - subModelNumber)); + return currentModelsMap.containsKey( + ChimUtils.makeModelKey(modelNubmer, subModelNumber)); } public void addChimeraModel(Integer modelNumber, Integer subModelNumber, @@ -188,7 +191,8 @@ public class ChimeraManager ChimUtils.makeModelKey(modelNumber, subModelNumber), model); } - public void removeChimeraModel(Integer modelNumber, Integer subModelNumber) + public void removeChimeraModel(Integer modelNumber, + Integer subModelNumber) { int modelKey = ChimUtils.makeModelKey(modelNumber, subModelNumber); if (currentModelsMap.containsKey(modelKey)) @@ -243,9 +247,8 @@ public class ChimeraManager if (!modelList.contains(newModel)) { newModel.setModelName(modelName); - sendChimeraCommand( - "setattr M name " + modelName + " #" - + newModel.getModelNumber(), false); + sendChimeraCommand("setattr M name " + modelName + " #" + + newModel.getModelNumber(), false); modelList.add(newModel); } } @@ -315,8 +318,8 @@ public class ChimeraManager { sendChimeraCommand("close " + model.toSpec(), false); // currentModelNamesMap.remove(model.getModelName()); - currentModelsMap.remove(ChimUtils.makeModelKey( - model.getModelNumber(), model.getSubModelNumber())); + currentModelsMap.remove(ChimUtils.makeModelKey(model.getModelNumber(), + model.getSubModelNumber())); // selectionList.remove(chimeraModel); } else @@ -329,15 +332,13 @@ public class ChimeraManager public void startListening() { - sendChimeraCommand("listen start models; listen start selection", false); + sendChimeraCommand("listen start models; listen start selection", + false); } public void stopListening() { - // 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 "; + String command = "listen stop models ; listen stop selection "; sendChimeraCommand(command, false); } @@ -351,19 +352,13 @@ public class ChimeraManager /* * listen for model changes */ - String command = isChimeraX - ? ("info notify start models prefix ModelChanged jalview url " - + uri) - : ("listen start models url " + uri); + String command = "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); + command = "listen start select prefix SelectionChanged url " + uri; sendChimeraCommand(command, false); } @@ -439,18 +434,7 @@ public class ChimeraManager { List selectedResidues = new ArrayList<>(); - /* - * 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"); + String command = "list selection level residue"; List chimeraReply = sendChimeraCommand(command, true); if (chimeraReply != null) { @@ -507,7 +491,7 @@ public class ChimeraManager { List modelList = new ArrayList<>(); String command = "list models type " - + (isChimeraX ? "AtomicStructure" : "molecule"); + + (isChimeraX() ? "AtomicStructure" : "molecule"); List list = sendChimeraCommand(command, true); if (list != null) { @@ -595,7 +579,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"); @@ -608,16 +591,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 = ""; @@ -633,8 +607,8 @@ public class ChimeraManager if (error.length() == 0) { this.chimeraRestPort = getPortNumber(); - System.out.println("Chimera REST API started on port " - + chimeraRestPort); + System.out.println( + "Chimera REST API started on port " + chimeraRestPort); // structureManager.initChimTable(); structureManager.setChimeraPathProperty(workingPath); // TODO: [Optional] Check Chimera version and show a warning if below 1.8 @@ -649,14 +623,27 @@ public class ChimeraManager } /** + * Adds command-line arguments to start the REST server + *

+ * Method extracted for Jalview to allow override in ChimeraXManager + * + * @param args + */ + protected void addLaunchArguments(List args) + { + args.add("--start"); + args.add("RESTServer"); + } + + /** * Read and return the port number returned in the reply to --start RESTServer */ private int getPortNumber() { int port = 0; InputStream readChan = chimera.getInputStream(); - BufferedReader lineReader = new BufferedReader(new InputStreamReader( - readChan)); + BufferedReader lineReader = new BufferedReader( + new InputStreamReader(readChan)); StringBuilder responses = new StringBuilder(); try { @@ -686,8 +673,8 @@ public class ChimeraManager } } catch (Exception e) { - logger.error("Failed to get REST port number from " + responses - + ": " + e.getMessage()); + logger.error("Failed to get REST port number from " + responses + ": " + + e.getMessage()); } finally { try @@ -699,11 +686,12 @@ public class ChimeraManager } if (port == 0) { - System.err - .println("Failed to start Chimera with REST service, response was: " + System.err.println( + "Failed to start Chimera with REST service, response was: " + responses); } - logger.info("Chimera REST service listening on port " + chimeraRestPort); + logger.info( + "Chimera REST service listening on port " + chimeraRestPort); return port; } @@ -760,7 +748,7 @@ public class ChimeraManager public List getAttrList() { List attributes = new ArrayList<>(); - String command = (isChimeraX ? "info " : "list") + "resattr"; + String command = (isChimeraX() ? "info " : "list ") + "resattr"; final List reply = sendChimeraCommand(command, true); if (reply != null) { @@ -789,8 +777,8 @@ public class ChimeraManager String[] lineParts = inputLine.split("\\s"); if (lineParts.length == 5) { - ChimeraResidue residue = ChimUtils - .getResidue(lineParts[2], model); + ChimeraResidue residue = ChimUtils.getResidue(lineParts[2], + model); String value = lineParts[4]; if (residue != null) { @@ -820,8 +808,6 @@ public class ChimeraManager private volatile boolean busy = false; - private boolean isChimeraX; - /** * Send a command to Chimera. * @@ -835,18 +821,27 @@ public class ChimeraManager */ public List sendChimeraCommand(String command, boolean reply) { - System.out.println("chimeradebug>> " + command); + if (debug) + { + System.out.println("chimeradebug>> " + command); + } if (!isChimeraLaunched() || command == null || "".equals(command.trim())) { return null; } - // TODO do we need a maximum wait time before aborting? - while (busy) + /* + * set a maximum wait time before trying anyway + * to avoid hanging indefinitely + */ + int waited = 0; + int pause = 25; + while (busy && waited < 1001) { try { - Thread.sleep(25); + Thread.sleep(pause); + waited += pause; } catch (InterruptedException q) { } @@ -868,7 +863,6 @@ public class ChimeraManager + (System.currentTimeMillis() - startTime) + "ms: " + command); } - } } @@ -882,11 +876,18 @@ public class ChimeraManager { String restUrl = "http://127.0.0.1:" + this.chimeraRestPort + "/run"; List commands = new ArrayList<>(1); - String method = isChimeraX() ? "GET" : "POST"; + String method = getHttpRequestMethod(); if ("GET".equals(method)) { - command = command.replace(" ", "+").replace("#", "%23") - .replace("|", "%7C").replace(";", "%3B"); + try + { + command = URLEncoder.encode(command, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) + { + command = command.replace(" ", "+").replace("#", "%23") + .replace("|", "%7C").replace(";", "%3B") + .replace(":", "%3A"); + } } commands.add(new BasicNameValuePair("command", command)); @@ -923,6 +924,17 @@ 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. * @@ -973,11 +985,6 @@ public class ChimeraManager public boolean isChimeraX() { - return isChimeraX; - } - - public void setChimeraX(boolean b) - { - isChimeraX = b; + return false; } }