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()
187 if (vclient instanceof uk.ac.vamsas.client.simpleclient.SimpleClient)
189 uk.ac.vamsas.client.simpleclient.SimpleClientConfig cfg = ((uk.ac.vamsas.client.simpleclient.SimpleClient) vclient).getSimpleClientConfig();
190 cfg._validatemergedroots = false;
191 cfg._validateupdatedroots= true; //we may write rubbish otherwise.
196 Cache.log.warn("Probable SERIOUS VAMSAS client incompatibility - carrying on regardless",e);
200 Cache.log.warn("Probable VAMSAS client incompatibility - carrying on regardless",e);
205 * make the appHandle for Jalview
209 private ClientHandle getJalviewHandle()
211 return new ClientHandle("jalview.bin.Jalview", jalview.bin.Cache
212 .getProperty("VERSION"));
217 * @return true if we are registered in a vamsas session
219 public boolean inSession()
221 return (vclient != null);
225 * called to connect to session inits handlers, does an initial document
228 public void initial_update()
233 "Impementation error! Vamsas Operations when client not initialised and connected.");
235 addDocumentUpdateHandler();
236 addStoreDocumentHandler();
239 .debug("Jalview loading the Vamsas Session for the first time.");
240 dealWithDocumentUpdate(false); // we don't push an update out to the
242 Cache.log.debug("... finished update for the first time.");
246 * Update all windows after a vamsas datamodel change. this could go on the
250 protected void updateJalviewGui()
252 JInternalFrame[] frames = jdesktop.getAllFrames();
262 for (int i = frames.length - 1; i > -1; i--)
264 if (frames[i] instanceof AlignFrame)
266 AlignFrame af = (AlignFrame) frames[i];
267 af.alignPanel.alignmentChanged();
270 } catch (Exception e)
274 "Exception whilst refreshing jalview windows after a vamsas document update.",
279 public void push_update()
281 Thread udthread = new Thread(new Runnable() {
285 Cache.log.info("Jalview updating to the Vamsas Session.");
287 dealWithDocumentUpdate(true);
289 * IClientDocument cdoc=null; try { cdoc = vclient.getClientDocument(); }
290 * catch (Exception e) { Cache.log.error("Failed to get client document for
291 * update."); // RAISE A WARNING DIALOG disableGui(false); return; }
292 * updateVamsasDocument(cdoc); updateJalviewGui();
293 * cdoc.setVamsasRoots(cdoc.getVamsasRoots()); // propagate update flags
294 * back vclient.updateDocument(cdoc);
296 Cache.log.info("Jalview finished updating to the Vamsas Session.");
297 // TODO Auto-generated method stub
304 public void end_session()
307 throw new Error("Jalview not connected to Vamsas session.");
308 Cache.log.info("Jalview disconnecting from the Vamsas Session.");
313 vclient.finalizeClient();
314 Cache.log.info("Jalview has left the session.");
319 .warn("JV Client leaving a session that's its not joined yet.");
321 joinedSession = false;
327 } catch (Exception e)
329 Cache.log.error("Vamsas Session finalization threw exceptions!", e);
333 public void updateJalview(IClientDocument cdoc)
335 Cache.log.debug("Jalview updating from sesion document ..");
337 VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj,
338 baseProvEntry(), alRedoState);
339 vds.updateToJalview();
340 Cache.log.debug(".. finished updating from sesion document.");
344 private void ensureJvVamsas()
348 jv2vobj = new IdentityHashMap();
349 vobj2jv = new Hashtable();
350 alRedoState = new Hashtable();
355 * jalview object binding to VorbaIds
357 IdentityHashMap jv2vobj = null;
359 Hashtable vobj2jv = null;
360 Hashtable alRedoState = null;
361 public void updateVamsasDocument(IClientDocument doc)
364 VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
365 baseProvEntry(), alRedoState);
366 // wander through frames
367 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
377 for (int i = frames.length - 1; i > -1; i--)
379 if (frames[i] instanceof AlignFrame)
381 AlignFrame af = (AlignFrame) frames[i];
383 // update alignment and root from frame.
384 vds.storeVAMSAS(af.getViewport(), af.getTitle());
388 for (int i = frames.length - 1; i > -1; i--)
390 if (frames[i] instanceof AlignFrame)
392 AlignFrame af = (AlignFrame) frames[i];
394 // add any AlignedCodonFrame mappings on this alignment to any other.
395 vds.storeSequenceMappings(af.getViewport(), af.getTitle());
398 } catch (Exception e)
400 Cache.log.error("Vamsas Document store exception", e);
404 private Entry baseProvEntry()
406 uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();
407 pentry.setUser(user.getFullName());
408 pentry.setApp(app.getClientUrn());
409 pentry.setDate(new java.util.Date());
410 pentry.setAction("created");
415 * do a vamsas document update or update jalview from the vamsas document
418 * true to update from jalview to the vamsas document
420 protected void dealWithDocumentUpdate(boolean fromJalview)
422 // called by update handler for document update.
423 Cache.log.debug("Updating jalview from changed vamsas document.");
427 long time = System.currentTimeMillis();
428 IClientDocument cdoc = vclient.getClientDocument();
429 if (Cache.log.isDebugEnabled())
431 Cache.log.debug("Time taken to get ClientDocument = "
432 + (System.currentTimeMillis() - time));
433 time = System.currentTimeMillis();
437 this.updateVamsasDocument(cdoc);
438 if (Cache.log.isDebugEnabled())
441 .debug("Time taken to update Vamsas Document from jalview\t= "
442 + (System.currentTimeMillis() - time));
443 time = System.currentTimeMillis();
445 cdoc.setVamsasRoots(cdoc.getVamsasRoots());
446 if (Cache.log.isDebugEnabled())
448 Cache.log.debug("Time taken to set Document Roots\t\t= "
449 + (System.currentTimeMillis() - time));
450 time = System.currentTimeMillis();
456 if (Cache.log.isDebugEnabled())
459 .debug("Time taken to update Jalview from vamsas document Roots\t= "
460 + (System.currentTimeMillis() - time));
461 time = System.currentTimeMillis();
465 vclient.updateDocument(cdoc);
466 if (Cache.log.isDebugEnabled())
468 Cache.log.debug("Time taken to update Session Document\t= "
469 + (System.currentTimeMillis() - time));
470 time = System.currentTimeMillis();
473 } catch (Exception ee)
475 System.err.println("Exception whilst updating :");
476 ee.printStackTrace(System.err);
478 Cache.log.debug("Finished updating from document change.");
482 private void addDocumentUpdateHandler()
484 final VamsasApplication client = this;
485 vclient.addDocumentUpdateHandler(new PropertyChangeListener()
487 public void propertyChange(PropertyChangeEvent evt)
489 Cache.log.debug("Dealing with document update event.");
490 client.dealWithDocumentUpdate(false);
491 Cache.log.debug("finished dealing with event.");
494 Cache.log.debug("Added Jalview handler for vamsas document updates.");
497 private void addStoreDocumentHandler()
499 final VamsasApplication client = this;
500 vclient.addVorbaEventHandler(uk.ac.vamsas.client.Events.DOCUMENT_REQUESTTOCLOSE, new PropertyChangeListener()
502 public void propertyChange(PropertyChangeEvent evt)
504 Cache.log.debug("Asking user if the vamsas session should be stored.");
505 int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
506 "The current VAMSAS session has unsaved data - do you want to save it ?",
507 "VAMSAS Session Shutdown",
508 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
510 if(reply==JOptionPane.YES_OPTION)
512 Cache.log.debug("Prompting for vamsas store filename.");
513 Desktop.instance.vamsasSave_actionPerformed(null);
514 Cache.log.debug("Finished attempt at storing document.");
516 Cache.log.debug("finished dealing with REQUESTTOCLOSE event.");
519 Cache.log.debug("Added Jalview handler for vamsas document updates.");
521 public void disableGui(boolean b)
523 Desktop.instance.setVamsasUpdate(b);
526 private boolean joinedSession = false;
528 private VamsasListener picker = null;
530 private void startSession()
536 vclient.joinSession();
537 joinedSession = true;
538 } catch (Exception e)
541 Cache.log.error("Failed to join vamsas session.", e);
546 final IPickManager pm = vclient.getPickManager();
547 final StructureSelectionManager ssm = StructureSelectionManager
548 .getStructureSelectionManager();
549 pm.registerMessageHandler(new IMessageHandler()
553 public void handleMessage(Message message)
555 if (message instanceof MouseOverMessage && vobj2jv != null)
557 MouseOverMessage mm = (MouseOverMessage) message;
558 String mstring = mm.getVorbaID() + " " + mm.getPosition();
559 if (last != null && mstring.equals(last))
563 // if (Cache.log.isDebugEnabled())
565 // Cache.log.debug("Received MouseOverMessage "+mm.getVorbaID()+"
566 // "+mm.getPosition());
568 Object jvobj = vobj2jv.get(mm.getVorbaID());
569 if (jvobj != null && jvobj instanceof SequenceI)
572 // Cache.log.debug("Handling Mouse over "+mm.getVorbaID()+"
573 // bound to "+jvobj+" at "+mm.getPosition());
574 // position is character position in aligned sequence
575 ssm.mouseOverVamsasSequence((SequenceI) jvobj, mm
581 picker = new VamsasListener()
583 SequenceI last = null;
587 public void mouseOver(SequenceI seq, int index)
591 if (seq != last || i != index)
593 VorbaId v = (VorbaId) jv2vobj.get(seq);
596 Cache.log.debug("Mouse over " + v.getId() + " bound to "
597 + seq + " at " + index);
600 MouseOverMessage message = new MouseOverMessage(v.getId(),
602 pm.sendMessage(message);
607 ssm.addStructureViewerListener(picker); // better method here
608 } catch (Exception e)
610 Cache.log.error("Failed to init Vamsas Picking", e);