partially implemented simpleclient.EventGenerator
authorjprocter <jprocter@compbio.dundee.ac.uk>
Fri, 20 Jan 2006 18:03:29 +0000 (18:03 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Fri, 20 Jan 2006 18:03:29 +0000 (18:03 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@158 be28352e-c001-0410-b1a7-c7978e42abec

src/org/vamsas/client/Events.java
src/org/vamsas/client/simpleclient/EventGeneratorThread.java [new file with mode: 0644]
src/org/vamsas/client/simpleclient/VamsasFile.java
src/org/vamsas/client/simpleclient/VamsasSession.java

index fea1b79..00512a7 100644 (file)
@@ -45,6 +45,8 @@ public class Events {
    * created. Any client that handles this should call the
    * IClient.getDocument(), update and then IClient.updateDocument in the same
    * handler thread.
+   * EventName: <Vamsas-session URN>
+   * NewValue: org.vamsas.client.IClient for session.
    */
   public static final String DOCUMENT_FINALIZEAPPDATA = "org.vamsas.client.events.DocumentFinalizeAppData";
 
diff --git a/src/org/vamsas/client/simpleclient/EventGeneratorThread.java b/src/org/vamsas/client/simpleclient/EventGeneratorThread.java
new file mode 100644 (file)
index 0000000..e60a674
--- /dev/null
@@ -0,0 +1,117 @@
+package org.vamsas.client.simpleclient;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeSupport;
+import java.util.Hashtable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.vamsas.client.Events;
+
+/**
+ * monitors watcher objects and generates events.
+ */
+public class EventGeneratorThread extends Thread implements Runnable {
+  private static Log log = LogFactory.getLog(EventGeneratorThread.class);
+  private SimpleClient client;
+  private Hashtable handlers; // manager object
+  private VamsasSession session;
+  
+  protected FileWatcher clientfile=null;
+  protected FileWatcher vamsasfile=null;
+  protected FileWatcher storeFile=null;
+  
+  private boolean watch=false;
+  
+  
+  EventGeneratorThread(VamsasSession s, SimpleClient _client, Hashtable eventhandlers) {
+    if (eventhandlers==null || s==null || _client==null)
+      throw new Error("Null arguments to EventGeneratorThread constructor.");
+    handlers = eventhandlers;
+    session = s;
+    client = _client;
+    setName(s.sessionDir.getName());
+    initWatchers();
+  }
+  
+  private void initWatchers() {
+    if (clientfile==null)
+      clientfile = session.getClientWatcher();
+    if (vamsasfile ==null)
+      vamsasfile = session.getDocWatcher();
+    if (storeFile == null)
+      storeFile = session.getStoreWatcher();
+    clientfile.setState();
+    vamsasfile.setState();
+    storeFile.setState();
+  }
+  boolean ownsf = false;
+  /**
+   * scans all watchers and fires changeEvents if necessary
+   * @return number of events generated.
+   */
+  private int checkforEvents() {
+    Lock watchlock;
+    //TODO : leave slog.info messages for the events that occur.
+    int raised=0;
+    // could make this general - but for now keep simple
+    if ((watchlock=storeFile.getChangedState())!=null) {
+      // 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).
+      if (storeFile.exists) { 
+        PropertyChangeSupport h = (PropertyChangeSupport) handlers.get(Events.DOCUMENT_FINALIZEAPPDATA);
+        if (h!=null) {
+          log.debug("Triggering DOCUMENT_FINALIZEAPPDATA");
+          raised++;
+          h.firePropertyChange(client.getSessionUrn(), null, client);
+          // expect client to 
+          vamsasfile.setState();
+        }
+      }
+    }
+    if ((watchlock=clientfile.getChangedState())!=null) {
+      // see what happened to the clientfile - compare our internal version with the one in the file, or just send the updated list out...?
+      raised++;
+    }
+    if ((watchlock=vamsasfile.getChangedState())!=null) {
+      // pass IClientDocument instance to app handler ?
+    }
+    return raised;
+  }
+  
+  private void initEvents() {
+    
+  }
+  
+  /**
+   * probably don't need any of these below.
+   */
+  /* (non-Javadoc)
+   * @see java.lang.Thread#destroy()
+   */
+  public void destroy() {
+    super.destroy();
+  }
+  /* (non-Javadoc)
+   * @see java.lang.Thread#interrupt()
+   */
+  public void interrupt() {
+    // TODO Auto-generated method stub
+    super.interrupt();
+  }
+  /* (non-Javadoc)
+   * @see java.lang.Thread#isInterrupted()
+   */
+  public boolean isInterrupted() {
+    // TODO Auto-generated method stub
+    return super.isInterrupted();
+  }
+  /* (non-Javadoc)
+   * @see java.lang.Thread#run()
+   */
+  public void run() {
+    // TODO Auto-generated method stub
+    super.run();
+  }
+  
+
+}
index 6d5f13c..ffb1485 100644 (file)
@@ -59,30 +59,25 @@ public class VamsasFile extends SessionFile {
     
   }
   */
-  
   /**
-   * gets a locked Reader for the vamsas document.
-   * @return reader for vamsasdocument.xml enrty
+   * public interface for getting a lock.
+   * The lock object is internally referenced 
+   * so the lock will persist even after the
+   * return value of the method goes out of scope.
+   * @return null if lock couldn't be got or a valid Lock object.
    */
   public Lock getLock() {
-    lockFile();
-    return fileLock;
+    if (lockFile())
+      return fileLock;
+    return null;
   }
+  /**
+   * explicitly unlocks vamsas file.
+   * if you have called getLock() you *must* 
+   * call this to release the lock.
+   */
   public void unLock() {
     this.unlockFile();
   }
-  public java.io.Reader getDocumentReader() {
-    
-    try {
-      JarFile session = new JarFile("vamsasJar");
-      //JarEntry vamsasDocument = session.getJarEntry("vamsasDocument.xml");
-      //return new InputStreamReader(session.getInputStream(vamsasDocument));
-    } catch (IOException e) {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
-    }
-    return null;
-  }
-  
   
 }
index ef76d71..242cf36 100644 (file)
@@ -1,6 +1,13 @@
 package org.vamsas.client.simpleclient;
 
 import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.Appender;
+import org.apache.log4j.Logger;
+import org.apache.log4j.FileAppender;
 /**
  * 
  * Vamsas client is intialised with a path to create live session directories. 
@@ -41,11 +48,133 @@ import java.io.File;
 
 public class VamsasSession {
   /**
-   * Holds the file handlers for a session.
+   * Holds the file handlers and watchers for a session.
+   */
+  /**
+   * TODO: make sessionDir signature to allow VamsasSession instances to recognise the form of the directory
+   */
+  /**
+   * indicator file for informing other processes that 
+   * they should finalise their vamsas datasets for 
+   * storing in a vamsas archive.
+   */
+  public static final String CLOSEANDSAVE_FILE="exiting";
+  /**
+   * log file location
+   */
+  public static final String SESSION_LOG="Log.txt";
+  private static Log log = LogFactory.getLog(VamsasSession.class);
+  protected Logger slog = Logger.getLogger("org.vamsas.client.SessionLog");
+  /**
+   * setup the sessionLog using Log4j.
+   * @throws IOException
+   */
+  private void initLog() throws IOException {
+    Appender app = slog.getAppender("SESSION_LOG");
+    slog.addAppender(new FileAppender(app.getLayout(), new File(sessionDir, SESSION_LOG).getAbsolutePath()));
+  }
+  
+  /**
+   * the sessionDir is given as the session location for new clients.
    */
   File sessionDir;
+  /**
+   * holds the list of attached clients
+   */
   ClientsFile clist;
-  File vamArchive;
+  public static final String CLIENT_LIST="Clients.obj";
+  /**
+   * holds the data
+   */
+  VamsasFile vamArchive; 
+  public static final String VAMSAS_OBJ="VamDoc.jar";
   
+  /**
+   * sets up the vamsas session files and watchers in sessionDir
+   * @param sessionDir
+   */
+  protected VamsasSession(File sessionDir) throws IOException {
+    if (sessionDir==null)
+      throw new Error("Null directory for VamsasSession.");
+    if (sessionDir.exists()) {
+      if (!sessionDir.isDirectory() || !sessionDir.canWrite() || sessionDir.canRead())
+        throw new IOException("Cannot access '"+sessionDir+"' as a read/writable Directory.");
+      if (checkSessionFiles(sessionDir)) {
+        // session files exist in the directory
+        this.sessionDir = sessionDir;
+        initSessionObjects();
+        slog.debug("Initialising additional VamsasSession instance");
+        log.debug("Attached to VamsasSession in "+sessionDir);
+      } 
+    } else {
+      // start from scratch
+      if (!sessionDir.mkdir())
+        throw new IOException("Failed to make VamsasSession directory in "+sessionDir);
+      this.sessionDir = sessionDir; 
+      createSessionFiles();
+      initSessionObjects();
+      slog.debug("Session directory created.");
+      log.debug("Initialised VamsasSession in "+sessionDir);
+    }
+  }
+  /**
+   * tests presence of existing sessionfiles files in dir
+   * @param dir
+   * @return
+   */
+  private boolean checkSessionFiles(File dir) throws IOException {
+    File c_file = new File(dir,CLIENT_LIST);
+    File v_doc = new File(dir,VAMSAS_OBJ);
+    if (c_file.exists() && v_doc.exists())
+      return true;
+    return false;
+  }
+  /**
+   * create new empty files in dir
+   *
+   */
+  private void createSessionFiles() throws IOException {
+    if (sessionDir==null)
+      throw new IOException("Invalid call to createSessionFiles() with null sessionDir");
+    File c_file = new File(sessionDir,CLIENT_LIST);
+    File v_doc = new File(sessionDir,VAMSAS_OBJ);
+    if (c_file.createNewFile())
+      log.debug("Created new ClientFile "+c_file); // don't care if this works or not
+    if (v_doc.createNewFile())
+      log.debug("Created new Vamsas Session Document File "+v_doc); 
+  }
+  /**
+   * construct SessionFile objects and watchers for each
+   */
+  private void initSessionObjects() throws IOException {
+    if (clist!=null || vamArchive!=null)
+      throw new IOException("initSessionObjects called for initialised VamsasSession object.");
+    clist = new ClientsFile(new File(sessionDir,CLIENT_LIST));
+    vamArchive = new VamsasFile(new File(sessionDir,VAMSAS_OBJ));
+  }
+  /**
+   * make a new watcher object for the clientFile
+   * @return new ClientFile watcher instance
+   */
+  public FileWatcher getClientWatcher() {
+    return new FileWatcher(clist.sessionFile);
+  }
+  /**
+   * make a new watcher object for the vamsas Document
+   * @return new ClientFile watcher instance
+   */
+  public FileWatcher getDocWatcher() {
+    return new FileWatcher(vamArchive.sessionFile);
+  }
+
+  /**
+   * make a new watcher object for the messages file
+   * @return new watcher instance
+   */
+  public FileWatcher getStoreWatcher() {
+    return new FileWatcher(new File(CLOSEANDSAVE_FILE));
+  }
   
 }
+
+