5 * Dec 13, 2006 - VamsasClient
9 package uk.ac.vamsas.client.simpleclient;
12 import java.io.FileNotFoundException;
13 import java.io.FileOutputStream;
14 import java.io.ObjectInputStream;
15 import java.io.ObjectOutputStream;
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
21 import uk.ac.vamsas.client.SessionHandle;
24 * @author <a href="mailto:pierre@ebi.ac.uk">Pierre MARGUERITE</a>
28 public class SessionsFile extends ListFile {
30 private static Log log = LogFactory.getLog(SessionsFile.class);
32 * when set true - get FileNotFoundExceptions on WinXP when writing to locked stream after the backup has been made (via the backupFile method)
36 * number of my session in list - passed back when a session
37 * is added to list, and used (if valid) for quickly
38 * looking up presence of session handle in the list.
40 private int syncnum = 1;
44 public SessionsFile(File file) throws java.io.IOException {
50 * internal method for getting sessionsList - ensures a lock has been made but
51 * does not release it.
53 * @return list of clients
55 private SessionHandle[] retrieveSessionHandles() {
58 SessionHandle[] sessions =null;
59 if (this.fileLock.length()>0) {
61 ObjectInputStream is = new ObjectInputStream(this.fileLock.getBufferedInputStream(true));
66 sessions = (SessionHandle[]) o;
69 log.error("Garbage in the clientHandle list "+this.sessionFile,e);
75 } catch (FileNotFoundException e) {
76 // e.printStackTrace(System.err);
78 } catch (Exception e) {
80 //e.printStackTrace(System.err);
87 * get the SessionsList from the file. May return null if lock failed!
88 * @return sessionsList
90 public SessionHandle[] retrieveSessionsList() {
92 SessionHandle[] clients = retrieveSessionHandles();
100 * get list from the locked SessionsList.
102 * @return sessionList or null if lock failed (or file was empty)
104 public SessionHandle[] retrieveSessionsList(Lock extantlock) {
105 if (lockFile(extantlock)) {
106 SessionHandle[] sessions = retrieveSessionHandles();
115 * adds SessionHandle me to the sessionList under an existing lock extantLock.
118 * @return session index in list or 0 if lock was invalid or addSession operation failed.
120 public int addSession(SessionHandle newSession, Lock extantLock) {
121 return addSession(newSession, true, extantLock);
125 * adds SessionsHandle me to the sessionsList under an existing lock.
126 * @param newSession - sessionsHandle
127 * @param disambig - if true then add will fail if an identical sessionHandle already exists
128 * @param extantLock - existing lock
129 * @return client index in list or 0 if addSession (or the lock) failed.
132 public int addSession(SessionHandle newSession, boolean disambig, Lock extantLock) {
133 if (lockFile(extantLock)) {
134 this.syncnum = addSession(newSession, disambig);
142 * removes the current session from the SessionsList without complaint if the session isn't in the sessionsList already.
143 * @param session session handle to be removed
144 * @param sessionlock existing lock passed from watcher.
146 public void removeSession(SessionHandle session, Lock sessionlock) {
148 if (lockFile(sessionlock)) {
150 SessionHandle[] sessions = retrieveSessionHandles();
151 if (sessions != null) {
152 if ((this.syncnum<=0 || this.syncnum>sessions.length) || !sessions[this.syncnum-1].equals(session)) {
153 for (int i = 0, j = sessions.length; i < j; i++)
154 { if (sessions[i].equals(session)) {
160 mynum=this.syncnum-1;
164 SessionHandle[] newlist = new SessionHandle[sessions.length - 1];
165 for (int k=0,i = 0, j = sessions.length; i < j; i++)
167 newlist[k++] = sessions[i];
168 if (!putSessionsList(newlist))
169 throw new Error("Failed to write new sessionsList!"); // failed to put the sessionList to disk.
174 throw new Error("Couldn't get lock for "+((this.sessionFile==null) ? "Unitialised sessionFile in SessionsFile" : this.sessionFile.getAbsolutePath()));
178 * Adds a SessionHandle to the SessionList file - optionally disambiguating
179 * the SessionHandle (modifes the URN).
180 * Note: Caller is left to release the lock on the SessionList.
182 * @param disambiguate -
183 * flag indicating if the URN for me should be disambiguated to
184 * differentiate between sessions.
185 * @return index of sessionHandle in new list, or -1-position of existing
186 * sessionHandle (if disambiguate is true)
188 protected int addSession(SessionHandle session, boolean disambiguate) {
191 while (tries-->0 && !lockFile())
192 try { Thread.sleep(1); } catch (Exception e){};
194 SessionHandle[] sessions = retrieveSessionHandles();
196 if (sessions == null) {
197 sessions = new SessionHandle[1];
198 sessions[0] = session;
202 for (int i = 0, j = sessions.length; i < j; i++) {
203 if ( sessions[i].equals(session)) {
205 while (sessions[i].equals(session)) {
206 // me.setClientUrn(me.getClientUrn() + k++); // TODO: make a better
211 // will not write the ambiguous clientHandle to disk, just return
218 SessionHandle[] newlist = new SessionHandle[sessions.length + 1];
219 for (i = 0, j = sessions.length; i < j; i++)
220 newlist[i] = sessions[i];
221 newlist[j] = session;
225 if (!putSessionsList(sessions))
226 return 0; // failed to put the clientList to disk.
233 * safely writes sessions array to the file referred to by sessionFile.
236 * @return true if successful write. Throws Errors otherwise.
238 protected boolean putSessionsList(SessionHandle[] clients) {
241 if (!this.backup || (templist = backupSessionFile()) != null) {
243 while (retries-->0) {
245 ObjectOutputStream os =
246 new ObjectOutputStream(this.fileLock.getBufferedOutputStream(true));
247 log.debug("About to write "+clients.length+" sessionHandles to output stream.");
248 os.writeObject(clients);
251 // All done - remove the backup.
256 } catch (Exception e) {
258 //.println("Serious - problems writing to sessionFile.");
259 log.error("Serious - problems writing to sessionFile.",e);
260 if (retries>0 && templist != null) {
261 // System.err.println("Recovering from Backup in "
262 // + templist.getAbsolutePath());
263 log.error("Recovering from Backup in "+ templist.getAbsolutePath());
264 templist.renameTo(this.fileLock.target);
266 //e.printStackTrace(System.err);
272 // .println("Serious - problems writing to sessionFile. Giving Up.");
273 log.error("Serious - problems writing to sessionFile. Giving Up.");
278 "Couldn't create backup of the clientList before writing to it!");
281 throw new Error("Could not lock the clientList: "
282 + ((this.sessionFile == null) ? "Unitialized ClientsFile"
283 : " failed to get lock on " + this.sessionFile.getAbsolutePath()));
289 public void clearList() {
292 FileOutputStream fout = this.fileLock.getFileOutputStream(true);
295 } catch (Exception e) {
296 throw new Error("Problems trying to clear clientlist!",e);