1 package jalview.ext.rbvi.chimera;
3 import java.net.BindException;
5 import javax.servlet.http.HttpServletRequest;
6 import javax.servlet.http.HttpServletResponse;
8 import jalview.httpserver.AbstractRequestHandler;
9 import jalview.httpserver.HttpServer;
10 import jalview.structure.SelectionSource;
13 * This is a simple Http handler that can listen for selections in Chimera.
17 * <li>Start the Chimera process</li>
18 * <li>Start the REST service on Chimera, get the port number it is listening on
20 * <li>Start the ChimeraListener, get the URL it is listening on</li>
21 * <li>The first listener started will start the singleton HttpServer</li>
22 * <li>Send a 'listen' command to Chimera with the URL of the listener</li>
23 * <li>When Jalview's Chimera window is closed, shut down the ChimeraListener</li>
24 * <li>Multiple linked Chimera instances will each have a separate listener (but
25 * share one Http server)</li>
31 public class ChimeraListener extends AbstractRequestHandler implements
34 private static final String CHIMERA_NOTIFICATION = "chimeraNotification";
36 private static final String MODEL_CHANGED = "ModelChanged: ";
38 private static final String SELECTION_CHANGED = "SelectionChanged: selection changed\n";
41 * A static counter so each listener can be associated with a distinct context
42 * root (/chimera0,1,2,3...). This is needed so we can fetch selections from
43 * multiple Chimera instances without confusion.
45 private static int chimeraId = 0;
48 * Path below context root that identifies this handler
50 private static final String LISTENER_PATH = "chimera";
53 * Value of chimeraId (0, 1, 2...) for this instance
55 private int myChimeraId = 0;
58 * A reference to the object by which we can talk to Chimera
60 private JalviewChimeraBinding chimeraBinding;
63 * The URI of this listener
68 * Constructor that also registers this as an Http request handler on path
69 * /chimeraN, where N is incremented for each instance. Call getUri to get the
70 * resulting URI for this handler.
72 * @param chimeraBinding
73 * @throws BindException
74 * if no free port can be assigned
76 public ChimeraListener(JalviewChimeraBinding binding)
79 myChimeraId = chimeraId++;
80 this.chimeraBinding = binding;
81 final String path = LISTENER_PATH + myChimeraId;
82 this.uri = HttpServer.getInstance().registerHandler(path, this);
86 * Returns the URI on which we are listening
90 public String getUri()
96 * Process a message from Chimera
99 protected void processRequest(HttpServletRequest request,
100 HttpServletResponse response)
102 // dumpRequest(request);
103 String message = request.getParameter(CHIMERA_NOTIFICATION);
104 if (SELECTION_CHANGED.equals(message))
106 this.chimeraBinding.highlightChimeraSelection();
108 else if (message != null && message.startsWith(MODEL_CHANGED))
110 processModelChanged(message.substring(MODEL_CHANGED.length()));
114 System.err.println("Unexpected chimeraNotification: " + message);
119 * Handler a ModelChanged notification from Chimera
123 protected void processModelChanged(String message)
125 // System.out.println(message + " (not implemented in Jalview)");
129 * Deregister this listener and close it down
133 public void shutdown()
137 HttpServer.getInstance().removeHandler(this);
139 } catch (Exception e)
141 System.err.println("Error stopping chimera listener: "