X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fuk%2Fac%2Fvamsas%2Ftest%2FExampleApplication.java;h=df95ec8e6da2c649b5e059f081296228cd7ff23e;hb=c5ae09e2372eabd49d9d186ec1b0f150287aca86;hp=328495b6796498c7a34d6167cd7946e62774b8a9;hpb=8a09da71c5939ec3198084eccea06f6e88e69a8b;p=vamsas.git diff --git a/src/uk/ac/vamsas/test/ExampleApplication.java b/src/uk/ac/vamsas/test/ExampleApplication.java index 328495b..df95ec8 100644 --- a/src/uk/ac/vamsas/test/ExampleApplication.java +++ b/src/uk/ac/vamsas/test/ExampleApplication.java @@ -1,9 +1,3 @@ -/** - * Created on 14-Sep-2005 - * - * TODO To change the template for this generated file go to - * Window - Preferences - Java - Code Style - Code Templates - */ package uk.ac.vamsas.test; import uk.ac.vamsas.client.*; @@ -16,134 +10,438 @@ import uk.ac.vamsas.test.objects.Core; import java.awt.Event; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; import java.util.Vector; + /** - * Toy vamsas command line client application demonstrating the API. + * 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 (currently: modifies document on start up, then modifies every 2 updates before finalizing after 5 updates. + * + * 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 static ClientHandle app; - private static UserHandle user; // TODO: make this something defined by the api - private static IClientFactory clientfactory; - private static IClient vorbaclient; - private static byte[] mydata; - private static Vector vamsasObjects; - private static boolean isUpdated = false; - private static boolean isShuttingdown = false; - private static boolean isFinalizing = false; - private static void processVamsasDocument(IClientDocument doc) { - doc.addVamsasRoot(Core.getDemoVamsas()); - vorbaclient.updateDocument(doc); - // merge vamsasObjects with vamsas objects in document + 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 int calls = 0; + + private long mdatahash = 0; + + private long muserdatahash = 0; + + 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) { + + } + } // get this apps 'mydata' if it hasn't got it already. + System.out.println("Trying to get appdata and modify it....."); + try { + processAppData(doc); + System.out.println(".....Finished."); + } catch (Exception e) { + System.err.println("Failed to process appdata for our application."); + e.printStackTrace(System.err); + } + // .. access this application's 'public' mydata' if there is any. + vorbaclient.updateDocument(doc); + // merge vamsasObjects with vamsas objects in document + + } + + private int appdatareads = 0; + + boolean clientappd = true; + + boolean userappd = false; + + private void processAppData(IClientDocument doc) throws Exception { + appdatareads++; + boolean writtenonce = false; + if (doc != null) { + uk.ac.vamsas.client.IClientAppdata appd = doc.getClientAppdata(); + if (clientappd) { + if (appd.hasClientAppdata() && !(appdatareads % 2 == 0)) { + // byte[] cappd = appd.getClientAppdata(); + // if (cappd!=null) + // System.out.println("Client appdata\n"+cappd.toString()+"\nEnd of + // Appdata\n"); + System.out.println("Testing read from inputstream"); + String cappds = readData(appd.getClientInputStream()); + System.out + .println("Client appdata\n" + cappds + "\nEnd of Appdata\n"); + } else { + if (!writtenonce) { + String newapd = "Client Appdata:"; + if (appd.hasClientAppdata()) { + AppDataInputStream is; + newapd = readData(is = appd.getClientInputStream()); + is.close(); + } + writtenonce = true; + // appd.setClientAppdata(makeappData("Client Appdata for + // "+user.toString()+" written")); + writeData(appd.getClientOutputStream(), newapd + + " : Client Appdata for all users written on " + appdatareads + + " read by " + vorbaclient.getUserHandle()); + System.out.println("Written to ClientAppdata stream."); + } + } + } + if (userappd) { + if (appd.hasUserAppdata() && !(appdatareads % 2 == 0)) { + byte[] cappd = appd.getUserAppdata(); + if (cappd != null) + System.out.println("User appdata\n" + new String(cappd) + + "\nEnd of Users' Appdata\n"); + else { + System.out.println("No user appdata."); + appd + .setUserAppdata(("no default - overwritten null byte set on " + + appdatareads + " read by " + vorbaclient.getUserHandle() + "") + .getBytes()); + } + } else if (!writtenonce) { + writtenonce = true; + byte[] bts = makeappData("User Appdata for " + user + " written on " + + appdatareads + " read at "); + System.out.println("Setting appData bytes to\n" + new String(bts) + + "\nEnd."); + appd.setUserAppdata(bts); + System.out.println("Written to UserAppdata stream."); + } + } + } } - private static void addHandlers(IClient avorbaclient) { + + private byte[] makeappData(String message) { + StringBuffer sb = new StringBuffer(); + sb.append(message); + sb.append("on " + new java.util.Date()); + return sb.toString().getBytes(); + } + + private boolean writeData(AppDataOutputStream os, String message) { + StringBuffer sb = new StringBuffer(); + sb.append(message); + sb.append("on " + new java.util.Date()); + try { + ObjectOutputStream oos = new ObjectOutputStream(os); + oos.writeObject(sb.toString()); + oos.flush(); + oos.close(); + } catch (Exception e) { + System.err.println("Problem serialising this message:\n" + sb); + e.printStackTrace(System.err); + return false; + } + return true; + } + + private String readData(AppDataInputStream is) { + if (is != null) { + try { + if (is.available() > 0) { + ObjectInputStream ois = new ObjectInputStream(is); + String rs = (String) ois.readObject(); + return rs; + } + } catch (Exception e) { + System.err.println("Failed to read a string from input stream!"); + e.printStackTrace(System.err); + } + } + return ""; + } + + private void addHandlers(IClient avorbaclient) { + final ExampleApplication me = this; // 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()); + 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); + if (calls > 2 && cdoc.getVamsasRoots().length > 0 + && !cdoc.getVamsasRoots()[0].is__stored_in_document()) { + System.err + .println("Pathological Update Detected - Document is zeroed!"); + } + calls++; + 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."); + System.err + .println("Exception whilst dumping document tree after an update."); e.printStackTrace(System.err); } - isUpdated=true; // tell main thread to reflect change... + isUpdated = true; // tell main thread to reflect change... } }); // register close handler - vorbaclient.addVorbaEventHandler(Events.DOCUMENT_REQUESTTOCLOSE, + 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")); - } - }); - + 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, + + 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, + 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, + 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, + 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 void propertyChange(PropertyChangeEvent evt) { + boolean finalized = false; + System.out + .println("Application received a DOCUMENT_FINALIZEAPPDATA event."); + IClientDocument cdoc = null; + try { + cdoc = vorbaclient.getClientDocument(); + if (cdoc != null) { + IClientAppdata apd = cdoc.getClientAppdata(); + if (apd != null) { + String userd = ""; + if (apd.getUserAppdata() != null) { + userd = new String(apd.getUserAppdata()); + } + String appdat = me.readData(apd.getClientInputStream()); + me.writeData(apd.getClientOutputStream(), appdat + + "\nUser Data merged\n" + userd + "\n"); + } + finalized = true; + vorbaclient.updateDocument(cdoc); + } + // tell app to finalize its session data prior to the + // storage of the current session as an archive. + } catch (Exception e) { + if (!finalized) { + System.err + .println("Probable library problem - exception when trying to update document after writing merged appdata."); + e.printStackTrace(System.err); + } else { + System.err + .println("Recovering from exception when writing merged appdata"); + e.printStackTrace(System.err); + try { + if (cdoc != null) { + vorbaclient.updateDocument(cdoc); + } + } catch (Exception e2) { + System.err + .println("Probable library problem - exception when trying to update document after an exception when writing merged appdata."); + e2.printStackTrace(System.err); + } + } + return; + } + System.out.println("Application finalized appdata successfuly."); + } + + }); } - public static String - Usage="ExampleApplication [session urn] watch/n( future usage is :/n [+]\n" - +" is one of :\n\tsave,update,close,watch"; - static String sess=null; - private static boolean parseArgs(String args[]) { - if (args.length==0) { + + 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; } - if (!args[0].toLowerCase().equals("watch")) { - sess=args[0]; + int cpos = 0; + boolean parsed = false; + while (!parsed && cpos < args.length) { + if (args[cpos].toLowerCase().equals("load") && cpos + 1 < args.length) { + importFile = args[cpos + 1]; + cpos += 2; + continue; + } + if (args[cpos].toLowerCase().equals("save") && cpos + 1 < args.length) { + outputFile = args[cpos + 1]; + cpos += 2; + continue; + } + // default behaviour - if not anything else its probably a session urn + if (!args[cpos].toLowerCase().equals("watch")) { + sess = args[cpos]; + } + cpos++; } return true; } - public static void main(String[] args) { - class ExamplePicker implements Runnable { - String me=null; - public IPickManager pm = null; - ExamplePicker(String me,IPickManager pm) { - this.me = me; - this.pm = pm; - } - public void run() { - int mcount=1; - while (pm!=null) { - try { Thread.sleep(1000+(long) Math.random()*10000); } - catch (Exception e){ }; - if (pm!=null) - { - pm.sendMessage(new uk.ac.vamsas.client.picking.CustomMessage("Message "+mcount+++" from "+me)); - } + + class ExamplePicker extends Thread { + String me = null; + + public IPickManager pm = null; + + ExamplePicker(String me, IPickManager pm) { + this.me = me; + this.pm = pm; + } + + public void run() { + int mcount = 1; + while (pm != null) { + try { + Thread.sleep(1000 + (long) Math.random() * 10000); + } catch (Exception e) { + } + + if (pm != null) { + pm.sendMessage(new uk.ac.vamsas.client.picking.CustomMessage( + "Message " + mcount++ + " from " + me)); } } - - }; + } + } + + long shutdown = -1; + + public void runMe(String[] args) { if (!parseArgs(args)) { System.err.print(Usage); } @@ -151,88 +449,150 @@ public class ExampleApplication { try { clientfactory = new uk.ac.vamsas.client.simpleclient.SimpleClientFactory(); } catch (IOException e) { - System.err.println(e+"\n"+Usage); + System.err.println(e + "\n" + Usage); System.exit(1); } - + // get an Iclient with session data - app = new ClientHandle("uk.ac.vamsas.test.ExampleApplication","0.1"); - user = new UserHandle("arnolduser","deathsdoor"); + app = new ClientHandle("uk.ac.vamsas.test.ExampleApplication", "0.1"); + user = new UserHandle("arnolduser", "deathsdoor"); try { - vorbaclient = clientfactory.getIClient(app, user); + if (sess != null) { + System.out.println("Connecting to " + sess); + vorbaclient = clientfactory.getIClient(app, user, sess); + } else { + vorbaclient = clientfactory.getIClient(app, user); + } } catch (NoDefaultSessionException e) { - System.err.println("There appear to be several sessions to choose from :"); + System.err + .println("There appear to be several sessions to choose from :"); String[] sessions = clientfactory.getCurrentSessions(); - for (int s=0;s shutdown) { + isShuttingdown = true; } } - try { Thread.sleep(15); } catch (Exception e) {}; + + 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 (pickthread.isAlive()) { + picker.pm = null; + while (picker.isAlive()) { System.out.println("Waiting for picker to die..."); - try { Thread.sleep(1000); - } catch (Exception e) {}; + try { + Thread.sleep(1000); + } catch (Exception e) { + } + ; } - - System.out.println("Finalizing."); - // call finalizeClient - vorbaclient.finalizeClient(); + // { meanwhile, eventHandlers are called to do any saves if need be } // and all registered listeners will be deregistered to avoid deadlock. - + // finish + vorbaclient = null; + clientfactory = null; + System.out.println("Byee!"); + // try { Thread.sleep(100000); } catch (Exception e) {} + } + + public static void main(String[] args) { + ExampleApplication example = new ExampleApplication(); + example.runMe(args); } - }