+++ /dev/null
-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.RandomAccessFile;
-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
- * just uses the one on the classpath).
- *
- * A vamsas session consists of :
- * SessionDir - translates to urn of a live session.
- * Contains: Vamsas Document (as a jar), Session client list file,
- * both of which may be locked, and additional
- * temporary versions of these files when write
- * operations are taking place.
- *
- * Zip file entries
- * - vamsasdocument.xml : core info
- * one or more:
- * - <applicationname>.version.sessionnumber.raw (string given in vamsasdocument.xml applicationData entry)
- *
- * Lockfile
- * - filename given in the vamsasdocument.xml. Should be checked for validity by any client and rewritten if necessary.
- * The lockfile can point to the jar itself.
- * Mode of operation.
- * Initially - documentHandler either:
- * - creates a zip for a new session for the client
- * - connect to an existing session zip
- * 1. reads session urn file
- * 2. waits for lock
- * 3. examines session - decide whether to create new application data slice or connect to one stored in session.
- * 4. writes info into session file
- * 5. releases lock and generates local client events.
- * 6. Creates Watcher thread to generate events.
- *
- * During the session
- * - Update watcher checks for file change -
- *
- * Procedures for file based session message exchange
- * - session document modification flag
- *
- */
-
-public class VamsasSession {
- /**
- * 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";
- /**
- * session file storing the last_stored_stat data
- */
- public static final String MODIFIEDDOC_FILE="modified";
-
- /**
- * called to clear update flag after a successful offline storage event
- */
- 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
- */
- 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 {
- // 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()));
- }
-
- /**
- * the sessionDir is given as the session location for new clients.
- */
- protected File sessionDir;
- /**
- * holds the list of attached clients
- */
- ClientsFile clist;
- 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));
- initLog();
- }
- /**
- * make a new watcher object for the clientFile
- * @return new ClientFile watcher instance
- */
- 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);
- RandomAccessFile sfwfile=sfw.fileLock.getRaFile();
- sfwfile.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?)
- sfwfile.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
- */
- public 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;
- }
-}
-
-