1 package uk.ac.vamsas.test;
3 import uk.ac.vamsas.client.*;
4 import uk.ac.vamsas.client.picking.IMessageHandler;
5 import uk.ac.vamsas.client.picking.IPickManager;
6 import uk.ac.vamsas.client.picking.Message;
7 import uk.ac.vamsas.objects.core.VAMSAS;
8 import uk.ac.vamsas.test.objects.Core;
10 import java.awt.Event;
11 import java.beans.PropertyChangeEvent;
12 import java.beans.PropertyChangeListener;
14 import java.io.IOException;
15 import java.util.Vector;
18 * Toy vamsas command line client application demonstrating the API.
19 * Currently runs with one argument: ExampleApplication.main(new String("watch"))
20 * Test: Start up at least two of these processes independently and they will
21 * successively modify and handle update events from the document model.
23 * Behaviour of each client:
24 * Event handlers are registered for documentUpdate.
25 * - every document update:
26 * * the vamsas document will be dumped to standard out using uk.ac.vamsas.test.simpleclient.ArchiveReports
27 * * 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.
28 * 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).
29 * A new vamsas root generated from uk.ac.vamsas.test.objects.Core.getDemoVamsas is added to the document.
30 * Then a while loop waits around for events until shutdown:
31 * - currently it will shutdown after 9 updates (totalUpdates)
32 * - an update will be made after every other update that is detected.
34 * 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).
37 * appData get/set methods
39 * TODO: verify and test pickManager and interaction
40 * between it and other session events
42 * TODO: add more session interaction events
44 * TODO: test client add/leave events - currently library generates exceptions for sessionlist and clientlist modifications.
49 public class ExampleApplication
51 private ClientHandle app;
53 private UserHandle user; // TODO: make this something defined by the
56 private IClientFactory clientfactory;
58 private IClient vorbaclient;
60 private byte[] mydata;
62 private Vector vamsasObjects;
64 private boolean isUpdated = false;
66 private boolean isShuttingdown = false;
68 private boolean isFinalizing = false;
69 private int totalUpdates = 9;
70 private uk.ac.vamsas.client.VorbaId recover = null;
72 private void processVamsasDocument(IClientDocument doc)
74 if (doc.getVamsasRoots().length<4) {
75 doc.addVamsasRoot(Core.getDemoVamsas());
78 uk.ac.vamsas.objects.core.DataSet ds = doc.getVamsasRoots()[1].getDataSet(0);
79 uk.ac.vamsas.objects.core.AlignmentSequence alsq = ds.getAlignment(0).getAlignmentSequence(0);
82 recover = alsq.getVorbaId();
84 Vobject recoverd = doc.getObject(recover);
85 System.out.println("Recovery of "+recover+" was "+((recoverd==null) ? "A FAILURE" : "SUCCESSFUL"));
87 System.out.println("Modifying Sequence:\n"+alsq.hashCode());
88 alsq.setSequence(alsq.getSequence()+ds.getAlignment(0).getGapChar());
89 System.out.println("Modifying Sequence:\n"+alsq.hashCode());
90 System.out.println("Modified Sequence:\n"+alsq.getSequence());
91 doc.setVamsasRoots(doc.getVamsasRoots());
92 } catch (Exception ee) {
96 vorbaclient.updateDocument(doc);
97 // merge vamsasObjects with vamsas objects in document
98 // get this apps 'mydata' if it hasn't got it already.
99 // .. access this application's 'public' mydata' if there is any.
102 private void addHandlers(IClient avorbaclient)
104 // make a non-volatile reference to the client instance.
105 final IClient vorbaclient = avorbaclient;
106 // register update handler
107 vorbaclient.addDocumentUpdateHandler(new PropertyChangeListener() {
108 public void propertyChange(PropertyChangeEvent evt)
110 System.out.println("Vamsas document update for "
111 + evt.getPropertyName() + ": " + evt.getOldValue()
112 + " to " + evt.getNewValue());
113 // merge new data into ours.
114 // example - output doc
117 IClientDocument cdoc = vorbaclient.getClientDocument();
118 if (calls>2 && cdoc.getVamsasRoots().length>0 && !cdoc.getVamsasRoots()[0].is__stored_in_document())
120 System.err.println("Pathological Update Detected - Document is zeroed!");
123 uk.ac.vamsas.test.simpleclient.ArchiveReports.rootReport(
124 cdoc.getVamsasRoots(), true, System.out);
127 if (cdoc.getVamsasRoots().length>2) {
128 uk.ac.vamsas.objects.core.DataSet ds = cdoc.getVamsasRoots()[1].getDataSet(0);
129 uk.ac.vamsas.objects.core.AlignmentSequence alsq = ds.getAlignment(0).getAlignmentSequence(0);
130 if (alsq.isUpdated())
131 System.out.println("Seqeuence was updated since last time.");
132 alsq.setSequence(alsq.getSequence()+ds.getAlignment(0).getGapChar());
133 System.out.println("Newly Modified Sequence:\n"+alsq.getSequence());
134 cdoc.setVamsasRoots(cdoc.getVamsasRoots());
136 } catch (Exception ee) {
137 System.err.println("Exception whilst updating :");
138 ee.printStackTrace(System.err);
140 vorbaclient.updateDocument(cdoc);
145 .println("Exception whilst dumping document tree after an update.");
146 e.printStackTrace(System.err);
148 isUpdated = true; // tell main thread to reflect change...
151 // register close handler
152 vorbaclient.addVorbaEventHandler(Events.DOCUMENT_REQUESTTOCLOSE,
153 new PropertyChangeListener() {
154 public void propertyChange(PropertyChangeEvent evt)
157 .println("Received request to close vamsas document.");
158 // ask user for a filename to save it to.
159 // Then pass it to the vorba object...
160 vorbaclient.storeDocument(new java.io.File(
165 // register some more handlers to monitor the session :
167 vorbaclient.addVorbaEventHandler(Events.CLIENT_CREATION,
168 new PropertyChangeListener() {
169 public void propertyChange(PropertyChangeEvent evt)
171 System.out.println("New Vamsas client for "
172 + evt.getPropertyName() + ": "
173 + evt.getOldValue() + " to "
174 + evt.getNewValue());
175 // tell app add new client to its list of clients.
178 vorbaclient.addVorbaEventHandler(Events.CLIENT_FINALIZATION,
179 new PropertyChangeListener() {
180 public void propertyChange(PropertyChangeEvent evt)
182 System.out.println("Vamsas client finalizing for "
183 + evt.getPropertyName() + ": "
184 + evt.getOldValue() + " to "
185 + evt.getNewValue());
186 // tell app to update its list of clients to communicate
190 vorbaclient.addVorbaEventHandler(Events.SESSION_SHUTDOWN,
191 new PropertyChangeListener() {
192 public void propertyChange(PropertyChangeEvent evt)
194 System.out.println("Session " + evt.getPropertyName()
195 + " is shutting down.");
196 // tell app to finalize its session data before
200 vorbaclient.addVorbaEventHandler(Events.DOCUMENT_FINALIZEAPPDATA,
201 new PropertyChangeListener() {
202 public void propertyChange(PropertyChangeEvent evt)
205 .println("Application received a DOCUMENT_FINALIZEAPPDATA event.");
206 // tell app to finalize its session data prior to the
207 // storage of the current session as an archive.
213 public String Usage = "ExampleApplication :/n [-arena <vamsasFileDirectory>][-session <vamsasSessionURN>] <action> [+<arguments>]\n"
214 + "<action> is one of :\n\tsave,update,close,watch";
217 String importFile=null;
218 String outputFile=null;
219 private boolean parseArgs(String args[])
221 if (args.length == 0)
226 boolean parsed=false;
227 while (!parsed && cpos<args.length)
229 if (args[cpos].toLowerCase().equals("load") && cpos+1<args.length)
231 importFile=args[cpos+1];
235 if (args[cpos].toLowerCase().equals("save") && cpos+1<args.length)
237 outputFile=args[cpos+1];
241 // default behaviour - if not anything else its probably a session urn
242 if (!args[cpos].toLowerCase().equals("watch"))
251 class ExamplePicker extends Thread
255 public IPickManager pm = null;
257 ExamplePicker(String me, IPickManager pm)
268 try { Thread.sleep(1000 + (long) Math.random() * 10000); }
269 catch (Exception e) {}
273 pm.sendMessage(new uk.ac.vamsas.client.picking.CustomMessage("Message " + mcount++ + " from " + me));
280 public void runMe(String[] args)
282 if (!parseArgs(args))
284 System.err.print(Usage);
286 // get IClientFactory
289 clientfactory = new uk.ac.vamsas.client.simpleclient.SimpleClientFactory();
291 catch (IOException e)
293 System.err.println(e + "\n" + Usage);
297 // get an Iclient with session data
298 app = new ClientHandle("uk.ac.vamsas.test.ExampleApplication", "0.1");
299 user = new UserHandle("arnolduser", "deathsdoor");
304 System.out.println("Connecting to "+sess);
305 vorbaclient = clientfactory.getIClient(app, user, sess);
309 vorbaclient = clientfactory.getIClient(app, user);
312 catch (NoDefaultSessionException e)
315 .println("There appear to be several sessions to choose from :");
316 String[] sessions = clientfactory.getCurrentSessions();
317 for (int s = 0; s < sessions.length; s++)
318 System.err.println(sessions[s]);
321 addHandlers(vorbaclient);
324 vorbaclient.joinSession();
328 se.printStackTrace();
329 System.err.println(se + " when joining session.\n" + Usage);
332 // register an update listener and a close listener.
333 // import any data if requested to
334 if (importFile!=null)
336 File vfile = new File(importFile);
339 vorbaclient.importDocument(vfile);
343 System.err.println("Failed to import file "+importFile);
344 System.err.println("Exception received was "+e);
345 e.printStackTrace(System.err);
349 // Write out any data if requested to
350 if (outputFile!=null)
352 File vfile = new File(outputFile);
355 vorbaclient.storeDocument(vfile);
359 System.err.println("Failed to export session as file "+outputFile);
360 System.err.println("Exception received was "+e);
361 e.printStackTrace(System.err);
367 IClientDocument cdoc = vorbaclient.getClientDocument();
368 processVamsasDocument(cdoc);
373 .println("Unexpected exception when retrieving the client document for the first time!");
374 e.printStackTrace(System.err);
378 ExamplePicker picker = new ExamplePicker(vorbaclient.getClientHandle()
379 .getClientUrn(), vorbaclient.getPickManager());
382 if (picker.pm!=null) {
383 picker.pm.registerMessageHandler(new IMessageHandler() {
385 public void handleMessage(Message message)
388 .println("Received |" + message.getRawMessage() + "|");
389 shutdown +=100; // hang around for 5 seconds or so before dying naturally.
395 shutdown = System.currentTimeMillis()+10000; // hang around for 10 seconds or so before dying naturally.
396 while (!isShuttingdown && update < totalUpdates)
398 // do something with data
399 // , update document, or something.
403 System.out.println("Update handler called " + (++update)
406 .println("******************************************");
407 isUpdated = false; // TODO: saner update det method.
408 shutdown = System.currentTimeMillis()+10000;
413 IClientDocument cdoc = vorbaclient.getClientDocument();
414 processVamsasDocument(cdoc);
419 .println("Error when updating document after an even numbered update.");
420 e.printStackTrace(System.err);
424 if (System.currentTimeMillis()>shutdown)
430 try { Thread.sleep(50); }
431 catch (Exception e) {}
434 System.out.println("Finalizing.");
435 // call finalizeClient
436 vorbaclient.finalizeClient();
437 System.out.println("Shutting down picker.");
439 while (picker.isAlive())
441 System.out.println("Waiting for picker to die...");
452 // { meanwhile, eventHandlers are called to do any saves if need be }
453 // and all registered listeners will be deregistered to avoid deadlock.
456 System.out.println("Byee!");
458 public static void main(String[] args)
460 ExampleApplication example = new ExampleApplication();