From: jprocter Date: Thu, 14 Dec 2006 17:52:40 +0000 (+0000) Subject: refactored org to uk X-Git-Tag: Release_0.2~250 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=fb053ddd3462c204422eac279f20eceae62e1d01;p=vamsas.git refactored org to uk git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@270 be28352e-c001-0410-b1a7-c7978e42abec --- diff --git a/src/org/vamsas/client/simpleclient/AppDataInputStream.java b/src/org/vamsas/client/simpleclient/AppDataInputStream.java deleted file mode 100644 index 0785ed6..0000000 --- a/src/org/vamsas/client/simpleclient/AppDataInputStream.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * - */ -package org.vamsas.client.simpleclient; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.jar.JarInputStream; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * @author jimp - * LATER: this may not be a necessary or useful class to return from IClientAppdata get*InputStream() methods - */ -public class AppDataInputStream extends DataInputStream implements DataInput { - private Log log = LogFactory.getLog(AppDataInputStream.class); - private boolean isOpen = false; - /** - * Wrapper for writing to/from AppData Entries in a Vamsas Document. - */ - public AppDataInputStream(InputStream inputstream) { - super(inputstream); - isOpen=true; - } - - /* (non-Javadoc) - * @see java.io.FilterInputStream#close() - */ - public void close() throws IOException { - if (!isOpen) { - log.debug("close() called on closed AppDataInputStream."); - // throw new IOException("Attempt to close an already closed AppDataInputStream"); - } else { - isOpen=false; - } - } - - /** - * Will return zero if stream has been closed. - * @see java.io.FilterInputStream#available() - */ - public int available() throws IOException { - if (isOpen) - return super.available(); - else - return 0; - } - -} diff --git a/src/org/vamsas/client/simpleclient/AppDataOutputStream.java b/src/org/vamsas/client/simpleclient/AppDataOutputStream.java deleted file mode 100644 index db13652..0000000 --- a/src/org/vamsas/client/simpleclient/AppDataOutputStream.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * - */ -package org.vamsas.client.simpleclient; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * @author jimp - * - */ -public class AppDataOutputStream extends DataOutputStream { - private Log log = LogFactory.getLog(AppDataOutputStream.class); - private boolean isOpen=true; - /** - * @param out - */ - public AppDataOutputStream(OutputStream out) { - super(out); - isOpen=true; - } - /* (non-Javadoc) - * @see java.io.DataOutputStream#flush() - */ - public void flush() throws IOException { - if (isOpen) - super.flush(); - else - log.warn("flush() called on closed AppDataOutputStream"); - } - /* (non-Javadoc) - * @see java.io.DataOutputStream#write(byte[], int, int) - */ - public synchronized void write(byte[] b, int off, int len) throws IOException { - if (isOpen) { - super.write(b, off, len); - } else { - log.debug("write(b,off,len) called on closed AppDataOutputStream"); - throw new IOException("Attempt to write to closed AppDataOutputStream"); - } - } - /* (non-Javadoc) - * @see java.io.DataOutputStream#write(int) - */ - public synchronized void write(int b) throws IOException { - if (isOpen) { - super.write(b); - } else { - log.debug("write(b) called on closed AppDataOutputStream"); - throw new IOException("Attempt to write to closed AppDataOutputStream"); - } - } - /** - * Sets an internal flag preventing further write operations - * to the AppData output stream and flushes any pending writes. - * @see java.io.FilterOutputStream#close() - */ - public void close() throws IOException { - isOpen=false; - super.flush(); - log.debug("AppDataOutputStream was closed."); - } - /* (non-Javadoc) - * @see java.io.FilterOutputStream#write(byte[]) - */ - public void write(byte[] b) throws IOException { - if (isOpen) { - super.write(b); - } else { - log.debug("write(b[]) called on closed AppDataOutputStream"); - throw new IOException("Attempt to write to closed AppDataOutputStream"); - } - } - /** - * @return true if stream is still Open. - */ - public boolean isOpen() { - return isOpen; - } - -} diff --git a/src/org/vamsas/client/simpleclient/ArchiveUrn.java b/src/org/vamsas/client/simpleclient/ArchiveUrn.java deleted file mode 100644 index 304e1f2..0000000 --- a/src/org/vamsas/client/simpleclient/ArchiveUrn.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.io.File; -import java.net.MalformedURLException; - -/** - * Vamsas Document URN for files understood by ArchiveReader and - * written by VamsasArchive. - * vdoc://{Absolute path to file} - * @author jimp - * - */ -public class ArchiveUrn extends org.vamsas.client.SessionUrn { - /** - * a simple vamsas document urn prefix - */ - public static String VAMSASDOCUMENT="vdoc"; - static { - TYPES.put(ArchiveUrn.VAMSASDOCUMENT, ArchiveUrn.class); - } - - public ArchiveUrn(File docLocation) throws MalformedURLException { - super(VAMSASDOCUMENT, docLocation.getAbsoluteFile().toURL()); - } - - /** - * TODO: LATER: think about this again. - * @return File(urn.getPath()) - */ - public File asFile() { - return new File(urn.getPath()); - } - // TODO: add abstract 'handler' methods for resolving the URN to a particular class -} diff --git a/src/org/vamsas/client/simpleclient/ClientDocument.java b/src/org/vamsas/client/simpleclient/ClientDocument.java deleted file mode 100644 index 3b654f8..0000000 --- a/src/org/vamsas/client/simpleclient/ClientDocument.java +++ /dev/null @@ -1,510 +0,0 @@ -/* - * - */ -package org.vamsas.client.simpleclient; - -import java.io.IOException; -import java.util.Vector; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.vamsas.client.ClientHandle; -import org.vamsas.client.IClientAppdata; -import org.vamsas.client.IClientDocument; -import org.vamsas.client.UserHandle; -import org.vamsas.client.Vobject; -import org.vamsas.client.VorbaId; -import org.vamsas.objects.core.ApplicationData; -import org.vamsas.objects.core.User; -import org.vamsas.objects.core.VAMSAS; -import org.vamsas.objects.core.VamsasDocument; -import org.vamsas.objects.utils.AppDataReference; -import org.vamsas.test.objects.Core; - -/** - * Maintains a collection of vamsas objects, appdatas and states, and provides api for a SimpleClient's client. - * @author jimp - */ -public class ClientDocument extends org.vamsas.client.ClientDocument implements IClientDocument { - private static Log log = LogFactory.getLog(ClientDocument.class); - private VamsasDocument doc; - protected SimpleClient sclient; - protected VamsasArchive archive = null; - /** - * indicate if new data has been incorporated - */ - private boolean isModified = false; - /** - * Public method for internal use by SimpleClient. - * @return true if document has been modified. - */ - public boolean isModified() { - return isModified; - } - private Vector updatedObjects=null; - /** - * - * prepare Application-side dataset from the vamsas Document archive - * @param doc - the dataset - * @param docHandler - the sessionFile IO handler - * @param Factory - the source of current and new vorbaIds - * @param sclient - the simpleclient instance - */ - protected ClientDocument(VamsasDocument doc, VamsasArchive docHandler, IdFactory Factory, SimpleClient sclient) { - super(Factory.getVorbaIdHash(), Factory); - - - /** - * prepare Application-side dataset from the vamsas Document archive - */ - this.sclient = sclient; - archive = docHandler; - this.doc = doc; - updatedObjects=null; /// TODO: correct this line - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClientDocument#getObject(org.vamsas.client.VorbaId) - */ - public Vobject getObject(VorbaId id) { - if (vamsasObjects==null) { - log.debug("getObject called on null objrefs list."); - return null; - } - if (vamsasObjects.containsKey(id)) - return (Vobject) vamsasObjects.get(id); - log.debug("Returning null Vobject reference for id "+id.getId()); - return null; - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClientDocument#getObjects(org.vamsas.client.VorbaId[]) - */ - public Vobject[] getObjects(VorbaId[] ids) { - if (vamsasObjects==null) { - log.debug("getObject[] called on null vamsasObjects list."); - return null; - } - Vobject[] vo = new Vobject[ids.length]; - for (int i=0,j=ids.length; i-1) { - if (isValidUpdate(newr[k], original[i])) { - modified=true; - rts.add(newr[k]); - newr[k]=null; - } else { - // LATER: try harder to merge ducument roots. - log.warn("Couldn't merge new VAMSAS root "+newr[k].getId()); - newr[k] = null; // LATER: this means we ignore mangled roots. NOT GOOD - } - } else { - // add in order. - rts.add(original[i]); - } - } - // add remaining (new) roots - for (int i=0,j=newr.length; i0) { - - ObjectInputStream is = new ObjectInputStream(fileLock.getBufferedInputStream(true)); - Object o; - o=is.readObject(); - if (o!=null) { - try { - clients = (ClientHandle[]) o; - } - catch (Exception e) { - System.err.println("Garbage in the clientHandle list "+this.sessionFile); - } - } - } - return clients; - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(System.err); - } catch (Exception e) { - e.printStackTrace(System.err); - } - } - return null; - } - /** - * get the clientList from the file. May return null if lock failed! - * @return clientList - */ - public ClientHandle[] retrieveClientList() { - if (lockFile()) { - ClientHandle[] clients = retrieveClientHandles(); - unlockFile(); - return clients; - } - return null; - } - /** - * get list from the locked ClientList. - * @param extantlock - * @return clientList or null if lock failed (or file was empty) - */ - public ClientHandle[] retrieveClientList(Lock extantlock) { - if (lockFile(extantlock)) { - ClientHandle[] clients = retrieveClientHandles(); - unlockFile(); - return clients; - } - return null; - } - /** - * adds clientHandle me to the clientList under an existing lock extantLock. - * @param me - * @param extantLock - * @return client index in list or 0 if lock was invalid or addClient operation failed. - */ - public int addClient(ClientHandle me, Lock extantLock) { - return addClient(me, true, extantLock); - } - - /** - * adds clientHandle me to the clientList under an existing lock. - * @param me - clientHandle - * @param disambig - if true then add will fail if an identical clientHandle already exists - * @param extantLock - existing lock - * @return client index in list or 0 if addClient (or the lock) failed. - */ - - public int addClient(ClientHandle me, boolean disambig, Lock extantLock) { - if (lockFile(extantLock)) { - syncnum = addClient(me, disambig); - unlockFile(); - return syncnum; - } - return 0; - } - - /** - * adds the ClientHandle to the list - if it is not unique, then the - * ClientHandle object is modified to make it unique in the list. returns the - * clientNumber for the client in the session. - * - * @param me - * @return - */ - - public int addClient(ClientHandle me) { - syncnum = addClient(me, true); - unlockFile(); - return syncnum; - } - - /** - * removes 'me' from the session ClientList without complaint if 'me' isn't in the clientList already. - * @param me client handle to be removed - * @param clientlock existing lock passed from watcher. - */ - public void removeClient(ClientHandle me, Lock clientlock) { - int mynum=-1; - if (lockFile(clientlock)) { - ClientHandle[] clients = retrieveClientHandles(); - if (clients != null) { - if ((syncnum<=0 || syncnum>clients.length) || clients[syncnum-1]!=me) { - for (int i = 0, j = clients.length; i < j; i++) - if (clients[i].equals(me)) { - mynum=i; - break; - } - } else { - mynum=syncnum-1; - } - if (mynum>-1) { - ClientHandle[] newlist = new ClientHandle[clients.length - 1]; - for (int k=0,i = 0, j = clients.length; i < j; i++) - if (i!=mynum) - newlist[k++] = clients[i]; - if (!putClientList(newlist)) - throw new Error("Failed to write new clientList!"); // failed to put the clientList to disk. - } - } - unlockFile(); - } else { - throw new Error("Couldn't get lock for "+((sessionFile==null) ? "Unitialised sessionFile in ClientsFile" : sessionFile.getAbsolutePath())); - } - } - /** - * Adds a ClientHandle to the ClientList file - optionally disambiguating - * the ClientHandle (modifes the URN). - * Note: Caller is left to release the lock on the ClientList. - * @param me - * @param disambiguate - - * flag indicating if the URN for me should be disambiguated to - * differentiate between sessions. - * @return index of clientHandle in new list, or -1-position of existing - * clientHandle (if disambiguate is true) - */ - protected int addClient(ClientHandle me, boolean disambiguate) { - int newclient = 0; - int tries=5; - while (tries-->0 && !lockFile()) - try { Thread.sleep(1); } catch (Exception e){}; - if (lockFile()) { - ClientHandle[] clients = retrieveClientHandles(); - if (me.getClientUrn()==null) { - // TODO: move this into ClientUrn as a standard form method. - me.setClientUrn("vamsas://"+me.getClientName()+":"+me.getVersion()+"/"); - } - if (clients == null) { - clients = new ClientHandle[1]; - clients[0] = me; - newclient = 1; - } else { - int k = 0; - for (int i = 0, j = clients.length; i < j; i++) { - if (clients[i].equals(me)) { - if (disambiguate) { - while (clients[i].equals(me)) { - me.setClientUrn(me.getClientUrn() + k++); // TODO: make a better - // disambiguation of - // urn. - } - } else { - // will not write the ambiguous clientHandle to disk, just return - // its index. - return -1 - i; - } - } - } - int i, j; - ClientHandle[] newlist = new ClientHandle[clients.length + 1]; - for (i = 0, j = clients.length; i < j; i++) - newlist[i] = clients[i]; - newlist[j] = me; - clients = newlist; - newclient = j+1; - } - if (!putClientList(clients)) - return 0; // failed to put the clientList to disk. - } - return newclient; - } - /** - * when set true - get FileNotFoundExceptions on WinXP when writing to locked stream after the backup has been made (via the backupFile method) - */ - boolean backup=false; - /** - * safely writes clients array to the file referred to by sessionFile. - * - * @param clients - * @return true if successful write. Throws Errors otherwise. - */ - protected boolean putClientList(ClientHandle[] clients) { - if (lockFile()) { - File templist=null; - if (!backup || (templist = backupSessionFile()) != null) { - int retries=3; - while (retries-->0) { - try { - ObjectOutputStream os = - new ObjectOutputStream(fileLock.getBufferedOutputStream(true)); - log.debug("About to write "+clients.length+" clientHandles to output stream."); - os.writeObject(clients); - os.close(); - // All done - remove the backup. - if (backup) - templist.delete(); - templist = null; - retries=-1; - } catch (Exception e) { - System.err - .println("Serious - problems writing to sessionFile."); - if (retries>0 && templist != null) { - System.err.println("Recovering from Backup in " - + templist.getAbsolutePath()); - templist.renameTo(fileLock.target); - } - e.printStackTrace(System.err); - } - } - if (retries>-2) { - System.err - .println("Serious - problems writing to sessionFile. Giving Up."); - return false; - } - } else { - throw new Error( - "Couldn't create backup of the clientList before writing to it!"); - } - } else { - throw new Error("Could not lock the clientList: " - + ((sessionFile == null) ? "Unitialized ClientsFile" - : " failed to get lock on " + sessionFile.getAbsolutePath())); - } - // successful! - return true; - } - - public void clearList() { - if (lockFile()) { - try { - FileOutputStream fout = fileLock.getFileOutputStream(true); - fout.flush(); - fout.close(); - } catch (Exception e) { - throw new Error("Problems trying to clear clientlist!",e); - - } - } - - } -} diff --git a/src/org/vamsas/client/simpleclient/EventGeneratorThread.java b/src/org/vamsas/client/simpleclient/EventGeneratorThread.java deleted file mode 100644 index d9aa1db..0000000 --- a/src/org/vamsas/client/simpleclient/EventGeneratorThread.java +++ /dev/null @@ -1,277 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.util.Hashtable; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.vamsas.client.Events; - -/** - * monitors watcher objects and generates events. - */ -public class EventGeneratorThread extends Thread implements Runnable { - private static Log log = LogFactory.getLog(EventGeneratorThread.class); - private SimpleClient client; - private Hashtable handlers; // manager object - private VamsasSession session; - - /** - * list with all the clientHandles for the session - */ - protected FileWatcher clientfile=null; - /** - * the session's vamsasDocument - */ - protected FileWatcher vamsasfile=null; - /** - * written to by client when its app calls storeDocument. - */ - protected FileWatcher storeFile=null; - - private boolean watch=false; - - - EventGeneratorThread(VamsasSession s, SimpleClient _client, Hashtable eventhandlers) { - if (eventhandlers==null || s==null || _client==null) - throw new Error("Null arguments to EventGeneratorThread constructor."); - handlers = eventhandlers; - session = s; - client = _client; - setName(s.sessionDir.getName()); - initWatchers(); - } - - private void initWatchers() { - if (clientfile==null) - clientfile = session.getClientWatcher(); - if (vamsasfile ==null) - vamsasfile = session.getDocWatcher(); - if (storeFile == null) - storeFile = session.getStoreWatcher(); - clientfile.setState(); - vamsasfile.setState(); - storeFile.setState(); - } - boolean ownsf = false; - /** - * scans all watchers and fires changeEvents if necessary - * @return number of events generated. - */ - private int checkforEvents() { - Lock watchlock; - //TODO : leave slog.info messages for the events that occur. - int raised=0; - // could make this general - but for now keep simple - if ((watchlock=storeFile.getChangedState())!=null) { - // TODO: define the storeFile semaphore mechanism : file exists - all clients inform their apps, and then the client that wrote the file should delete the file (it should hold the lock to it). - if (storeFile.exists) { - PropertyChangeSupport h = (PropertyChangeSupport) handlers.get(Events.DOCUMENT_FINALIZEAPPDATA); - if (h!=null) { - log.debug("Triggering DOCUMENT_FINALIZEAPPDATA"); - raised++; - h.firePropertyChange(client.getSessionUrn(), null, client); - // expect client to - vamsasfile.setState(); - } - } - } - if ((watchlock=clientfile.getChangedState())!=null) { - // see what happened to the clientfile - compare our internal version with the one in the file, or just send the updated list out...? - // - /** - * Generated when a new vamsas client is attached to a session (Handle is - * passed) Note: the newly created client does not receive the event. - * - public static final String CLIENT_CREATION = "org.vamsas.client.events.clientCreateEvent"; - */ // as the test - /** - * Generated when a vamsas client leaves a session (Handle is passed to all - * others). - public static final String CLIENT_FINALIZATION = "org.vamsas.client.events.clientFinalizationEvent"; - */ // again - as the test. - raised++; - } - if ((watchlock=vamsasfile.getChangedState())!=null) { - - /** - * Generated when a client has finished updating the document. Passes - * applicationHandle of client so the updating client can recognise its own - * updates. - public static final String DOCUMENT_UPDATE = "org.vamsas.client.events.documentUpdateEvent"; - */ - // read apphandle from 'lastUpdate' session file. - // pass apphandle name to appHandler ? - - } - /** - * Generated when a new vamsas document is created (perhaps from some existing - * Vamsas data) so an application may do its own data space initialization. - * TODO: decide if this is called when an app is connected to a stored - * session... - public static final String DOCUMENT_CREATE = "org.vamsas.client.events.documentCreateEvent"; - */ - // check if this session's appInit flag is set - if not - generate event for this app. - // prolly don't need this at the moment - when an app does getDocument it can to the initing then. - - - /** - * Generated prior to session Shutdown, after the last participating vamsas - * client has finalized. - * TODO: decide on purpose of this ? is this for benefit of multi-session Apps only ? - public static final String SESSION_SHUTDOWN = "org.vamsas.client.events.SessionShutdownEvent"; - */ - - /** - * Generated for all clients when any client calls IClient.storeDocument() to - * allow them to store any updates before an offline copy of the session is - * created. Any client that handles this should call the - * IClient.getDocument(), update and then IClient.updateDocument in the same - * handler thread. - * EventName: - * NewValue: org.vamsas.client.IClient for session. - * - public static final String DOCUMENT_FINALIZEAPPDATA = "org.vamsas.client.events.DocumentFinalizeAppData"; -*/ - // watch for finalization semaphore (last finalised sessionFile). - - /** - * Generated by Vorba stub after the penultimate client makes a call to - * closeDocument(). Sequence is as follows : 1. All other vamsas clients have - * called closeDocument() 2. Final living client monitors closures, and - * realises that it is last. 3. Final client generates event to prompt - * associated application to inquire if the user wishes to save the document - * for future reference. - * * Any call to closeDocument in a thread other than the registered - * EventListener will block until the RequestToClose handler has exited. - * - */ - // public static final String DOCUMENT_REQUESTTOCLOSE = "org.vamas.client.DocumentRequestToCloseEvent"; - - return raised; - } - - private void initEvents() { - - } - /** - * Events raised by IClient and propagated to others in session - */ - - /** - * number of milliseconds between any file state check. - */ - long POLL_UNIT = 20; - protected void wait(int u) { - if (u<=0) - u=1; - long l = System.currentTimeMillis()+POLL_UNIT*u; - while (System.currentTimeMillis()0) { - sequence++; - } else { - idstring+="1/"; - sequence=1; - } - newidstring=idstring+Integer.toString(sequence); - } while (extantids.containsKey(newidstring)); - extantids.put(newidstring, vobject); // hash the Vobject by its new Id - VorbaId id = newId(newidstring); // VorbaId.hash()==newidstring.hash() so we can still recover vobject - return id; - } - - /* (non-Javadoc) - * @see org.vamsas.client.VorbaIdFactory#setSession(org.vamsas.client.SessionHandle) - */ - protected void setSession(SessionHandle sessionhandle) { - if (sessionhandle!=null) - session=sessionhandle; - else - log.warn("setSession(null) called."); - } - - /* (non-Javadoc) - * @see org.vamsas.client.VorbaIdFactory#getSessionHandle() - */ - public SessionHandle getSessionHandle() { - return session; - } - - /* (non-Javadoc) - * @see org.vamsas.client.VorbaIdFactory#setClient(org.vamsas.client.ClientHandle) - */ - protected void setClient(ClientHandle appHandle) { - if (appHandle!=null) - client = appHandle; - else - log.warn("setClient(null) called."); - } - - /* (non-Javadoc) - * @see org.vamsas.client.VorbaIdFactory#getClientHandle() - */ - public ClientHandle getClientHandle() { - return client; - } - - /* (non-Javadoc) - * @see org.vamsas.client.VorbaIdFactory#setUser(org.vamsas.client.UserHandle) - */ - protected void setUser(UserHandle userHandle) { - if (userHandle!=null) - user = userHandle; - else - log.warn("setUser(null) called."); - } - - /* (non-Javadoc) - * @see org.vamsas.client.VorbaIdFactory#getUserHandle() - */ - public UserHandle getUserHandle() { - return user; - } - /** - * Convenience method used for default behaviour in testing - * and any anonymous internal vamsasDocument unmarshalling - * @param clientname - * @return - */ - protected static IdFactory getDummyFactory(String clientname) { - if (clientname==null) - clientname="org.vamsas.client.simpleclient.IdFactory"; - return new IdFactory(new SessionHandle("dummy.session"), - new ClientHandle(clientname,VersionEntries.latestVersion()), - new UserHandle(clientname, "Arnold User's Inc.")); - } -} diff --git a/src/org/vamsas/client/simpleclient/ListFile.java b/src/org/vamsas/client/simpleclient/ListFile.java deleted file mode 100644 index 30956e9..0000000 --- a/src/org/vamsas/client/simpleclient/ListFile.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * - */ -package org.vamsas.client.simpleclient; - -import java.io.File; - - -/** - * base class for generic list storage and retrieval operations from a locked IO file - * TODO: LATER: generalize for all list storage and retrieval operations - * (pull-up from ClientsFile object) - */ -public class ListFile extends SessionFile { - - /** - * @param file - */ - public ListFile(File file) throws java.io.IOException { - super(file); - if (!this.sessionFile.exists()) - this.sessionFile.createNewFile(); - } - -} diff --git a/src/org/vamsas/client/simpleclient/Lock.java b/src/org/vamsas/client/simpleclient/Lock.java deleted file mode 100644 index d3a5889..0000000 --- a/src/org/vamsas/client/simpleclient/Lock.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.nio.channels.ByteChannel; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; - -import org.apache.commons.logging.LogFactory; - -/** - * transient object representing a file lock - * This lock should hold for all processes interacting in a session. - * @author jimp - */ - -public abstract class Lock { - protected org.apache.commons.logging.Log log = LogFactory.getLog(Lock.class); - File target = null; // The file that is being locked - protected RandomAccessFile rafile=null; - - /** - * creates a valid Lock (test with isLocked) - * if a lock could be obtained for lockfile - * @param lockfile - */ - protected Lock(java.io.File lockfile) { - target = lockfile; - } - /** - * - * @return true if lock is held on the target - */ - public abstract boolean isLocked(); - /** - * release lock and close all managed channels to file - * - */ - public abstract void release(); - /** - * optionally close the open random access channel on the file when releasing lock - * @param closeChannel - */ - public abstract void release(boolean closeChannel); - - /** - * gets Locked Stream for reading from - * @param atStart true to start reading at beginning of file. - * @return null if file not locked - * @throws IOException - */ - public abstract FileInputStream getFileInputStream(boolean atStart) throws IOException; - - /** - * gets Locked stream to write to - * FileInput always starts at the *end* of the file (after any truncation) - * @param clear true means file will be cleared to zero length - * @return null if file is not locked - * @throws IOException - */ - public abstract FileOutputStream getFileOutputStream(boolean clear) throws IOException; - /** - * return buffered output stream to locked file. - * @param clear - true means file is truncated to 0 length before writing - * @return - */ - public abstract BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException; - - protected void finalize() throws Throwable { - target=null; - } - /** - * return buffered input stream for locked file. - * @param atStart - true means read from begining of file - * @return null if file is not locked. - */ - public BufferedInputStream getBufferedInputStream(boolean atStart) throws IOException { - FileInputStream fis = getFileInputStream(atStart); - if (fis!=null) - return new BufferedInputStream(fis); - return null; - } - /** - * safe lock target length() function. - * @return -1 for non-lockable target, otherwise target's file length - */ - public abstract long length(); - public abstract RandomAccessFile getRaFile() throws IOException; - public abstract FileChannel getRaChannel() throws IOException; -} diff --git a/src/org/vamsas/client/simpleclient/LockFactory.java b/src/org/vamsas/client/simpleclient/LockFactory.java deleted file mode 100644 index 5fdde6c..0000000 --- a/src/org/vamsas/client/simpleclient/LockFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.io.File; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class LockFactory { - protected static Log log = LogFactory.getLog(LockFactory.class); - public static int locktype=0; // use file lock by default - public static String[] locktypes = {"file","native"}; - { - String lockt = System.getProperty("vamsas.locktype"); - if (lockt!=null) { - int i,j; - for (i=0, j=locktypes.length; i=j) { - String lt = "'"+locktypes[0]+"'"; - for (i=1; i0 && !fileLock.isLocked()); - if (!fileLock.isLocked()) - log.error("Failed to get lock for "+sessionFile); - // fileLock = new Lock(sessionFile); - return fileLock.isLocked(); - } - - /** - * Explicitly release the SessionFile's lock. - * - * @return true if lock was released. - */ - protected void unlockFile() { - if (fileLock != null) { - fileLock.release(); - fileLock = null; - } - } - - /** - * Makes a backup of the sessionFile. - * @return Backed up SessionFile or null if failed to make backup. - */ - protected File backupSessionFile() { - return backupSessionFile(null, sessionFile.getName(),".old", sessionFile.getParentFile()); - } - - protected File backupSessionFile(Lock extantLock, String backupPrefix, String backupSuffix, File backupDir) { - File tempfile=null; - if (lockFile(extantLock)) { - try { - tempfile = File.createTempFile(backupPrefix, backupSuffix, backupDir); - if (fileLock.length()>0) { - FileOutputStream tos = new FileOutputStream(tempfile); - ReadableByteChannel channel; - tos.getChannel().transferFrom(channel=fileLock.getRaChannel(), 0, - fileLock.length()); - tos.close(); - if (!channel.isOpen()) - throw new Error(tos.getChannel().getClass()+".transferFrom closes source channel!"); - if (!lockFile(extantLock)) - throw new Error("Lost lock for "+sessionFile.getName()+" after backup."); - - } - } catch (FileNotFoundException e1) { - log.warn("Can't create temp file for "+sessionFile.getName(),e1); - tempfile=null; - } catch (IOException e1) { - log.warn("Error when copying content to temp file for "+sessionFile.getName(),e1); - tempfile=null; - } - } - return tempfile; - } - /** - * Replaces data in sessionFile with data from file handled by another sessionFile - * passes up any exceptions. - * @param newData source for new data - */ - protected void updateFrom(Lock extantLock, SessionFile newData) throws IOException { - log.debug("Updating "+sessionFile.getAbsolutePath()+" from "+newData.sessionFile.getAbsolutePath()); - if (newData==null) - throw new IOException("Null newData object."); - if (newData.sessionFile==null) - throw new IOException("Null SessionFile in newData."); - - if (!lockFile(extantLock)) - throw new IOException("Failed to get write lock for "+sessionFile); - if (!newData.lockFile()) - throw new IOException("Failed to get lock for updateFrom "+newData.sessionFile); - RandomAccessFile nrafile = newData.fileLock.getRaFile(); - nrafile.seek(0); - RandomAccessFile trafile = fileLock.getRaFile(); - /*long tries=5000; - while (trafile==null && --tries>0) { - log.debug("Lost lock on "+sessionFile+"! Re-trying for a transfer."); - lockFile(); - trafile = fileLock.getRaFile(); - }*/ - trafile.seek(0); - trafile.getChannel().transferFrom(nrafile.getChannel(), 0, - nrafile.length()); - } - /** - * remove all trace of the sessionFile file - * - */ - protected void eraseExistence() { - unlockFile(); - if (sessionFile!=null) { - sessionFile.delete(); - sessionFile = null; - } - } - /* (non-Javadoc) - * @see org.vamsas.client.simpleclient.Lock#getBufferedInputStream(boolean) - */ - public BufferedInputStream getBufferedInputStream(boolean atStart) throws IOException { - lockFile(); - return fileLock.getBufferedInputStream(atStart); - } - - /* (non-Javadoc) - * @see org.vamsas.client.simpleclient.Lock#getBufferedOutputStream(boolean) - */ - public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException { - lockFile(); - return fileLock.getBufferedOutputStream(clear); - } - - /* (non-Javadoc) - * @see org.vamsas.client.simpleclient.Lock#getFileInputStream(boolean) - */ - public FileInputStream getFileInputStream(boolean atStart) throws IOException { - lockFile(); - return fileLock.getFileInputStream(atStart); - } - - /* (non-Javadoc) - * @see org.vamsas.client.simpleclient.Lock#getFileOutputStream(boolean) - */ - public FileOutputStream getFileOutputStream(boolean clear) throws IOException { - lockFile(); - return fileLock.getFileOutputStream(clear); - } - -} diff --git a/src/org/vamsas/client/simpleclient/SessionFlagFile.java b/src/org/vamsas/client/simpleclient/SessionFlagFile.java deleted file mode 100644 index 7826fbc..0000000 --- a/src/org/vamsas/client/simpleclient/SessionFlagFile.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.io.File; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * methods for setting and checking - * binary flags in a vamsas session directory. - * all methods apart from the constructor will - * throw a fatal error if the flagFile is not - * a valid java.io.File object. - * LATER: extract SessionFlag interface for generalizing the vamsas session code - * @author jimp - * - */ -public class SessionFlagFile { - private static Log log = LogFactory.getLog(SessionFlagFile.class); - protected File flagFile=null; - private void checkFlagFile() { - if (flagFile==null) { - log.fatal("Implementation error - uninitialized SessionFlagFile", - new Error("Implementation error - uninitialized SessionFlagFile")); - } - } - /** - * will log a warning if exceptions occur during flag creation. - * @return true if flag was set successfully - */ - public boolean setFlag() { - checkFlagFile(); - try { - if (flagFile.createNewFile()) { - log.debug("Set session flag "+flagFile); - } else { - log.debug("Session flag already set "+flagFile); - } - return true; - } - catch (Exception e) { - log.warn("Couldn't set session flag "+flagFile, e); - } - return false; - } - /** - * - * @return true if flag was cleared successfully - */ - public boolean clearFlag() { - checkFlagFile(); - if (flagFile.exists()) { - log.debug("clearing session flag "+flagFile); - if (!flagFile.delete()) { - log.warn("failed to clear session flag "+flagFile); - return false; - } - } else { - log.debug("clearFlag called for already cleared flag "+flagFile); - } - return true; - } - /** - * - * @return state of session flag - */ - public boolean checkFlag() { - checkFlagFile(); - if (flagFile.exists()) { - if (log.isDebugEnabled()) - log.debug("Flag '"+flagFile+"' is set."); - return true; - } - if (log.isDebugEnabled()) - log.debug("Flag '"+flagFile+"' is not set."); - return false; - } - /** - * @param flagFile - */ - public SessionFlagFile(File flagFile) { - super(); - this.flagFile = flagFile; - }; -} diff --git a/src/org/vamsas/client/simpleclient/SessionUrn.java b/src/org/vamsas/client/simpleclient/SessionUrn.java deleted file mode 100644 index 13b6f23..0000000 --- a/src/org/vamsas/client/simpleclient/SessionUrn.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.io.File; -import java.net.MalformedURLException; - -/** - * SessionUrn for simpleclient sessions: - * simpleclient://{Absolute path to session directory} - * @author jimp - * - */ -public class SessionUrn extends org.vamsas.client.SessionUrn { - /** - * a simple client session urn prefix - */ - public static final String SIMPLECLIENT="simpleclient"; - public static String VAMSASDOCUMENT="vdoc"; - static { - TYPES.put(SIMPLECLIENT, SessionUrn.class); - TYPES.put(SessionUrn.VAMSASDOCUMENT, SessionUrn.class); - } - - public SessionUrn(File sessionLocation) throws MalformedURLException { - // TODO: LATER: implement switch to have vamsas document or simpleclient sessions for same constructor - super(SIMPLECLIENT, sessionLocation.getAbsoluteFile().toURL()); - //else - // super(VAMSASDOCUMENT, sessionLocation); - } - public SessionUrn(VamsasSession session) throws MalformedURLException { - super(SIMPLECLIENT, session.sessionDir.getAbsoluteFile().toURL()); - } - /** - * TODO: LATER: think about this again. - * @return File(urn.getPath()) - */ - public File asFile() { - return new File(urn.getPath()); - } - // TODO: add abstract 'handler' methods for resolving the URN to a particular class -} diff --git a/src/org/vamsas/client/simpleclient/SessionsFile.java b/src/org/vamsas/client/simpleclient/SessionsFile.java deleted file mode 100644 index eb80f45..0000000 --- a/src/org/vamsas/client/simpleclient/SessionsFile.java +++ /dev/null @@ -1,342 +0,0 @@ -/* EMBL - The European Bioinformatics institute -* MSD Group -* VAMSAS Project -* -* Copyright (c) 2005-2006 Thr European Bioinformatics Institute. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided with the -* distribution. -* -* 3. The name MSD must not be used to endorse or promote products -* derived from this software without prior written permission. For -* written permission, please contact msd-help@ebi.ac.uk -* -* 4. Products derived from this software may not be called "MSD" -* nor may "MSD" appear in their names without prior written -* permission of the MSD developers. -* -* 5. Redistributions of any form whatsoever must retain the following -* acknowledgment: -* "This product includes software developed by MSD -* (http://www.ebi.ac.uk/)" -* -* THIS SOFTWARE IS PROVIDED BY THE MSD GROUP ``AS IS'' AND ANY -* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ENSEMBL GROUP OR -* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -* OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The European Bioinformatics Institute may publish revised and/or new -* versions of this license with new releases of VAMSAS software. -*============================================================================== -* -* @author Pierre MARGUERITE -* -* Dec 13, 2006 - VamsasClientV4 -* -*/ - -package org.vamsas.client.simpleclient; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.vamsas.client.SessionHandle; - -/** - * @author Pierre MARGUERITE - * - * - */ -public class SessionsFile extends ListFile { - - private static Log log = LogFactory.getLog(SessionsFile.class); - /** - * when set true - get FileNotFoundExceptions on WinXP when writing to locked stream after the backup has been made (via the backupFile method) - */ - boolean backup=false; - /** - * number of my session in list - passed back when a session - * is added to list, and used (if valid) for quickly - * looking up presence of session handle in the list. - */ - private int syncnum = 1; - /** - * @param file - */ - public SessionsFile(File file) throws java.io.IOException { - super(file); - } - - - /** - * internal method for getting sessionsList - ensures a lock has been made but - * does not release it. - * - * @return list of clients - */ - private SessionHandle[] retrieveSessionHandles() { - if (lockFile()) { - try { - SessionHandle[] clients=null; - if (this.fileLock.length()>0) { - - ObjectInputStream is = new ObjectInputStream(this.fileLock.getBufferedInputStream(true)); - Object o; - o=is.readObject(); - if (o!=null) { - try { - clients = (SessionHandle[]) o; - } - catch (Exception e) { - log.error("Garbage in the clientHandle list "+this.sessionFile,e); - } - } - } - return clients; - } catch (FileNotFoundException e) { - // e.printStackTrace(System.err); - log.error(e); - } catch (Exception e) { - log.error(e); - //e.printStackTrace(System.err); - } - } - return null; - } - - /** - * get the SessionsList from the file. May return null if lock failed! - * @return sessionsList - */ - public SessionHandle[] retrieveSessionsList() { - if (lockFile()) { - SessionHandle[] clients = retrieveSessionHandles(); - unlockFile(); - return clients; - } - return null; - } - - /** - * get list from the locked ClientList. - * @param extantlock - * @return clientList or null if lock failed (or file was empty) - */ - public SessionHandle[] retrieveSessionsList(Lock extantlock) { - if (lockFile(extantlock)) { - SessionHandle[] clients = retrieveSessionHandles(); - unlockFile(); - return clients; - } - return null; - } - - - /** - * adds clientHandle me to the clientList under an existing lock extantLock. - * @param me - * @param extantLock - * @return client index in list or 0 if lock was invalid or addClient operation failed. - */ - public int addSession(SessionHandle me, Lock extantLock) { - return addSession(me, true, extantLock); - } - - /** - * adds SessionsHandle me to the sessionsList under an existing lock. - * @param me - sessionsHandle - * @param disambig - if true then add will fail if an identical clientHandle already exists - * @param extantLock - existing lock - * @return client index in list or 0 if addClient (or the lock) failed. - */ - - public int addSession(SessionHandle session, boolean disambig, Lock extantLock) { - if (lockFile(extantLock)) { - this.syncnum = addSession(session, disambig); - unlockFile(); - return this.syncnum; - } - return 0; - } - - /** - * removes the current session from the SessionsList without complaint if the session isn't in the sessionsList already. - * @param me client handle to be removed - * @param clientlock existing lock passed from watcher. - */ - public void removeSession(SessionHandle session, Lock clientlock) { - int mynum =-1; - if (lockFile(clientlock)) { - SessionHandle[] sessions = retrieveSessionHandles(); - if (sessions != null) { - if ((this.syncnum<=0 || this.syncnum>sessions.length) || sessions[this.syncnum-1]!=session) { - for (int i = 0, j = sessions.length; i < j; i++) - if (sessions[i].equals(session)) { - mynum=i; - break; - } - } else { - mynum=this.syncnum-1; - } - if (mynum>-1) { - SessionHandle[] newlist = new SessionHandle[sessions.length - 1]; - for (int k=0,i = 0, j = sessions.length; i < j; i++) - if (i!=mynum) - newlist[k++] = sessions[i]; - if (!putSessionsList(newlist)) - throw new Error("Failed to write new sessionsList!"); // failed to put the sessionList to disk. - } - } - unlockFile(); - } else { - throw new Error("Couldn't get lock for "+((sessionFile==null) ? "Unitialised sessionFile in SessionsFile" : this.sessionFile.getAbsolutePath())); - } - } - /** - * Adds a SessionHandle to the SessionList file - optionally disambiguating - * the SessionHandle (modifes the URN). - * Note: Caller is left to release the lock on the SessionList. - * @param me - * @param disambiguate - - * flag indicating if the URN for me should be disambiguated to - * differentiate between sessions. - * @return index of sessionHandle in new list, or -1-position of existing - * sessionHandle (if disambiguate is true) - */ - protected int addSession(SessionHandle session, boolean disambiguate) { - int newsession = 0; - int tries=5; - while (tries-->0 && !lockFile()) - try { Thread.sleep(1); } catch (Exception e){}; - if (lockFile()) { - SessionHandle[] sessions = retrieveSessionHandles(); - - if (sessions == null) { - sessions = new SessionHandle[1]; - sessions[0] = session; - newsession = 1; - } else { - int k = 0; - for (int i = 0, j = sessions.length; i < j; i++) { - if ( sessions[i].equals(session)) { - if (disambiguate) { - while (sessions[i].equals(session)) { - // me.setClientUrn(me.getClientUrn() + k++); // TODO: make a better - // disambiguation of - // urn. - } - } else { - // will not write the ambiguous clientHandle to disk, just return - // its index. - return -1 - i; - } - } - } - int i, j; - SessionHandle[] newlist = new SessionHandle[sessions.length + 1]; - for (i = 0, j = sessions.length; i < j; i++) - newlist[i] = sessions[i]; - newlist[j] = session; - sessions = newlist; - newsession = j+1; - } - if (!putSessionsList(sessions)) - return 0; // failed to put the clientList to disk. - } - return newsession; - } - - - /** - * safely writes sessions array to the file referred to by sessionFile. - * - * @param clients - * @return true if successful write. Throws Errors otherwise. - */ - protected boolean putSessionsList(SessionHandle[] clients) { - if (lockFile()) { - File templist=null; - if (!this.backup || (templist = backupSessionFile()) != null) { - int retries=3; - while (retries-->0) { - try { - ObjectOutputStream os = - new ObjectOutputStream(this.fileLock.getBufferedOutputStream(true)); - log.debug("About to write "+clients.length+" sessionHandles to output stream."); - os.writeObject(clients); - os.close(); - // All done - remove the backup. - if (this.backup) - templist.delete(); - templist = null; - retries=-1; - } catch (Exception e) { - // System.err - //.println("Serious - problems writing to sessionFile."); - log.error("Serious - problems writing to sessionFile.",e); - if (retries>0 && templist != null) { - // System.err.println("Recovering from Backup in " - // + templist.getAbsolutePath()); - log.error("Recovering from Backup in "+ templist.getAbsolutePath()); - templist.renameTo(this.fileLock.target); - } - //e.printStackTrace(System.err); - log.error(e); - } - } - if (retries>-2) { - // System.err - // .println("Serious - problems writing to sessionFile. Giving Up."); - log.error("Serious - problems writing to sessionFile. Giving Up."); - return false; - } - } else { - throw new Error( - "Couldn't create backup of the clientList before writing to it!"); - } - } else { - throw new Error("Could not lock the clientList: " - + ((this.sessionFile == null) ? "Unitialized ClientsFile" - : " failed to get lock on " + this.sessionFile.getAbsolutePath())); - } - // successful! - return true; - } - - public void clearList() { - if (lockFile()) { - try { - FileOutputStream fout = this.fileLock.getFileOutputStream(true); - fout.flush(); - fout.close(); - } catch (Exception e) { - throw new Error("Problems trying to clear clientlist!",e); - - } - } - - } -} diff --git a/src/org/vamsas/client/simpleclient/SimpleClient.java b/src/org/vamsas/client/simpleclient/SimpleClient.java deleted file mode 100644 index 2041c11..0000000 --- a/src/org/vamsas/client/simpleclient/SimpleClient.java +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Created on 15-Sep-2005 - * - * TODO To change the template for this generated file go to - * Window - Preferences - Java - Code Style - Code Templates - */ -package org.vamsas.client.simpleclient; - -import java.beans.EventHandler; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.Hashtable; -import java.util.Vector; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.vamsas.client.ClientHandle; -import org.vamsas.client.Events; -import org.vamsas.client.IClient; -import org.vamsas.client.IClientDocument; -import org.vamsas.client.IObjectUpdate; -import org.vamsas.client.InvalidSessionUrnException; -import org.vamsas.client.SessionHandle; -import org.vamsas.client.UserHandle; -import org.vamsas.objects.core.ApplicationData; -import org.vamsas.objects.core.Entry; -import org.vamsas.objects.core.LockFile; -import org.vamsas.objects.core.VamsasDocument; -import org.vamsas.objects.utils.AppDataReference; -import org.vamsas.objects.utils.ProvenanceStuff; -import org.vamsas.objects.utils.document.VersionEntries; - -/** - * @author jimp - */ -public class SimpleClient implements IClient { - - private static Log log = LogFactory.getLog(SimpleClient.class); - - protected UserHandle user = null; - - protected SessionUrn session = null; - protected VamsasSession _session; - protected ClientHandle client = null; - protected EventGeneratorThread evgen = null; - protected ClientDocument cdocument = null; - /** - * object hash table that persists in each client holding vorbaIds and hash values after a document write - */ - protected Hashtable extantobjects=null; - /** - * construct a transient IdFactory instance - this should last only as long as the - * SimpleClient object holds the lock on the vamsas document being created/manipulated. - * @return - */ - private IdFactory makeVorbaIdFactory() { - return new IdFactory(getSessionHandle(), client, user); - } - - /** - * construct SimpleClient for user, client and VamsasSession directory - * use the SimpleClientFactory rather than this constructor directly. - * @param user - * @param client - * @param sess - */ - protected SimpleClient(UserHandle user, ClientHandle client, VamsasSession sess) throws InvalidSessionUrnException { - // TODO: validate user/client/session - _session = sess; - this.user = user; - this.client = client; - try { - session = new SessionUrn(_session); - } catch (MalformedURLException e) { - log.error("Couldn't form a valid SessionUrn object!",e); - throw new InvalidSessionUrnException(_session.toString()); - } - } - /** - * construct new session by importing objects from an existing vamsas document - * @param user - * @param client - * @param sess - * @param importingArchive - * @throws Exception IOExceptions for Session IO problems, and general Exception if importing document is invalid. - */ - protected SimpleClient(UserHandle user, ClientHandle client, VamsasSession sess, File importingArchive) throws Exception { - this(user, client, sess); - VamsasArchive sessdoc = _session.getVamsasDocument(); - try { - VamsasArchiveReader odoc = new VamsasArchiveReader(importingArchive); - SimpleDocument sdoc = new SimpleDocument(makeVorbaIdFactory()); - VamsasDocument doc = sdoc.getVamsasDocument(odoc); - sessdoc.putVamsasDocument(doc, sdoc.vorba); - sessdoc.closeArchive(); - } catch (Exception e) { - sessdoc.cancelArchive(); - // write a dummy archive - _session.slog.info("Exception when importing document data from "+importingArchive); - throw new Exception("Failed to import data from "+importingArchive, e); - } - } - - /* - * (non-Javadoc) - * LATER: check that build substitution variables are correct - * @see org.vamsas.client.IClient#getAbout() - */ - public String getAbout() { - return new String("VORBA SimpleClient version $version$ build $build$"); - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#getSessionUrn() - */ - public String getSessionUrn() { - return session.getSessionUrn(); - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#getSessionHandle() - */ - public SessionHandle getSessionHandle() { - // TODO: eliminate SessionHandle ? need to refactor interfaces. - SessionHandle sh = new SessionHandle(session.getSessionUrn()); - return sh; - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#getClientHandle() - */ - public ClientHandle getClientHandle() { - return client; - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#getUserHandle() - */ - public UserHandle getUserHandle() { - return user; - } - /** - * - * @return user field for a provenance entry - */ - protected String getProvenanceUser() { - return new String(user.getFullName()); - } - /** - * construct a provenance entry for this client with the specified action string. - * @param action - * @return properly completed provenance entry - */ - protected Entry getProvenanceEntry(String action) { - Entry prov = ProvenanceStuff.newProvenanceEntry(client.getClientUrn(), getProvenanceUser(), action); - return prov; - } - private Hashtable handlers = initHandlers(); - - private Vector listeners = new Vector(); - - /** - * make all the PropertyChangeSupport objects for the - * events described in org.vamsas.client.Event - * @return - */ - private static Hashtable initHandlers() { - Hashtable events = new Hashtable(); - java.util.Iterator evt = Events.EventList.iterator(); - while (evt.hasNext()) { - Object ths = evt.next(); - events.put(ths, (Object) new PropertyChangeSupport(ths)); - } - return events; - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#addDocumentUpdateHandler(java.util.EventListener) - */ - public void addDocumentUpdateHandler(PropertyChangeListener evt) { - if (handlers.containsKey(Events.DOCUMENT_UPDATE)) { - Object handler; - ((PropertyChangeSupport) (handler = handlers.get(Events.DOCUMENT_UPDATE))) - .addPropertyChangeListener(evt); - listeners.add(handler); - listeners.add((Object) evt); - } - } - boolean finalized=false; - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#finalizeClient() - */ - public void finalizeClient() { - // TODO: determine if this is last client in session - // TODO: raise events like : ((lst_client && document.request.to.close), (client_finalization), ( - - // if (handlers.containsKey(Events.)) - // if (handlers.containsKey(Events.CLIENT_FINALIZATION)) - // deregister listeners. - // mark this instance as finalized - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#getClientDocument() - */ - public IClientDocument getClientDocument() throws IOException { - if (cdocument!=null) { - // cdocument is non-nill if the ClientDocument.finalise() method hasn't been called. - return cdocument; - } - VamsasArchive va = null; - try { - // LATER: bail out if it takes too long to get the lock ? - va = _session.getVamsasDocument(); - } - catch (IOException e) { - throw new IOException("Failed to get lock on session document"); - } - VamsasDocument doc=null; - IdFactory vorba = null; - // TODO: reduce size of vorba ids generated from these parameters to IdFactory (mainly sessionHandle rationalization ?) - try { - va.setVorba(vorba=makeVorbaIdFactory()); - // if session currently holds data - read it in - or get a dummy - _session.slog.debug("Accessing document"); - doc = - va.getVamsasDocument(getProvenanceUser(), - "created new session document.", null); - if (doc!=null) - _session.slog.debug("Successfully retrieved document."); - else - log.error("Unexpectedly retrieved null document!"); - } - catch (Exception e) { - log.error("Failed to get session document for session directory '"+_session.sessionDir+"'", e); - throw new IOException("Failed to get session document for session directory '"+_session.sessionDir+"'"); - } - // Construct the IClientDocument instance - - ClientDocument cdoc = new ClientDocument(doc, va, vorba, this); - return cdoc; - } - - /* - * (non-Javadoc) - * @throws Errors for invalid newdoc parameter - * @see org.vamsas.client.IClient#updateDocument(org.vamsas.client.IClientDocument) - */ - public void updateDocument(IClientDocument newdoc) { - if (!(newdoc instanceof ClientDocument)) { - throw new Error("Invalid IClientDocument instance for SimpleClient."); - } - if (cdocument==null) - throw new Error("Client Error - updateDocument() called before getClientDocument()."); - if (newdoc!=cdocument) - throw new Error("Client Error - SimpleClient.updateDocument() can only take the IClientDocument instance returned from SimpleClient.getClientDocument()"); - if (!cdocument.isModified()) { - if (log.isDebugEnabled()) - log.debug("updateDocument for "+session.getSessionUrn()+" with unmodified IClientDocument."); - } else { - try { - if (!cdocument.updateSessionDocument()) { - log.warn("Session document did not update properly for session directory "+_session.sessionDir); - // cdocument.archive.cancelArchive(); // LATER: could be done - would need to prevent updateSessionDocument closing the archive. - _session.slog.warn("Session Document updated but may not be valid (false return from org.vamsas.simpleclient.ClientDocument.updateSessionDocument()"); - } - } - catch (IOException e) { - log.warn("IO Problems when updating document!",e); - _session.slog.error("IO problems when attempting to update document."); - } - } - // garbage collect the ClientDocument instance. - try { - cdocument.finalize(); - - } catch (Throwable e) { - log.error("Exception when trying to garbage collect ClientDocument for "+session.getSessionUrn(), e); - } - cdocument = null; // this is probably done by finalize - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#storeDocument(java.io.File) - */ - public void storeDocument(File location) { - - // write storeDocument file to inform other clients that they should raise - Lock vamlock = evgen.want_to_store(); - // Events.DOCUMENT_FINALIZEAPPDATA - try { - _session.writeVamsasDocument(location, vamlock); - _session.clearUnsavedFlag(); - } catch (Exception e) { - log.warn("Exception whilst trying to store document in "+location,e); - } - - vamlock.release(); - } - - /* - * (non-Javadoc) - * - * @see org.vamsas.client.IClient#addVorbaEventHandler(java.lang.String, - * java.beans.PropertyChangeListener) - */ - public void addVorbaEventHandler(String EventChain, PropertyChangeListener evt) { - if (handlers.containsKey(EventChain)) { - Object handler; - ((PropertyChangeSupport) (handler = handlers.get(EventChain))) - .addPropertyChangeListener(evt); - listeners.add(handler); - listeners.add((Object) evt); - } - } - - /* (non-Javadoc) - * @see org.vamsas.client.IClient#pollUpdate() - */ - public void pollUpdate() { - - if (evgen==null) { - log.warn("pollUpdate called on incomplete SimpleClient object."); - return; - } - - if (!evgen.isAlive()) { - log.warn("pollUpdate called before joinSession() - trying to do this."); - try { - joinSession(); - } catch (Exception e) { - log.error("Unexpected exception on default call to joinSession",e); - } - } - - //TODO ensure event generator robustly handles these interrupts. - log.debug("interrrupting event generator."); - evgen.interrupt(); - log.debug("interrrupted event generator."); - } - - /* (non-Javadoc) - * @see org.vamsas.client.IClient#joinSession() - */ - public void joinSession() throws Exception { - // start the EventGenerator thread. - if (evgen==null) { - log.warn("joinSession called on incomplete SimpleClient object."); - return; - } - if (evgen.isAlive()) - throw new Error("Join session called twice for the same SimpleClient (IClient instance)."); - evgen.start(); - if (evgen.isAlive()) - log.debug("Started EventGenerator thread."); - else { - log.warn("Failed to start EventGenerator thread."); - throw new Exception("Failed to start event generator thread - client cannot be instantiated."); - } - if (evgen.countHandlersFor(Events.DOCUMENT_CREATE)>0) { - //TODO: is this application connecting to a newly created session document ? - //evgen.raise(Events.DOCUMENT_CREATE); - } - } - - - - /* (non-Javadoc) - * @see org.vamsas.client.IClient#importDocument(java.io.File) - */ - public void importDocument(File location) { - // TODO LATER: implement SimpleClient.importDocument() - log.error("importDocument is not yet implemented for a SimpleClient Session."); - } - - public IObjectUpdate getUpdateHandler(Class rootObject) { - // TODO Auto-generated method stub - return null; - } - - public IObjectUpdate[] getUpdateHandlers() { - // TODO Auto-generated method stub - return null; - } - - public void removeUpdateHandler(Class rootObject) { - // TODO Auto-generated method stub - - } - - public void setUpdateHandler(IObjectUpdate handler) { - // TODO Auto-generated method stub - - } -} diff --git a/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java b/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java deleted file mode 100644 index 84bc48a..0000000 --- a/src/org/vamsas/client/simpleclient/SimpleClientAppdata.java +++ /dev/null @@ -1,543 +0,0 @@ -/** - * - */ -package org.vamsas.client.simpleclient; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Vector; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; -import java.util.jar.JarOutputStream; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.vamsas.client.IClientAppdata; -import org.vamsas.objects.core.AppData; -import org.vamsas.objects.core.ApplicationData; -import org.vamsas.objects.core.User; -import org.vamsas.objects.utils.AppDataReference; - -/** - * @author jimp - * Access interface to data chunks read from a VamsasArchiveReader stream - * (or byte buffer input stream) or written to a VamsasArchive stream. - * // TODO: get VamsasArchiveReader from sclient - */ -public class SimpleClientAppdata implements IClientAppdata { - private static Log log = LogFactory.getLog(SimpleClientAppdata.class); - /** - * has the session's document been accessed to get the AppData entrys? - */ - protected boolean accessedDocument = false; - /** - * has the user datablock been modified ? - * temporary file containing new user specific application data chunk - */ - SessionFile newUserData=null; - JarOutputStream newUserDataStream = null; - /** - * has the apps global datablock been modified ? - * temporary file containing new global application data chunk - */ - SessionFile newAppData=null; - JarOutputStream newAppDataStream=null; - /** - * set by extractAppData - */ - protected ApplicationData appsGlobal = null; - /** - * set by extractAppData - */ - protected User usersData = null; - - ClientDocument clientdoc; - /** - * state flags - * - accessed ClientAppdata - * - accessed UserAppdata - * => inputStream from embedded xml or jar entry of backup has been created - * - set ClientAppdata - * - set UserAppdata - * => an output stream has been created and written to - or a data chunk has been written. - * - need flag for switching between embedded and jar entry mode ? - always write a jar entry for a stream. - * - need code for rewind and overwriting if the set*Appdata methods are called more than once. - * - need flags for streams to except a call to set*Appdata when an output stream exists and is open. - * - need - * @param clientdoc The ClientDocument instance that this IClientAppData is accessing - */ - protected SimpleClientAppdata(ClientDocument clientdoc) { - if (clientdoc==null) { - log.fatal("Implementation error - Null ClientDocument for SimpleClientAppdata construction."); - throw new Error("Implementation error - Null ClientDocument for SimpleClientAppdata construction."); - } - this.clientdoc = clientdoc; - } - /** - * gets appropriate app data for the application, if it exists in this dataset - * Called by every accessor to ensure data has been retrieved from document. - */ - private void extractAppData(org.vamsas.objects.core.VamsasDocument doc) { - if (doc==null) { - log.debug("extractAppData called for null document object"); - return; - } - if (accessedDocument) { - return; - } - Vector apldataset = AppDataReference.getUserandApplicationsData( - doc, clientdoc.sclient.getUserHandle(), clientdoc.sclient.getClientHandle()); - accessedDocument = true; - if (apldataset!=null) { - if (apldataset.size()>0) { - AppData clientdat = (AppData) apldataset.get(0); - if (clientdat instanceof ApplicationData) { - appsGlobal = (ApplicationData) clientdat; - if (apldataset.size()>1) { - clientdat = (AppData) apldataset.get(1); - if (clientdat instanceof User) { - usersData = (User) clientdat; - } - if (apldataset.size()>2) - log.info("Ignoring additional ("+(apldataset.size()-2)+") AppDatas returned by document appdata query."); - } - } else { - log.warn("Unexpected entry in AppDataReference query: id="+clientdat.getVorbaId()+" type="+clientdat.getClass().getName()); - } - apldataset.removeAllElements(); // destroy references. - } - } - } - /** - * LATER: generalize this for different low-level session implementations (it may not always be a Jar) - * @param appdata - * @param docreader - * @return - */ - private JarInputStream getAppDataStream(AppData appdata, VamsasArchiveReader docreader) { - String entryRef = appdata.getDataReference(); - if (entryRef!=null) { - log.debug("Resolving appData reference +"+entryRef); - InputStream entry = docreader.getAppdataStream(entryRef); - if (entry!=null) { - if (entry instanceof JarInputStream) { - return (JarInputStream) entry; - } - log.warn("Implementation problem - docreader didn't return a JarInputStream entry."); - } - } else { - log.debug("GetAppDataStream called for an AppData without a data reference."); - } - return null; - } - /** - * yuk - size of buffer used for slurping appData JarEntry into a byte array. - */ - private final int _TRANSFER_BUFFER=4096*4; - - /** - * Resolve AppData object to a byte array. - * @param appdata - * @param archiveReader - * @return null or the application data as a byte array - */ - private byte[] getAppDataAsByteArray(AppData appdata, VamsasArchiveReader docreader) { - if (appdata.getData()==null) { - if (docreader==null) { - log.warn("Silently failing getAppDataAsByteArray with null docreader.",new Exception()); - return null; - } - // resolve and load data - JarInputStream entry = getAppDataStream(appdata, docreader); - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try { - byte buff[] = new byte[_TRANSFER_BUFFER]; - int olen=0; - while (entry.available()>0) { - int len = entry.read(buff, olen, _TRANSFER_BUFFER); - bytes.write(buff, 0, len); - olen+=len; - } - buff=null; - } catch (Exception e) { - log.warn("Unexpected exception - probable truncation when accessing VamsasDocument entry "+appdata.getDataReference(), e); - } - if (bytes.size()>0) { - // LATER: deal with probable OutOfMemoryErrors here - log.debug("Got "+bytes.size()+" bytes from AppDataReference "+appdata.getDataReference()); - byte data[] = bytes.toByteArray(); - bytes = null; - return data; - } - return null; - } else { - log.debug("Returning inline AppData block for "+appdata.getVorbaId()); - return appdata.getData(); - } - } - /** - * internal method for getting a DataInputStream from an AppData object. - * @param appdata - * @param docreader - * @return data in object or null if no data is accessible - */ - private DataInput getAppDataAsDataInputStream(AppData appdata, VamsasArchiveReader docreader) { - if (appdata!=null && docreader!=null) { - String entryRef = appdata.getDataReference(); - if (entryRef!=null) { - log.debug("Resolving AppData reference for "+entryRef); - InputStream jstrm = docreader.getAppdataStream(entryRef); - if (jstrm!=null) - return new AppDataInputStream(jstrm); - else { - log.debug("Returning null input stream for unresolved reference ("+entryRef+") id="+appdata.getVorbaId()); - return null; - } - } else { - // return a byteArray input stream - byte[] data=appdata.getData(); - if (data.length>0) { - ByteArrayInputStream stream = new ByteArrayInputStream(data); - return new DataInputStream(stream); - } else { - log.debug("Returning null input stream for empty Appdata data block in id="+appdata.getVorbaId()); - return null; - } - } - } else { - log.debug("Returning null DataInputStream for appdata entry:"+appdata.getVorbaId()); - } - return null; - } - - /** - * internal method for getting ByteArray from AppData object - * @param clientOrUser - true for returning userData, otherwise return Client AppData. - * @return null or byte array - */ - private byte[] _getappdataByteArray(boolean clientOrUser) { - if (clientdoc==null) - throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); - byte[] data=null; - String appdName; - if (!clientOrUser) { - appdName = "Client's Appdata"; - } else { - appdName = "User's Appdata"; - } - log.debug("getting "+appdName+" as a byte array"); - extractAppData(clientdoc.getVamsasDocument()); - AppData object; - if (!clientOrUser) { - object = appsGlobal; - } else { - object = usersData; - } - if (object!=null) { - log.debug("Trying to resolve "+appdName+" object to byte array."); - data = getAppDataAsByteArray(object, clientdoc.getVamsasArchiveReader()); - } - if (data == null) - log.debug("Returning null for "+appdName+"ClientAppdata byte[] array"); - return data; - - } - - /** - * common method for Client and User AppData->InputStream accessor - * @param clientOrUser - the appData to resolve - false for client, true for user appdata. - * @return null or the DataInputStream desired. - */ - private DataInput _getappdataInputStream(boolean clientOrUser) { - if (clientdoc==null) - throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); - String appdName; - if (!clientOrUser) { - appdName = "Client's Appdata"; - } else { - appdName = "User's Appdata"; - } - if (log.isDebugEnabled()) - log.debug("getting "+appdName+" as an input stream."); - extractAppData(clientdoc.getVamsasDocument()); - AppData object; - if (!clientOrUser) { - object = appsGlobal; - } else { - object = usersData; - } - if (object!=null) { - log.debug("Trying to resolve ClientAppdata object to an input stream."); - return getAppDataAsDataInputStream(object, clientdoc.getVamsasArchiveReader()); - } - log.debug("getClientInputStream returning null."); - return null; - } - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getClientAppdata() - */ - public byte[] getClientAppdata() { - return _getappdataByteArray(false); - } - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getClientInputStream() - */ - public DataInput getClientInputStream() { - return _getappdataInputStream(false); - } - - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getUserAppdata() - */ - public byte[] getUserAppdata() { - return _getappdataByteArray(true); - } - - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getUserInputStream() - */ - public DataInput getUserInputStream() { - return _getappdataInputStream(true); - } - /** - * methods for writing new AppData entries. - */ - private DataOutput _getAppdataOutputStream(boolean clientOrUser) { - String apdname; - SessionFile apdfile=null; - if (!clientOrUser) { - apdname = "clientAppData"; - apdfile = newAppData; - } else { - apdname = "userAppData"; - apdfile = newUserData; - } - try { - if (apdfile==null) { - apdfile=clientdoc.sclient._session.getTempSessionFile(apdname,".jar"); - log.debug("Successfully made temp appData file for "+apdname); - } else { - // truncate to remove existing data. - apdfile.fileLock.getRaFile().setLength(0); - log.debug("Successfully truncated existing temp appData for "+apdname); - } - } catch (Exception e) { - log.error("Whilst opening temp file in directory "+clientdoc.sclient._session.sessionDir, e); - } - // we do not make another file for the new entry if one exists already - if (!clientOrUser) { - newAppData = apdfile; - } else { - newUserData = apdfile; - } - try { - apdfile.lockFile(); - // LATER: Refactor these local AppDatastream IO stuff to their own class. - JarOutputStream dstrm = - new JarOutputStream(apdfile.fileLock.getBufferedOutputStream(true)); - if (!clientOrUser) { - newAppDataStream = dstrm; - } else { - newUserDataStream = dstrm; - } - dstrm.putNextEntry(new JarEntry("appData_entry.dat")); - // LATER: there may be trouble ahead if an AppDataOutputStream is written to by one thread when another truncates the file. This situation should be prevented if possible - return new AppDataOutputStream(dstrm); - } - catch (Exception e) { - log.error("Whilst opening jar output stream for file "+apdfile.sessionFile); - } - // tidy up and return null - apdfile.unlockFile(); - return null; - } - /** - * copy data from the appData jar file to an appropriately - * referenced jar or Data entry for the given ApplicationData - * Assumes the JarFile is properly closed. - * @param vdoc session Document handler - * @param appd the AppData whose block is being updated - * @param apdjar the new data in a Jar written by this class - */ - protected void updateAnAppdataEntry(VamsasArchive vdoc, AppData appd, SessionFile apdjar) throws IOException { - if (apdjar==null || apdjar.sessionFile==null || !apdjar.sessionFile.exists()) { - throw new IOException("No temporary Appdata to recover and transfer."); - } - if (vdoc==null) { - log.fatal("FATAL! NO DOCUMENT TO WRITE TO!"); - throw new IOException("FATAL! NO DOCUMENT TO WRITE TO!"); - } - log.debug("Recovering AppData entry from "+apdjar.sessionFile); - JarInputStream istrm = new JarInputStream(apdjar.getBufferedInputStream(true)); - JarEntry je=null; - while (istrm.available()>0 && (je=istrm.getNextJarEntry())!=null && !je.getName().equals("appData_entry.dat")) { - if (je!=null) - log.debug("Ignoring extraneous entry "+je.getName()); - } - if (istrm.available()>0 && je!=null) { - log.debug("Found appData_entry.dat in Jar"); - String ref = appd.getDataReference(); - if (ref==null) { - throw new IOException("Null AppData.DataReference passed."); - } - if (vdoc.writeAppdataFromStream(ref, istrm)) { - log.debug("Entry updated successfully."); - } else { - throw new IOException("writeAppdataFromStream did not return true - expect future badness."); // LATER - verify why this might occur. - } - } else { - throw new IOException("Couldn't find appData_entry.dat in temporary jar file "+apdjar.sessionFile.getAbsolutePath()); - } - istrm.close(); - } - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getClientOutputStream() - */ - public DataOutput getClientOutputStream() { - if (clientdoc==null) - throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); - if (log.isDebugEnabled()) - log.debug("trying to getClientOutputStream for "+clientdoc.sclient.client.getClientUrn()); - return _getAppdataOutputStream(false); - } - - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#getUserOutputStream() - */ - public DataOutput getUserOutputStream() { - if (clientdoc==null) - throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); - if (log.isDebugEnabled()) - log.debug("trying to getUserOutputStream for (" - +clientdoc.sclient.getUserHandle().getFullName()+")"+clientdoc.sclient.client.getClientUrn()); - return _getAppdataOutputStream(true); - } - - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#hasClientAppdata() - */ - public boolean hasClientAppdata() { - if (clientdoc==null) - throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); - extractAppData(clientdoc.getVamsasDocument()); - // LATER - check validity of a DataReference before we return true - if ((appsGlobal!=null) && (appsGlobal.getDataReference()!=null || appsGlobal.getData()!=null)) - return true; - return false; - } - - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#hasUserAppdata() - */ - public boolean hasUserAppdata() { - if (clientdoc==null) - throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); - extractAppData(clientdoc.getVamsasDocument()); - // LATER - check validity of a DataReference before we return true - if ((appsGlobal!=null) && (appsGlobal.getDataReference()!=null || appsGlobal.getData()!=null)) - return true; - return false; - } - private boolean _writeAppDataStream(JarOutputStream ostrm, byte[] data) { - try { - if (data!=null && data.length>0) - ostrm.write(data); - ostrm.closeEntry(); - return true; - } - catch (Exception e) { - log.error("Serious! - IO error when writing AppDataStream to file "+newAppData.sessionFile, e); - } - return false; - } - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#setClientAppdata(byte[]) - */ - public void setClientAppdata(byte[] data) { - if (clientdoc==null) - throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); - _getAppdataOutputStream(false); - if (newAppDataStream==null) { - // LATER: define an exception for this ? - operation may fail even if file i/o not involved - log.error("Serious! - couldn't open new AppDataStream in session directory "+clientdoc.sclient._session.sessionDir); - } else { - _writeAppDataStream(newAppDataStream, data); - // LATER: deal with error case - do we make session read only, or what ? - } - } - - /* (non-Javadoc) - * @see org.vamsas.client.IClientAppdata#setUserAppdata(byte[]) - */ - public void setUserAppdata(byte[] data) { - if (clientdoc==null) - throw new Error("Implementation error, Improperly initialized SimpleClientAppdata."); - _getAppdataOutputStream(true); - if (newUserDataStream==null) { - // LATER: define an exception for this ? - operation may fail even if file i/o not involved - log.error("Serious! - couldn't open new UserDataStream in session directory "+clientdoc.sclient._session.sessionDir); - } else { - _writeAppDataStream(newUserDataStream, data); - // LATER: deal with error case - do we make session read only, or what ? - } - } - /** - * flush and close outstanding output streams. - * - do this before checking data length. - * @throws IOException - */ - protected void closeForWriting() throws IOException { - if (newAppDataStream!=null) { - newAppDataStream.flush(); - newAppDataStream.closeEntry(); - newAppDataStream.close(); - } - if (newUserDataStream!=null) { - newUserDataStream.flush(); - newUserDataStream.closeEntry(); - newUserDataStream.close(); - } - } - - - /** - * - * @return true if any AppData blocks have to be updated in session Jar - */ - protected boolean isModified() { - // LATER differentiate between core xml modification and Jar Entry modification. - if (newAppData.sessionFile.exists() || newUserData.sessionFile.exists()) - return true; - return false; - } - /* (non-Javadoc) - * @see java.lang.Object#finalize() - */ - protected void finalize() throws Throwable { - if (newAppDataStream!=null) { - newAppDataStream = null; - } - if (newAppDataStream!=null) { - newUserDataStream = null; - } - if (newAppData!=null) { - newAppData.eraseExistence(); - newAppData = null; - } - if (newUserData!=null) { - newUserData.eraseExistence(); - newUserData = null; - } - super.finalize(); - } - -} diff --git a/src/org/vamsas/client/simpleclient/SimpleClientFactory.java b/src/org/vamsas/client/simpleclient/SimpleClientFactory.java deleted file mode 100644 index 6f5509a..0000000 --- a/src/org/vamsas/client/simpleclient/SimpleClientFactory.java +++ /dev/null @@ -1,262 +0,0 @@ -/* -* VAMSAS Project -* - -* -* Dec 13, 2006 -* -*/ - -package org.vamsas.client.simpleclient; - -import java.io.File; - -import java.io.IOException; - - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.vamsas.client.ClientHandle; -import org.vamsas.client.IClient; -import org.vamsas.client.IClientFactory; -import org.vamsas.client.InvalidSessionUrnException; -import org.vamsas.client.NoDefaultSessionException; -import org.vamsas.client.SessionHandle; -import org.vamsas.client.UserHandle; - -/** - * - * - */ -public class SimpleClientFactory implements IClientFactory { - - private static Log log = LogFactory.getLog(SimpleClientFactory.class); - - private File sessionArena = null; - - private String vamsasSubdirectoryName = ".vamsas"; - - private SessionsFile sessionFile = null; - private static final String SESSION_LIST="sessions.obj"; - - //private String[] currentlyAvailableDessions = null; - - /** - * default constructor - called by CreateClientFactory only. - * - *Inits the sessionarena to the directory .vamsas of the user home directory. - * - */ - public SimpleClientFactory() throws IOException - { - // sessionArena - - //retrieves user home directory - String userHomeDirectory = System.getProperty("user.home"); - if (userHomeDirectory == null || userHomeDirectory.length()<1) - { - new IOException("Unable to detect user home directory"); - } - String sessionArenaPath = userHomeDirectory.concat(File.separator.concat(this.vamsasSubdirectoryName)); - - this.initSessionArena(sessionArenaPath); - this.initFactoryObjects(); - } - - - /** - * Create a client factory that works with sessions at the given - * path. - * @param path path to directory called session arena, where will be created session directories and session files. - */ - public SimpleClientFactory(String path) throws IOException - { - this.initSessionArena(path); - } - /** - * Inits sessionArena to a given path. - * checks if path is valid. - * - * @param path path to a directory to use - * @throws IOException if the path is incorrect - */ - private void initSessionArena (String path) throws IOException - { - // Check path is valid and read/writeable. - File arenaFile = new File (path); - if (!arenaFile.exists()) - { - if (! arenaFile.mkdirs()) - { - this.sessionArena = null; - throw(new IOException("Unable to create a directory called "+path)); - } - } - if (arenaFile.exists() && arenaFile.isDirectory() && arenaFile.canRead() && arenaFile.canWrite()) - { - this.sessionArena = arenaFile; - } - else - { - this.sessionArena = null; - throw(new IOException("Cannot read and write to a directory called "+path)); - } - } - - /** - * construct SessionFile objects and watchers for each - */ - private void initFactoryObjects() throws IOException { - if (this.sessionFile!=null ) - throw new IOException("initFactoryObjects called for initialised ClientFactory object."); - this.sessionFile = new SessionsFile(new File(this.sessionArena,SESSION_LIST)); - - } - /** - * @see org.vamsas.client.IClientFactory#getCurrentSessions() - */ - public String[] getCurrentSessions() - { - String[] sessions = null; - if (this.sessionFile!=null ) - { - SessionHandle[] sessionHandles = this.sessionFile.retrieveSessionsList(); - if (sessionHandles != null) - { - sessions = new String[sessionHandles.length]; - for (int i = sessionHandles.length -1; i > 0; i--) - { - SessionHandle sessionHandle = sessionHandles[i]; - sessions [i] = sessionHandle.getSessionUrn(); - } - } - } - return sessions; - } - - - private void discoverSession() - { - - } - - /** - * @see org.vamsas.client.IClientFactory#getIClient(org.vamsas.client.ClientHandle) - * - * Creates a IClient object, using default UserHandle with system variables:"user.name" or "USERNAME")), - "host.name" or "HOSTNAME" - */ - public IClient getIClient(ClientHandle applicationHandle) - throws NoDefaultSessionException { - - return this.getIClient(applicationHandle, (UserHandle) null); - } - - /** - * @see org.vamsas.client.IClientFactory#getIClient(org.vamsas.client.ClientHandle, java.lang.String) - */ - public IClient getIClient(ClientHandle applicationHandle, String sessionUrn) { - // TODO Auto-generated method stub - return null; - } - - /** - * @see org.vamsas.client.IClientFactory#getIClient(org.vamsas.client.ClientHandle, org.vamsas.client.UserHandle, java.lang.String) - */ - public IClient getIClient(ClientHandle applicationHandle, UserHandle userId, - String sessionUrn) { - // TODO Auto-generated method stub - return null; - } - - /** - * @see org.vamsas.client.IClientFactory#getIClient(org.vamsas.client.ClientHandle, org.vamsas.client.UserHandle) - */ - public IClient getIClient(ClientHandle applicationHandle, UserHandle userId) - throws NoDefaultSessionException { - SimpleClient client = null; - if (this.sessionArena==null) - throw new Error("Improperly initialised SimpleClientFactory object - null sessionArena."); - - ClientHandle clientHandle =applicationHandle; - //create default clientHandle with "SimpleVamsasClientApp","0.1", - if (clientHandle == null) - clientHandle = new ClientHandle("SimpleVamsasClientApp","0.1"); - - //check if any available session(s) - String[] availableSessions = this.getCurrentSessions(); - if (availableSessions != null) - {//there are available sessions - if (availableSessions.length>1) - {//more than one session if available... can not choose - - //represents list of session as String - StringBuffer sessionURNs = new StringBuffer(""); - for (int i = 0; i< availableSessions.length ; i++) - { - sessionURNs.append(availableSessions[i]+" "); - } - throw new NoDefaultSessionException("Several sessions available, please pick one: "+sessionURNs); - } - - //check if only one session available. if yes, open it - if (availableSessions.length == 1) - { - //only one session available, open it. - return this.getIClient(clientHandle, availableSessions[0]); - } - } - //no session available - create a new one - - - try - { - //create sessionDirectory - File sessdir = File.createTempFile("sess", ".simpleclient", this.sessionArena); - log.debug("Creating new session directory"); - if (!(sessdir.delete() && sessdir.mkdir())) - throw new IOException("Could not make session directory "+sessdir); - //create session - VamsasSession vamsasSession = new VamsasSession(sessdir); - - this.getSessionFile().addSession(new SessionHandle(new SessionUrn(vamsasSession).getSessionUrn()), false); - if (userId == null) - { - //create a default userHandle - //with current OS user and hostname - userId = new UserHandle(System.getProperty("user.name", System.getProperty("USERNAME","Joe Doe")), - System.getProperty("host.name",System.getProperty("HOSTNAME", "Unknown") ));// clientName, clientVersion, sessionPath); - } - - - //create simple client - client = new SimpleClient(userId, clientHandle, vamsasSession); - } - catch (IOException e) - { - log.error("error while creating new IClient",e); - } - catch (InvalidSessionUrnException e) - { - log.error("Unable to create new IClient. The session urn is incorrect ",e); - } - - return client; - } - - - /** - * @return the sessionFile - */ - private SessionsFile getSessionFile() throws IOException - { - if (this.sessionFile == null) - { - this.sessionFile = new SessionsFile( new File (this.sessionArena, SESSION_LIST)); - } - return this.sessionFile; - } - - - -} diff --git a/src/org/vamsas/client/simpleclient/SimpleDocBinding.java b/src/org/vamsas/client/simpleclient/SimpleDocBinding.java deleted file mode 100644 index c0c8084..0000000 --- a/src/org/vamsas/client/simpleclient/SimpleDocBinding.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Vector; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.vamsas.client.Vobject; -import org.vamsas.client.VorbaIdFactory; -import org.vamsas.client.VorbaXmlBinder; -import org.vamsas.objects.core.VAMSAS; -import org.vamsas.objects.core.VamsasDocument; -import org.vamsas.objects.utils.AppDataReference; -import org.vamsas.objects.utils.DocumentStuff; -import org.vamsas.objects.utils.ProvenanceStuff; -import org.vamsas.objects.utils.document.VersionEntries; - -/** - * Base class for SimpleClient Vamsas Document Object Manipulation - * holds static vamsasDocument from XML routines and - * state objects for a particular unmarshalled Document instance. - * @author jimp - */ - - -public class SimpleDocBinding { - - protected VorbaIdFactory vorba; - protected static Log log = LogFactory.getLog(SimpleDocBinding.class); - - /** - * @return Returns the vorba. - */ - public VorbaIdFactory getVorba() { - return vorba; - } - - /** - * @param vorba The vorba to set. - */ - public void setVorba(VorbaIdFactory vorba) { - this.vorba = vorba; - } - - /** - * Uses VorbaXmlBinder to retrieve the VamsasDocument from the given stream - */ - public VamsasDocument getVamsasDocument(VamsasArchiveReader oReader) throws IOException, org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - if (oReader!=null) { - // check the factory - if (vorba==null) { - log.error("Invalid SimpleDocument construction - no VorbaIdFactory defined!"); - return null; - } - - if (oReader.isValid()) { - // Read vamsasDocument.xsd instance - InputStreamReader vdoc = new InputStreamReader(oReader.getVamsasDocumentStream()); - Object unmarsh[] = VorbaXmlBinder.getVamsasObjects(vdoc, vorba, new VamsasDocument()); - if (unmarsh==null) - log.fatal("Couldn't unmarshall document!"); - - Vobject vobjs = (Vobject) unmarsh[0]; - if (vobjs!=null) { - VamsasDocument doc=(VamsasDocument) vobjs; - if (doc!=null) - return doc; - } - log.debug("Found no VamsasDocument object in properly formatted Vamsas Archive."); - } else { - // deprecated data handler (vamsas.xsd instance) - InputStream vxmlis = oReader.getVamsasXmlStream(); - if (vxmlis!=null) { // Might be an old vamsas file. - BufferedInputStream ixml = new BufferedInputStream(oReader.getVamsasXmlStream()); - InputStreamReader vxml = new InputStreamReader(ixml); - Object unmarsh[] = VorbaXmlBinder.getVamsasObjects(vxml, vorba, new VAMSAS()); - - if (unmarsh==null) - log.fatal("Couldn't unmarshall document!"); - - VAMSAS root[]= new VAMSAS[] { null}; - root[0] = (VAMSAS) unmarsh[0]; - - if (root[0]==null) { - log.debug("Found no VAMSAS object in VamsasXML stream."); - } else { - log.debug("Making new VamsasDocument from VamsasXML stream."); - VamsasDocument doc = DocumentStuff.newVamsasDocument(root, - ProvenanceStuff.newProvenance( - vorba.getUserHandle().getFullName(), - "Vamsas Document constructed from vamsas.xml"), VersionEntries.ALPHA_VERSION); - // VAMSAS: decide on 'system' operations provenance form - // LATER: implement classes for translating Vorba properties into provenance user fields. - // VAMSAS: decide on machine readable info embedding in provenance should be done - root[0]=null; - root=null; - return doc; - } - } - } - } - // otherwise - there was no valid original document to read. - return null; - } - - /** - * Extract all jarEntries in an archive referenced by the vamsas document - * LATER: a family of methods for finding extraneous jarEntries , and invalid appDataReferences - * @param doc - * @param oReader - * @return array of the subset of JarEntry names that are referenced in doc - */ - public Vector getReferencedEntries(VamsasDocument doc, VamsasArchiveReader oReader) { - if (oReader==null) - return null; - if (doc==null) { - try { doc = getVamsasDocument(oReader); } - catch (Exception e) { log.warn("Failed to get document from "+oReader.jfile.getName()); }; - } - Vector docrefs = AppDataReference.getAppDataReferences(doc); - if (docrefs==null) - return null; - Vector entries = oReader.getExtraEntries(); - if (entries!=null && docrefs.size()>0) { - int i=0, j=entries.size(); - do { - if (!docrefs.contains(entries.get(i))) { - entries.remove(i); - j--; - } else - i++; - } while (iarchive - * @throws IOException - */ - public VamsasArchive(File archive, boolean overwrite, boolean vamsasdocument, SessionFile extantLock) throws IOException { - super(); - if (archive==null || (archive!=null && !(archive.getAbsoluteFile().getParentFile().canWrite() && (!archive.exists() || archive.canWrite())))) { - log.fatal("Expect Badness! -- Invalid parameters for VamsasArchive constructor:"+((archive!=null) - ? "File cannot be overwritten." : "Null Object not valid constructor parameter")); - return; - } - - this.vamsasdocument = vamsasdocument; - if (archive.exists() && !overwrite) { - this.original = archive; - if (extantLock!=null) { - this.odoclock = extantLock; - if (odoclock.fileLock==null || !odoclock.fileLock.isLocked()) - odoclock.lockFile(); - } else { - this.odoclock = new SessionFile(archive); - } - odoclock.lockFile(); // lock the file *immediatly* - this.archive = null; // archive will be a temp file when the open method is called - virginArchive=false; - try { - this.accessOriginal(); - } catch (IOException e) { - throw new IOException("Lock failed for existing archive"+archive); - } - } else { - this.original = null; - this.archive = archive; // archive is written in place. - if (extantLock!=null) - rchive=extantLock; - else - rchive = new SessionFile(archive); - rchive.lockFile(); - if (rchive.fileLock==null || !rchive.fileLock.isLocked()) - throw new IOException("Lock failed for new archive"+archive); - rchive.fileLock.getRaFile().setLength(0); // empty the archive. - virginArchive = true; - } - this.openArchive(); // open archive - } - /** - * open original archive file for exclusive (locked) reading. - * @throws IOException - */ - private void accessOriginal() throws IOException { - if (original!=null && original.exists()) { - if (odoclock==null) - odoclock = new SessionFile(original); - odoclock.lockFile(); - if (odoc == null) - odoc = new VamsasArchiveReader(original); - // this constructor is not implemented yet odoc = new VamsasArchiveReader(odoclock.fileLock); - } - } - - /** - * Add unique entry strings to internal JarEntries list. - * @param entry - * @return true if entry was unique and was added. - */ - private boolean addEntry(String entry) { - if (entries!=null) - entries=new Hashtable(); - if (entries.containsKey(entry)) - return false; - entries.put(entry, new Integer(entries.size())); - return true; - } - /** - * adds named entry to newarchive or returns false. - * @param entry - * @return true if entry was unique and could be added - * @throws IOException if entry name was invalid or a new entry could not be made on newarchive - */ - private boolean addValidEntry(String entry) throws IOException { - JarEntry je = new JarEntry(entry); - if (!addEntry(entry)) - return false; - newarchive.flush(); - newarchive.putNextEntry(je); - return true; - } - /** - * called by app to get name of backup if it was made. - * If this is called, the caller app *must* delete the backup themselves. - * @return null or a valid file object - */ - public File backupFile() { - - if (!virginArchive) { - makeBackup(); - donotdeletebackup=false; // external reference has been made. - return ((original!=null) ? originalBackup : null); - } - return null; - } - - /** - * Stops any current write to archive, and reverts to the backup if it exists. - * All existing locks on the original will be released. All backup files are removed. - */ - public boolean cancelArchive() { - if (newarchive!=null) { - try { - newarchive.closeEntry(); - newarchive.putNextEntry(new JarEntry("deleted")); - newarchive.closeEntry(); - newarchive.close(); - - } catch (Exception e) { - log.debug("Whilst closing newarchive",e); - }; - if (!virginArchive) { - // then there is something to recover. - try { - recoverBackup(); - } - catch (Exception e) { - log.warn("Problems when trying to cancel Archive "+archive.getAbsolutePath(), e); - return false; - } - } - - } else { - log.warn("Client Error: cancelArchive called before archive("+original.getAbsolutePath()+") has been opened!"); - } - closeAndReset(); // tidy up and release locks. - return true; - } - - /** - * only do this if you want to destroy the current file output stream - * - */ - private void closeAndReset() { - if (rchive!=null) { - rchive.unlockFile(); - rchive=null; - } - if (original!=null) { - if (odoc!=null) { - odoc.close(); - odoc=null; - } - if (archive!=null) - archive.delete(); - if (odoclock!=null) { - odoclock.unlockFile(); - odoclock = null; - } - } - removeBackup(); - newarchive=null; - original=null; - entries=null; - } - /** - * Tidies up and closes archive, removing any backups that were created. - * NOTE: It is up to the caller to delete the original archive backup obtained from backupFile() - * TODO: ensure all extant AppDataReference jar entries are transferred to new Jar - * TODO: provide convenient mechanism for generating new unique AppDataReferences and adding them to the document - */ - public void closeArchive() throws IOException { - if (newarchive!=null) { - newarchive.flush(); - newarchive.closeEntry(); - if (!isDocumentWritten()) - log.warn("Premature closure of archive '"+archive.getAbsolutePath()+"': No document has been written."); - newarchive.finish();// close(); // use newarchive.finish(); for a stream IO - newarchive.flush(); - // - updateOriginal(); - closeAndReset(); - } else { - log.warn("Attempt to close archive that has not been opened for writing."); - } - } - /** - * Opens and returns the applicationData output stream for the appdataReference string. - * @param appdataReference - * @return Output stream to write to - * @throws IOException - */ - public AppDataOutputStream getAppDataStream(String appdataReference) throws IOException { - if (newarchive==null) - throw new IOException("Attempt to write to closed VamsasArchive object."); - if (addValidEntry(appdataReference)) { - return new AppDataOutputStream(newarchive); - } - return null; - } - - /** - * - * @return JarEntry name for the vamsas XML stream in this archive - */ - protected String getDocumentJarEntry() { - if (vamsasdocument) - return VamsasArchiveReader.VAMSASDOC; - return VamsasArchiveReader.VAMSASXML; - } - /** - * Safely initializes the VAMSAS XML document Jar Entry. - * @return Writer to pass to the marshalling function. - * @throws IOException if a document entry has already been written. - */ - public PrintWriter getDocumentOutputStream() throws IOException { - if (newarchive==null) - openArchive(); - if (!isDocumentWritten()) { - try { - if (addValidEntry(getDocumentJarEntry())) - return new PrintWriter(new java.io.OutputStreamWriter(newarchive, "UTF-8")); - } catch (Exception e) { - log.warn("Problems opening XML document JarEntry stream",e); - } - } else { - throw new IOException("Vamsas Document output stream is already written."); - } - return null; - } - - /** - * Access original archive if it exists, pass the reader to the client - * Note: this is NOT thread safe and a call to closeArchive() will by necessity - * close and invalidate the VamsasArchiveReader object. - * @return null if no original archive exists. - */ - public VamsasArchiveReader getOriginalArchiveReader() throws IOException { - if (!virginArchive) { - accessOriginal(); - return odoc; - } - return null; - } - /** - * returns original document's root vamsas elements. - * @return - * @throws IOException - * @throws org.exolab.castor.xml.MarshalException - * @throws org.exolab.castor.xml.ValidationException - */ - public Vobject[] getOriginalRoots() throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - return VamsasArchive.getOriginalRoots(this); - } - /** - * @return original document or a new empty document (with default provenance) - * @throws IOException - * @throws org.exolab.castor.xml.MarshalException - * @throws org.exolab.castor.xml.ValidationException - */ - public VamsasDocument getVamsasDocument() throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - return getVamsasDocument("org.vamsas.simpleclient.VamsasArchive", "Created new empty document", null); - } - /** - * Return the original document or a new empty document with initial provenance entry. - * @param provenance_user (null sets user to be the class name) - * @param provenance_action (null sets action to be 'created new document') - * @param version (null means use latest version) - * @return (original document or a new vamsas document with supplied provenance and version info) - * @throws IOException - * @throws org.exolab.castor.xml.MarshalException - * @throws org.exolab.castor.xml.ValidationException - */ - public VamsasDocument getVamsasDocument(String provenance_user, String provenance_action, String version) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - if (_doc!=null) - return _doc; - _doc = getOriginalVamsasDocument(this, getVorba()); - if (_doc!=null) - return _doc; - // validate parameters - if (provenance_user==null) - provenance_user = "org.vamsas.simpleclient.VamsasArchive"; - if (provenance_action == null) - provenance_action="Created new empty document"; - if (version==null) - version = VersionEntries.latestVersion(); - // Create a new document and return it - _doc = DocumentStuff.newVamsasDocument(new VAMSAS[] { new VAMSAS()}, - ProvenanceStuff.newProvenance(provenance_user, provenance_action), version); - return _doc; - } - /** - * @return Returns the current VorbaIdFactory for the archive. - */ - public VorbaIdFactory getVorba() { - if (vorba==null) - vorba = new SimpleDocument("simpleclient.VamsasArchive"); - return vorba.getVorba(); - } - /** - * @return true if Vamsas Document has been written to archive - */ - protected boolean isDocumentWritten() { - if (newarchive==null) - log.warn("isDocumentWritten() called for unopened archive."); - if (entries!=null) { - if (entries.containsKey(getDocumentJarEntry())) - return true; - } - return false; - } - private void makeBackup() { - if (!virginArchive) { - if (originalBackup==null && original!=null && original.exists()) { - try { - accessOriginal(); - originalBackup = odoclock.backupSessionFile(null, original.getName(), ".bak", original.getParentFile()); - } - catch (IOException e) { - log.warn("Problem whilst making a backup of original archive.",e); - } - } - } - } - /** - * opens the new archive ready for writing. If the new archive is replacing an existing one, - * then the existing archive will be locked, and the new archive written to a temporary file. - * The new archive will be put in place once close() is called. - * @param doclock LATER - pass existing lock on document, if it exists.... no need yet? - * @throws IOException - */ - private void openArchive() throws IOException { - - if (newarchive!=null) { - log.warn("openArchive() called multiple times."); - throw new IOException("Vamsas Archive '"+archive.getAbsolutePath()+"' is already open."); - } - if (archive==null && (virginArchive || original==null)) { - log.warn("openArchive called on uninitialised VamsasArchive object."); - throw new IOException("Badly initialised VamsasArchive object - no archive file specified."); - } - if (!virginArchive) { - // lock the original - accessOriginal(); - // make a temporary file to write to - archive = File.createTempFile(original.getName(), ".new",original.getParentFile()); - } else { - if (archive.exists()) - log.warn("New archive file name already in use! Possible lock failure imminent?"); - } - - if (rchive==null) - rchive = new SessionFile(archive); - if (!rchive.lockFile()) - throw new IOException("Failed to get lock on file "+archive); - // LATER: locked IO stream based access. - Manifest newmanifest = new Manifest(); - newarchive = new JarOutputStream(rchive.fileLock.getBufferedOutputStream(true), newmanifest); - //newarchive = new JarOutputStream(new BufferedOutputStream(new java.io.FileOutputStream(archive))); - entries = new Hashtable(); - } - public void putVamsasDocument(VamsasDocument doc) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - putVamsasDocument(doc, getVorba()); - } - /** - * - * @param doc - * @param vorba - * @return (vorbaId string, Vobjhash) pairs for last hash of each object in document - * @throws IOException - * @throws org.exolab.castor.xml.MarshalException - * @throws org.exolab.castor.xml.ValidationException - */ - public void putVamsasDocument(VamsasDocument doc, VorbaIdFactory vorba) throws IOException, - org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { - if (vamsasdocument) - doc.setVersion(VersionEntries.latestVersion()); // LATER: ensure this does the correct thing. - VorbaXmlBinder.putVamsasDocument(getDocumentOutputStream(), vorba, doc); - } - - /** - * recovers the original file's contents from the (temporary) backup. - * @throws Exception if any SessionFile or file removal operations fail. - */ - private void recoverBackup() throws Exception { - if (originalBackup!=null) { - // backup has been made. - // revert from backup and delete it (changing backup filename) - if (rchive==null) { - rchive = new SessionFile(original); - } - SessionFile bckup = new SessionFile(originalBackup); - - rchive.updateFrom(null, bckup); // recover from backup file. - bckup.unlockFile(); - bckup=null; - removeBackup(); - } - } - - /** - * forget about any backup that was made - removing it first if it was only temporary. - */ - private void removeBackup() { - if (originalBackup!=null) { - log.debug("Removing backup in "+originalBackup.getAbsolutePath()); - if (!donotdeletebackup) - if (!originalBackup.delete()) - log.info("VamsasArchive couldn't remove temporary backup "+originalBackup.getAbsolutePath()); - originalBackup=null; - } - } - /** - * @param vorba the VorbaIdFactory to use for accessing vamsas objects. - */ - public void setVorba(VorbaIdFactory Vorba) { - if (Vorba!=null) { - if (vorba==null) - vorba = new SimpleDocument(Vorba); - else - vorba.setVorba(Vorba); - } else - getVorba(); - } - /** - * Convenience method to copy over the referred entry from the backup to the new version. - * Warning messages are raised if no backup exists or the - * entry doesn't exist in the backed-up original. - * Duplicate writes return true - but a warning message will also be raised. - * @param AppDataReference - * @return true if AppDataReference now exists in the new document - * @throws IOException - */ - public boolean transferAppDataEntry(String AppDataReference) throws IOException { - return transferAppDataEntry(AppDataReference, AppDataReference); - } - /** - * Validates the AppDataReference: not null and not already written to archive. - * @param AppDataReference - * @return true if valid. false if not - * @throws IOException for really broken references! - */ - protected boolean _validNewAppDataReference(String newAppDataReference) throws IOException { - // LATER: Specify valid AppDataReference form in all VamsasArchive handlers - if (newAppDataReference==null) - throw new IOException("null newAppDataReference!"); - if (entries.containsKey(newAppDataReference)) { - log.warn("Attempt to write '"+newAppDataReference+"' twice! - IGNORED"); - // LATER: fix me? warning message should raise an exception here. - return false; - } - return true; - } - /** - * Transfers an AppDataReference from old to new vamsas archive, with a name change. - * @see transferAppDataEntry(String AppDataReference) - * @param AppDataReference - * @param NewAppDataReference - AppDataReference in new Archive - * @return - * @throws IOException - */ - public boolean transferAppDataEntry(String AppDataReference, String NewAppDataReference) throws IOException { - if (original==null || !original.exists()) { - log.warn("No backup archive exists."); - return false; - } - if (AppDataReference==null) - throw new IOException("null AppDataReference!"); - - if (!_validNewAppDataReference(NewAppDataReference)) - return false; - - accessOriginal(); - - java.io.InputStream adstream = odoc.getAppdataStream(AppDataReference); - - if (adstream==null) { - log.warn("AppDataReference '"+AppDataReference+"' doesn't exist in backup archive."); - return false; - } - - java.io.OutputStream adout = getAppDataStream(NewAppDataReference); - // copy over the bytes - int written=-1; - long count=0; - byte[] buffer = new byte[_TRANSFER_BUFFER]; // conservative estimate of a sensible buffer - do { - if ((written = adstream.read(buffer))>-1) { - adout.write(buffer, 0, written); - log.debug("Transferring "+written+"."); - count+=written; - } - } while (written>-1); - log.debug("Sucessfully transferred AppData for '" - +AppDataReference+"' as '"+NewAppDataReference+"' ("+count+" bytes)"); - return true; - } - /** - * write data from a stream into an appData reference. - * @param AppDataReference - New AppDataReference not already written to archive - * @param adstream Source of data for appData reference - read until .read(buffer) returns -1 - * @return true on success. - * @throws IOException for file IO or invalid AppDataReference string - */ - public boolean writeAppdataFromStream(String AppDataReference, java.io.InputStream adstream) throws IOException { - if (!_validNewAppDataReference(AppDataReference)) { - log.warn("Invalid AppDataReference passed to writeAppdataFromStream"); - throw new IOException("Invalid AppDataReference! (null, or maybe non-unique)!"); - } - - if (AppDataReference==null) { - log.warn("null appdata passed."); - throw new IOException("Null AppDataReference"); - } - - java.io.OutputStream adout = getAppDataStream(AppDataReference); - // copy over the bytes - int written=-1; - long count=0; - byte[] buffer = new byte[_TRANSFER_BUFFER]; // conservative estimate of a sensible buffer - do { - if ((written = adstream.read(buffer))>-1) { - adout.write(buffer, 0, written); - log.debug("Transferring "+written+"."); - count+=written; - } - } while (written>-1); - return true; - } - /** - * transfers any AppDataReferences existing in the old document - * that haven't already been transferred to the new one - * LATER: do the same for transfers requiring a namechange - more document dependent. - * @return true if data was transferred. - */ - public boolean transferRemainingAppDatas() throws IOException { - boolean transfered=false; - if (original==null || !original.exists()) { - log.warn("No backup archive exists."); - return false; - } - accessOriginal(); - - if (getVorba()!=null) { - Vector originalRefs=null; - try { - originalRefs = vorba.getReferencedEntries(getVamsasDocument(), getOriginalArchiveReader()); - } catch (Exception e) { - log.warn("Problems accessing original document entries!",e); - } - if (originalRefs!=null) { - Iterator ref = originalRefs.iterator(); - while (ref.hasNext()) { - String oldentry = (String) ref.next(); - if (oldentry!=null && !entries.containsKey(oldentry)) { - log.debug("Transferring remaining entry '"+oldentry+"'"); - transfered |= transferAppDataEntry(oldentry); - } - } - } - } - return transfered; - } - /** - * called after archive is written to put file in its final place - */ - private void updateOriginal() { - if (!virginArchive) { - // make sure original document really is backed up and then overwrite it. - if (odoc!=null) { - // try to shut the odoc reader. - odoc.close(); - odoc = null; - } - // Make a backup if it isn't done already - makeBackup(); - try { - // copy new Archive data that was writen to a temporary file - odoclock.updateFrom(null, rchive); - } - catch (IOException e) { - // LATER: decide if leaving nastily named backup files around is necessary. - File backupFile=backupFile(); - if (backupFile!=null) - log.error("Problem updating archive from temporary file! - backup left in '" - +backupFile().getAbsolutePath()+"'",e); - else - log.error("Problems updating, and failed to even make a backup file. Ooops!", e); - } - // Tidy up if necessary. - removeBackup(); - } else { - - - } - } -} diff --git a/src/org/vamsas/client/simpleclient/VamsasArchiveReader.java b/src/org/vamsas/client/simpleclient/VamsasArchiveReader.java deleted file mode 100644 index 2df47f5..0000000 --- a/src/org/vamsas/client/simpleclient/VamsasArchiveReader.java +++ /dev/null @@ -1,313 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.RandomAccessFile; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Vector; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarInputStream; -import java.util.jar.JarOutputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.vamsas.objects.utils.document.VersionEntries; -/** - * Basic methods for accessing an existing Vamsas Archive, - * and Jar entry names for creating new vamsas archives. - * - * @author jimp - * - */ -public class VamsasArchiveReader { - private static Log log = LogFactory.getLog(VamsasArchiveReader.class); - JarFile jfile=null; - boolean stream=false; // true if we are seeking on the stream. - RandomAccessFile rfile; - ZipInputStream jstream=null; - Hashtable strmentries = null; - private void streamInit() { - //throw new Error("VamsasArchiveReader(Stream) Not implemented!"); - if (!stream) { - log.debug("Skipping init for Jar Stream input."); - return; - } - strmentries = new Hashtable(); - log.debug("Jar Stream input Initialisation"); - try { - rfile.seek(0); - // no buffering - we need to be able to move around the random access stream. - jstream = new ZipInputStream(new FileInputStream(rfile.getFD())); // no manifest (probably) - if (jstream.available()==0) - log.warn("Can't read from JarInputStream (Locked stream!)"); - ZipEntry entry=null; - long pos=0; - do { - if ((entry=jstream.getNextEntry())!=null) { - if (strmentries.containsKey(entry.getName())) { - log.info("Only recording last of duplicate entries '"+entry.getName()+"'"); - } - strmentries.put(entry.getName(), new Long(pos++)); - jstream.closeEntry(); - } - } while (entry!=null); - } - catch (Exception e) { - log.warn("Exceptions during init!",e); - jstream=null; - } - } - - public VamsasArchiveReader(File vamsasfile) { - jfile=null; - if (vamsasfile.exists()) { - try { - jfile=new JarFile(vamsasfile); - } - catch (Exception e) { - log.debug("non-serious? couldn't open new JarFile on "+vamsasfile,e); - jfile=null; - } - } - - } - /** - * in an ideal world - this constructor will create a reader object - * for the locked file's random access stream. - * - * @param vamsaslock - */ - public VamsasArchiveReader(Lock vamsaslock) { - // LATER: implement or remove - if (vamsaslock==null || !vamsaslock.isLocked()) - throw new Error("IMPLEMENTATION ERROR: Cannot create a VamsasArchiveReader without a valid lock."); - // throw new Error("VamsasArchiveReading from locked IO stream not yet implemented."); - try { - rfile = vamsaslock.getRaFile(); - } catch (Exception e) { - log.warn("Unexpected IO Exception when accessing locked vamsas archive stream "+vamsaslock.target,e); - } - stream = true; - streamInit(); - if (jstream==null) - throw new Error("Failed to open archive from Locked random access stream."); - } - - /** - * the vamsas document version(s) handled by this Reader - */ - final public static String DOCUMENT_VERSION=VersionEntries.BETA_VERSION; - /** - * name of the jarEntry containing a well formatted vamsas XML Document - */ - - final public static String VAMSASDOC="vamsasDocument.xml"; - - /** - * name of the jarEntry containing a root VAMSAS element, and containing a - * random sequence of VAMSAS DataSet elements - */ - - final public static String VAMSASXML="vamsas.xml"; - /** - * seeks jstream to the given entry name and reads it. - * @param entryname - * @return - */ - private JarEntry seekEntry(String entryname) { - if (jstream==null) - return null; - if (!strmentries.containsKey(entryname)) - return null; - Long entrypos = (Long) strmentries.get(entryname); - if (entrypos==null) { - log.error("Null entry position for "+entryname); - return null; - } - try { - jstream=null; - rfile.seek(0); - jstream = new ZipInputStream(new FileInputStream(rfile.getFD())); - ZipEntry entry = null; - long epos = entrypos.longValue(); - do { - entry = jstream.getNextEntry(); - } while (entry!=null && --epos>=0); - // rfile.seek(entrypos.longValue()); - // make a Jar entry from a zip entry. - return new JarEntry(entry); - } - catch (Exception e) { - log.warn("Whilst seeking for "+entryname, e); - } - return null; - } - /** - * - * @return JarEntry for VamsasArchiveReader.VAMSASDOC - */ - protected JarEntry getVamsasDocumentEntry() { - return getJarEntry(VAMSASDOC); - } - /** - * - * @return JarEntry for VamsasArchiveReader.VAMSASXML - */ - protected JarEntry getVamsasXmlEntry() { - return getJarEntry(VAMSASXML); - } - /** - * Test for valid vamsas document archive - * @return true if getVamsasDocumentStream will return a stream likely to contain valid XML - */ - public boolean isValid() { - // TODO: check if VAMSASDOC is well formed (follows www.vamsas.ac.uk/schemas/vamsasDocument.xsd) and all appData references are resolvable - preferably as jar entries - if (jfile!=null || jstream!=null) - return (getVamsasDocumentEntry()!=null); - return false; - } - - - protected JarEntry getAppdataEntry(String AppdataRef) { - JarEntry entry; - if ((jfile==null && jstream==null) || !isValid() || (entry=getJarEntry(AppdataRef))==null) - return null; - - return entry; - } - - public InputStream getAppdataStream(String AppdataRef) { - JarEntry entry=getAppdataEntry(AppdataRef); - try { - if (entry!=null) - return getInputStream(entry); - } catch (IOException e) { - log.error("Failed when opening AppdataStream for "+AppdataRef, e); - } - return null; - } - /** - * get the VamsasDocument input stream, if it exists. - * @return null or valid input stream - */ - public InputStream getVamsasDocumentStream() { - InputStream vdoc; - if ((jfile==null && jstream==null) || !isValid()) - return null; - try { - vdoc = getInputStream(getVamsasDocumentEntry()); - } catch (IOException e) { - log.error("Whilst geting document stream",e); - vdoc=null; - } - return vdoc; - } - - /** - * get the VamsasXML input stream, if it exists. - * Note: Deprecated beyond our prealpha testing. - * @return null or valid input stream. - */ - - public InputStream getVamsasXmlStream() { - // log.warn("Deprecated call"); - JarEntry xmle=getVamsasXmlEntry(); - InputStream vdoc; - if (xmle==null) - return null; - try { - vdoc = getInputStream(xmle); - } catch (IOException e) { - log.error("Whilst getting VamsasXmlStream",e); - vdoc=null; - } - return vdoc; - } - - /** - * silently close the jar file. - * - */ - public void close() { - if (jfile!=null) { - try { - jfile.close(); - } catch (IOException e) { - log.error("Whilst closing JarFile "+jfile.getName(), e); - } - } - if (jstream!=null) { - try { - jstream.closeEntry(); - jstream=null; - // LATER: reference counting for random access file instances is necessary. - } - catch (Exception e) { - log.error("Whilst finishing reading from jar input stream",e); - } - } - } - - /** - * returns all entries not matching the filespec of a vamsas xml entry - * @return array of entries. - */ - public Vector getExtraEntries() { - if ((jfile==null && jstream==null)|| !isValid()) - return null; - Vector e = new Vector(); - if (jstream!=null) { - Enumeration entries = strmentries.keys(); - if (entries!=null && entries.hasMoreElements()) { - do { - JarEntry el = (JarEntry) entries.nextElement(); - if (!el.getName().equals(VAMSASDOC) && !el.getName().equals(VAMSASXML)) - e.add(new String(el.getName())); // avoid references - } while (entries.hasMoreElements()); - } - } else { - Enumeration entries = jfile.entries(); - if (entries!=null && entries.hasMoreElements()) { - do { - JarEntry el = (JarEntry) entries.nextElement(); - if (!el.getName().equals(VAMSASDOC) && !el.getName().equals(VAMSASXML)) - e.add(new String(el.getName())); // avoid references - } while (entries.hasMoreElements()); - } - return e; - } - return null; - } - - /* (non-Javadoc) - * @see java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry) - */ - private InputStream getInputStream(ZipEntry ze) throws IOException { - if (jfile!=null) - return jfile.getInputStream(ze); - if (jstream!=null) { - seekEntry(ze.getName()); - return new AppDataInputStream(jstream); - } - return null; - } - - /* (non-Javadoc) - * @see java.util.jar.JarFile#getJarEntry(java.lang.String) - */ - private JarEntry getJarEntry(String name) { - if (jfile!=null) - return jfile.getJarEntry(name); - if (jstream!=null) - return seekEntry(name); - return null; - } - } diff --git a/src/org/vamsas/client/simpleclient/VamsasFile.java b/src/org/vamsas/client/simpleclient/VamsasFile.java deleted file mode 100644 index 3dd2581..0000000 --- a/src/org/vamsas/client/simpleclient/VamsasFile.java +++ /dev/null @@ -1,100 +0,0 @@ - -package org.vamsas.client.simpleclient; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.util.Timer; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarInputStream; -import java.util.jar.JarOutputStream; - -import org.vamsas.objects.core.LockFileDescriptor; - -/** - * low level vamsas document management routines - * analogous to ClientsFile - * Grew out of io tests on VamsasArchive class in org.vamsas.test.simpleclient.VamsasArchive - * This class is not thread safe. - * @author jimp - * - */ -public class VamsasFile extends SessionFile { - /** - * - * Connect to an existing Vamsas document in a given sessionDir - * or create a new one. - * - * @param sessionDir - * @throws java.io.IOException - */ - public VamsasFile(File sessionFile) throws java.io.IOException { - super(sessionFile); - } - /** - * - * @return the VamsasFile - */ - public File getVamsasFile() { - return sessionFile; - } - /** - * Expand a previously stored session into the sessionDir - * @param sessionDir - * @param storedSession - - public VamsasFile(File sessionDir, JarFile storedSession) throws IOException { - // check if sessionDir is live or not - if (!sessionDir.exists()) { - sessionDir.mkdir(); - } - - { - // check its actually a writable directory - } - - File sfile = new File(sessionDir, "vamsas.jar"); - VamsasFile(sfile); - // if live - try to merge storedSession with sessionDir - // - will probably fail through duplicate Vobject references needing to be dereferenced. - // TODO: think of a way of specifying vorba_id scope for an application's references to allow merging of one vamsasDocument with another. - - } - */ - /** - * public interface for getting a lock. - * The lock object is internally referenced - * so the lock will persist even after the - * return value of the method goes out of scope. - * @return null if lock couldn't be got or a valid Lock object. - */ - public Lock getLock() { - if (lockFile()) - return fileLock; - return null; - } - /** - * - * @param extantLock - * @return null, extantLock or new Lock. - */ - public Lock getLock(Lock extantLock) { - if (lockFile(extantLock)) - return fileLock; - return null; - } - /** - * explicitly unlocks vamsas file. - * if you have called getLock() you *must* - * call this to release the lock. - */ - public void unLock() { - this.unlockFile(); - } - -} diff --git a/src/org/vamsas/client/simpleclient/VamsasSession.java b/src/org/vamsas/client/simpleclient/VamsasSession.java deleted file mode 100644 index a5359ad..0000000 --- a/src/org/vamsas/client/simpleclient/VamsasSession.java +++ /dev/null @@ -1,312 +0,0 @@ -package org.vamsas.client.simpleclient; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.RandomAccessFile; -import java.io.Writer; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.log4j.Appender; -import org.apache.log4j.Logger; -import org.apache.log4j.FileAppender; -import org.vamsas.client.ClientHandle; -import org.vamsas.client.UserHandle; -/** - * Does all the IO operations for a SimpleClient instance accessing - * a SimpleClient vamsas session. - * - * Basically, it defines the various standard names for the files - * in the session directory (that maps to the sessionUrn), - * provides constructors for the file handlers and watchers of - * those file entities, and some higher level methods - * to check and change the state flags for the session. - * - * TODO: move the stuff below to the SimpleClientFactory documentation. - * much may not be valid now : - * Vamsas client is intialised with a path to create live session directories. - * This path may contain a vamsas.properties file - * that sets additional parameters (otherwise client - * just uses the one on the classpath). - * - * A vamsas session consists of : - * SessionDir - translates to urn of a live session. - * Contains: Vamsas Document (as a jar), Session client list file, - * both of which may be locked, and additional - * temporary versions of these files when write - * operations are taking place. - * - * Zip file entries - * - vamsasdocument.xml : core info - * one or more: - * - .version.sessionnumber.raw (string given in vamsasdocument.xml applicationData entry) - * - * Lockfile - * - filename given in the vamsasdocument.xml. Should be checked for validity by any client and rewritten if necessary. - * The lockfile can point to the jar itself. - * Mode of operation. - * Initially - documentHandler either: - * - creates a zip for a new session for the client - * - connect to an existing session zip - * 1. reads session urn file - * 2. waits for lock - * 3. examines session - decide whether to create new application data slice or connect to one stored in session. - * 4. writes info into session file - * 5. releases lock and generates local client events. - * 6. Creates Watcher thread to generate events. - * - * During the session - * - Update watcher checks for file change - - * - * Procedures for file based session message exchange - * - session document modification flag - * - */ - -public class VamsasSession { - /** - * indicator file for informing other processes that - * they should finalise their vamsas datasets for - * storing into a vamsas archive. - */ - public static final String CLOSEANDSAVE_FILE="stored.log"; - /** - * session file storing the last_stored_stat data - */ - public static final String MODIFIEDDOC_FILE="modified"; - - /** - * called to clear update flag after a successful offline storage event - */ - protected void clearUnsavedFlag() { - SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, MODIFIEDDOC_FILE)); - if (!laststored.clearFlag()) - log.warn("Unsaved flag was not cleared for "+sessionDir); - } - /** - * called to indicate session document has been modified. - * - */ - protected void setUnsavedFlag() { - SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, MODIFIEDDOC_FILE)); - if (!laststored.setFlag()) - log.warn("Couldn't set the Unsaved flag for "+sessionDir); - } - /** - * - * @return true if session document has been modified since last offline storage event - */ - protected boolean getUnsavedFlag() { - SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, MODIFIEDDOC_FILE)); - return laststored.checkFlag(); - } - /** - * log file location - */ - public static final String SESSION_LOG="Log.txt"; - private static Log log = LogFactory.getLog(VamsasSession.class); - protected Logger slog = Logger.getLogger("org.vamsas.client.SessionLog"); - /** - * setup the sessionLog using Log4j. - * @throws IOException - */ - private void initLog() throws IOException { - // LATER: make dedicated appender format for session log. - Appender app = slog.getAppender("SESSION_LOG"); - slog.addAppender(new FileAppender(app.getLayout(), new File(sessionDir, SESSION_LOG).getAbsolutePath())); - } - - /** - * the sessionDir is given as the session location for new clients. - */ - protected File sessionDir; - /** - * holds the list of attached clients - */ - ClientsFile clist; - public static final String CLIENT_LIST="Clients.obj"; - /** - * holds the data - */ - VamsasFile vamArchive; - public static final String VAMSAS_OBJ="VamDoc.jar"; - - /** - * sets up the vamsas session files and watchers in sessionDir - * @param sessionDir - */ - protected VamsasSession(File sessionDir) throws IOException { - if (sessionDir==null) - throw new Error("Null directory for VamsasSession."); - if (sessionDir.exists()) { - if (!sessionDir.isDirectory() || !sessionDir.canWrite() || !sessionDir.canRead()) - throw new IOException("Cannot access '"+sessionDir+"' as a read/writable Directory."); - if (checkSessionFiles(sessionDir)) { - // session files exist in the directory - this.sessionDir = sessionDir; - initSessionObjects(); - slog.debug("Initialising additional VamsasSession instance"); - log.debug("Attached to VamsasSession in "+sessionDir); - } - } else { - // start from scratch - if (!sessionDir.mkdir()) - throw new IOException("Failed to make VamsasSession directory in "+sessionDir); - this.sessionDir = sessionDir; - createSessionFiles(); - initSessionObjects(); - slog.debug("Session directory created."); - log.debug("Initialised VamsasSession in "+sessionDir); - } - } - /** - * tests presence of existing sessionfiles files in dir - * @param dir - * @return - */ - private boolean checkSessionFiles(File dir) throws IOException { - File c_file = new File(dir,CLIENT_LIST); - File v_doc = new File(dir,VAMSAS_OBJ); - if (c_file.exists() && v_doc.exists()) - return true; - return false; - } - /** - * create new empty files in dir - * - */ - private void createSessionFiles() throws IOException { - if (sessionDir==null) - throw new IOException("Invalid call to createSessionFiles() with null sessionDir"); - File c_file = new File(sessionDir,CLIENT_LIST); - File v_doc = new File(sessionDir,VAMSAS_OBJ); - if (c_file.createNewFile()) - log.debug("Created new ClientFile "+c_file); // don't care if this works or not - if (v_doc.createNewFile()) - log.debug("Created new Vamsas Session Document File "+v_doc); - } - /** - * construct SessionFile objects and watchers for each - */ - private void initSessionObjects() throws IOException { - if (clist!=null || vamArchive!=null) - throw new IOException("initSessionObjects called for initialised VamsasSession object."); - clist = new ClientsFile(new File(sessionDir,CLIENT_LIST)); - vamArchive = new VamsasFile(new File(sessionDir,VAMSAS_OBJ)); - initLog(); - } - /** - * make a new watcher object for the clientFile - * @return new ClientFile watcher instance - */ - public FileWatcher getClientWatcher() { - return new FileWatcher(clist.sessionFile); - } - FileWatcher session_doc_watcher=null; - /** - * make a new watcher object for the vamsas Document - * @return new ClientFile watcher instance - */ - public FileWatcher getDocWatcher() { - if (session_doc_watcher==null) - return session_doc_watcher = new FileWatcher(vamArchive.sessionFile); - return new FileWatcher(vamArchive.sessionFile); - } - FileWatcher store_doc_file=null; - /** - * make a new watcher object for the messages file - * (thread safe - keeps a reference to the first watcher) - * @return new watcher instance - */ - public FileWatcher getStoreWatcher() { - if (store_doc_file==null) - return store_doc_file = new FileWatcher(new File(CLOSEANDSAVE_FILE)); - return new FileWatcher(new File(CLOSEANDSAVE_FILE)); - - } - /** - * write to the StoreWatcher file to indicate that a storeDocumentRequest has been made. - * The local client's storeWatcher FileWatcher object is updated so the initial change is not registered. - * @param client - * @param user - * @return - */ - public void addStoreDocumentRequest(ClientHandle client, UserHandle user) throws IOException { - SessionFile sfw = new SessionFile(new File(sessionDir, CLOSEANDSAVE_FILE)); - while (!sfw.lockFile()) - log.debug("Trying to get lock for "+CLOSEANDSAVE_FILE); - RandomAccessFile sfwfile=sfw.fileLock.getRaFile(); - sfwfile.setLength(0); // wipe out any old info. - // TODO: rationalise what gets written to this file (ie do we want other clients to read the id of the requestor?) - sfwfile.writeUTF(client.getClientUrn()+":"+user.getFullName()+"@"+user.getOrganization()); - sfw.unlockFile(); - if (store_doc_file!=null) - store_doc_file.setState(); - slog.info("FinalizeAppData request from "+user.getFullName()+" using "+client.getClientUrn()+""); - } - /** - * create a new session with an existing vamsas Document - by copying it into the session. - * @param archive - */ - public void setVamsasDocument(File archive) throws IOException { - log.debug("Transferring vamsas data from "+archive+" to session:"+vamArchive.sessionFile); - SessionFile xtantdoc = new SessionFile(archive); - vamArchive.updateFrom(null, xtantdoc); - // LATER: decide if session archive provenance should be updated to reflect access. - // TODO: soon! do a proper import objects from external file - log.debug("Transfer complete."); - } - /** - * write session as a new vamsas Document (this will overwrite any existing file without warning) - * TODO: test - * TODO: verify that lock should be released for vamsas document. - * @param destarchive - */ - protected void writeVamsasDocument(File destarchive, Lock extlock) throws IOException { - log.debug("Transferring vamsas data from "+vamArchive.sessionFile+" to session:"+destarchive); - SessionFile newdoc = new SessionFile(destarchive); - if (extlock==null && !vamArchive.lockFile()) - while (!vamArchive.lockFile()) - log.info("Trying to get lock for "+vamArchive.sessionFile); - // TODO: LATER: decide if session archive provenance should be written in vamsasDocument file for this export. - newdoc.updateFrom(extlock, vamArchive); - // LATER: LATER: fix use of updateFrom for file systems where locks cannot be made (because they don't have a lockManager, ie NFS/Unix, etc). - vamArchive.unLock(); - newdoc.unlockFile(); - log.debug("Transfer complete."); - } - - /** - * Creates a VamsasArchive Vobject for accessing and updating document - * Note: this will lock the Vamsas Document for exclusive access to the client. - * @return session vamsas document - * @throws IOException if locks fail or vamsas document read fails. - */ - protected VamsasArchive getVamsasDocument() throws IOException { - // TODO: check we haven't already done this once - if (!vamArchive.lockFile()) - throw new IOException("Failed to get lock for vamsas archive."); - - VamsasArchive va = new VamsasArchive(vamArchive.sessionFile, false, true, vamArchive); - - return va; - } - /** - * create a uniquely named file in the session Directory - * @see java.io.File.createTempFile - * @param pref Prefix for name - * @param suff Suffix for name - * @return SessionFile object configured for the new file (of length zero) - * @throws IOException - */ - protected SessionFile getTempSessionFile(String pref, String suff) throws IOException { - File tfile = File.createTempFile(pref,suff,sessionDir); - SessionFile tempFile = new SessionFile(tfile); - return tempFile; - } -} - -