verson 0.2 LGPL licensed source and jars
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / SessionsFile.java
index f931118..ab26d20 100644 (file)
-/* EMBL - The European Bioinformatics institute
-* MSD Group
-* VAMSAS Project
-*
-*  Copyright (c) 2005-2006 Thr European Bioinformatics Institute. All rights reserved.
-*
-*   Redistribution and use in source and binary forms, with or without
-*   modification, are permitted provided that the following conditions
-*   are met:
-*  
-*   1. Redistributions of source code must retain the above copyright
-*      notice, this list of conditions and the following disclaimer. 
-*  
-*   2. Redistributions in binary form must reproduce the above copyright
-*      notice, this list of conditions and the following disclaimer in
-*      the documentation and/or other materials provided with the
-*      distribution.
-*  
-*   3. The name MSD must not be used to endorse or promote products 
-*      derived from this software without prior written permission. For 
-*      written permission, please contact msd-help@ebi.ac.uk
-*  
-*   4. Products derived from this software may not be called "MSD"
-*      nor may "MSD" appear in their names without prior written
-*      permission of the MSD developers.
-*  
-*   5. Redistributions of any form whatsoever must retain the following
-*      acknowledgment:
-*      "This product includes software developed by MSD 
-*       (http://www.ebi.ac.uk/)"
-*  
-*   THIS SOFTWARE IS PROVIDED BY THE MSD GROUP ``AS IS'' AND ANY
-*   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-*   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-*   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ENSEMBL GROUP OR
-*   ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-*   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-*   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-*   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-*   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-*   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-*   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-*   OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* The European Bioinformatics Institute may publish revised and/or new
-* versions of this license with new releases of VAMSAS software.
-*==============================================================================
-*
-*  @author <a href="mailto:pierre@ebi.ac.uk">Pierre MARGUERITE</a>
-* 
-* Dec 13, 2006  - VamsasClientV4
-*
-*/
-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 org.vamsas.client.SessionHandle;
-
-/**
- * @author <a href="mailto:pierre@ebi.ac.uk">Pierre MARGUERITE</a>
- * 
- * 
- */
-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[] clients=null;
-        if (this.fileLock.length()>0) {
-          
-          ObjectInputStream is = new ObjectInputStream(this.fileLock.getBufferedInputStream(true));
-          Object o;
-          o=is.readObject();
-          if (o!=null) {
-            try {
-              clients = (SessionHandle[]) o;
-            }
-            catch (Exception e) {
-              log.error("Garbage in the clientHandle list "+this.sessionFile,e);
-            }
-          }
-        }
-        return clients;
-      } 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 ClientList.
-   * @param extantlock
-   * @return clientList or null if lock failed (or file was empty)
-   */
-  public SessionHandle[] retrieveSessionsList(Lock extantlock) {
-    if (lockFile(extantlock)) {
-     SessionHandle[] clients = retrieveSessionHandles();
-      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 addSession(SessionHandle me, Lock extantLock) {
-    return addSession(me, true, extantLock);
-  }
-  
-  /**
-   * adds SessionsHandle me to the sessionsList under an existing lock.
-   * @param me - sessionsHandle
-   * @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 addSession(SessionHandle session, boolean disambig, Lock extantLock) {
-    if (lockFile(extantLock)) {
-      this.syncnum = addSession(session, 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 me client handle to be removed
-   * @param clientlock existing lock passed from watcher.
-   */
-  public void removeSession(SessionHandle session, Lock clientlock) {
-    int mynum =-1;
-    if (lockFile(clientlock)) {
-      SessionHandle[] sessions = retrieveSessionHandles();
-      if (sessions != null) {
-        if ((this.syncnum<=0 || this.syncnum>sessions.length) || sessions[this.syncnum-1]!=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 "+((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 me
-   * @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.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);
-        
-      }
-    }
-    
-  }
-}
+/*\r
+ * This file is part of the Vamsas Client version 0.2. \r
+ * Copyright 2010 by Jim Procter, Iain Milne, Pierre Marguerite, \r
+ *  Andrew Waterhouse and Dominik Lindner.\r
+ * \r
+ * Earlier versions have also been incorporated into Jalview version 2.4 \r
+ * since 2008, and TOPALi version 2 since 2007.\r
+ * \r
+ * The Vamsas Client is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU Lesser General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *  \r
+ * The Vamsas Client is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU Lesser General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU Lesser General Public License\r
+ * along with the Vamsas Client.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package uk.ac.vamsas.client.simpleclient;\r
+\r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.ObjectInputStream;\r
+import java.io.ObjectOutputStream;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+\r
+import uk.ac.vamsas.client.SessionHandle;\r
+import uk.ac.vamsas.client.simpleclient.SimpleSessionHandle;\r
+\r
+/**\r
+ * @author <a href="mailto:pierre@ebi.ac.uk">Pierre MARGUERITE</a>\r
+ * \r
+ * \r
+ */\r
+public class SessionsFile extends ListFile {\r
+\r
+  private static Log log = LogFactory.getLog(SessionsFile.class);\r
+\r
+  /**\r
+   * when set true - get FileNotFoundExceptions on WinXP when writing to locked\r
+   * stream after the backup has been made (via the backupFile method)\r
+   */\r
+  boolean backup = false;\r
+\r
+  /**\r
+   * number of my session in list - passed back when a session is added to list,\r
+   * and used (if valid) for quickly looking up presence of session handle in\r
+   * the list.\r
+   */\r
+  private int syncnum = 1;\r
+\r
+  /**\r
+   * @param file\r
+   */\r
+  public SessionsFile(File file) throws java.io.IOException {\r
+    super(file);\r
+  }\r
+\r
+  /**\r
+   * internal method for getting sessionsList - ensures a lock has been made but\r
+   * does not release it.\r
+   * \r
+   * @return list of clients\r
+   */\r
+  private SimpleSessionHandle[] retrieveSessionHandles() {\r
+    if (lockFile()) {\r
+      try {\r
+        SimpleSessionHandle[] sessions = null;\r
+        if (this.fileLock.length() > 0) {\r
+\r
+          ObjectInputStream is = new ObjectInputStream(this.fileLock\r
+              .getBufferedInputStream(true));\r
+          Object o;\r
+          o = is.readObject();\r
+          if (o != null) {\r
+            try {\r
+              sessions = (SimpleSessionHandle[]) o;\r
+            } catch (Exception e) {\r
+              log.error("Garbage in the clientHandle list " + this.sessionFile,\r
+                  e);\r
+            }\r
+          }\r
+          // is.close();\r
+        }\r
+        return sessions;\r
+      } catch (FileNotFoundException e) {\r
+        // e.printStackTrace(System.err);\r
+        log.error(e);\r
+      } catch (Exception e) {\r
+        log.error(e);\r
+        // e.printStackTrace(System.err);\r
+      }\r
+    }\r
+    return null;\r
+  }\r
+\r
+  /**\r
+   * get the SessionsList from the file. May return null if lock failed!\r
+   * \r
+   * @return sessionsList\r
+   */\r
+  public SimpleSessionHandle[] retrieveSessionsList() {\r
+    if (lockFile()) {\r
+      SimpleSessionHandle[] clients = retrieveSessionHandles();\r
+      unlockFile();\r
+      return clients;\r
+    }\r
+    return null;\r
+  }\r
+\r
+  /**\r
+   * get list from the locked SessionsList.\r
+   * \r
+   * @param extantlock\r
+   * @return sessionList or null if lock failed (or file was empty)\r
+   */\r
+  public SimpleSessionHandle[] retrieveSessionsList(Lock extantlock) {\r
+    if (lockFile(extantlock)) {\r
+      SimpleSessionHandle[] sessions = retrieveSessionHandles();\r
+      unlockFile();\r
+      return sessions;\r
+    }\r
+    return null;\r
+  }\r
+\r
+  /**\r
+   * adds SessionHandle me to the sessionList under an existing lock extantLock.\r
+   * \r
+   * @param newSession\r
+   * @param extantLock\r
+   * @return session index in list or 0 if lock was invalid or addSession\r
+   *         operation failed.\r
+   */\r
+  public int addSession(SimpleSessionHandle newSession, Lock extantLock) {\r
+    return addSession(newSession, true, extantLock);\r
+  }\r
+\r
+  /**\r
+   * adds SessionsHandle me to the sessionsList under an existing lock.\r
+   * \r
+   * @param newSession\r
+   *          - sessionsHandle\r
+   * @param disambig\r
+   *          - if true then add will fail if an identical sessionHandle already\r
+   *          exists\r
+   * @param extantLock\r
+   *          - existing lock\r
+   * @return client index in list or 0 if addSession (or the lock) failed.\r
+   */\r
+\r
+  public int addSession(SimpleSessionHandle newSession, boolean disambig,\r
+      Lock extantLock) {\r
+    if (lockFile(extantLock)) {\r
+      this.syncnum = addSession(newSession, disambig);\r
+      unlockFile();\r
+      return this.syncnum;\r
+    }\r
+    return 0;\r
+  }\r
+\r
+  /**\r
+   * removes the current session from the SessionsList without complaint if the\r
+   * session isn't in the sessionsList already.\r
+   * \r
+   * @param session\r
+   *          session handle to be removed\r
+   * @param sessionlock\r
+   *          existing lock passed from watcher.\r
+   */\r
+  public void removeSession(SessionHandle session, Lock sessionlock) {\r
+    int mynum = -1;\r
+    if (lockFile(sessionlock)) {\r
+\r
+      SimpleSessionHandle[] sessions = retrieveSessionHandles();\r
+      if (sessions != null) {\r
+        if ((this.syncnum <= 0 || this.syncnum > sessions.length)\r
+            || !session.equals(sessions[this.syncnum - 1])) {\r
+          for (int i = 0, j = sessions.length; i < j; i++) {\r
+            if (sessions[i].equals(session)) {\r
+              mynum = i;\r
+              break;\r
+            }\r
+          }\r
+        } else {\r
+          mynum = this.syncnum - 1;\r
+        }\r
+\r
+        if (mynum > -1) {\r
+          SimpleSessionHandle[] newlist = new SimpleSessionHandle[sessions.length - 1];\r
+          for (int k = 0, i = 0, j = sessions.length; i < j; i++)\r
+            if (i != mynum)\r
+              newlist[k++] = sessions[i];\r
+          if (!putSessionsList(newlist))\r
+            throw new Error("Failed to write new sessionsList!"); // failed to\r
+                                                                  // put the\r
+                                                                  // sessionList\r
+                                                                  // to disk.\r
+        }\r
+      }\r
+      unlockFile();\r
+    } else {\r
+      throw new Error(\r
+          "Couldn't get lock for "\r
+              + ((this.sessionFile == null) ? "Unitialised sessionFile in SessionsFile"\r
+                  : this.sessionFile.getAbsolutePath()));\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Adds a SessionHandle to the SessionList file - optionally disambiguating\r
+   * the SessionHandle (modifes the URN). Note: Caller is left to release the\r
+   * lock on the SessionList.\r
+   * \r
+   * @param session\r
+   * @param disambiguate\r
+   *          - flag indicating if the URN for me should be disambiguated to\r
+   *          differentiate between sessions.\r
+   * @return index of sessionHandle in new list, or -1-position of existing\r
+   *         sessionHandle (if disambiguate is true)\r
+   */\r
+  protected int addSession(SimpleSessionHandle session, boolean disambiguate) {\r
+    int newsession = 0;\r
+    int tries = 5;\r
+    while (tries-- > 0 && !lockFile())\r
+      try {\r
+        Thread.sleep(1);\r
+      } catch (Exception e) {\r
+      }\r
+    ;\r
+    if (lockFile()) {\r
+      SimpleSessionHandle[] sessions = retrieveSessionHandles();\r
+\r
+      if (sessions == null) {\r
+        sessions = new SimpleSessionHandle[1];\r
+        sessions[0] = session;\r
+        newsession = 1;\r
+      } else {\r
+        int k = 0;\r
+        for (int i = 0, j = sessions.length; i < j; i++) {\r
+          if (sessions[i].equals(session)) {\r
+            if (disambiguate) {\r
+              while (sessions[i].equals(session)) {\r
+                // me.setClientUrn(me.getClientUrn() + k++); // TODO: make a\r
+                // better\r
+                // disambiguation of\r
+                // urn.\r
+              }\r
+            } else {\r
+              // will not write the ambiguous clientHandle to disk, just return\r
+              // its index.\r
+              return -1 - i;\r
+            }\r
+          }\r
+        }\r
+        int i, j;\r
+        SimpleSessionHandle[] newlist = new SimpleSessionHandle[sessions.length + 1];\r
+        for (i = 0, j = sessions.length; i < j; i++)\r
+          newlist[i] = sessions[i];\r
+        newlist[j] = session;\r
+        sessions = newlist;\r
+        newsession = j + 1;\r
+      }\r
+      if (!putSessionsList(sessions))\r
+        return 0; // failed to put the clientList to disk.\r
+    }\r
+    return newsession;\r
+  }\r
+\r
+  /**\r
+   * safely writes sessions array to the file referred to by sessionFile.\r
+   * \r
+   * @param clients\r
+   * @return true if successful write. Throws Errors otherwise.\r
+   */\r
+  protected boolean putSessionsList(SimpleSessionHandle[] clients) {\r
+    if (lockFile()) {\r
+      File templist = null;\r
+      if (!this.backup || (templist = backupSessionFile()) != null) {\r
+        int retries = 3;\r
+        while (retries-- > 0) {\r
+          try {\r
+            ObjectOutputStream os = new ObjectOutputStream(this.fileLock\r
+                .getBufferedOutputStream(true));\r
+            log.debug("About to write " + clients.length\r
+                + " sessionHandles to output stream.");\r
+            os.writeObject(clients);\r
+            // os.flush();\r
+            os.close();\r
+            // All done - remove the backup.\r
+            if (this.backup)\r
+              templist.delete();\r
+            templist = null;\r
+            retries = -1;\r
+          } catch (Exception e) {\r
+            // System.err\r
+            // .println("Serious - problems writing to sessionFile.");\r
+            log.error("Serious - problems writing to sessionFile.", e);\r
+            if (retries > 0 && templist != null) {\r
+              // System.err.println("Recovering from Backup in "\r
+              // + templist.getAbsolutePath());\r
+              log.error("Recovering from Backup in "\r
+                  + templist.getAbsolutePath());\r
+              templist.renameTo(this.fileLock.target);\r
+            }\r
+            // e.printStackTrace(System.err);\r
+            log.error(e);\r
+          }\r
+        }\r
+        if (retries > -2) {\r
+          // System.err\r
+          // .println("Serious - problems writing to sessionFile. Giving Up.");\r
+          log.error("Serious - problems writing to sessionFile. Giving Up.");\r
+          return false;\r
+        }\r
+      } else {\r
+        throw new Error(\r
+            "Couldn't create backup of the clientList before writing to it!");\r
+      }\r
+    } else {\r
+      throw new Error("Could not lock the clientList: "\r
+          + ((this.sessionFile == null) ? "Unitialized ClientsFile"\r
+              : " failed to get lock on " + this.sessionFile.getAbsolutePath()));\r
+    }\r
+    // successful!\r
+    return true;\r
+  }\r
+\r
+  public void clearList() {\r
+    if (lockFile()) {\r
+      try {\r
+        FileOutputStream fout = this.fileLock.getFileOutputStream(true);\r
+        fout.flush();\r
+        fout.close();\r
+      } catch (Exception e) {\r
+        throw new Error("Problems trying to clear clientlist!", e);\r
+\r
+      }\r
+    }\r
+\r
+  }\r
+}\r