X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fuk%2Fac%2Fvamsas%2Fclient%2Fsimpleclient%2FClientsFile.java;h=f83324aa6f6ad51e3a347e479d30dcac93594f73;hb=844ccad5a3fcbedec17b2af66d460f31abc7cff1;hp=e700ee44abe27fdf3196f97523aa6c413577c08f;hpb=6f33f705957d674dc2ab6c994a6ea87f7a91f40f;p=vamsas.git diff --git a/src/uk/ac/vamsas/client/simpleclient/ClientsFile.java b/src/uk/ac/vamsas/client/simpleclient/ClientsFile.java index e700ee4..f83324a 100644 --- a/src/uk/ac/vamsas/client/simpleclient/ClientsFile.java +++ b/src/uk/ac/vamsas/client/simpleclient/ClientsFile.java @@ -1,298 +1,355 @@ -package uk.ac.vamsas.client.simpleclient; - -import uk.ac.vamsas.client.*; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.ObjectInputStream; -import java.io.ObjectOutput; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.util.Vector; - -/** - * Handler for the clientsFile within a vamsas session thread. - * @author jim - */ -public class ClientsFile extends ListFile { - private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(ClientsFile.class); - /** - * number of my client in list - passed back when a client - * is added to list, and used (if valid) for quickly - * looking up presence of client handle in the list. - */ - private int syncnum = 1; - - public ClientsFile(File filelist) throws IOException { - super(filelist); - } - - /** - * internal method for getting clientList - ensures a lock has been made but - * does not release it. - * - * @return list of clients - */ - private ClientHandle[] retrieveClientHandles() { - if (lockFile()) { - try { - ClientHandle[] clients=null; - if (fileLock.length()>0) { - - ObjectInputStream is = new ObjectInputStream(fileLock.getBufferedInputStream(true)); - Object o; - o=is.readObject(); - if (o!=null) { - try { - clients = (ClientHandle[]) o; - } - catch (Exception e) { - System.err.println("Garbage in the clientHandle list "+this.sessionFile); - } - } - } - return clients; - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(System.err); - } catch (Exception e) { - e.printStackTrace(System.err); - } - } - return null; - } - /** - * get the clientList from the file. May return null if lock failed! - * @return clientList - */ - public ClientHandle[] retrieveClientList() { - if (lockFile()) { - ClientHandle[] clients = retrieveClientHandles(); - unlockFile(); - return clients; - } - return null; - } - /** - * get list from the locked ClientList. - * @param extantlock - * @return clientList or null if lock failed (or file was empty) - */ - public ClientHandle[] retrieveClientList(Lock extantlock) { - if (lockFile(extantlock)) { - ClientHandle[] clients = retrieveClientHandles(); - unlockFile(); - return clients; - } - return null; - } - /** - * adds clientHandle me to the clientList under an existing lock extantLock. - * @param me - * @param extantLock - * @return client index in list or 0 if lock was invalid or addClient operation failed. - */ - public int addClient(ClientHandle me, Lock extantLock) { - return addClient(me, true, extantLock); - } - - /** - * adds clientHandle me to the clientList under an existing lock. - * @param me - clientHandle - * @param disambig - if true then add will fail if an identical clientHandle already exists - * @param extantLock - existing lock - * @return client index in list or 0 if addClient (or the lock) failed. - */ - - public int addClient(ClientHandle me, boolean disambig, Lock extantLock) { - if (lockFile(extantLock)) { - syncnum = addClient(me, disambig); - unlockFile(); - return syncnum; - } - return 0; - } - - /** - * adds the ClientHandle to the list - if it is not unique, then the - * ClientHandle object is modified to make it unique in the list. returns the - * clientNumber for the client in the session. - * - * @param me - * @return - */ - - public int addClient(ClientHandle me) { - syncnum = addClient(me, true); - unlockFile(); - return syncnum; - } - - /** - * removes 'me' from the session ClientList without complaint if 'me' isn't in the clientList already. - * @param me client handle to be removed - * @param clientlock existing lock passed from watcher. - */ - public void removeClient(ClientHandle me, Lock clientlock) { - int mynum=-1; - if (lockFile(clientlock)) { - ClientHandle[] clients = retrieveClientHandles(); - if (clients != null) { - if ((syncnum<=0 || syncnum>clients.length) || clients[syncnum-1]!=me) { - for (int i = 0, j = clients.length; i < j; i++) - if (clients[i].equals(me)) { - mynum=i; - break; - } - } else { - mynum=syncnum-1; - } - if (mynum>-1) { - ClientHandle[] newlist = new ClientHandle[clients.length - 1]; - for (int k=0,i = 0, j = clients.length; i < j; i++) - if (i!=mynum) - newlist[k++] = clients[i]; - if (!putClientList(newlist)) - throw new Error("Failed to write new clientList!"); // failed to put the clientList to disk. - } - } - unlockFile(); - } else { - throw new Error("Couldn't get lock for "+((sessionFile==null) ? "Unitialised sessionFile in ClientsFile" : sessionFile.getAbsolutePath())); - } - } - /** - * Adds a ClientHandle to the ClientList file - optionally disambiguating - * the ClientHandle (modifes the URN). - * Note: Caller is left to release the lock on the ClientList. - * @param me - * @param disambiguate - - * flag indicating if the URN for me should be disambiguated to - * differentiate between sessions. - * @return index of clientHandle in new list, or -1-position of existing - * clientHandle (if disambiguate is true) - */ - protected int addClient(ClientHandle me, boolean disambiguate) { - int newclient = 0; - int tries=5; - while (tries-->0 && !lockFile()) - try { Thread.sleep(1); } catch (Exception e){}; - if (lockFile()) { - ClientHandle[] clients = retrieveClientHandles(); - if (me.getClientUrn()==null) { - // TODO: move this into ClientUrn as a standard form method. - me.setClientUrn("vamsas://"+me.getClientName()+":"+me.getVersion()+"/"); - } - if (clients == null) { - clients = new ClientHandle[1]; - clients[0] = me; - newclient = 1; - } else { - int k = 0; - for (int i = 0, j = clients.length; i < j; i++) { - if (clients[i].equals(me)) { - if (disambiguate) { - while (clients[i].equals(me)) { - 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; - ClientHandle[] newlist = new ClientHandle[clients.length + 1]; - for (i = 0, j = clients.length; i < j; i++) - newlist[i] = clients[i]; - newlist[j] = me; - clients = newlist; - newclient = j+1; - } - if (!putClientList(clients)) - return 0; // failed to put the clientList to disk. - } - return newclient; - } - /** - * 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; - /** - * safely writes clients array to the file referred to by sessionFile. - * - * @param clients - * @return true if successful write. Throws Errors otherwise. - */ - protected boolean putClientList(ClientHandle[] clients) { - if (lockFile()) { - File templist=null; - if (backup) { - templist = backupSessionFile(); - } - if (!backup || (templist != null)) { - int retries=3; - while (retries-->0) { - try { - ObjectOutputStream os = - new ObjectOutputStream(fileLock.getBufferedOutputStream(true)); - log.debug("About to write "+clients.length+" clientHandles to output stream."); - os.writeObject(clients); - os.close(); - // All done - remove the backup. - if (backup) - templist.delete(); - templist = null; - retries=-1; - } catch (Exception e) { - System.err - .println("Serious - problems writing to sessionFile."); - if (retries>0 && templist != null) { - System.err.println("Recovering from Backup in " - + templist.getAbsolutePath()); - templist.renameTo(fileLock.target); - } - e.printStackTrace(System.err); - } - } - if (retries>-2) { - System.err - .println("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: " - + ((sessionFile == null) ? "Unitialized ClientsFile" - : " failed to get lock on " + sessionFile.getAbsolutePath())); - } - // successful! - return true; - } - - public void clearList() { - if (lockFile()) { - try { - FileOutputStream fout = 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.1. + * Copyright 2009 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 uk.ac.vamsas.client.*; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.util.Vector; + +/** + * Handler for the clientsFile within a vamsas session thread. + * + * @author jim + */ +public class ClientsFile extends ListFile { + private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory + .getLog(ClientsFile.class); + + /** + * number of my client in list - passed back when a client is added to list, + * and used (if valid) for quickly looking up presence of client handle in the + * list. + */ + private int syncnum = 1; + + public ClientsFile(File filelist) throws IOException { + super(filelist); + } + + /** + * internal method for getting clientList - ensures a lock has been made but + * does not release it. + * + * @return list of clients + */ + private ClientHandle[] retrieveClientHandles() { + if (lockFile()) { + try { + ClientHandle[] clients = null; + if (fileLock.length() > 0) { + + ObjectInputStream is = new ObjectInputStream(fileLock + .getBufferedInputStream(true)); + Object o; + o = is.readObject(); + if (o != null) { + try { + clients = (ClientHandle[]) o; + } catch (Exception e) { + System.err.println("Garbage in the clientHandle list " + + this.sessionFile); + } + } + } + return clients; + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(System.err); + } catch (Exception e) { + e.printStackTrace(System.err); + } + } + return null; + } + + /** + * get the clientList from the file. May return null if lock failed! + * + * @return clientList + */ + public ClientHandle[] retrieveClientList() { + if (lockFile()) { + ClientHandle[] clients = retrieveClientHandles(); + unlockFile(); + return clients; + } + return null; + } + + /** + * get list from the locked ClientList. + * + * @param extantlock + * @return clientList or null if lock failed (or file was empty) + */ + public ClientHandle[] retrieveClientList(Lock extantlock) { + if (lockFile(extantlock)) { + ClientHandle[] clients = retrieveClientHandles(); + unlockFile(); + return clients; + } + return null; + } + + /** + * adds clientHandle me to the clientList under an existing lock extantLock. + * + * @param me + * @param extantLock + * @return client index in list or 0 if lock was invalid or addClient + * operation failed. + */ + public int addClient(ClientHandle me, Lock extantLock) { + return addClient(me, true, extantLock); + } + + /** + * adds clientHandle me to the clientList under an existing lock. + * + * @param me + * - clientHandle + * @param disambig + * - if true then add will fail if an identical clientHandle already + * exists + * @param extantLock + * - existing lock + * @return client index in list or 0 if addClient (or the lock) failed. + */ + + public int addClient(ClientHandle me, boolean disambig, Lock extantLock) { + if (lockFile(extantLock)) { + syncnum = addClient(me, disambig); + unlockFile(); + return syncnum; + } + return 0; + } + + /** + * adds the ClientHandle to the list - if it is not unique, then the + * ClientHandle object is modified to make it unique in the list. returns the + * clientNumber for the client in the session. + * + * @param me + * @return + */ + + public int addClient(ClientHandle me) { + syncnum = addClient(me, true); + unlockFile(); + return syncnum; + } + + /** + * removes 'me' from the session ClientList without complaint if 'me' isn't in + * the clientList already. + * + * @param me + * client handle to be removed + * @param clientlock + * existing lock passed from watcher. + */ + public void removeClient(ClientHandle me, Lock clientlock) { + int mynum = -1; + if (lockFile(clientlock)) { + ClientHandle[] clients = retrieveClientHandles(); + if (clients != null) { + if ((syncnum <= 0 || syncnum > clients.length) + || clients[syncnum - 1] != me) { + for (int i = 0, j = clients.length; i < j; i++) + if (clients[i].equals(me)) { + mynum = i; + break; + } + } else { + mynum = syncnum - 1; + } + if (mynum > -1) { + ClientHandle[] newlist = new ClientHandle[clients.length - 1]; + for (int k = 0, i = 0, j = clients.length; i < j; i++) + if (i != mynum) + newlist[k++] = clients[i]; + if (!putClientList(newlist)) + throw new Error("Failed to write new clientList!"); // failed to put + // the + // clientList to + // disk. + } + } + unlockFile(); + } else { + throw new Error("Couldn't get lock for " + + ((sessionFile == null) ? "Unitialised sessionFile in ClientsFile" + : sessionFile.getAbsolutePath())); + } + } + + /** + * Adds a ClientHandle to the ClientList file - optionally disambiguating the + * ClientHandle (modifes the URN). Note: Caller is left to release the lock on + * the ClientList. + * + * @param me + * @param disambiguate + * - flag indicating if the URN for me should be disambiguated to + * differentiate between sessions. + * @return index of clientHandle in new list, or -1-position of existing + * clientHandle (if disambiguate is true) + */ + protected int addClient(ClientHandle me, boolean disambiguate) { + int newclient = 0; + int tries = 5; + while (tries-- > 0 && !lockFile()) + try { + Thread.sleep(1); + } catch (Exception e) { + } + ; + if (lockFile()) { + ClientHandle[] clients = retrieveClientHandles(); + if (me.getClientUrn() == null) { + // TODO: move this into ClientUrn as a standard form method. + me.setClientUrn("vamsas://" + me.getClientName() + ":" + + me.getVersion() + "/"); + } + if (clients == null) { + clients = new ClientHandle[1]; + clients[0] = me; + newclient = 1; + } else { + int k = 0; + for (int i = 0, j = clients.length; i < j; i++) { + if (clients[i].equals(me)) { + if (disambiguate) { + while (clients[i].equals(me)) { + 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; + ClientHandle[] newlist = new ClientHandle[clients.length + 1]; + for (i = 0, j = clients.length; i < j; i++) + newlist[i] = clients[i]; + newlist[j] = me; + clients = newlist; + newclient = j + 1; + } + if (!putClientList(clients)) + return 0; // failed to put the clientList to disk. + } + return newclient; + } + + /** + * 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; + + /** + * safely writes clients array to the file referred to by sessionFile. + * + * @param clients + * @return true if successful write. Throws Errors otherwise. + */ + protected boolean putClientList(ClientHandle[] clients) { + if (lockFile()) { + File templist = null; + if (backup) { + templist = backupSessionFile(); + } + if (!backup || (templist != null)) { + int retries = 3; + while (retries-- > 0) { + try { + ObjectOutputStream os = new ObjectOutputStream(fileLock + .getBufferedOutputStream(true)); + log.debug("About to write " + clients.length + + " clientHandles to output stream."); + os.writeObject(clients); + os.close(); + // All done - remove the backup. + if (backup) + templist.delete(); + templist = null; + retries = -1; + } catch (Exception e) { + System.err.println("Serious - problems writing to sessionFile."); + if (retries > 0 && templist != null) { + System.err.println("Recovering from Backup in " + + templist.getAbsolutePath()); + templist.renameTo(fileLock.target); + } + e.printStackTrace(System.err); + } + } + if (retries > -2) { + System.err + .println("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: " + + ((sessionFile == null) ? "Unitialized ClientsFile" + : " failed to get lock on " + sessionFile.getAbsolutePath())); + } + // successful! + return true; + } + + public void clearList() { + if (lockFile()) { + try { + FileOutputStream fout = fileLock.getFileOutputStream(true); + fout.flush(); + fout.close(); + } catch (Exception e) { + throw new Error("Problems trying to clear clientlist!", e); + + } + } + + } +}