*/
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;
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.
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,
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))
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);
}
}
{
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
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);
}
/*
* 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);
}
{
List<String> 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
- ? "info"
- : "list") + " selection level residue";
+ String command = "list selection level residue";
List<String> chimeraReply = sendChimeraCommand(command, true);
if (chimeraReply != null)
{
{
List<ChimeraModel> modelList = new ArrayList<>();
String command = "list models type "
- + (isChimeraX ? "AtomicStructure" : "molecule");
+ + (isChimeraX() ? "AtomicStructure" : "molecule");
List<String> list = sendChimeraCommand(command, true);
if (list != null)
{
{
// 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");
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 = "";
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
}
/**
+ * 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()
{
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
{
}
} 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
}
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;
}
public List<String> getAttrList()
{
List<String> attributes = new ArrayList<>();
- String command = (isChimeraX ? "info " : "list ") + "resattr";
+ String command = (isChimeraX() ? "info " : "list ") + "resattr";
final List<String> reply = sendChimeraCommand(command, true);
if (reply != null)
{
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)
{
private volatile boolean busy = false;
- private boolean isChimeraX;
-
/**
* Send a command to Chimera.
*
*/
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()))
{
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)
{
}
+ (System.currentTimeMillis() - startTime) + "ms: "
+ command);
}
-
}
}
{
String restUrl = "http://127.0.0.1:" + this.chimeraRestPort + "/run";
List<NameValuePair> 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));
}
/**
+ * 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.
*
public boolean isChimeraX()
{
- return isChimeraX;
- }
-
- public void setChimeraX(boolean b)
- {
- isChimeraX = b;
+ return false;
}
}