X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fuk%2Fac%2Fvamsas%2Fclient%2Fsimpleclient%2FSessionsFile.java;h=ab26d201a367f2de4262a76d8f2b8a80397df152;hb=1eea4b639911330e7cd65e17c5421cc584f0d22e;hp=230c633ff5840fee76c265bb2eb380c410547bdc;hpb=9cb512e89c7e3016e8149d9e3df8ae6fcf9a410d;p=vamsas.git diff --git a/src/uk/ac/vamsas/client/simpleclient/SessionsFile.java b/src/uk/ac/vamsas/client/simpleclient/SessionsFile.java index 230c633..ab26d20 100644 --- a/src/uk/ac/vamsas/client/simpleclient/SessionsFile.java +++ b/src/uk/ac/vamsas/client/simpleclient/SessionsFile.java @@ -1,302 +1,347 @@ -/* - * -* VAMSAS Project -* -* Dec 13, 2006 - VamsasClient -* -*/ - -package uk.ac.vamsas.client.simpleclient; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import uk.ac.vamsas.client.SessionHandle; - -/** - * @author Pierre MARGUERITE - * - * - */ -public class SessionsFile extends ListFile { - - private static Log log = LogFactory.getLog(SessionsFile.class); - /** - * when set true - get FileNotFoundExceptions on WinXP when writing to locked stream after the backup has been made (via the backupFile method) - */ - boolean backup=false; - /** - * number of my session in list - passed back when a session - * is added to list, and used (if valid) for quickly - * looking up presence of session handle in the list. - */ - private int syncnum = 1; - /** - * @param file - */ - public SessionsFile(File file) throws java.io.IOException { - super(file); - } - - - /** - * internal method for getting sessionsList - ensures a lock has been made but - * does not release it. - * - * @return list of clients - */ - private SessionHandle[] retrieveSessionHandles() { - if (lockFile()) { - try { - SessionHandle[] sessions =null; - if (this.fileLock.length()>0) { - - ObjectInputStream is = new ObjectInputStream(this.fileLock.getBufferedInputStream(true)); - Object o; - o=is.readObject(); - if (o!=null) { - try { - sessions = (SessionHandle[]) o; - } - catch (Exception e) { - log.error("Garbage in the clientHandle list "+this.sessionFile,e); - } - } - // is.close(); - } - return sessions; - } catch (FileNotFoundException e) { - // e.printStackTrace(System.err); - log.error(e); - } catch (Exception e) { - log.error(e); - //e.printStackTrace(System.err); - } - } - return null; - } - - /** - * get the SessionsList from the file. May return null if lock failed! - * @return sessionsList - */ - public SessionHandle[] retrieveSessionsList() { - if (lockFile()) { - SessionHandle[] clients = retrieveSessionHandles(); - unlockFile(); - return clients; - } - return null; - } - - /** - * get list from the locked SessionsList. - * @param extantlock - * @return sessionList or null if lock failed (or file was empty) - */ - public SessionHandle[] retrieveSessionsList(Lock extantlock) { - if (lockFile(extantlock)) { - SessionHandle[] sessions = retrieveSessionHandles(); - unlockFile(); - return sessions; - } - return null; - } - - - /** - * adds SessionHandle me to the sessionList under an existing lock extantLock. - * @param newSession - * @param extantLock - * @return session index in list or 0 if lock was invalid or addSession operation failed. - */ - public int addSession(SessionHandle newSession, Lock extantLock) { - return addSession(newSession, true, extantLock); - } - - /** - * adds SessionsHandle me to the sessionsList under an existing lock. - * @param newSession - sessionsHandle - * @param disambig - if true then add will fail if an identical sessionHandle already exists - * @param extantLock - existing lock - * @return client index in list or 0 if addSession (or the lock) failed. - */ - - public int addSession(SessionHandle newSession, boolean disambig, Lock extantLock) { - if (lockFile(extantLock)) { - this.syncnum = addSession(newSession, disambig); - unlockFile(); - return this.syncnum; - } - return 0; - } - - /** - * removes the current session from the SessionsList without complaint if the session isn't in the sessionsList already. - * @param session session handle to be removed - * @param sessionlock existing lock passed from watcher. - */ - public void removeSession(SessionHandle session, Lock sessionlock) { - int mynum =-1; - if (lockFile(sessionlock)) { - - SessionHandle[] sessions = retrieveSessionHandles(); - if (sessions != null) { - if ((this.syncnum<=0 || this.syncnum>sessions.length) || !sessions[this.syncnum-1].equals(session)) { - for (int i = 0, j = sessions.length; i < j; i++) - { if (sessions[i].equals(session)) { - mynum=i; - break; - } - } - } else { - mynum=this.syncnum-1; - } - - if (mynum>-1) { - SessionHandle[] newlist = new SessionHandle[sessions.length - 1]; - for (int k=0,i = 0, j = sessions.length; i < j; i++) - if (i!=mynum) - newlist[k++] = sessions[i]; - if (!putSessionsList(newlist)) - throw new Error("Failed to write new sessionsList!"); // failed to put the sessionList to disk. - } - } - unlockFile(); - } else { - throw new Error("Couldn't get lock for "+((this.sessionFile==null) ? "Unitialised sessionFile in SessionsFile" : this.sessionFile.getAbsolutePath())); - } - } - /** - * Adds a SessionHandle to the SessionList file - optionally disambiguating - * the SessionHandle (modifes the URN). - * Note: Caller is left to release the lock on the SessionList. - * @param session - * @param disambiguate - - * flag indicating if the URN for me should be disambiguated to - * differentiate between sessions. - * @return index of sessionHandle in new list, or -1-position of existing - * sessionHandle (if disambiguate is true) - */ - protected int addSession(SessionHandle session, boolean disambiguate) { - int newsession = 0; - int tries=5; - while (tries-->0 && !lockFile()) - try { Thread.sleep(1); } catch (Exception e){}; - if (lockFile()) { - SessionHandle[] sessions = retrieveSessionHandles(); - - if (sessions == null) { - sessions = new SessionHandle[1]; - sessions[0] = session; - newsession = 1; - } else { - int k = 0; - for (int i = 0, j = sessions.length; i < j; i++) { - if ( sessions[i].equals(session)) { - if (disambiguate) { - while (sessions[i].equals(session)) { - // me.setClientUrn(me.getClientUrn() + k++); // TODO: make a better - // disambiguation of - // urn. - } - } else { - // will not write the ambiguous clientHandle to disk, just return - // its index. - return -1 - i; - } - } - } - int i, j; - SessionHandle[] newlist = new SessionHandle[sessions.length + 1]; - for (i = 0, j = sessions.length; i < j; i++) - newlist[i] = sessions[i]; - newlist[j] = session; - sessions = newlist; - newsession = j+1; - } - if (!putSessionsList(sessions)) - return 0; // failed to put the clientList to disk. - } - return newsession; - } - - - /** - * safely writes sessions array to the file referred to by sessionFile. - * - * @param clients - * @return true if successful write. Throws Errors otherwise. - */ - protected boolean putSessionsList(SessionHandle[] clients) { - if (lockFile()) { - File templist=null; - if (!this.backup || (templist = backupSessionFile()) != null) { - int retries=3; - while (retries-->0) { - try { - ObjectOutputStream os = - new ObjectOutputStream(this.fileLock.getBufferedOutputStream(true)); - log.debug("About to write "+clients.length+" sessionHandles to output stream."); - os.writeObject(clients); - // os.flush(); - os.close(); - // All done - remove the backup. - if (this.backup) - templist.delete(); - templist = null; - retries=-1; - } catch (Exception e) { - // System.err - //.println("Serious - problems writing to sessionFile."); - log.error("Serious - problems writing to sessionFile.",e); - if (retries>0 && templist != null) { - // System.err.println("Recovering from Backup in " - // + templist.getAbsolutePath()); - log.error("Recovering from Backup in "+ templist.getAbsolutePath()); - templist.renameTo(this.fileLock.target); - } - //e.printStackTrace(System.err); - log.error(e); - } - } - if (retries>-2) { - // System.err - // .println("Serious - problems writing to sessionFile. Giving Up."); - log.error("Serious - problems writing to sessionFile. Giving Up."); - return false; - } - } else { - throw new Error( - "Couldn't create backup of the clientList before writing to it!"); - } - } else { - throw new Error("Could not lock the clientList: " - + ((this.sessionFile == null) ? "Unitialized ClientsFile" - : " failed to get lock on " + this.sessionFile.getAbsolutePath())); - } - // successful! - return true; - } - - public void clearList() { - if (lockFile()) { - try { - FileOutputStream fout = this.fileLock.getFileOutputStream(true); - fout.flush(); - fout.close(); - } catch (Exception e) { - throw new Error("Problems trying to clear clientlist!",e); - - } - } - - } -} +/* + * This file is part of the Vamsas Client version 0.2. + * Copyright 2010 by Jim Procter, Iain Milne, Pierre Marguerite, + * Andrew Waterhouse and Dominik Lindner. + * + * Earlier versions have also been incorporated into Jalview version 2.4 + * since 2008, and TOPALi version 2 since 2007. + * + * The Vamsas Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Vamsas Client is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the Vamsas Client. If not, see . + */ +package uk.ac.vamsas.client.simpleclient; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import uk.ac.vamsas.client.SessionHandle; +import uk.ac.vamsas.client.simpleclient.SimpleSessionHandle; + +/** + * @author Pierre MARGUERITE + * + * + */ +public class SessionsFile extends ListFile { + + private static Log log = LogFactory.getLog(SessionsFile.class); + + /** + * when set true - get FileNotFoundExceptions on WinXP when writing to locked + * stream after the backup has been made (via the backupFile method) + */ + boolean backup = false; + + /** + * number of my session in list - passed back when a session is added to list, + * and used (if valid) for quickly looking up presence of session handle in + * the list. + */ + private int syncnum = 1; + + /** + * @param file + */ + public SessionsFile(File file) throws java.io.IOException { + super(file); + } + + /** + * internal method for getting sessionsList - ensures a lock has been made but + * does not release it. + * + * @return list of clients + */ + private SimpleSessionHandle[] retrieveSessionHandles() { + if (lockFile()) { + try { + SimpleSessionHandle[] sessions = null; + if (this.fileLock.length() > 0) { + + ObjectInputStream is = new ObjectInputStream(this.fileLock + .getBufferedInputStream(true)); + Object o; + o = is.readObject(); + if (o != null) { + try { + sessions = (SimpleSessionHandle[]) o; + } catch (Exception e) { + log.error("Garbage in the clientHandle list " + this.sessionFile, + e); + } + } + // is.close(); + } + return sessions; + } catch (FileNotFoundException e) { + // e.printStackTrace(System.err); + log.error(e); + } catch (Exception e) { + log.error(e); + // e.printStackTrace(System.err); + } + } + return null; + } + + /** + * get the SessionsList from the file. May return null if lock failed! + * + * @return sessionsList + */ + public SimpleSessionHandle[] retrieveSessionsList() { + if (lockFile()) { + SimpleSessionHandle[] clients = retrieveSessionHandles(); + unlockFile(); + return clients; + } + return null; + } + + /** + * get list from the locked SessionsList. + * + * @param extantlock + * @return sessionList or null if lock failed (or file was empty) + */ + public SimpleSessionHandle[] retrieveSessionsList(Lock extantlock) { + if (lockFile(extantlock)) { + SimpleSessionHandle[] sessions = retrieveSessionHandles(); + unlockFile(); + return sessions; + } + return null; + } + + /** + * adds SessionHandle me to the sessionList under an existing lock extantLock. + * + * @param newSession + * @param extantLock + * @return session index in list or 0 if lock was invalid or addSession + * operation failed. + */ + public int addSession(SimpleSessionHandle newSession, Lock extantLock) { + return addSession(newSession, true, extantLock); + } + + /** + * adds SessionsHandle me to the sessionsList under an existing lock. + * + * @param newSession + * - sessionsHandle + * @param disambig + * - if true then add will fail if an identical sessionHandle already + * exists + * @param extantLock + * - existing lock + * @return client index in list or 0 if addSession (or the lock) failed. + */ + + public int addSession(SimpleSessionHandle newSession, boolean disambig, + Lock extantLock) { + if (lockFile(extantLock)) { + this.syncnum = addSession(newSession, disambig); + unlockFile(); + return this.syncnum; + } + return 0; + } + + /** + * removes the current session from the SessionsList without complaint if the + * session isn't in the sessionsList already. + * + * @param session + * session handle to be removed + * @param sessionlock + * existing lock passed from watcher. + */ + public void removeSession(SessionHandle session, Lock sessionlock) { + int mynum = -1; + if (lockFile(sessionlock)) { + + SimpleSessionHandle[] sessions = retrieveSessionHandles(); + if (sessions != null) { + if ((this.syncnum <= 0 || this.syncnum > sessions.length) + || !session.equals(sessions[this.syncnum - 1])) { + for (int i = 0, j = sessions.length; i < j; i++) { + if (sessions[i].equals(session)) { + mynum = i; + break; + } + } + } else { + mynum = this.syncnum - 1; + } + + if (mynum > -1) { + SimpleSessionHandle[] newlist = new SimpleSessionHandle[sessions.length - 1]; + for (int k = 0, i = 0, j = sessions.length; i < j; i++) + if (i != mynum) + newlist[k++] = sessions[i]; + if (!putSessionsList(newlist)) + throw new Error("Failed to write new sessionsList!"); // failed to + // put the + // sessionList + // to disk. + } + } + unlockFile(); + } else { + throw new Error( + "Couldn't get lock for " + + ((this.sessionFile == null) ? "Unitialised sessionFile in SessionsFile" + : this.sessionFile.getAbsolutePath())); + } + } + + /** + * Adds a SessionHandle to the SessionList file - optionally disambiguating + * the SessionHandle (modifes the URN). Note: Caller is left to release the + * lock on the SessionList. + * + * @param session + * @param disambiguate + * - flag indicating if the URN for me should be disambiguated to + * differentiate between sessions. + * @return index of sessionHandle in new list, or -1-position of existing + * sessionHandle (if disambiguate is true) + */ + protected int addSession(SimpleSessionHandle session, boolean disambiguate) { + int newsession = 0; + int tries = 5; + while (tries-- > 0 && !lockFile()) + try { + Thread.sleep(1); + } catch (Exception e) { + } + ; + if (lockFile()) { + SimpleSessionHandle[] sessions = retrieveSessionHandles(); + + if (sessions == null) { + sessions = new SimpleSessionHandle[1]; + sessions[0] = session; + newsession = 1; + } else { + int k = 0; + for (int i = 0, j = sessions.length; i < j; i++) { + if (sessions[i].equals(session)) { + if (disambiguate) { + while (sessions[i].equals(session)) { + // me.setClientUrn(me.getClientUrn() + k++); // TODO: make a + // better + // disambiguation of + // urn. + } + } else { + // will not write the ambiguous clientHandle to disk, just return + // its index. + return -1 - i; + } + } + } + int i, j; + SimpleSessionHandle[] newlist = new SimpleSessionHandle[sessions.length + 1]; + for (i = 0, j = sessions.length; i < j; i++) + newlist[i] = sessions[i]; + newlist[j] = session; + sessions = newlist; + newsession = j + 1; + } + if (!putSessionsList(sessions)) + return 0; // failed to put the clientList to disk. + } + return newsession; + } + + /** + * safely writes sessions array to the file referred to by sessionFile. + * + * @param clients + * @return true if successful write. Throws Errors otherwise. + */ + protected boolean putSessionsList(SimpleSessionHandle[] clients) { + if (lockFile()) { + File templist = null; + if (!this.backup || (templist = backupSessionFile()) != null) { + int retries = 3; + while (retries-- > 0) { + try { + ObjectOutputStream os = new ObjectOutputStream(this.fileLock + .getBufferedOutputStream(true)); + log.debug("About to write " + clients.length + + " sessionHandles to output stream."); + os.writeObject(clients); + // os.flush(); + os.close(); + // All done - remove the backup. + if (this.backup) + templist.delete(); + templist = null; + retries = -1; + } catch (Exception e) { + // System.err + // .println("Serious - problems writing to sessionFile."); + log.error("Serious - problems writing to sessionFile.", e); + if (retries > 0 && templist != null) { + // System.err.println("Recovering from Backup in " + // + templist.getAbsolutePath()); + log.error("Recovering from Backup in " + + templist.getAbsolutePath()); + templist.renameTo(this.fileLock.target); + } + // e.printStackTrace(System.err); + log.error(e); + } + } + if (retries > -2) { + // System.err + // .println("Serious - problems writing to sessionFile. Giving Up."); + log.error("Serious - problems writing to sessionFile. Giving Up."); + return false; + } + } else { + throw new Error( + "Couldn't create backup of the clientList before writing to it!"); + } + } else { + throw new Error("Could not lock the clientList: " + + ((this.sessionFile == null) ? "Unitialized ClientsFile" + : " failed to get lock on " + this.sessionFile.getAbsolutePath())); + } + // successful! + return true; + } + + public void clearList() { + if (lockFile()) { + try { + FileOutputStream fout = this.fileLock.getFileOutputStream(true); + fout.flush(); + fout.close(); + } catch (Exception e) { + throw new Error("Problems trying to clear clientlist!", e); + + } + } + + } +}