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;
+
+import uk.ac.vamsas.client.ClientHandle;
+import uk.ac.vamsas.client.Events;
+import uk.ac.vamsas.client.IClient;
+import uk.ac.vamsas.client.IClientDocument;
+import uk.ac.vamsas.client.IObjectUpdate;
+import uk.ac.vamsas.client.InvalidSessionUrnException;
+import uk.ac.vamsas.client.SessionHandle;
+import uk.ac.vamsas.client.UserHandle;
+import uk.ac.vamsas.client.picking.IPickManager;
+import uk.ac.vamsas.objects.core.ApplicationData;
+import uk.ac.vamsas.objects.core.Entry;
+import uk.ac.vamsas.objects.core.LockFile;
+import uk.ac.vamsas.objects.core.VamsasDocument;
+import uk.ac.vamsas.objects.utils.AppDataReference;
+import uk.ac.vamsas.objects.utils.ProvenanceStuff;
+import uk.ac.vamsas.objects.utils.document.VersionEntries;
/**
* @author jimp
_session = sess;
this.user = user;
this.client = client;
- try {
+ //try {
+ log.debug("Creating new session for "+_session);
session = new SessionUrn(_session);
- } catch (MalformedURLException e) {
+ log.debug("Creating new Event Generator");
+ evgen = new EventGeneratorThread(_session, this, handlers);
+ /*} catch (MalformedURLException e) {
log.error("Couldn't form a valid SessionUrn object!",e);
throw new InvalidSessionUrnException(_session.toString());
- }
+ }*/
+ log.debug("SimpleClient constructed for session "+session.getSessionUrn());
+
}
/**
* construct new session by importing objects from an existing vamsas document
VamsasDocument doc = sdoc.getVamsasDocument(odoc);
sessdoc.putVamsasDocument(doc, sdoc.vorba);
sessdoc.closeArchive();
+ log.debug("Imported new vamsas data from "+importingArchive);
} catch (Exception e) {
sessdoc.cancelArchive();
- // write a dummy archive
+ // write a dummy iohandler
_session.slog.info("Exception when importing document data from "+importingArchive);
+ log.warn("While importing session data from existing archive in "+importingArchive, e);
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()
+ * @see uk.ac.vamsas.client.IClient#getAbout()
*/
public String getAbout() {
return new String("VORBA SimpleClient version $version$ build $build$");
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#getSessionUrn()
+ * @see uk.ac.vamsas.client.IClient#getSessionUrn()
*/
public String getSessionUrn() {
return session.getSessionUrn();
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#getSessionHandle()
+ * @see uk.ac.vamsas.client.IClient#getSessionHandle()
*/
public SessionHandle getSessionHandle() {
// TODO: eliminate SessionHandle ? need to refactor interfaces.
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#getClientHandle()
+ * @see uk.ac.vamsas.client.IClient#getClientHandle()
*/
public ClientHandle getClientHandle() {
return client;
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#getUserHandle()
+ * @see uk.ac.vamsas.client.IClient#getUserHandle()
*/
public UserHandle getUserHandle() {
return user;
/**
* make all the PropertyChangeSupport objects for the
- * events described in org.vamsas.client.Event
+ * events described in uk.ac.vamsas.client.Event
* @return
*/
private static Hashtable initHandlers() {
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#addDocumentUpdateHandler(java.util.EventListener)
+ * @see uk.ac.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);
- }
+ this.addVorbaEventHandler(Events.DOCUMENT_UPDATE, evt);
}
boolean finalized=false;
+ private void haltPickmanager() {
+ if (pickmanager!=null) {
+ final SimpleClient dying=this;
+ new Thread() {
+ public void run() {
+ SimpleClient.log.debug("Stopping pickManager..");
+ dying.pickmanager.shutdown();
+ SimpleClient.log.debug("pickManager halted.");
+ }
+ }.start();
+ }
+ }
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#finalizeClient()
+ * @see uk.ac.vamsas.client.IClient#finalizeClient()
*/
public void finalizeClient() {
+ if (finalized)
+ throw new Error("VAMSAS Client Implementation Error: Finalized called twice for same client instance.");
+
+ // mark this instance as finalized
+ finalized=true;
+
// TODO: determine if this is last client in session
- // TODO: raise events like : ((lst_client && document.request.to.close), (client_finalization), (
+ // TODO: raise events like : ((lst_client && document.request.to.close), (client_finalization), (
+ evgen._raise(Events.CLIENT_FINALIZATION, null, this,null);
// if (handlers.containsKey(Events.))
// if (handlers.containsKey(Events.CLIENT_FINALIZATION))
// deregister listeners.
- // mark this instance as finalized
+ log.debug("Stopping pickManager");
+ haltPickmanager();
+ log.debug("Stopping EventGenerator..");
+ evgen.stopWatching();
+ SimpleClient.log.debug("EventGenerator halted.");
+ log.debug("Deregistering Client");
+ _session.removeClient(this);
+ log.debug("finalization Complete.");
}
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#getClientDocument()
+ * @see uk.ac.vamsas.client.IClient#getClientDocument()
*/
public IClientDocument getClientDocument() throws IOException {
+ log.debug("getClientDocument");
if (cdocument!=null) {
// cdocument is non-nill if the ClientDocument.finalise() method hasn't been called.
return cdocument;
}
+ evgen.disableDocumentWatch();
VamsasArchive va = null;
try {
// LATER: bail out if it takes too long to get the lock ?
}
VamsasDocument doc=null;
IdFactory vorba = null;
- // TODO: reduce size of vorba ids generated from these parameters to IdFactory (mainly sessionHandle rationalization ?)
+ // TODO: LATER: 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");
+ log.debug("Accessing document");
doc =
va.getVamsasDocument(getProvenanceUser(),
"created new session document.", null);
if (doc!=null)
- _session.slog.debug("Successfully retrieved document.");
+ log.debug("Successfully retrieved document.");
else
log.error("Unexpectedly retrieved null document!");
}
}
// Construct the IClientDocument instance
- ClientDocument cdoc = new ClientDocument(doc, va, vorba, this);
- return cdoc;
+ cdocument = new ClientDocument(doc, va, vorba, this);
+ return cdocument;
}
/*
* (non-Javadoc)
* @throws Errors for invalid newdoc parameter
- * @see org.vamsas.client.IClient#updateDocument(org.vamsas.client.IClientDocument)
+ * @see uk.ac.vamsas.client.IClient#updateDocument(uk.ac.vamsas.client.IClientDocument)
*/
public void updateDocument(IClientDocument newdoc) {
+ log.debug("updateDocument:");
+ // Check validity of simpleclient instance and that it holds a lock on the session's document
if (!(newdoc instanceof ClientDocument)) {
- throw new Error("Invalid IClientDocument instance for SimpleClient.");
+ throw new Error("Invalid IClientDocument passsed to SimpleClient.");
}
if (cdocument==null)
- throw new Error("Client Error - updateDocument() called before getClientDocument().");
+ throw new Error("Client Error - updateDocument() called before getClientDocument() on this SimpleClient instance.");
if (newdoc!=cdocument)
throw new Error("Client Error - SimpleClient.updateDocument() can only take the IClientDocument instance returned from SimpleClient.getClientDocument()");
+
+ if (evgen.isDocumentWatchEnabled())
+ throw new Error("Client Error - or Library Bug : Document watcher still enabled whilst ClientDocument instance exists.");
+
if (!cdocument.isModified()) {
+ // client document is silently got rid of, with no session update events.
if (log.isDebugEnabled())
- log.debug("updateDocument for "+session.getSessionUrn()+" with unmodified IClientDocument.");
+ log.debug("updateDocument for "+session.getSessionUrn()+" with unmodified IClientDocument (skipping the write)");
} 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.
+ // cdocument.archive.cancelArchive(); // LATER: could be done - would need to prevent updateSessionDocument closing the iohandler.
_session.slog.warn("Session Document updated but may not be valid (false return from org.vamsas.simpleclient.ClientDocument.updateSessionDocument()");
}
+ log.debug("Document update successful.");
+ _session.setUnsavedFlag();
}
catch (IOException e) {
log.warn("IO Problems when updating document!",e);
}
// garbage collect the ClientDocument instance.
try {
+ log.debug("Finalizing ClientDocument instance.");
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
+
+ try {
+ _session.unlockVamsasDocument();
+ evgen.enableDocumentWatch();
+ } catch (IOException e) {
+ log.warn("IO Problems when releasing lock on session document!",e);
+ _session.slog.error("IO problems when attempting to release lock on session document.");
+ }
}
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#storeDocument(java.io.File)
+ * @see uk.ac.vamsas.client.IClient#storeDocument(java.io.File)
*/
public void storeDocument(File location) {
-
+ if (location==null)
+ throw new Error("Vamsas Client API Usage Error: storeDocument called with null location.");
+ log.debug("StoreDocument to "+location);
// write storeDocument file to inform other clients that they should raise
Lock vamlock = evgen.want_to_store();
// Events.DOCUMENT_FINALIZEAPPDATA
/*
* (non-Javadoc)
*
- * @see org.vamsas.client.IClient#addVorbaEventHandler(java.lang.String,
+ * @see uk.ac.vamsas.client.IClient#addVorbaEventHandler(java.lang.String,
* java.beans.PropertyChangeListener)
*/
public void addVorbaEventHandler(String EventChain, PropertyChangeListener evt) {
if (handlers.containsKey(EventChain)) {
+ log.debug("Adding new handler for "+EventChain);
Object handler;
((PropertyChangeSupport) (handler = handlers.get(EventChain)))
.addPropertyChangeListener(evt);
}
/* (non-Javadoc)
- * @see org.vamsas.client.IClient#pollUpdate()
+ * @see uk.ac.vamsas.client.IClient#pollUpdate()
*/
public void pollUpdate() {
-
+ log.debug("pollUpdate");
if (evgen==null) {
log.warn("pollUpdate called on incomplete SimpleClient object.");
return;
}
- if (!evgen.isAlive()) {
+ if (!evgen.isWatcherAlive()) {
log.warn("pollUpdate called before joinSession() - trying to do this.");
try {
joinSession();
//TODO ensure event generator robustly handles these interrupts.
log.debug("interrrupting event generator.");
- evgen.interrupt();
+ evgen.interruptWatching();
log.debug("interrrupted event generator.");
}
/* (non-Javadoc)
- * @see org.vamsas.client.IClient#joinSession()
+ * @see uk.ac.vamsas.client.IClient#joinSession()
*/
public void joinSession() throws Exception {
+ log.debug("Joining Session.");
// start the EventGenerator thread.
if (evgen==null) {
log.warn("joinSession called on incomplete SimpleClient object.");
return;
}
- if (evgen.isAlive())
+ if (evgen.isWatcherAlive())
throw new Error("Join session called twice for the same SimpleClient (IClient instance).");
- evgen.start();
- if (evgen.isAlive())
+ evgen.startWatching();
+ if (evgen.isWatcherAlive())
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 ?
+ //TODO: LATER: 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)
+ * @see uk.ac.vamsas.client.IClient#importDocument(java.io.File)
*/
public void importDocument(File location) {
// TODO LATER: implement SimpleClient.importDocument()
// TODO Auto-generated method stub
}
+
+ /**
+ * retrieves the current VamsasSession to which belong the client
+ * @return the _session
+ */
+ protected VamsasSession get_session() {
+ return this._session;
+ }
+ SimplePickManager pickmanager=null;
+ /* (non-Javadoc)
+ * @see uk.ac.vamsas.client.IClient#getPickManager()
+ */
+ public IPickManager getPickManager() {
+ createPickManager();
+ return pickmanager;
+ }
+
+ private void createPickManager() {
+ if (pickmanager==null){
+ // TODO: Construct PickManager for session using details from sessionURN!
+ log.debug("Creating PickManager (not from sessionURN yet)");
+ pickmanager = new SimplePickManager(new uk.ac.vamsas.client.picking.SocketManager());
+ }
+ }
}