1 package org.vamsas.client.simpleclient;
3 import org.vamsas.client.*;
5 import java.io.BufferedInputStream;
6 import java.io.BufferedOutputStream;
8 import java.io.FileInputStream;
9 import java.io.FileNotFoundException;
10 import java.io.FileOutputStream;
11 import java.io.IOException;
12 import java.io.InputStreamReader;
13 import java.io.ObjectInputStream;
14 import java.io.ObjectOutput;
15 import java.io.ObjectOutputStream;
16 import java.io.OutputStream;
17 import java.util.Vector;
20 * Handler for the clientsFile within a vamsas session thread.
23 public class ClientsFile extends ListFile {
24 private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(ClientsFile.class);
26 * number of my client in list - passed back when a client
27 * is added to list, and used (if valid) for quickly
28 * looking up presence of client handle in the list.
30 private int syncnum = 1;
32 public ClientsFile(File filelist) throws IOException {
37 * internal method for getting clientList - ensures a lock has been made but
38 * does not release it.
40 * @return list of clients
42 private ClientHandle[] retrieveClientHandles() {
45 ClientHandle[] clients=null;
46 if (fileLock.length()>0) {
48 ObjectInputStream is = new ObjectInputStream(fileLock.getBufferedInputStream(true));
53 clients = (ClientHandle[]) o;
56 System.err.println("Garbage in the clientHandle list "+this.sessionFile);
61 } catch (FileNotFoundException e) {
62 // TODO Auto-generated catch block
63 e.printStackTrace(System.err);
64 } catch (Exception e) {
65 e.printStackTrace(System.err);
71 * get the clientList from the file. May return null if lock failed!
74 public ClientHandle[] retrieveClientList() {
76 ClientHandle[] clients = retrieveClientHandles();
83 * get list from the locked ClientList.
85 * @return clientList or null if lock failed (or file was empty)
87 public ClientHandle[] retrieveClientList(Lock extantlock) {
88 if (lockFile(extantlock)) {
89 ClientHandle[] clients = retrieveClientHandles();
96 * adds clientHandle me to the clientList under an existing lock extantLock.
99 * @return client index in list or 0 if lock was invalid or addClient operation failed.
101 public int addClient(ClientHandle me, Lock extantLock) {
102 return addClient(me, true, extantLock);
106 * adds clientHandle me to the clientList under an existing lock.
107 * @param me - clientHandle
108 * @param disambig - if true then add will fail if an identical clientHandle already exists
109 * @param extantLock - existing lock
110 * @return client index in list or 0 if addClient (or the lock) failed.
113 public int addClient(ClientHandle me, boolean disambig, Lock extantLock) {
114 if (lockFile(extantLock)) {
115 syncnum = addClient(me, disambig);
123 * adds the ClientHandle to the list - if it is not unique, then the
124 * ClientHandle object is modified to make it unique in the list. returns the
125 * clientNumber for the client in the session.
131 public int addClient(ClientHandle me) {
132 syncnum = addClient(me, true);
138 * removes 'me' from the session ClientList without complaint if 'me' isn't in the clientList already.
139 * @param me client handle to be removed
140 * @param clientlock existing lock passed from watcher.
142 public void removeClient(ClientHandle me, Lock clientlock) {
144 if (lockFile(clientlock)) {
145 ClientHandle[] clients = retrieveClientHandles();
146 if (clients != null) {
147 if ((syncnum<=0 || syncnum>clients.length) || clients[syncnum-1]!=me) {
148 for (int i = 0, j = clients.length; i < j; i++)
149 if (clients[i].equals(me)) {
157 ClientHandle[] newlist = new ClientHandle[clients.length - 1];
158 for (int k=0,i = 0, j = clients.length; i < j; i++)
160 newlist[k++] = clients[i];
161 if (!putClientList(newlist))
162 throw new Error("Failed to write new clientList!"); // failed to put the clientList to disk.
167 throw new Error("Couldn't get lock for "+((sessionFile==null) ? "Unitialised sessionFile in ClientsFile" : sessionFile.getAbsolutePath()));
171 * Adds a ClientHandle to the ClientList file - optionally disambiguating
172 * the ClientHandle (modifes the URN).
173 * Note: Caller is left to release the lock on the ClientList.
175 * @param disambiguate -
176 * flag indicating if the URN for me should be disambiguated to
177 * differentiate between sessions.
178 * @return index of clientHandle in new list, or -1-position of existing
179 * clientHandle (if disambiguate is true)
181 protected int addClient(ClientHandle me, boolean disambiguate) {
184 while (tries-->0 && !lockFile())
185 try { Thread.sleep(1); } catch (Exception e){};
187 ClientHandle[] clients = retrieveClientHandles();
188 if (me.getClientUrn()==null) {
189 // TODO: move this into ClientUrn as a standard form method.
190 me.setClientUrn("vamsas://"+me.getClientName()+":"+me.getVersion()+"/");
192 if (clients == null) {
193 clients = new ClientHandle[1];
198 for (int i = 0, j = clients.length; i < j; i++) {
199 if (clients[i].equals(me)) {
201 while (clients[i].equals(me)) {
202 me.setClientUrn(me.getClientUrn() + k++); // TODO: make a better
207 // will not write the ambiguous clientHandle to disk, just return
214 ClientHandle[] newlist = new ClientHandle[clients.length + 1];
215 for (i = 0, j = clients.length; i < j; i++)
216 newlist[i] = clients[i];
221 if (!putClientList(clients))
222 return 0; // failed to put the clientList to disk.
227 * when set true - get FileNotFoundExceptions on WinXP when writing to locked stream after the backup has been made (via the backupFile method)
229 boolean backup=false;
231 * safely writes clients array to the file referred to by sessionFile.
234 * @return true if successful write. Throws Errors otherwise.
236 protected boolean putClientList(ClientHandle[] clients) {
239 if (!backup || (templist = backupSessionFile()) != null) {
241 while (retries-->0) {
243 ObjectOutputStream os =
244 new ObjectOutputStream(fileLock.getBufferedOutputStream(true));
245 log.debug("About to write "+clients.length+" clientHandles to output stream.");
246 os.writeObject(clients);
248 // All done - remove the backup.
253 } catch (Exception e) {
255 .println("Serious - problems writing to sessionFile.");
256 if (retries>0 && templist != null) {
257 System.err.println("Recovering from Backup in "
258 + templist.getAbsolutePath());
259 templist.renameTo(fileLock.target);
261 e.printStackTrace(System.err);
266 .println("Serious - problems writing to sessionFile. Giving Up.");
271 "Couldn't create backup of the clientList before writing to it!");
274 throw new Error("Could not lock the clientList: "
275 + ((sessionFile == null) ? "Unitialized ClientsFile"
276 : " failed to get lock on " + sessionFile.getAbsolutePath()));
282 public void clearList() {
285 FileOutputStream fout = fileLock.getFileOutputStream(true);
288 } catch (Exception e) {
289 throw new Error("Problems trying to clear clientlist!",e);