1 package org.vamsas.client.simpleclient;
3 import java.beans.PropertyChangeEvent;
4 import java.beans.PropertyChangeSupport;
5 import java.util.Hashtable;
7 import org.apache.commons.logging.Log;
8 import org.apache.commons.logging.LogFactory;
9 import org.vamsas.client.Events;
12 * monitors watcher objects and generates events.
14 public class EventGeneratorThread extends Thread implements Runnable {
15 private static Log log = LogFactory.getLog(EventGeneratorThread.class);
16 private SimpleClient client;
17 private Hashtable handlers; // manager object
18 private VamsasSession session;
21 * list with all the clientHandles for the session
23 protected FileWatcher clientfile=null;
25 * the session's vamsasDocument
27 protected FileWatcher vamsasfile=null;
29 * written to by client when its app calls storeDocument.
31 protected FileWatcher storeFile=null;
33 private boolean watch=false;
36 EventGeneratorThread(VamsasSession s, SimpleClient _client, Hashtable eventhandlers) {
37 if (eventhandlers==null || s==null || _client==null)
38 throw new Error("Null arguments to EventGeneratorThread constructor.");
39 handlers = eventhandlers;
42 setName(s.sessionDir.getName());
46 private void initWatchers() {
48 clientfile = session.getClientWatcher();
49 if (vamsasfile ==null)
50 vamsasfile = session.getDocWatcher();
51 if (storeFile == null)
52 storeFile = session.getStoreWatcher();
53 clientfile.setState();
54 vamsasfile.setState();
57 boolean ownsf = false;
59 * scans all watchers and fires changeEvents if necessary
60 * @return number of events generated.
62 private int checkforEvents() {
64 //TODO : leave slog.info messages for the events that occur.
66 // could make this general - but for now keep simple
67 if ((watchlock=storeFile.getChangedState())!=null) {
68 // TODO: define the storeFile semaphore mechanism : file exists - all clients inform their apps, and then the client that wrote the file should delete the file (it should hold the lock to it).
69 if (storeFile.exists) {
70 PropertyChangeSupport h = (PropertyChangeSupport) handlers.get(Events.DOCUMENT_FINALIZEAPPDATA);
72 log.debug("Triggering DOCUMENT_FINALIZEAPPDATA");
74 h.firePropertyChange(client.getSessionUrn(), null, client);
76 vamsasfile.setState();
80 if ((watchlock=clientfile.getChangedState())!=null) {
81 // see what happened to the clientfile - compare our internal version with the one in the file, or just send the updated list out...?
84 * Generated when a new vamsas client is attached to a session (Handle is
85 * passed) Note: the newly created client does not receive the event.
87 public static final String CLIENT_CREATION = "org.vamsas.client.events.clientCreateEvent";
90 * Generated when a vamsas client leaves a session (Handle is passed to all
92 public static final String CLIENT_FINALIZATION = "org.vamsas.client.events.clientFinalizationEvent";
93 */ // again - as the test.
96 if ((watchlock=vamsasfile.getChangedState())!=null) {
99 * Generated when a client has finished updating the document. Passes
100 * applicationHandle of client so the updating client can recognise its own
102 public static final String DOCUMENT_UPDATE = "org.vamsas.client.events.documentUpdateEvent";
104 // read apphandle from 'lastUpdate' session file.
105 // pass apphandle name to appHandler ?
109 * Generated when a new vamsas document is created (perhaps from some existing
110 * Vamsas data) so an application may do its own data space initialization.
111 * TODO: decide if this is called when an app is connected to a stored
113 public static final String DOCUMENT_CREATE = "org.vamsas.client.events.documentCreateEvent";
115 // check if this session's appInit flag is set - if not - generate event for this app.
116 // prolly don't need this at the moment - when an app does getDocument it can to the initing then.
120 * Generated prior to session Shutdown, after the last participating vamsas
121 * client has finalized.
122 * TODO: decide on purpose of this ? is this for benefit of multi-session Apps only ?
123 public static final String SESSION_SHUTDOWN = "org.vamsas.client.events.SessionShutdownEvent";
127 * Generated for all clients when any client calls IClient.storeDocument() to
128 * allow them to store any updates before an offline copy of the session is
129 * created. Any client that handles this should call the
130 * IClient.getDocument(), update and then IClient.updateDocument in the same
132 * EventName: <Vamsas-session URN>
133 * NewValue: org.vamsas.client.IClient for session.
135 public static final String DOCUMENT_FINALIZEAPPDATA = "org.vamsas.client.events.DocumentFinalizeAppData";
137 // watch for finalization semaphore (last finalised sessionFile).
140 * Generated by Vorba stub after the penultimate client makes a call to
141 * closeDocument(). Sequence is as follows : 1. All other vamsas clients have
142 * called closeDocument() 2. Final living client monitors closures, and
143 * realises that it is last. 3. Final client generates event to prompt
144 * associated application to inquire if the user wishes to save the document
145 * for future reference.
146 * * Any call to closeDocument in a thread other than the registered
147 * EventListener will block until the RequestToClose handler has exited.
150 // public static final String DOCUMENT_REQUESTTOCLOSE = "org.vamas.client.DocumentRequestToCloseEvent";
155 private void initEvents() {
159 * Events raised by IClient and propagated to others in session
163 * number of milliseconds between any file state check.
166 protected void wait(int u) {
169 long l = System.currentTimeMillis()+POLL_UNIT*u;
170 while (System.currentTimeMillis()<l)
176 int STORE_WAIT=5; // how many units before we decide all clients have finalized their appdatas
179 * client App requests offline storage of vamsas data.
180 * Call blocks whilst other apps do any appData finalizing
181 * and then returns (after locking the vamsasDocument in the session)
182 * @return Lock for session.vamArchive
184 protected Lock want_to_store() {
185 log.debug("Waiting for other apps to do FinalizeApp handling.");
187 session.addStoreDocumentRequest(client.getClientHandle(), client.getUserHandle());
188 } catch (Exception e) {
189 log.warn("Whilst writing StoreDocumentRequest for ("+client.getClientHandle().getClientUrn()+" "+client.getUserHandle(),
191 log.info("trying to continue.");
195 while (units<STORE_WAIT) {
197 if (storeFile.hasChanged() || vamsasfile.hasChanged())
202 log.debug("finished waiting.");
203 return session.vamArchive.getLock();
207 * probably don't need any of these below.
210 * @see java.lang.Thread#destroy()
212 public void destroy() {
216 * @see java.lang.Thread#interrupt()
218 public void interrupt() {
219 // TODO Auto-generated method stub
223 * @see java.lang.Thread#isInterrupted()
225 public boolean isInterrupted() {
226 // TODO Auto-generated method stub
227 return super.isInterrupted();
230 * @see java.lang.Thread#run()
233 // TODO Auto-generated method stub