X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fuk%2Fac%2Fvamsas%2Fclient%2Fsimpleclient%2FVamsasSession.java;h=05014abad6c3565502e0520a017b57ee09bec456;hb=8879baa96b917d81b39fee0c2e2cc9e5021865bc;hp=e2e170c73a995206c3b81243ab3b0f183e9f1845;hpb=63844eaba88bbcde5e9ee51b111f849c2e71970d;p=vamsas.git diff --git a/src/uk/ac/vamsas/client/simpleclient/VamsasSession.java b/src/uk/ac/vamsas/client/simpleclient/VamsasSession.java index e2e170c..05014ab 100644 --- a/src/uk/ac/vamsas/client/simpleclient/VamsasSession.java +++ b/src/uk/ac/vamsas/client/simpleclient/VamsasSession.java @@ -1,20 +1,22 @@ package uk.ac.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 java.util.Enumeration; 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.apache.log4j.PatternLayout; import uk.ac.vamsas.client.ClientHandle; +import uk.ac.vamsas.client.IClient; import uk.ac.vamsas.client.UserHandle; /** * Does all the IO operations for a SimpleClient instance accessing @@ -79,6 +81,9 @@ public class VamsasSession { */ public static final String MODIFIEDDOC_FILE="modified"; + + private SimpleSessionManager sessionManager = null; + /** * called to clear update flag after a successful offline storage event */ @@ -115,22 +120,22 @@ public class VamsasSession { * @throws IOException */ private void initLog() throws IOException { + // TODO: fix session event logging // 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())); - - //Appender app = slog.getAppender("SESSION_LOG"); - if (app == null) log.info("No appender for SESSION_LOG"); + /*Appender app = slog.getAppender("log4j.appender.SESSIONLOG"); + // slog.addAppender(new FileAppender(app.getLayout(), new File(sessionDir, SESSION_LOG).getAbsolutePath())); + // slog.addAppender(new FileAppender(app.getLayout(), new File(sessionDir, SESSION_LOG).getAbsolutePath())); + for (Enumeration e = slog.getAllAppenders() ; e.hasMoreElements() ;) { + System.out.println(e.nextElement()); + + }*/ - if (slog!= null && app != null) - { - if (app instanceof FileAppender) - { - File sessionLogFile = new File(this.sessionDir, ((FileAppender)app).getFile()); - slog.addAppender(new FileAppender(app.getLayout(), sessionLogFile.getAbsolutePath())); - } - // slog.removeAppender("SESSION_LOG"); - } + if (slog!= null ) { + File sessionLogFile = new File(this.sessionDir, SESSION_LOG); + slog.addAppender(new FileAppender(new PatternLayout("%-4r [%t] %-5p %c %x - %m%n"), sessionLogFile.getAbsolutePath(), true)); + } else { + log.info("No appender for SessionLog"); + } } /** @@ -158,20 +163,17 @@ public class VamsasSession { if (sessionDir1.exists()) { if (!sessionDir1.isDirectory() || !sessionDir1.canWrite() || !sessionDir1.canRead()) throw new IOException("Cannot access '"+sessionDir1+"' as a read/writable Directory."); - if (checkSessionFiles(sessionDir1)) { - createSessionFiles(); - } - // session files exist in the directory - this.sessionDir = sessionDir1; - initSessionObjects(); - slog.debug("Initialising additional VamsasSession instance"); - log.debug("Attached to VamsasSession in "+sessionDir1); + if (!checkSessionFiles(sessionDir1)) + log.warn("checkSessionFiles() returned false. Possible client implementation error"); + this.sessionDir = sessionDir1; + initSessionObjects(); + slog.debug("Initialising additional VamsasSession instance"); + log.debug("Attached to VamsasSession in "+sessionDir1); //} } else { // start from scratch if (!sessionDir1.mkdir()) throw new IOException("Failed to make VamsasSession directory in "+sessionDir1); - this.sessionDir = sessionDir1; createSessionFiles(); initSessionObjects(); slog.debug("Session directory created."); @@ -199,19 +201,21 @@ public class VamsasSession { 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()) + if (!c_file.exists() && c_file.createNewFile()) log.debug("Created new ClientFile "+c_file); // don't care if this works or not - if (v_doc.createNewFile()) + if (!v_doc.exists() && 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 { + createSessionFiles(); 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)); + storedocfile=new ClientsFile(new File(sessionDir, CLOSEANDSAVE_FILE)); initLog(); } /** @@ -221,26 +225,21 @@ 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; + public ClientsFile storedocfile=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)); + return new FileWatcher(new File(sessionDir,CLOSEANDSAVE_FILE)); } /** @@ -251,6 +250,7 @@ public class VamsasSession { * @return */ public void addStoreDocumentRequest(ClientHandle client, UserHandle user) throws IOException { + // TODO: replace this with clientsFile mechanism SessionFile sfw = new SessionFile(new File(sessionDir, CLOSEANDSAVE_FILE)); while (!sfw.lockFile()) log.debug("Trying to get lock for "+CLOSEANDSAVE_FILE); @@ -287,14 +287,17 @@ public class VamsasSession { 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. + // TODO: LATER: decide if a provenance entry should be written in the exported document recording the export from the session 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."); } - + /** + * extant archive IO handler + */ + VamsasArchive _va=null; /** * Creates a VamsasArchive Vobject for accessing and updating document * Note: this will lock the Vamsas Document for exclusive access to the client. @@ -302,16 +305,36 @@ public class VamsasSession { * @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()) + // check we haven't already done this once - probably should be done by caller + if (_va!=null) + return _va; + // patiently wait for a lock on the document. (from ArchiveClient.getUpdateable()) + long tries=5000; + while (vamArchive.getLock()==null && --tries>0) { +// Thread.sleep(1); + log.debug("Trying to get a document lock for the "+tries+"'th time."); + } + if (tries==0) 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 + * Unlocks the vamsas archive session document after it has been closed. + * @throws IOException + */ + protected void unlockVamsasDocument() throws IOException { + if (_va!=null) + _va.closeArchive(); + _va=null; + if (vamArchive!=null) + vamArchive.unLock(); + + } + /** + * create a uniquely named uk.ac.vamsas.client.simpleclient.ClientsFile.addClient(ClientHandle)ile in the session Directory * @see java.io.File.createTempFile * @param pref Prefix for name * @param suff Suffix for name @@ -323,6 +346,90 @@ public class VamsasSession { SessionFile tempFile = new SessionFile(tfile); return tempFile; } + + /** + * add a IClient to the session + * + * add the client to the client list file + * @param client client to add to the session + */ + protected void addClient(IClient client) + { + if (client == null) + slog.error("Try to add a null client to the session "); + else { + log.debug("Adding client "+client.getClientHandle().getClientUrn()); + getClientWatcherElement().haltWatch(); + clist.addClient(client.getClientHandle()); + getClientWatcherElement().enableWatch(); + log.debug("Added."); + } + } + +/** + * + * removes a client from the current session + * removes the client from the session client list + * if the client is the last one from the session (ClientList), the current session is removed + * from active session list. + * + * @param client client to remove + */ + protected void removeClient(IClient client) + { + if (client == null) + { + log.error("Null client passed to removeClient"); + return; + } + SessionFileWatcherElement cwe=getClientWatcherElement(); + if (cwe!=null && cwe.isWatchEnabled()) { + cwe.haltWatch(); + } else { + cwe=null; + } + clist.removeClient(client.getClientHandle(),null); + if (this.clist.retrieveClientList() == null|| this.clist.retrieveClientList().length<1) + {//assume it is the last client has been removed shutting down session + slog.info("last client removed: removing session"); + log.debug("last client removed: removing session"); + this.getSessionManager().removeSession(client.getSessionHandle()); + } + else + { + int active=clist.retrieveClientList().length; + log.debug("Still "+active+" active clients"); + slog.info("Still "+active+" active clients"); + } + if (cwe!=null) { + cwe.enableWatch(); + } + } +/** + * @return the sessionManager + */ +protected SimpleSessionManager getSessionManager() { + return sessionManager; +} +/** + * @param sessionManager the sessionManager to set + */ +protected void setSessionManager(SimpleSessionManager sessionManager) { + this.sessionManager = sessionManager; +} +public ClientsFile getStoreDocFile() { + if (storedocfile==null) { + + } + return storedocfile; +} +SessionFileWatcherElement clistWatchElement=null; +public SessionFileWatcherElement getClientWatcherElement() { + if (clistWatchElement==null) { + clistWatchElement=new SessionFileWatcherElement(clist,null); + } + return clistWatchElement; +} }