1 /* EMBL - The European Bioinformatics institute
5 * Copyright (c) 2005-2006 Thr European Bioinformatics Institute. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * 3. The name MSD must not be used to endorse or promote products
20 * derived from this software without prior written permission. For
21 * written permission, please contact msd-help@ebi.ac.uk
23 * 4. Products derived from this software may not be called "MSD"
24 * nor may "MSD" appear in their names without prior written
25 * permission of the MSD developers.
27 * 5. Redistributions of any form whatsoever must retain the following
29 * "This product includes software developed by MSD
30 * (http://www.ebi.ac.uk/)"
32 * THIS SOFTWARE IS PROVIDED BY THE MSD GROUP ``AS IS'' AND ANY
33 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
35 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ENSEMBL GROUP OR
36 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43 * OF THE POSSIBILITY OF SUCH DAMAGE.
45 * The European Bioinformatics Institute may publish revised and/or new
46 * versions of this license with new releases of VAMSAS software.
47 *==============================================================================
49 * @author <a href="mailto:pierre@ebi.ac.uk">Pierre MARGUERITE</a>
51 * Dec 13, 2006 - VamsasClientV4
55 package uk.ac.vamsas.client.simpleclient;
58 import java.io.FileNotFoundException;
59 import java.io.FileOutputStream;
60 import java.io.ObjectInputStream;
61 import java.io.ObjectOutputStream;
64 import org.apache.commons.logging.Log;
65 import org.apache.commons.logging.LogFactory;
67 import uk.ac.vamsas.client.SessionHandle;
70 * @author <a href="mailto:pierre@ebi.ac.uk">Pierre MARGUERITE</a>
74 public class SessionsFile extends ListFile {
76 private static Log log = LogFactory.getLog(SessionsFile.class);
78 * when set true - get FileNotFoundExceptions on WinXP when writing to locked stream after the backup has been made (via the backupFile method)
82 * number of my session in list - passed back when a session
83 * is added to list, and used (if valid) for quickly
84 * looking up presence of session handle in the list.
86 private int syncnum = 1;
90 public SessionsFile(File file) throws java.io.IOException {
96 * internal method for getting sessionsList - ensures a lock has been made but
97 * does not release it.
99 * @return list of clients
101 private SessionHandle[] retrieveSessionHandles() {
104 SessionHandle[] clients=null;
105 if (this.fileLock.length()>0) {
107 ObjectInputStream is = new ObjectInputStream(this.fileLock.getBufferedInputStream(true));
112 clients = (SessionHandle[]) o;
114 catch (Exception e) {
115 log.error("Garbage in the clientHandle list "+this.sessionFile,e);
120 } catch (FileNotFoundException e) {
121 // e.printStackTrace(System.err);
123 } catch (Exception e) {
125 //e.printStackTrace(System.err);
132 * get the SessionsList from the file. May return null if lock failed!
133 * @return sessionsList
135 public SessionHandle[] retrieveSessionsList() {
137 SessionHandle[] clients = retrieveSessionHandles();
145 * get list from the locked ClientList.
147 * @return clientList or null if lock failed (or file was empty)
149 public SessionHandle[] retrieveSessionsList(Lock extantlock) {
150 if (lockFile(extantlock)) {
151 SessionHandle[] clients = retrieveSessionHandles();
160 * adds clientHandle me to the clientList under an existing lock extantLock.
163 * @return client index in list or 0 if lock was invalid or addClient operation failed.
165 public int addSession(SessionHandle me, Lock extantLock) {
166 return addSession(me, true, extantLock);
170 * adds SessionsHandle me to the sessionsList under an existing lock.
171 * @param me - sessionsHandle
172 * @param disambig - if true then add will fail if an identical clientHandle already exists
173 * @param extantLock - existing lock
174 * @return client index in list or 0 if addClient (or the lock) failed.
177 public int addSession(SessionHandle session, boolean disambig, Lock extantLock) {
178 if (lockFile(extantLock)) {
179 this.syncnum = addSession(session, disambig);
187 * removes the current session from the SessionsList without complaint if the session isn't in the sessionsList already.
188 * @param me client handle to be removed
189 * @param clientlock existing lock passed from watcher.
191 public void removeSession(SessionHandle session, Lock clientlock) {
193 if (lockFile(clientlock)) {
194 SessionHandle[] sessions = retrieveSessionHandles();
195 if (sessions != null) {
196 if ((this.syncnum<=0 || this.syncnum>sessions.length) || sessions[this.syncnum-1]!=session) {
197 for (int i = 0, j = sessions.length; i < j; i++)
198 if (sessions[i].equals(session)) {
203 mynum=this.syncnum-1;
206 SessionHandle[] newlist = new SessionHandle[sessions.length - 1];
207 for (int k=0,i = 0, j = sessions.length; i < j; i++)
209 newlist[k++] = sessions[i];
210 if (!putSessionsList(newlist))
211 throw new Error("Failed to write new sessionsList!"); // failed to put the sessionList to disk.
216 throw new Error("Couldn't get lock for "+((sessionFile==null) ? "Unitialised sessionFile in SessionsFile" : this.sessionFile.getAbsolutePath()));
220 * Adds a SessionHandle to the SessionList file - optionally disambiguating
221 * the SessionHandle (modifes the URN).
222 * Note: Caller is left to release the lock on the SessionList.
224 * @param disambiguate -
225 * flag indicating if the URN for me should be disambiguated to
226 * differentiate between sessions.
227 * @return index of sessionHandle in new list, or -1-position of existing
228 * sessionHandle (if disambiguate is true)
230 protected int addSession(SessionHandle session, boolean disambiguate) {
233 while (tries-->0 && !lockFile())
234 try { Thread.sleep(1); } catch (Exception e){};
236 SessionHandle[] sessions = retrieveSessionHandles();
238 if (sessions == null) {
239 sessions = new SessionHandle[1];
240 sessions[0] = session;
244 for (int i = 0, j = sessions.length; i < j; i++) {
245 if ( sessions[i].equals(session)) {
247 while (sessions[i].equals(session)) {
248 // me.setClientUrn(me.getClientUrn() + k++); // TODO: make a better
253 // will not write the ambiguous clientHandle to disk, just return
260 SessionHandle[] newlist = new SessionHandle[sessions.length + 1];
261 for (i = 0, j = sessions.length; i < j; i++)
262 newlist[i] = sessions[i];
263 newlist[j] = session;
267 if (!putSessionsList(sessions))
268 return 0; // failed to put the clientList to disk.
275 * safely writes sessions array to the file referred to by sessionFile.
278 * @return true if successful write. Throws Errors otherwise.
280 protected boolean putSessionsList(SessionHandle[] clients) {
283 if (!this.backup || (templist = backupSessionFile()) != null) {
285 while (retries-->0) {
287 ObjectOutputStream os =
288 new ObjectOutputStream(this.fileLock.getBufferedOutputStream(true));
289 log.debug("About to write "+clients.length+" sessionHandles to output stream.");
290 os.writeObject(clients);
292 // All done - remove the backup.
297 } catch (Exception e) {
299 //.println("Serious - problems writing to sessionFile.");
300 log.error("Serious - problems writing to sessionFile.",e);
301 if (retries>0 && templist != null) {
302 // System.err.println("Recovering from Backup in "
303 // + templist.getAbsolutePath());
304 log.error("Recovering from Backup in "+ templist.getAbsolutePath());
305 templist.renameTo(this.fileLock.target);
307 //e.printStackTrace(System.err);
313 // .println("Serious - problems writing to sessionFile. Giving Up.");
314 log.error("Serious - problems writing to sessionFile. Giving Up.");
319 "Couldn't create backup of the clientList before writing to it!");
322 throw new Error("Could not lock the clientList: "
323 + ((this.sessionFile == null) ? "Unitialized ClientsFile"
324 : " failed to get lock on " + this.sessionFile.getAbsolutePath()));
330 public void clearList() {
333 FileOutputStream fout = this.fileLock.getFileOutputStream(true);
336 } catch (Exception e) {
337 throw new Error("Problems trying to clear clientlist!",e);