X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Forg%2Fvamsas%2Fclient%2Fsimpleclient%2FVamsasSession.java;h=365311d8a49bba996e89a0b1ab46e2e69eefeeaf;hb=05cfd5783f5307bbcedb0b9205cebef11dae22df;hp=242cf368be81740d3c8a39b4fbfaaca6b4cd2262;hpb=a612f023ecf10c639a99540f79894e52a2151aba;p=vamsas.git diff --git a/src/org/vamsas/client/simpleclient/VamsasSession.java b/src/org/vamsas/client/simpleclient/VamsasSession.java index 242cf36..365311d 100644 --- a/src/org/vamsas/client/simpleclient/VamsasSession.java +++ b/src/org/vamsas/client/simpleclient/VamsasSession.java @@ -1,15 +1,31 @@ package org.vamsas.client.simpleclient; +import java.io.BufferedWriter; import java.io.File; import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Writer; 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; +import org.vamsas.client.ClientHandle; +import org.vamsas.client.UserHandle; /** + * Does all the IO operations for a SimpleClient instance accessing + * a SimpleClient vamsas session. * + * Basically, it defines the various standard names for the files + * in the session directory (that maps to the sessionUrn), + * provides constructors for the file handlers and watchers of + * those file entities, and some higher level methods + * to check and change the state flags for the session. + * + * TODO: move the stuff below to the SimpleClientFactory documentation. + * much may not be valid now : * Vamsas client is intialised with a path to create live session directories. * This path may contain a vamsas.properties file * that sets additional parameters (otherwise client @@ -44,21 +60,48 @@ import org.apache.log4j.FileAppender; * During the session * - Update watcher checks for file change - * + * Procedures for file based session message exchange + * - session document modification flag + * */ public class VamsasSession { /** - * Holds the file handlers and watchers for a session. + * indicator file for informing other processes that + * they should finalise their vamsas datasets for + * storing into a vamsas archive. */ + public static final String CLOSEANDSAVE_FILE="stored.log"; /** - * TODO: make sessionDir signature to allow VamsasSession instances to recognise the form of the directory + * session file storing the last_stored_stat data */ + public static final String MODIFIEDDOC_FILE="modified"; + /** - * indicator file for informing other processes that - * they should finalise their vamsas datasets for - * storing in a vamsas archive. + * called to clear update flag after a successful offline storage event */ - public static final String CLOSEANDSAVE_FILE="exiting"; + protected void clearUnsavedFlag() { + SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, MODIFIEDDOC_FILE)); + if (!laststored.clearFlag()) + log.warn("Unsaved flag was not cleared for "+sessionDir); + } + /** + * called to indicate session document has been modified. + * + */ + protected void setUnsavedFlag() { + SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, MODIFIEDDOC_FILE)); + if (!laststored.setFlag()) + log.warn("Couldn't set the Unsaved flag for "+sessionDir); + } + /** + * + * @return true if session document has been modified since last offline storage event + */ + protected boolean getUnsavedFlag() { + SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, MODIFIEDDOC_FILE)); + return laststored.checkFlag(); + } /** * log file location */ @@ -70,6 +113,7 @@ public class VamsasSession { * @throws IOException */ private void initLog() throws IOException { + // LATER: make dedicated appender format for session log. Appender app = slog.getAppender("SESSION_LOG"); slog.addAppender(new FileAppender(app.getLayout(), new File(sessionDir, SESSION_LOG).getAbsolutePath())); } @@ -151,6 +195,7 @@ public class VamsasSession { 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)); + initLog(); } /** * make a new watcher object for the clientFile @@ -159,22 +204,107 @@ public class VamsasSession { public FileWatcher getClientWatcher() { return new FileWatcher(clist.sessionFile); } + FileWatcher session_doc_watcher=null; /** * make a new watcher object for the vamsas Document * @return new ClientFile watcher instance */ public FileWatcher getDocWatcher() { + if (session_doc_watcher==null) + return session_doc_watcher = new FileWatcher(vamArchive.sessionFile); return new FileWatcher(vamArchive.sessionFile); } - + FileWatcher store_doc_file=null; /** * make a new watcher object for the messages file + * (thread safe - keeps a reference to the first watcher) * @return new watcher instance */ public FileWatcher getStoreWatcher() { + if (store_doc_file==null) + return store_doc_file = new FileWatcher(new File(CLOSEANDSAVE_FILE)); return new FileWatcher(new File(CLOSEANDSAVE_FILE)); + + } + /** + * write to the StoreWatcher file to indicate that a storeDocumentRequest has been made. + * The local client's storeWatcher FileWatcher object is updated so the initial change is not registered. + * @param client + * @param user + * @return + */ + public void addStoreDocumentRequest(ClientHandle client, UserHandle user) throws IOException { + SessionFile sfw = new SessionFile(new File(sessionDir, CLOSEANDSAVE_FILE)); + while (!sfw.lockFile()) + log.debug("Trying to get lock for "+CLOSEANDSAVE_FILE); + sfw.fileLock.rafile.setLength(0); // wipe out any old info. + // TODO: rationalise what gets written to this file (ie do we want other clients to read the id of the requestor?) + sfw.fileLock.rafile.writeUTF(client.getClientUrn()+":"+user.getFullName()+"@"+user.getOrganization()); + sfw.unlockFile(); + if (store_doc_file!=null) + store_doc_file.setState(); + slog.info("FinalizeAppData request from "+user.getFullName()+" using "+client.getClientUrn()+""); + } + /** + * create a new session with an existing vamsas Document - by copying it into the session. + * @param archive + */ + protected void setVamsasDocument(File archive) throws IOException { + log.debug("Transferring vamsas data from "+archive+" to session:"+vamArchive.sessionFile); + SessionFile xtantdoc = new SessionFile(archive); + vamArchive.updateFrom(null, xtantdoc); + // LATER: decide if session archive provenance should be updated to reflect access. + // TODO: soon! do a proper import objects from external file + log.debug("Transfer complete."); + } + /** + * write session as a new vamsas Document (this will overwrite any existing file without warning) + * TODO: test + * TODO: verify that lock should be released for vamsas document. + * @param destarchive + */ + protected void writeVamsasDocument(File destarchive, Lock extlock) throws IOException { + log.debug("Transferring vamsas data from "+vamArchive.sessionFile+" to session:"+destarchive); + SessionFile newdoc = new SessionFile(destarchive); + if (extlock==null && !vamArchive.lockFile()) + while (!vamArchive.lockFile()) + log.info("Trying to get lock for "+vamArchive.sessionFile); + // TODO: LATER: decide if session archive provenance should be written in vamsasDocument file for this export. + newdoc.updateFrom(extlock, vamArchive); + // LATER: LATER: fix use of updateFrom for file systems where locks cannot be made (because they don't have a lockManager, ie NFS/Unix, etc). + vamArchive.unLock(); + newdoc.unlockFile(); + log.debug("Transfer complete."); } + /** + * Creates a VamsasArchive Vobject for accessing and updating document + * Note: this will lock the Vamsas Document for exclusive access to the client. + * @return session vamsas document + * @throws IOException if locks fail or vamsas document read fails. + */ + protected VamsasArchive getVamsasDocument() throws IOException { + // TODO: check we haven't already done this once + if (!vamArchive.lockFile()) + throw new IOException("Failed to get lock for vamsas archive."); + + VamsasArchive va = new VamsasArchive(vamArchive.sessionFile, false, true, vamArchive); + + return va; + } + /** + * create a uniquely named file in the session Directory + * @see java.io.File.createTempFile + * @param pref Prefix for name + * @param suff Suffix for name + * @return SessionFile object configured for the new file (of length zero) + * @throws IOException + */ + protected SessionFile getTempSessionFile(String pref, String suff) throws IOException { + File tfile = File.createTempFile(pref,suff,sessionDir); + SessionFile tempFile = new SessionFile(tfile); + return tempFile; + } }