/** * */ package uk.ac.vamsas.test.simpleclient.simpleapp; import java.io.File; import java.io.FileOutputStream; 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 uk.ac.vamsas.client.UserHandle; import uk.ac.vamsas.client.simpleclient.FileWatcher; import uk.ac.vamsas.client.simpleclient.VamsasArchive; import uk.ac.vamsas.client.simpleclient.VamsasFile; import uk.ac.vamsas.objects.core.Entry; import uk.ac.vamsas.objects.core.VamsasDocument; import uk.ac.vamsas.test.simpleclient.ArchiveClient; import uk.ac.vamsas.test.simpleclient.ClientDoc; /** * @author jimp * */ public class VamsasClient extends ArchiveClient { org.apache.commons.logging.Log log=org.apache.commons.logging.LogFactory.getLog(VamsasClient.class); /** * create a new vamsas client session from the archive at sessionPath. * @param sessionPath */ public VamsasClient(File sessionPath) { super(System.getProperty("user.name"),System.getProperty("host.name"), "SimpleVamsasClientApp","0.1", sessionPath); } /** * Called by gui to read anything from the vamsas session into the apps datamodel * after it has started up. * */ public void initial_update() { log.info("Jalview loading the Vamsas Session."); // load in the vamsas archive for the first time ClientDoc cdoc = this.getUpdateable(); updateJalview(cdoc); // TODO: flush any new VorbaIds to the document : updateVamsasClient may actually generate new Vamsas Document data in the form of vamsas element ids - these should be written back to the document. //doUpdate(cdoc); // JBPNote: this should flush new VorbaIds but I've not tested it yet. cdoc.closeDoc(); // then tell app to update its display based on the datamodel changes. } VamsasClientWatcher watcher=null; /** * Called by app when internal datamodel should exported (syncrhonised outwards) to vamsas document * */ public void push_update() { watchForChange=false; // this makes any watch(long) loops return. // we should also wait arount for this.WATCH_SLEEP to really make sure the watcher thread has stopped. try { Thread.sleep(WATCH_SLEEP); } catch (Exception e) { }; ClientDoc cdoc = getUpdateable(); updateVamsasDocument(cdoc); doUpdate(cdoc); cdoc.closeDoc(); cdoc=null; watchForChange=true; startWatcher(); } public void end_session() { watchForChange=false; // this makes any watch(long) loops return. // we should also wait arount for this.WATCH_SLEEP to really make sure the watcher thread has stopped. try { Thread.sleep(WATCH_SLEEP); } catch (Exception e) { }; // stop any update/watcher thread. log.info("VamsasClientApplication disconnecting from the Vamsas Session."); } public void updateJalview(ClientDoc cdoc) { ensureVamsasBindings(); VamsasDatastore vds = new VamsasDatastore(cdoc, vobj2jv, jv2vobj, baseProvEntry()); vds.updateToJalview(); } private void ensureVamsasBindings() { if (jv2vobj==null) { jv2vobj = new IdentityHashMap(); vobj2jv = new Hashtable(); } } /** * App's object binding to VorbaIds */ IdentityHashMap jv2vobj = null; Hashtable vobj2jv = null; /** * called with a vamsas document which will be updated with new data from the app * @param doc */ public void updateVamsasDocument(ClientDoc doc) { ensureVamsasBindings(); VamsasDatastore vds = new VamsasDatastore(doc, vobj2jv, jv2vobj, baseProvEntry()); // wander through frames vds.storeVAMSAS(new Object()); // Object is the apps datamodel ;) } /** * * @return a base provenance entry used by the VamsasDatastore object to get attributes from. this isn't particularly elegant either. */ private Entry baseProvEntry() { uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry(); pentry.setUser(this.getProvenanceUser()); pentry.setApp(this.getClientHandle().getClientName()); pentry.setDate(new java.util.Date()); pentry.setAction("created"); return pentry; } protected class VamsasClientWatcher extends Thread implements Runnable { /* (non-Javadoc) * @see java.lang.Thread#run() */ VamsasClient client=null; VamsasClientWatcher(VamsasClient client) { this.client = client; } boolean running=false; public void run() { running=true; while (client.watchForChange) { ClientDoc docio = client.watch(0); if (docio!=null) { // VamsasClient GUI bits should be disabled whilst an update is in progress so the user doesn't screw anything up. client.disableGui(true); log.debug("Updating VamsasClient app from changed vamsas document."); client.updateJalview(docio); log.debug("Finished updating from document change."); docio.closeDoc(); docio=null; client.disableGui(false); } } running=false; } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub } /** * disable (if b is true) or enable (if b is true) the VamsasClient's vamsas session gui bits whilst a document change is being updated to the app. * @param b */ public void disableGui(boolean b) { // in jalview, we turn off the VAMSAS Session menu : Desktop.instance.setVamsasUpdate(b); } /** * spawn a new thread to start the VamsasClientWatcher. * */ public void startWatcher() { if (watcher==null) watcher=new VamsasClientWatcher(this); Thread thr = new Thread() { public void run() { watcher.start(); } }; thr.start(); } }