From a612f023ecf10c639a99540f79894e52a2151aba Mon Sep 17 00:00:00 2001 From: jprocter Date: Fri, 20 Jan 2006 18:03:29 +0000 Subject: [PATCH] partially implemented simpleclient.EventGenerator git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@158 be28352e-c001-0410-b1a7-c7978e42abec --- src/org/vamsas/client/Events.java | 2 + .../client/simpleclient/EventGeneratorThread.java | 117 +++++++++++++++++ src/org/vamsas/client/simpleclient/VamsasFile.java | 31 ++--- .../vamsas/client/simpleclient/VamsasSession.java | 133 +++++++++++++++++++- 4 files changed, 263 insertions(+), 20 deletions(-) create mode 100644 src/org/vamsas/client/simpleclient/EventGeneratorThread.java diff --git a/src/org/vamsas/client/Events.java b/src/org/vamsas/client/Events.java index fea1b79..00512a7 100644 --- a/src/org/vamsas/client/Events.java +++ b/src/org/vamsas/client/Events.java @@ -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: + * 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 index 0000000..e60a674 --- /dev/null +++ b/src/org/vamsas/client/simpleclient/EventGeneratorThread.java @@ -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(); + } + + +} diff --git a/src/org/vamsas/client/simpleclient/VamsasFile.java b/src/org/vamsas/client/simpleclient/VamsasFile.java index 6d5f13c..ffb1485 100644 --- a/src/org/vamsas/client/simpleclient/VamsasFile.java +++ b/src/org/vamsas/client/simpleclient/VamsasFile.java @@ -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; - } - } diff --git a/src/org/vamsas/client/simpleclient/VamsasSession.java b/src/org/vamsas/client/simpleclient/VamsasSession.java index ef76d71..242cf36 100644 --- a/src/org/vamsas/client/simpleclient/VamsasSession.java +++ b/src/org/vamsas/client/simpleclient/VamsasSession.java @@ -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)); + } } + + -- 1.7.10.2