/** * */ package jalview.gui; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Vector; import java.util.jar.JarOutputStream; import javax.swing.JInternalFrame; import jalview.bin.Cache; import jalview.io.VamsasAppDatastore; import uk.ac.vamsas.client.*; import uk.ac.vamsas.*; import uk.ac.vamsas.objects.*; import uk.ac.vamsas.objects.core.Entry; /** * @author jimp * */ public class VamsasApplication { IClient vclient=null; ClientHandle app=null; UserHandle user=null; Desktop jdesktop = null; // our jalview desktop reference // Cache.preferences for vamsas client session arena // preferences for check for default session at startup. // user and organisation stuff. public VamsasApplication(Desktop jdesktop, File sessionPath) { // JBPNote: // we should create a session URI from the sessionPath and pass it to // the clientFactory - but the vamsas api doesn't cope with that yet. this(jdesktop); throw new Error("Sorry - can't start from session file yet."); // make this a warning } private static uk.ac.vamsas.client.IClientFactory getClientFactory() throws IOException { return new uk.ac.vamsas.client.simpleclient.SimpleClientFactory(); } public VamsasApplication(Desktop jdesktop) { this.jdesktop = jdesktop; initClientSession(null); } /** * @throws IOException or other if clientfactory instantiation failed. * @return list of current sessions or null if no session exists. */ public static String[] getSessionList() throws Exception { return getClientFactory().getCurrentSessions(); } /** * initialise, possibly with e valid session url * @param sess * @return */ private boolean initClientSession(String sess) { try { // Only need to tell the library what the application is here app = new ClientHandle("jalview.bin.Jalview", jalview.bin.Cache.getProperty("VERSION")); uk.ac.vamsas.client.IClientFactory clientfactory = getClientFactory(); if (sess==null) { vclient = clientfactory.getIClient(app); } else { vclient = clientfactory.getIClient(app,sess); } user = vclient.getUserHandle(); } catch (NoDefaultSessionException e) { return false; } catch (Exception e) { jalview.bin.Cache.log.error("Couldn't instantiate vamsas client !",e); return false; } return true; } /** * * @return true if we are registered in a vamsas session */ public boolean inSession() { return (vclient!=null); } /** * called to connect to session * inits handlers, does an initial document update. */ public void initial_update() { if (!inSession()) { throw new Error("Impementation error! Vamsas Operations when client not initialised and connected."); } addDocumentUpdateHandler(); startSession(); Cache.log.debug("Jalview loading the Vamsas Session for the first time."); dealWithDocumentUpdate(false); // we don't push an update out to the document yet. Cache.log.debug("... finished update for the first time."); } /** * Update all windows after a vamsas datamodel change. * this could go on the desktop object! * */ protected void updateJalviewGui() { JInternalFrame[] frames = jdesktop.getAllFrames(); if (frames == null) { return; } try { //REVERSE ORDER for (int i = frames.length - 1; i > -1; i--) { if (frames[i] instanceof AlignFrame) { AlignFrame af = (AlignFrame) frames[i]; af.alignPanel.alignmentChanged(); } } } catch (Exception e) { Cache.log.warn( "Exception whilst refreshing jalview windows after a vamsas document update.", e); } } public void push_update() { Cache.log.info("Jalview updating to the Vamsas Session."); dealWithDocumentUpdate(true); /* IClientDocument cdoc=null; try { cdoc = vclient.getClientDocument(); } catch (Exception e) { Cache.log.error("Failed to get client document for update."); // RAISE A WARNING DIALOG disableGui(false); return; } updateVamsasDocument(cdoc); updateJalviewGui(); cdoc.setVamsasRoots(cdoc.getVamsasRoots()); // propagate update flags back vclient.updateDocument(cdoc); */ Cache.log.info("Jalview finished updating to the Vamsas Session."); } public void end_session() { if (!inSession()) throw new Error("Jalview not connected to Vamsas session."); Cache.log.info("Jalview disconnecting from the Vamsas Session."); try { if (joinedSession) { vclient.finalizeClient(); Cache.log.info("Jalview has left the session."); } else { Cache.log.warn("JV Client leaving a session that's its not joined yet."); } joinedSession=false; vclient = null; app=null; user = null; jv2vobj = null; vobj2jv = null; } catch (Exception e) { Cache.log.error("Vamsas Session finalization threw exceptions!",e); } } public void updateJalview(IClientDocument cdoc) { Cache.log.debug("Jalview updating from sesion document .."); ensureJvVamsas(); VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj, baseProvEntry()); vds.updateToJalview(); Cache.log.debug(".. finished updating from sesion document."); } private void ensureJvVamsas() { if (jv2vobj == null) { jv2vobj = new IdentityHashMap(); vobj2jv = new Hashtable(); } } /** * jalview object binding to VorbaIds */ IdentityHashMap jv2vobj = null; Hashtable vobj2jv = null; public void updateVamsasDocument(IClientDocument doc) { ensureJvVamsas(); VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj, baseProvEntry()); // wander through frames JInternalFrame[] frames = Desktop.desktop.getAllFrames(); if (frames == null) { return; } try { //REVERSE ORDER for (int i = frames.length - 1; i > -1; i--) { if (frames[i] instanceof AlignFrame) { AlignFrame af = (AlignFrame) frames[i]; // update alignment and root from frame. vds.storeVAMSAS(af.getViewport(), af.getTitle()); } } } catch (Exception e) { Cache.log.error("Vamsas Document store exception", e); } } private Entry baseProvEntry() { uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry(); pentry.setUser(user.getFullName()); pentry.setApp(app.getClientUrn()); pentry.setDate(new java.util.Date()); pentry.setAction("created"); return pentry; } /** * do a vamsas document update or update jalview from the vamsas document * @param fromJalview true to update from jalview to the vamsas document */ protected void dealWithDocumentUpdate(boolean fromJalview) { // called by update handler for document update. Cache.log.debug("Updating jalview from changed vamsas document."); disableGui(true); try { IClientDocument cdoc = vclient.getClientDocument(); if (fromJalview) { this.updateVamsasDocument(cdoc); cdoc.setVamsasRoots(cdoc.getVamsasRoots()); } else { updateJalview(cdoc); } vclient.updateDocument(cdoc); cdoc=null; } catch (Exception ee) { System.err.println("Exception whilst updating :"); ee.printStackTrace(System.err); } Cache.log.debug("Finished updating from document change."); disableGui(false); } private void addDocumentUpdateHandler() { final VamsasApplication client = this; vclient.addDocumentUpdateHandler(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { Cache.log.debug("Dealing with document update event."); client.dealWithDocumentUpdate(false); Cache.log.debug("finished dealing with event."); } }); Cache.log.debug("Added Jalview handler for vamsas document updates."); } public void disableGui(boolean b) { Desktop.instance.setVamsasUpdate(b); } private boolean joinedSession=false; private void startSession() { if (inSession()) { try { vclient.joinSession(); joinedSession=true; } catch (Exception e) { // Complain to GUI Cache.log.error("Failed to join vamsas session.",e); vclient=null; } } } }