2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3 * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 import jalview.bin.Cache;
22 import jalview.datamodel.SequenceI;
23 import jalview.io.VamsasAppDatastore;
24 import jalview.structure.StructureSelectionManager;
25 import jalview.structure.VamsasListener;
27 import java.beans.PropertyChangeEvent;
28 import java.beans.PropertyChangeListener;
30 import java.io.IOException;
31 import java.util.Hashtable;
32 import java.util.IdentityHashMap;
34 import javax.swing.JInternalFrame;
35 import javax.swing.JOptionPane;
37 import uk.ac.vamsas.client.ClientHandle;
38 import uk.ac.vamsas.client.IClient;
39 import uk.ac.vamsas.client.IClientDocument;
40 import uk.ac.vamsas.client.InvalidSessionDocumentException;
41 import uk.ac.vamsas.client.NoDefaultSessionException;
42 import uk.ac.vamsas.client.UserHandle;
43 import uk.ac.vamsas.client.VorbaId;
44 import uk.ac.vamsas.client.picking.IMessageHandler;
45 import uk.ac.vamsas.client.picking.IPickManager;
46 import uk.ac.vamsas.client.picking.Message;
47 import uk.ac.vamsas.client.picking.MouseOverMessage;
48 import uk.ac.vamsas.objects.core.Entry;
54 public class VamsasApplication
56 IClient vclient = null;
58 ClientHandle app = null;
60 UserHandle user = null;
62 Desktop jdesktop = null; // our jalview desktop reference
64 // Cache.preferences for vamsas client session arena
65 // preferences for check for default session at startup.
66 // user and organisation stuff.
67 public VamsasApplication(Desktop jdesktop, File sessionPath)
70 // we should create a session URI from the sessionPath and pass it to
71 // the clientFactory - but the vamsas api doesn't cope with that yet.
72 this.jdesktop = jdesktop;
73 initClientSession(null, sessionPath);
76 private static uk.ac.vamsas.client.IClientFactory getClientFactory()
79 return new uk.ac.vamsas.client.simpleclient.SimpleClientFactory();
83 * Start a new vamsas session
87 public VamsasApplication(Desktop jdesktop)
89 this.jdesktop = jdesktop;
90 initClientSession(null, null);
94 * init a connection to the session at the given url
99 public VamsasApplication(Desktop jdesktop, String sessionUrl)
101 this.jdesktop = jdesktop;
102 initClientSession(sessionUrl, null);
106 * @throws IOException
107 * or other if clientfactory instantiation failed.
108 * @return list of current sessions or null if no session exists.
110 public static String[] getSessionList() throws Exception
112 return getClientFactory().getCurrentSessions();
116 * initialise, possibly with either a valid session url or a file for a new
120 * null or a valid session url
121 * @param vamsasDocument
122 * null or a valid vamsas document file
123 * @return false if no vamsas connection was made
125 private boolean initClientSession(String sess, File vamsasDocument)
129 // Only need to tell the library what the application is here
130 app = getJalviewHandle();
131 uk.ac.vamsas.client.IClientFactory clientfactory = getClientFactory();
132 if (vamsasDocument != null)
137 "Implementation Error - cannot import existing vamsas document into an existing session, Yet!");
141 vclient = clientfactory.openAsNewSessionIClient(app,
143 } catch (InvalidSessionDocumentException e)
146 .showInternalMessageDialog(
149 "VAMSAS Document could not be opened as a new session - please choose another",
150 "VAMSAS Document Import Failed",
151 JOptionPane.ERROR_MESSAGE);
157 // join existing or create a new session
160 vclient = clientfactory.getNewSessionIClient(app);
164 vclient = clientfactory.getIClient(app, sess);
167 // set some properties for our VAMSAS interaction
169 user = vclient.getUserHandle();
171 } catch (Exception e)
173 jalview.bin.Cache.log
174 .error("Couldn't instantiate vamsas client !", e);
180 private void setVclientConfig()
188 if (vclient instanceof uk.ac.vamsas.client.simpleclient.SimpleClient)
190 uk.ac.vamsas.client.simpleclient.SimpleClientConfig cfg = ((uk.ac.vamsas.client.simpleclient.SimpleClient) vclient)
191 .getSimpleClientConfig();
192 cfg._validatemergedroots = false;
193 cfg._validateupdatedroots = true; // we may write rubbish otherwise.
199 "Probable SERIOUS VAMSAS client incompatibility - carrying on regardless",
201 } catch (Exception e)
205 "Probable VAMSAS client incompatibility - carrying on regardless",
211 * make the appHandle for Jalview
215 private ClientHandle getJalviewHandle()
217 return new ClientHandle("jalview.bin.Jalview", jalview.bin.Cache
218 .getProperty("VERSION"));
223 * @return true if we are registered in a vamsas session
225 public boolean inSession()
227 return (vclient != null);
231 * called to connect to session inits handlers, does an initial document
234 public void initial_update()
239 "Impementation error! Vamsas Operations when client not initialised and connected.");
241 addDocumentUpdateHandler();
242 addStoreDocumentHandler();
245 .debug("Jalview loading the Vamsas Session for the first time.");
246 dealWithDocumentUpdate(false); // we don't push an update out to the
248 Cache.log.debug("... finished update for the first time.");
252 * Update all windows after a vamsas datamodel change. this could go on the
256 protected void updateJalviewGui()
258 JInternalFrame[] frames = jdesktop.getAllFrames();
268 for (int i = frames.length - 1; i > -1; i--)
270 if (frames[i] instanceof AlignFrame)
272 AlignFrame af = (AlignFrame) frames[i];
273 af.alignPanel.alignmentChanged();
276 } catch (Exception e)
280 "Exception whilst refreshing jalview windows after a vamsas document update.",
285 public void push_update()
287 Thread udthread = new Thread(new Runnable()
292 Cache.log.info("Jalview updating to the Vamsas Session.");
294 dealWithDocumentUpdate(true);
296 * IClientDocument cdoc=null; try { cdoc = vclient.getClientDocument(); }
297 * catch (Exception e) { Cache.log.error("Failed to get client document
298 * for update."); // RAISE A WARNING DIALOG disableGui(false); return; }
299 * updateVamsasDocument(cdoc); updateJalviewGui();
300 * cdoc.setVamsasRoots(cdoc.getVamsasRoots()); // propagate update flags
301 * back vclient.updateDocument(cdoc);
303 Cache.log.info("Jalview finished updating to the Vamsas Session.");
304 // TODO Auto-generated method stub
311 public void end_session()
314 throw new Error("Jalview not connected to Vamsas session.");
315 Cache.log.info("Jalview disconnecting from the Vamsas Session.");
320 vclient.finalizeClient();
321 Cache.log.info("Jalview has left the session.");
326 .warn("JV Client leaving a session that's its not joined yet.");
328 joinedSession = false;
334 } catch (Exception e)
336 Cache.log.error("Vamsas Session finalization threw exceptions!", e);
340 public void updateJalview(IClientDocument cdoc)
342 Cache.log.debug("Jalview updating from sesion document ..");
344 VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj,
345 baseProvEntry(), alRedoState);
346 vds.updateToJalview();
347 Cache.log.debug(".. finished updating from sesion document.");
351 private void ensureJvVamsas()
355 jv2vobj = new IdentityHashMap();
356 vobj2jv = new Hashtable();
357 alRedoState = new Hashtable();
362 * jalview object binding to VorbaIds
364 IdentityHashMap jv2vobj = null;
366 Hashtable vobj2jv = null;
368 Hashtable alRedoState = null;
370 public void updateVamsasDocument(IClientDocument doc)
373 VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
374 baseProvEntry(), alRedoState);
375 // wander through frames
376 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
386 for (int i = frames.length - 1; i > -1; i--)
388 if (frames[i] instanceof AlignFrame)
390 AlignFrame af = (AlignFrame) frames[i];
392 // update alignment and root from frame.
393 vds.storeVAMSAS(af.getViewport(), af.getTitle());
397 for (int i = frames.length - 1; i > -1; i--)
399 if (frames[i] instanceof AlignFrame)
401 AlignFrame af = (AlignFrame) frames[i];
403 // add any AlignedCodonFrame mappings on this alignment to any other.
404 vds.storeSequenceMappings(af.getViewport(), af.getTitle());
407 } catch (Exception e)
409 Cache.log.error("Vamsas Document store exception", e);
413 private Entry baseProvEntry()
415 uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();
416 pentry.setUser(user.getFullName());
417 pentry.setApp(app.getClientUrn());
418 pentry.setDate(new java.util.Date());
419 pentry.setAction("created");
424 * do a vamsas document update or update jalview from the vamsas document
427 * true to update from jalview to the vamsas document
429 protected void dealWithDocumentUpdate(boolean fromJalview)
431 // called by update handler for document update.
432 Cache.log.debug("Updating jalview from changed vamsas document.");
436 long time = System.currentTimeMillis();
437 IClientDocument cdoc = vclient.getClientDocument();
438 if (Cache.log.isDebugEnabled())
440 Cache.log.debug("Time taken to get ClientDocument = "
441 + (System.currentTimeMillis() - time));
442 time = System.currentTimeMillis();
446 this.updateVamsasDocument(cdoc);
447 if (Cache.log.isDebugEnabled())
450 .debug("Time taken to update Vamsas Document from jalview\t= "
451 + (System.currentTimeMillis() - time));
452 time = System.currentTimeMillis();
454 cdoc.setVamsasRoots(cdoc.getVamsasRoots());
455 if (Cache.log.isDebugEnabled())
457 Cache.log.debug("Time taken to set Document Roots\t\t= "
458 + (System.currentTimeMillis() - time));
459 time = System.currentTimeMillis();
465 if (Cache.log.isDebugEnabled())
468 .debug("Time taken to update Jalview from vamsas document Roots\t= "
469 + (System.currentTimeMillis() - time));
470 time = System.currentTimeMillis();
474 vclient.updateDocument(cdoc);
475 if (Cache.log.isDebugEnabled())
477 Cache.log.debug("Time taken to update Session Document\t= "
478 + (System.currentTimeMillis() - time));
479 time = System.currentTimeMillis();
482 } catch (Exception ee)
484 System.err.println("Exception whilst updating :");
485 ee.printStackTrace(System.err);
487 Cache.log.debug("Finished updating from document change.");
491 private void addDocumentUpdateHandler()
493 final VamsasApplication client = this;
494 vclient.addDocumentUpdateHandler(new PropertyChangeListener()
496 public void propertyChange(PropertyChangeEvent evt)
498 Cache.log.debug("Dealing with document update event.");
499 client.dealWithDocumentUpdate(false);
500 Cache.log.debug("finished dealing with event.");
503 Cache.log.debug("Added Jalview handler for vamsas document updates.");
506 private void addStoreDocumentHandler()
508 final VamsasApplication client = this;
509 vclient.addVorbaEventHandler(
510 uk.ac.vamsas.client.Events.DOCUMENT_REQUESTTOCLOSE,
511 new PropertyChangeListener()
513 public void propertyChange(PropertyChangeEvent evt)
516 .debug("Asking user if the vamsas session should be stored.");
517 int reply = JOptionPane
518 .showInternalConfirmDialog(
520 "The current VAMSAS session has unsaved data - do you want to save it ?",
521 "VAMSAS Session Shutdown",
522 JOptionPane.YES_NO_OPTION,
523 JOptionPane.QUESTION_MESSAGE);
525 if (reply == JOptionPane.YES_OPTION)
527 Cache.log.debug("Prompting for vamsas store filename.");
528 Desktop.instance.vamsasSave_actionPerformed(null);
529 Cache.log.debug("Finished attempt at storing document.");
532 .debug("finished dealing with REQUESTTOCLOSE event.");
535 Cache.log.debug("Added Jalview handler for vamsas document updates.");
538 public void disableGui(boolean b)
540 Desktop.instance.setVamsasUpdate(b);
543 private boolean joinedSession = false;
545 private VamsasListener picker = null;
547 private void startSession()
553 vclient.joinSession();
554 joinedSession = true;
555 } catch (Exception e)
558 Cache.log.error("Failed to join vamsas session.", e);
563 final IPickManager pm = vclient.getPickManager();
564 final StructureSelectionManager ssm = StructureSelectionManager
565 .getStructureSelectionManager();
566 pm.registerMessageHandler(new IMessageHandler()
570 public void handleMessage(Message message)
572 if (message instanceof MouseOverMessage && vobj2jv != null)
574 MouseOverMessage mm = (MouseOverMessage) message;
575 String mstring = mm.getVorbaID() + " " + mm.getPosition();
576 if (last != null && mstring.equals(last))
580 // if (Cache.log.isDebugEnabled())
582 // Cache.log.debug("Received MouseOverMessage "+mm.getVorbaID()+"
583 // "+mm.getPosition());
585 Object jvobj = vobj2jv.get(mm.getVorbaID());
586 if (jvobj != null && jvobj instanceof SequenceI)
589 // Cache.log.debug("Handling Mouse over "+mm.getVorbaID()+"
590 // bound to "+jvobj+" at "+mm.getPosition());
591 // position is character position in aligned sequence
592 ssm.mouseOverVamsasSequence((SequenceI) jvobj, mm
598 picker = new VamsasListener()
600 SequenceI last = null;
604 public void mouseOver(SequenceI seq, int index)
608 if (seq != last || i != index)
610 VorbaId v = (VorbaId) jv2vobj.get(seq);
613 Cache.log.debug("Mouse over " + v.getId() + " bound to "
614 + seq + " at " + index);
617 MouseOverMessage message = new MouseOverMessage(v.getId(),
619 pm.sendMessage(message);
624 ssm.addStructureViewerListener(picker); // better method here
625 } catch (Exception e)
627 Cache.log.error("Failed to init Vamsas Picking", e);