new marshaller instance ensures we use marshalling properties and correct validation...
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / SimpleClient.java
index 9cbdcb7..8e8fba2 100644 (file)
@@ -51,9 +51,7 @@ public class SimpleClient implements IClient {
   
   
   
-  private java.nio.channels.FileLock activeClientFilelock = null;
-  
-  private FileChannel activeClientFileChannel = null;
+  private Lock activeClientFilelock = null;
   private  File clientlockFile = null;
   
   /**
@@ -315,32 +313,23 @@ public class SimpleClient implements IClient {
       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();
@@ -357,7 +346,28 @@ public class SimpleClient implements IClient {
       _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)
    * 
@@ -513,20 +523,27 @@ public class SimpleClient implements IClient {
   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
@@ -550,60 +567,27 @@ public class SimpleClient implements IClient {
        }
     }
     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;
+  }
+
 }