import uk.ac.vamsas.client.IClient;
import uk.ac.vamsas.client.IClientDocument;
import uk.ac.vamsas.client.IObjectUpdate;
+import uk.ac.vamsas.client.InvalidSessionDocumentException;
import uk.ac.vamsas.client.InvalidSessionUrnException;
import uk.ac.vamsas.client.SessionHandle;
import uk.ac.vamsas.client.UserHandle;
- private java.nio.channels.FileLock activeClientFilelock = null;
-
- private FileChannel activeClientFileChannel = null;
+ private Lock activeClientFilelock = null;
private File clientlockFile = null;
/**
}
/**
- * construct new session by importing objects from an existing vamsas document
+ * construct new SimpleClientsession 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();
- log.debug("Imported new vamsas data from "+importingArchive);
- } catch (Exception e) {
- sessdoc.cancelArchive();
- // 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);
+ if (log.isDebugEnabled())
+ {
+ log.debug("Attempting to overwrite session document with file: "+importingArchive);
}
+ // TODO: write provenance entry for new session indicating the import.
+
}
+ */
/*
* (non-Javadoc)
_session.removeClient(this);
//log.debug("Stopping EventGenerator..");
//evgen.stopWatching();
- SimpleClient.log.debug("EventGenerator halted.");
this.cdocument = null;
+ SimpleClient.log.debug("EventGenerator halted.");
log.debug("finalization Complete.");
}
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 (skipping the write)");
+ if (evgen.isDocumentWatchEnabled())
+ 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.isInvalidModification())
+ {
+ log.info("Client has corrupted the vamsas document. It will not be written back to the session - sorry.");
+ // TODO: modify updateDocument signature: We should really raise an exception here to tell the client that it broke the datamodel.
} 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.");
+ // actually try to write - if necessary.
+ 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 {
+ writeSessionDocument();
}
}
- // garbage collect the ClientDocument instance.
+ // release locks, reset and start to receive events again
+ 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
+ {// Release the lock
+ log.debug("Releasing lock on active client lock file");
activeClientFilelock.release();
-
- if (activeClientFileChannel != null)
- // Close the file
- activeClientFileChannel.close();
+ 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)
{
- this.clientlockFile.delete();
- log.debug("deleted active client lock file");
+ log.debug("trying to delete active client lock file");
+ if (this.clientlockFile.exists())
+ {
+ 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
}
}
this.clientlockFile = new File (clientlockFileDir, this.getClientHandle().getClientUrn().replaceAll("[:;/\\\\]+",""));
-
- log.debug("Creating active client lock file "+ this.clientlockFile.getAbsolutePath());
- if (clientlockFile.exists())
- {//should not happen, file should be deleted when the application closes or when a crashed application has been detected
- log.error("client lock file already exits");
- }
- try {
- //create the empty file
- if(! clientlockFile.createNewFile())
- {
- log.error("Unable to create active client lock file");
-
- return;
- }
- else
- log.debug("file created");
- // Get a file channel for the file
- FileChannel channel = new RandomAccessFile(clientlockFile, "rw").getChannel();
-
- // Use the file channel to create a lock on the file.
- // This method blocks until it can retrieve the lock.
- java.nio.channels.FileLock activeClientFilelock ;// = channel.lock();
-
- // Try acquiring the lock without blocking. This method returns
- // null or throws an exception if the file is already locked.
- try
- {
- activeClientFilelock = channel.tryLock();
- log.debug("Got lock");
- }
- catch (OverlappingFileLockException e)
- {
- // File is already locked in this thread or virtual machine
- log.error("Oups the file is already locked",e);
-
- }
-
- // Release the lock
- /* lock.release();
-
- // Close the file
- channel.close();*/
- } catch (Exception e) {
- log.error("Error during lock file creation",e);
- }
-
-
+ log.debug("Creating active client lock file "+ this.clientlockFile.getAbsolutePath());
+ Lock clientLock = uk.ac.vamsas.client.simpleclient.LockFactory.getLock(clientlockFile, false);
+ if (clientLock==null || !clientLock.isLocked())
+ {
+ log.fatal("IMPLEMENTATION ERROR: Couldn't get a lock for the client lock file "+clientlockFile);
+ }
+ activeClientFilelock = clientLock;
}
-
/**
* @return the clientlockFile
*/
protected File getClientlockFile() {
return clientlockFile;
}
+ /**
+ *
+ * @return the lock for the client in the session
+ */
+ protected Lock getClientLock() {
+ return activeClientFilelock;
+ }
+ SimpleClientConfig _config = null;
+ public SimpleClientConfig getSimpleClientConfig() {
+ if (_config==null)
+ {
+ _config = new SimpleClientConfig();
+ }
+ return _config;
+ }
+
}