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 org.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;
66 import org.vamsas.client.SessionHandle;
69 * @author <a href="mailto:pierre@ebi.ac.uk">Pierre MARGUERITE</a>
73 public class SessionsFile extends ListFile {
75 private static Log log = LogFactory.getLog(SessionsFile.class);
77 * when set true - get FileNotFoundExceptions on WinXP when writing to locked stream after the backup has been made (via the backupFile method)
81 * number of my session in list - passed back when a session
82 * is added to list, and used (if valid) for quickly
83 * looking up presence of session handle in the list.
85 private int syncnum = 1;
89 public SessionsFile(File file) throws java.io.IOException {
95 * internal method for getting sessionsList - ensures a lock has been made but
96 * does not release it.
98 * @return list of clients
100 private SessionHandle[] retrieveSessionHandles() {
103 SessionHandle[] clients=null;
104 if (this.fileLock.length()>0) {
106 ObjectInputStream is = new ObjectInputStream(this.fileLock.getBufferedInputStream(true));
111 clients = (SessionHandle[]) o;
113 catch (Exception e) {
114 log.error("Garbage in the clientHandle list "+this.sessionFile,e);
119 } catch (FileNotFoundException e) {
120 // e.printStackTrace(System.err);
122 } catch (Exception e) {
124 //e.printStackTrace(System.err);
131 * get the SessionsList from the file. May return null if lock failed!
132 * @return sessionsList
134 public SessionHandle[] retrieveSessionsList() {
136 SessionHandle[] clients = retrieveSessionHandles();
144 * get list from the locked ClientList.
146 * @return clientList or null if lock failed (or file was empty)
148 public SessionHandle[] retrieveSessionsList(Lock extantlock) {
149 if (lockFile(extantlock)) {
150 SessionHandle[] clients = retrieveSessionHandles();
159 * adds clientHandle me to the clientList under an existing lock extantLock.
162 * @return client index in list or 0 if lock was invalid or addClient operation failed.
164 public int addSession(SessionHandle me, Lock extantLock) {
165 return addSession(me, true, extantLock);
169 * adds SessionsHandle me to the sessionsList under an existing lock.
170 * @param me - sessionsHandle
171 * @param disambig - if true then add will fail if an identical clientHandle already exists
172 * @param extantLock - existing lock
173 * @return client index in list or 0 if addClient (or the lock) failed.
176 public int addSession(SessionHandle session, boolean disambig, Lock extantLock) {
177 if (lockFile(extantLock)) {
178 this.syncnum = addSession(session, disambig);
186 * removes the current session from the SessionsList without complaint if the session isn't in the sessionsList already.
187 * @param me client handle to be removed
188 * @param clientlock existing lock passed from watcher.
190 public void removeSession(SessionHandle session, Lock clientlock) {
192 if (lockFile(clientlock)) {
193 SessionHandle[] sessions = retrieveSessionHandles();
194 if (sessions != null) {
195 if ((this.syncnum<=0 || this.syncnum>sessions.length) || sessions[this.syncnum-1]!=session) {
196 for (int i = 0, j = sessions.length; i < j; i++)
197 if (sessions[i].equals(session)) {
202 mynum=this.syncnum-1;
205 SessionHandle[] newlist = new SessionHandle[sessions.length - 1];
206 for (int k=0,i = 0, j = sessions.length; i < j; i++)
208 newlist[k++] = sessions[i];
209 if (!putSessionsList(newlist))
210 throw new Error("Failed to write new sessionsList!"); // failed to put the sessionList to disk.
215 throw new Error("Couldn't get lock for "+((sessionFile==null) ? "Unitialised sessionFile in SessionsFile" : this.sessionFile.getAbsolutePath()));
219 * Adds a SessionHandle to the SessionList file - optionally disambiguating
220 * the SessionHandle (modifes the URN).
221 * Note: Caller is left to release the lock on the SessionList.
223 * @param disambiguate -
224 * flag indicating if the URN for me should be disambiguated to
225 * differentiate between sessions.
226 * @return index of sessionHandle in new list, or -1-position of existing
227 * sessionHandle (if disambiguate is true)
229 protected int addSession(SessionHandle session, boolean disambiguate) {
232 while (tries-->0 && !lockFile())
233 try { Thread.sleep(1); } catch (Exception e){};
235 SessionHandle[] sessions = retrieveSessionHandles();
237 if (sessions == null) {
238 sessions = new SessionHandle[1];
239 sessions[0] = session;
243 for (int i = 0, j = sessions.length; i < j; i++) {
244 if ( sessions[i].equals(session)) {
246 while (sessions[i].equals(session)) {
247 // me.setClientUrn(me.getClientUrn() + k++); // TODO: make a better
252 // will not write the ambiguous clientHandle to disk, just return
259 SessionHandle[] newlist = new SessionHandle[sessions.length + 1];
260 for (i = 0, j = sessions.length; i < j; i++)
261 newlist[i] = sessions[i];
262 newlist[j] = session;
266 if (!putSessionsList(sessions))
267 return 0; // failed to put the clientList to disk.
274 * safely writes sessions array to the file referred to by sessionFile.
277 * @return true if successful write. Throws Errors otherwise.
279 protected boolean putSessionsList(SessionHandle[] clients) {
282 if (!this.backup || (templist = backupSessionFile()) != null) {
284 while (retries-->0) {
286 ObjectOutputStream os =
287 new ObjectOutputStream(this.fileLock.getBufferedOutputStream(true));
288 log.debug("About to write "+clients.length+" sessionHandles to output stream.");
289 os.writeObject(clients);
291 // All done - remove the backup.
296 } catch (Exception e) {
298 //.println("Serious - problems writing to sessionFile.");
299 log.error("Serious - problems writing to sessionFile.",e);
300 if (retries>0 && templist != null) {
301 // System.err.println("Recovering from Backup in "
302 // + templist.getAbsolutePath());
303 log.error("Recovering from Backup in "+ templist.getAbsolutePath());
304 templist.renameTo(this.fileLock.target);
306 //e.printStackTrace(System.err);
312 // .println("Serious - problems writing to sessionFile. Giving Up.");
313 log.error("Serious - problems writing to sessionFile. Giving Up.");
318 "Couldn't create backup of the clientList before writing to it!");
321 throw new Error("Could not lock the clientList: "
322 + ((this.sessionFile == null) ? "Unitialized ClientsFile"
323 : " failed to get lock on " + this.sessionFile.getAbsolutePath()));
329 public void clearList() {
332 FileOutputStream fout = this.fileLock.getFileOutputStream(true);
335 } catch (Exception e) {
336 throw new Error("Problems trying to clear clientlist!",e);