package uk.ac.vamsas.test; import uk.ac.vamsas.client.*; import uk.ac.vamsas.client.picking.IMessageHandler; import uk.ac.vamsas.client.picking.IPickManager; import uk.ac.vamsas.client.picking.Message; import uk.ac.vamsas.objects.core.VAMSAS; import uk.ac.vamsas.test.objects.Core; import java.awt.Event; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.util.Vector; /** * Toy vamsas command line client application demonstrating the API. * Currently runs with one argument: ExampleApplication.main(new String("watch")) * Test: Start up at least two of these processes independently and they will * successively modify and handle update events from the document model. * * Behaviour of each client: * Event handlers are registered for documentUpdate. * - every document update: * * the vamsas document will be dumped to standard out using uk.ac.vamsas.test.simpleclient.ArchiveReports * * if there are more than 4 vamsas roots, the first sequence in the first alignment of the first dataset of the second vamsas root will be appended with a single gap character and then written back to the session document. * A pick thread is started, which sends random CUSTOM pick events every so often (tuning: flooding the pick channel seems to affect the behaviour of other vamsasClient threads, suggesting some object lock contention). * A new vamsas root generated from uk.ac.vamsas.test.objects.Core.getDemoVamsas is added to the document. * Then a while loop waits around for events until shutdown: * - currently it will shutdown after 9 updates (totalUpdates) * - an update will be made after every other update that is detected. * * Status: PickManager now shuts down correctly. Serial updates for two instances work correctly and are detected under j1.4 (need to test in 1.5 and 1.6). * * TODO: test * appData get/set methods * * TODO: verify and test pickManager and interaction * between it and other session events * * TODO: add more session interaction events * * TODO: test client add/leave events - currently library generates exceptions for sessionlist and clientlist modifications. * * @author jimp */ public class ExampleApplication { private ClientHandle app; private UserHandle user; // TODO: make this something defined by the // api private IClientFactory clientfactory; private IClient vorbaclient; private byte[] mydata; private Vector vamsasObjects; private boolean isUpdated = false; private boolean isShuttingdown = false; private boolean isFinalizing = false; private int totalUpdates = 9; private uk.ac.vamsas.client.VorbaId recover = null; private void processVamsasDocument(IClientDocument doc) { if (doc.getVamsasRoots().length<4) { doc.addVamsasRoot(Core.getDemoVamsas()); } else { try { uk.ac.vamsas.objects.core.DataSet ds = doc.getVamsasRoots()[1].getDataSet(0); uk.ac.vamsas.objects.core.AlignmentSequence alsq = ds.getAlignment(0).getAlignmentSequence(0); if (recover==null) { recover = alsq.getVorbaId(); } else { Vobject recoverd = doc.getObject(recover); System.out.println("Recovery of "+recover+" was "+((recoverd==null) ? "A FAILURE" : "SUCCESSFUL")); } System.out.println("Modifying Sequence:\n"+alsq.hashCode()); alsq.setSequence(alsq.getSequence()+ds.getAlignment(0).getGapChar()); System.out.println("Modifying Sequence:\n"+alsq.hashCode()); System.out.println("Modified Sequence:\n"+alsq.getSequence()); doc.setVamsasRoots(doc.getVamsasRoots()); } catch (Exception ee) { } } vorbaclient.updateDocument(doc); // merge vamsasObjects with vamsas objects in document // get this apps 'mydata' if it hasn't got it already. // .. access this application's 'public' mydata' if there is any. } private void addHandlers(IClient avorbaclient) { // make a non-volatile reference to the client instance. final IClient vorbaclient = avorbaclient; // register update handler vorbaclient.addDocumentUpdateHandler(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { System.out.println("Vamsas document update for " + evt.getPropertyName() + ": " + evt.getOldValue() + " to " + evt.getNewValue()); // merge new data into ours. // example - output doc try { IClientDocument cdoc = vorbaclient.getClientDocument(); uk.ac.vamsas.test.simpleclient.ArchiveReports.rootReport( cdoc.getVamsasRoots(), true, System.out); // Simple update try { if (cdoc.getVamsasRoots().length>2) { uk.ac.vamsas.objects.core.DataSet ds = cdoc.getVamsasRoots()[1].getDataSet(0); uk.ac.vamsas.objects.core.AlignmentSequence alsq = ds.getAlignment(0).getAlignmentSequence(0); if (alsq.isUpdated()) System.out.println("Seqeuence was updated since last time."); alsq.setSequence(alsq.getSequence()+ds.getAlignment(0).getGapChar()); System.out.println("Newly Modified Sequence:\n"+alsq.getSequence()); cdoc.setVamsasRoots(cdoc.getVamsasRoots()); } } catch (Exception ee) { System.err.println("Exception whilst updating :"); ee.printStackTrace(System.err); } vorbaclient.updateDocument(cdoc); } catch (Exception e) { System.err .println("Exception whilst dumping document tree after an update."); e.printStackTrace(System.err); } isUpdated = true; // tell main thread to reflect change... } }); // register close handler vorbaclient.addVorbaEventHandler(Events.DOCUMENT_REQUESTTOCLOSE, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { System.out .println("Received request to close vamsas document."); // ask user for a filename to save it to. // Then pass it to the vorba object... vorbaclient.storeDocument(new java.io.File( "UserLocation")); } }); // register some more handlers to monitor the session : vorbaclient.addVorbaEventHandler(Events.CLIENT_CREATION, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { System.out.println("New Vamsas client for " + evt.getPropertyName() + ": " + evt.getOldValue() + " to " + evt.getNewValue()); // tell app add new client to its list of clients. } }); vorbaclient.addVorbaEventHandler(Events.CLIENT_FINALIZATION, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { System.out.println("Vamsas client finalizing for " + evt.getPropertyName() + ": " + evt.getOldValue() + " to " + evt.getNewValue()); // tell app to update its list of clients to communicate // with. } }); vorbaclient.addVorbaEventHandler(Events.SESSION_SHUTDOWN, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { System.out.println("Session " + evt.getPropertyName() + " is shutting down."); // tell app to finalize its session data before // shutdown. } }); vorbaclient.addVorbaEventHandler(Events.DOCUMENT_FINALIZEAPPDATA, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { System.out .println("Application received a DOCUMENT_FINALIZEAPPDATA event."); // tell app to finalize its session data prior to the // storage of the current session as an archive. } }); } public String Usage = "ExampleApplication :/n [-arena ][-session ] [+]\n" + " is one of :\n\tsave,update,close,watch"; String sess = null; String importFile=null; String outputFile=null; private boolean parseArgs(String args[]) { if (args.length == 0) { return false; } int cpos=0; boolean parsed=false; while (!parsed && cposshutdown) { isShuttingdown=true; } } try { Thread.sleep(50); } catch (Exception e) {} } System.out.println("Finalizing."); // call finalizeClient vorbaclient.finalizeClient(); System.out.println("Shutting down picker."); picker.pm = null; while (picker.isAlive()) { System.out.println("Waiting for picker to die..."); try { Thread.sleep(1000); } catch (Exception e) { } ; } // { meanwhile, eventHandlers are called to do any saves if need be } // and all registered listeners will be deregistered to avoid deadlock. // finish System.out.println("Byee!"); } public static void main(String[] args) { ExampleApplication example = new ExampleApplication(); example.runMe(args); } }