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 * @author jim Handler for the clientsFile within a vamsas session.
22 public class ClientsFile {
23 private File filelist;
26 * number of my client in list (not known at start but used when known to make
29 private int syncnum = 1;
31 public ClientsFile(File filelist) throws IOException {
32 this.filelist = filelist;
33 if (!this.filelist.exists())
34 this.filelist.createNewFile();
37 private Lock listlock = null;
40 * Get a lock for the ClientsFile
42 * @return true if lock was made
44 protected boolean lockList() {
45 if (listlock != null && listlock.isLocked())
48 if (filelist != null) {
49 if (filelist.exists()) {
50 // TODO: see if we need to loop-wait for locks or they just block until
53 // listlock = new Lock(filelist); // TODO: wait around if we can't get
55 // } while (!listlock.isLocked());
56 listlock = new Lock(filelist);
57 return listlock.isLocked();
61 "org.vamsas.client.simpleclient.ClientsFile.lockList called for non-initialised ClientsFile!");
68 * Explicitly release the ClientsFile lock.
70 * @return true if lock was released.
72 protected boolean unlockList() {
73 if (listlock != null) {
75 if (listlock.isLocked()) {
77 listlock.lock.release();
78 } catch (IOException e) {
79 // TODO Deal with unlock Lock.release exception!
80 e.printStackTrace(System.err);
91 * internal method for getting clientList - ensures a lock has been made but
92 * does not release it.
94 * @return list of clients
96 private ClientHandle[] retrieveClientHandles() {
99 ClientHandle[] clients=null;
100 if (this.listlock.rafile.length()>0) {
101 ObjectInputStream is = new ObjectInputStream(new BufferedInputStream(
102 new java.io.FileInputStream(filelist)));
107 clients = (ClientHandle[]) o;
109 catch (Exception e) {
110 System.err.println("Garbage in the clientHandle list "+this.filelist);
115 } catch (FileNotFoundException e) {
116 // TODO Auto-generated catch block
117 e.printStackTrace(System.err);
118 } catch (Exception e) {
119 e.printStackTrace(System.err);
125 * get the clientList from the file. May return false if lock failed!
128 public ClientHandle[] retrieveClientList() {
130 ClientHandle[] clients = retrieveClientHandles();
138 * adds the ClientHandle to the list - if it is not unique, then the
139 * ClientHandle object is modified to make it unique in the list. returns the
140 * clientNumber for the client in the session.
146 public int addClient(ClientHandle me) {
147 syncnum = addClient(me, true);
153 * removes 'me' from the session ClientList without complaint if 'me' isn't in the clientList already.
156 public void removeClient(ClientHandle me) {
159 ClientHandle[] clients = retrieveClientHandles();
160 if (clients != null) {
161 if (clients[syncnum-1]!=me) {
162 for (int i = 0, j = clients.length; i < j; i++)
163 if (clients[i].equals(me)) {
171 ClientHandle[] newlist = new ClientHandle[clients.length - 1];
172 for (int k=0,i = 0, j = clients.length; i < j; i++)
174 newlist[k++] = clients[i];
175 if (!putClientList(newlist))
176 throw new Error("Failed to write new clientList!"); // failed to put the clientList to disk.
181 throw new Error("Couldn't get lock for "+((filelist==null) ? "Unitialised filelist in ClientsFile" : filelist.getAbsolutePath()));
185 * Adds a ClientHandle to the ClientList file - optionally disambiguating
186 * the ClientHandle (modifes the URN).
187 * Note: Caller is left to release the lock on the ClientList.
189 * @param disambiguate -
190 * flag indicating if the URN for me should be disambiguated to
191 * differentiate between sessions.
192 * @return index of clientHandle in new list, or -1-position of existing
193 * clientHandle (if disambiguate is true)
195 protected int addClient(ClientHandle me, boolean disambiguate) {
198 ClientHandle[] clients = retrieveClientHandles();
199 if (me.getClientUrn()==null) {
200 // TODO: move this into ClientUrn as a standard form method.
201 me.setClientUrn("vamsas://"+me.getClientName()+":"+me.getVersion()+"/");
203 if (clients == null) {
204 clients = new ClientHandle[1];
209 for (int i = 0, j = clients.length; i < j; i++) {
210 if (clients[i].equals(me)) {
212 while (clients[i].equals(me)) {
213 me.setClientUrn(me.getClientUrn() + k++); // TODO: make a better
218 // will not write the ambiguous clientHandle to disk, just return
225 ClientHandle[] newlist = new ClientHandle[clients.length + 1];
226 for (i = 0, j = clients.length; i < j; i++)
227 newlist[i] = clients[i];
232 if (!putClientList(clients))
233 return 0; // failed to put the clientList to disk.
239 * safely writes clients array to the file referred to by filelist.
242 * @return true if successful write. Throws Errors otherwise.
244 protected boolean putClientList(ClientHandle[] clients) {
246 File templist = null;
248 templist = File.createTempFile(filelist.getName(),".old", filelist.getParentFile());
249 FileOutputStream tos = new FileOutputStream(templist);
250 tos.getChannel().transferFrom(listlock.rafile.getChannel(), 0,
251 listlock.rafile.length());
253 } catch (FileNotFoundException e1) {
254 System.err.println("Can't create temp file for clientlist");
255 e1.printStackTrace(System.err);
256 } catch (IOException e1) {
258 .println("Error when copying content to temp file for clientlist");
259 e1.printStackTrace(System.err);
261 if (templist != null) {
263 listlock.rafile.setLength(0);
264 ObjectOutputStream os = new ObjectOutputStream(
265 new BufferedOutputStream(new FileOutputStream(this.filelist)));
266 os.writeObject(clients);
268 // All done - remove the backup.
271 } catch (Exception e) {
272 if (templist != null) {
274 .println("Serious - problems writing to filelist. Backup in "
275 + templist.getAbsolutePath());
276 e.printStackTrace(System.err);
281 "Couldn't create backup of the clientList before writing to it!");
284 throw new Error("Could not lock the clientList: "
285 + ((filelist == null) ? "Unitialized ClientsFile"
286 : " failed to get lock on " + filelist.getAbsolutePath()));