6 import jalview.bin.Cache;
7 import jalview.datamodel.SequenceI;
8 import jalview.io.VamsasAppDatastore;
9 import jalview.structure.StructureSelectionManager;
10 import jalview.structure.VamsasListener;
12 import java.beans.PropertyChangeEvent;
13 import java.beans.PropertyChangeListener;
15 import java.io.IOException;
16 import java.util.Hashtable;
17 import java.util.IdentityHashMap;
19 import javax.swing.JInternalFrame;
20 import javax.swing.JOptionPane;
22 import uk.ac.vamsas.client.ClientHandle;
23 import uk.ac.vamsas.client.IClient;
24 import uk.ac.vamsas.client.IClientDocument;
25 import uk.ac.vamsas.client.InvalidSessionDocumentException;
26 import uk.ac.vamsas.client.NoDefaultSessionException;
27 import uk.ac.vamsas.client.UserHandle;
28 import uk.ac.vamsas.client.VorbaId;
29 import uk.ac.vamsas.client.picking.IMessageHandler;
30 import uk.ac.vamsas.client.picking.IPickManager;
31 import uk.ac.vamsas.client.picking.Message;
32 import uk.ac.vamsas.client.picking.MouseOverMessage;
33 import uk.ac.vamsas.objects.core.Entry;
39 public class VamsasApplication
41 IClient vclient = null;
43 ClientHandle app = null;
45 UserHandle user = null;
47 Desktop jdesktop = null; // our jalview desktop reference
49 // Cache.preferences for vamsas client session arena
50 // preferences for check for default session at startup.
51 // user and organisation stuff.
52 public VamsasApplication(Desktop jdesktop, File sessionPath)
55 // we should create a session URI from the sessionPath and pass it to
56 // the clientFactory - but the vamsas api doesn't cope with that yet.
57 this.jdesktop = jdesktop;
58 initClientSession(null, sessionPath);
61 private static uk.ac.vamsas.client.IClientFactory getClientFactory()
64 return new uk.ac.vamsas.client.simpleclient.SimpleClientFactory();
68 * Start a new vamsas session
72 public VamsasApplication(Desktop jdesktop)
74 this.jdesktop = jdesktop;
75 initClientSession(null, null);
79 * init a connection to the session at the given url
84 public VamsasApplication(Desktop jdesktop, String sessionUrl)
86 this.jdesktop = jdesktop;
87 initClientSession(sessionUrl, null);
92 * or other if clientfactory instantiation failed.
93 * @return list of current sessions or null if no session exists.
95 public static String[] getSessionList() throws Exception
97 return getClientFactory().getCurrentSessions();
101 * initialise, possibly with either a valid session url or a file for a new
105 * null or a valid session url
106 * @param vamsasDocument
107 * null or a valid vamsas document file
108 * @return false if no vamsas connection was made
110 private boolean initClientSession(String sess, File vamsasDocument)
114 // Only need to tell the library what the application is here
115 app = getJalviewHandle();
116 uk.ac.vamsas.client.IClientFactory clientfactory = getClientFactory();
117 if (vamsasDocument != null)
122 "Implementation Error - cannot import existing vamsas document into an existing session, Yet!");
126 vclient = clientfactory.openAsNewSessionIClient(app,
128 } catch (InvalidSessionDocumentException e)
131 .showInternalMessageDialog(
134 "VAMSAS Document could not be opened as a new session - please choose another",
135 "VAMSAS Document Import Failed",
136 JOptionPane.ERROR_MESSAGE);
142 // join existing or create a new session
145 vclient = clientfactory.getNewSessionIClient(app);
149 vclient = clientfactory.getIClient(app, sess);
152 // set some properties for our VAMSAS interaction
154 user = vclient.getUserHandle();
156 } catch (Exception e)
158 jalview.bin.Cache.log
159 .error("Couldn't instantiate vamsas client !", e);
165 private void setVclientConfig()
172 if (vclient instanceof uk.ac.vamsas.client.simpleclient.SimpleClient)
174 uk.ac.vamsas.client.simpleclient.SimpleClientConfig cfg = ((uk.ac.vamsas.client.simpleclient.SimpleClient) vclient).getSimpleClientConfig();
175 cfg._validatemergedroots = false;
176 cfg._validateupdatedroots= true; //we may write rubbish otherwise.
181 Cache.log.warn("Probable SERIOUS VAMSAS client incompatibility - carrying on regardless",e);
185 Cache.log.warn("Probable VAMSAS client incompatibility - carrying on regardless",e);
190 * make the appHandle for Jalview
194 private ClientHandle getJalviewHandle()
196 return new ClientHandle("jalview.bin.Jalview", jalview.bin.Cache
197 .getProperty("VERSION"));
202 * @return true if we are registered in a vamsas session
204 public boolean inSession()
206 return (vclient != null);
210 * called to connect to session inits handlers, does an initial document
213 public void initial_update()
218 "Impementation error! Vamsas Operations when client not initialised and connected.");
220 addDocumentUpdateHandler();
221 addStoreDocumentHandler();
224 .debug("Jalview loading the Vamsas Session for the first time.");
225 dealWithDocumentUpdate(false); // we don't push an update out to the
227 Cache.log.debug("... finished update for the first time.");
231 * Update all windows after a vamsas datamodel change. this could go on the
235 protected void updateJalviewGui()
237 JInternalFrame[] frames = jdesktop.getAllFrames();
247 for (int i = frames.length - 1; i > -1; i--)
249 if (frames[i] instanceof AlignFrame)
251 AlignFrame af = (AlignFrame) frames[i];
252 af.alignPanel.alignmentChanged();
255 } catch (Exception e)
259 "Exception whilst refreshing jalview windows after a vamsas document update.",
264 public void push_update()
266 Thread udthread = new Thread(new Runnable() {
270 Cache.log.info("Jalview updating to the Vamsas Session.");
272 dealWithDocumentUpdate(true);
274 * IClientDocument cdoc=null; try { cdoc = vclient.getClientDocument(); }
275 * catch (Exception e) { Cache.log.error("Failed to get client document for
276 * update."); // RAISE A WARNING DIALOG disableGui(false); return; }
277 * updateVamsasDocument(cdoc); updateJalviewGui();
278 * cdoc.setVamsasRoots(cdoc.getVamsasRoots()); // propagate update flags
279 * back vclient.updateDocument(cdoc);
281 Cache.log.info("Jalview finished updating to the Vamsas Session.");
282 // TODO Auto-generated method stub
289 public void end_session()
292 throw new Error("Jalview not connected to Vamsas session.");
293 Cache.log.info("Jalview disconnecting from the Vamsas Session.");
298 vclient.finalizeClient();
299 Cache.log.info("Jalview has left the session.");
304 .warn("JV Client leaving a session that's its not joined yet.");
306 joinedSession = false;
312 } catch (Exception e)
314 Cache.log.error("Vamsas Session finalization threw exceptions!", e);
318 public void updateJalview(IClientDocument cdoc)
320 Cache.log.debug("Jalview updating from sesion document ..");
322 VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj,
323 baseProvEntry(), alRedoState);
324 vds.updateToJalview();
325 Cache.log.debug(".. finished updating from sesion document.");
329 private void ensureJvVamsas()
333 jv2vobj = new IdentityHashMap();
334 vobj2jv = new Hashtable();
335 alRedoState = new Hashtable();
340 * jalview object binding to VorbaIds
342 IdentityHashMap jv2vobj = null;
344 Hashtable vobj2jv = null;
345 Hashtable alRedoState = null;
346 public void updateVamsasDocument(IClientDocument doc)
349 VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
350 baseProvEntry(), alRedoState);
351 // wander through frames
352 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
362 for (int i = frames.length - 1; i > -1; i--)
364 if (frames[i] instanceof AlignFrame)
366 AlignFrame af = (AlignFrame) frames[i];
368 // update alignment and root from frame.
369 vds.storeVAMSAS(af.getViewport(), af.getTitle());
373 for (int i = frames.length - 1; i > -1; i--)
375 if (frames[i] instanceof AlignFrame)
377 AlignFrame af = (AlignFrame) frames[i];
379 // add any AlignedCodonFrame mappings on this alignment to any other.
380 vds.storeSequenceMappings(af.getViewport(), af.getTitle());
383 } catch (Exception e)
385 Cache.log.error("Vamsas Document store exception", e);
389 private Entry baseProvEntry()
391 uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();
392 pentry.setUser(user.getFullName());
393 pentry.setApp(app.getClientUrn());
394 pentry.setDate(new java.util.Date());
395 pentry.setAction("created");
400 * do a vamsas document update or update jalview from the vamsas document
403 * true to update from jalview to the vamsas document
405 protected void dealWithDocumentUpdate(boolean fromJalview)
407 // called by update handler for document update.
408 Cache.log.debug("Updating jalview from changed vamsas document.");
412 long time = System.currentTimeMillis();
413 IClientDocument cdoc = vclient.getClientDocument();
414 if (Cache.log.isDebugEnabled())
416 Cache.log.debug("Time taken to get ClientDocument = "
417 + (System.currentTimeMillis() - time));
418 time = System.currentTimeMillis();
422 this.updateVamsasDocument(cdoc);
423 if (Cache.log.isDebugEnabled())
426 .debug("Time taken to update Vamsas Document from jalview\t= "
427 + (System.currentTimeMillis() - time));
428 time = System.currentTimeMillis();
430 cdoc.setVamsasRoots(cdoc.getVamsasRoots());
431 if (Cache.log.isDebugEnabled())
433 Cache.log.debug("Time taken to set Document Roots\t\t= "
434 + (System.currentTimeMillis() - time));
435 time = System.currentTimeMillis();
441 if (Cache.log.isDebugEnabled())
444 .debug("Time taken to update Jalview from vamsas document Roots\t= "
445 + (System.currentTimeMillis() - time));
446 time = System.currentTimeMillis();
450 vclient.updateDocument(cdoc);
451 if (Cache.log.isDebugEnabled())
453 Cache.log.debug("Time taken to update Session Document\t= "
454 + (System.currentTimeMillis() - time));
455 time = System.currentTimeMillis();
458 } catch (Exception ee)
460 System.err.println("Exception whilst updating :");
461 ee.printStackTrace(System.err);
463 Cache.log.debug("Finished updating from document change.");
467 private void addDocumentUpdateHandler()
469 final VamsasApplication client = this;
470 vclient.addDocumentUpdateHandler(new PropertyChangeListener()
472 public void propertyChange(PropertyChangeEvent evt)
474 Cache.log.debug("Dealing with document update event.");
475 client.dealWithDocumentUpdate(false);
476 Cache.log.debug("finished dealing with event.");
479 Cache.log.debug("Added Jalview handler for vamsas document updates.");
482 private void addStoreDocumentHandler()
484 final VamsasApplication client = this;
485 vclient.addVorbaEventHandler(uk.ac.vamsas.client.Events.DOCUMENT_REQUESTTOCLOSE, new PropertyChangeListener()
487 public void propertyChange(PropertyChangeEvent evt)
489 Cache.log.debug("Asking user if the vamsas session should be stored.");
490 int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
491 "The current VAMSAS session has unsaved data - do you want to save it ?",
492 "VAMSAS Session Shutdown",
493 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
495 if(reply==JOptionPane.YES_OPTION)
497 Cache.log.debug("Prompting for vamsas store filename.");
498 Desktop.instance.vamsasSave_actionPerformed(null);
499 Cache.log.debug("Finished attempt at storing document.");
501 Cache.log.debug("finished dealing with REQUESTTOCLOSE event.");
504 Cache.log.debug("Added Jalview handler for vamsas document updates.");
506 public void disableGui(boolean b)
508 Desktop.instance.setVamsasUpdate(b);
511 private boolean joinedSession = false;
513 private VamsasListener picker = null;
515 private void startSession()
521 vclient.joinSession();
522 joinedSession = true;
523 } catch (Exception e)
526 Cache.log.error("Failed to join vamsas session.", e);
531 final IPickManager pm = vclient.getPickManager();
532 final StructureSelectionManager ssm = StructureSelectionManager
533 .getStructureSelectionManager();
534 pm.registerMessageHandler(new IMessageHandler()
538 public void handleMessage(Message message)
540 if (message instanceof MouseOverMessage && vobj2jv != null)
542 MouseOverMessage mm = (MouseOverMessage) message;
543 String mstring = mm.getVorbaID() + " " + mm.getPosition();
544 if (last != null && mstring.equals(last))
548 // if (Cache.log.isDebugEnabled())
550 // Cache.log.debug("Received MouseOverMessage "+mm.getVorbaID()+"
551 // "+mm.getPosition());
553 Object jvobj = vobj2jv.get(mm.getVorbaID());
554 if (jvobj != null && jvobj instanceof SequenceI)
557 // Cache.log.debug("Handling Mouse over "+mm.getVorbaID()+"
558 // bound to "+jvobj+" at "+mm.getPosition());
559 // position is character position in aligned sequence
560 ssm.mouseOverVamsasSequence((SequenceI) jvobj, mm
566 picker = new VamsasListener()
568 SequenceI last = null;
572 public void mouseOver(SequenceI seq, int index)
576 if (seq != last || i != index)
578 VorbaId v = (VorbaId) jv2vobj.get(seq);
581 Cache.log.debug("Mouse over " + v.getId() + " bound to "
582 + seq + " at " + index);
585 MouseOverMessage message = new MouseOverMessage(v.getId(),
587 pm.sendMessage(message);
592 ssm.addStructureViewerListener(picker); // better method here
593 } catch (Exception e)
595 Cache.log.error("Failed to init Vamsas Picking", e);