*/
log.debug("Watchers inited.");
}
- void _raise(String handlerEvent, String property, Object oldval, Object newval) {
+ /**
+ * Call registered handlers for a vamsas session event
+ * @param handlerEvent a named event
+ * @param property property name to pass to handler
+ * @param oldval old value of property to pass
+ * @param newval new value of property to pass
+ * @return true if event generation did not raise any exceptions.
+ */
+ boolean _raise(String handlerEvent, String property, Object oldval, Object newval) {
PropertyChangeSupport h = (PropertyChangeSupport) handlers.get(handlerEvent);
if (h!=null) {
log.debug("Triggering:"+handlerEvent);
h.firePropertyChange(property, oldval, newval);
} catch (Exception e) {
log.warn("Client Exception during handling of "+handlerEvent, e);
+ return false;
+ }
+ catch (Error e)
+ {
+ log.error("Serious! Client Error during handling of "+handlerEvent, e);
+ return false;
}
log.debug("Finished :"+handlerEvent);
} else
log.debug("No handlers for raised "+handlerEvent);
+ return true;
}
protected boolean storeDocRequest(Lock lock) {
if (log.isDebugEnabled())
session.vamArchive.fileLock=doclock;
if (client.pickmanager!=null)
client.pickmanager.setPassThru(false);
+ if (log.isDebugEnabled()) {
+ log.debug("Initiating a documentChanged event. Document is "+(client.cdocument==null ? "closed" : "open"));
+ }
// TODO: decide if individual object update handlers are called as well as overall event handler
- _raise(Events.DOCUMENT_UPDATE, client.getSessionUrn(), null, client);
+ if (!_raise(Events.DOCUMENT_UPDATE, client.getSessionUrn(), null, client))
+ {
+ log.info("Recovering from errors or exceptions generated by client application");
+ if (client.cdocument!=null)
+ {
+ try {
+ client.tidyAwaySessionDocumentState();
+ }
+ catch (Exception e)
+ {
+ log.warn("Exception generated by vamsas library - when tidying away session document:",e);
+ }
+ catch (Error e)
+ {
+ log.error("LIBRARY Implementation error - when tidying away session document:",e);
+ }
+ }
+
+ }
if (client.pickmanager!=null)
client.pickmanager.setPassThru(true);
if (log.isDebugEnabled()) {
log.debug("Finished handling a documentChanged event. Document is "+(client.cdocument==null ? "closed" : "open"));
}
+ if (client.cdocument!=null)
+ {
+ log.warn("Implementation Error ? ClientDocument instance has not been closed or updated by handler!");
+ }
/*try {
client._session.getVamsasDocument().closeArchive();
} catch (Exception e) {log.warn("Unexpected exception when closing document after update.",e);};
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.");
+ throw new Error("Probable Client Error (did you remember to call SimpleClient.updateDocument(clientdoc) at the end of the document update handler?) - 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 (skipping the write)");
} else {
- try {
- boolean updated=cdocument.updateSessionDocument();
- if (!updated) {
- 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 iohandler.
- _session.slog.warn("Session Document updated but may not be valid (false return from org.vamsas.simpleclient.ClientDocument.updateSessionDocument()");
- } else {
- log.debug("Document update successful.");
- }
- _session.setUnsavedFlag();
- }
- catch (IOException e) {
- log.warn("IO Problems when updating document!",e);
- _session.slog.error("IO problems when attempting to update document.");
- }
+ writeSessionDocument();
}
- // garbage collect the ClientDocument instance.
+ tidyAwaySessionDocumentState();
+ }
+ /**
+ * garbage collect the ClientDocument instance and re-enable watchers.
+ */
+ protected void tidyAwaySessionDocumentState() {
try {
log.debug("Finalizing ClientDocument instance.");
cdocument.finalize();
_session.slog.error("IO problems when attempting to release lock on session document.");
}
}
-
+
+ /**
+ * write the cdocument instance to the session for real.
+ */
+ private void writeSessionDocument() {
+ try {
+ boolean updated=cdocument.updateSessionDocument();
+ if (!updated) {
+ 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 iohandler.
+ _session.slog.warn("Session Document updated but may not be valid (false return from org.vamsas.simpleclient.ClientDocument.updateSessionDocument()");
+ } else {
+ log.debug("Document update successful.");
+ }
+ _session.setUnsavedFlag();
+ }
+ catch (IOException e) {
+ log.warn("IO Problems when updating document!",e);
+ _session.slog.error("IO problems when attempting to update document.");
+ }
+ }
+
/*
* (non-Javadoc)
*
protected void releaseActiveClientFile() throws IOException
{
- log.debug("Releasing active client file");
+ log.debug("Releasing active client locks");
if( activeClientFilelock != null)
{// Release the lock
+ log.debug("Releasing lock on active client lock file");
activeClientFilelock.release();
+ log.debug("ReleaseActiveClientFile called when client has no lock on its clientLockFile");
activeClientFilelock = null;
} else {
log.debug("ReleaseActiveClientFile called when client has no lock on its clientLockFile");
}
if (this.clientlockFile != null)
{
+ log.debug("trying to delete active client lock file");
if (this.clientlockFile.exists())
- this.clientlockFile.delete();
- log.debug("deleted active client lock file");
+ {
+ this.clientlockFile.delete();
+ log.debug("deleted active client lock file");
+ }
} else {
log.debug("ReleaseActiveClientFile called when client has no clientLockFile");
}
-
}
protected void createActiveClientFile() throws IOException
protected File getClientlockFile() {
return clientlockFile;
}
+ /**
+ *
+ * @return the lock for the client in the session
+ */
+ protected Lock getClientLock() {
+ return activeClientFilelock;
+ }
+
}
client.evgen.stopWatching();
cwe.setHandler(null);
-// ask to the client to copy application data into the document
+ // ask to the client to copy application data into the document
client.evgen._raise(Events.DOCUMENT_FINALIZEAPPDATA, null, client,null);
-
- if ( this.isLastActiveClient(client))
- {
+ boolean closeSession=isLastActiveClient(client);
+ if (closeSession)
+ {
log.debug("Raising request-to-save event");
client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client, null);
- //client.evgen._raise(Events.SESSION_SHUTDOWN, null, client.getSessionHandle(), null);
- log.debug("Last active client: closing session");
- log.info("Closing session");
- getSessionManager().removeSession(client.getSessionHandle());
- }
-
+ client.evgen._raise(Events.SESSION_SHUTDOWN, null, client.getSessionHandle(), null);
+ }
try
{
- log.debug("Releasing active client file");
+ log.debug("Attempting to release active client locks");
client.releaseActiveClientFile();
}
catch (IOException e)
{
log.error("error during active file client release");
}
- }
-
-
-
- /*clist.removeClient(client.getClientHandle(),null);
- if (this.clist.retrieveClientList() == null|| this.clist.retrieveClientList().length<1)
- {//assume it is the last client has been removed shutting down session
- slog.info("last client removed: removing session");
- log.debug("last client removed: removing session");
- this.getSessionManager().removeSession(client.getSessionHandle());
- }
- else
+ if (closeSession)
{
- int active=clist.retrieveClientList().length;
- log.debug("Still "+active+" active clients");
- slog.info("Still "+active+" active clients");
- }*/
-
+ log.debug("Last active client: closing session");
+ log.info("Closing session");
+ getSessionManager().removeSession(client.getSessionHandle());
+ }
+ }
}
private boolean isLastActiveClient(SimpleClient client)
{
log.debug("Testing if current client is the last one.");
+ log.debug("current client lockfile is '"+client.getClientlockFile()+"'");
boolean noOtherActiveClient = true;
//create, if need, subdirectory to contain client files
File clientlockFileDir = new File (this.sessionDir, clientFileDirectory);
{
File clientFile = clientFiles[i];
log.debug("testing file for lock: "+clientFile.getAbsolutePath());
- if(client.getClientlockFile().equals(clientFile))
+ if(client.getClientLock().isTargetLockFile(clientFile))
{
log.debug("current client file found");
continue;
}
log.debug("Stopping EventGenerator..");
+ // TODO: ensure ClientsFile lock is really released!! clist.unlockFile();
client.evgen.stopWatching();
}
watcher.setHandler(null);//Do not check if the client is the last client. watcher will shutdown anyway
// close document
client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client,null);
log.debug("close document request done");
- this.closeSession(client.getSessionHandle());
+ closeSession(client.getSessionHandle());
}
/**