locking for windows (XP) partly debugged. ClientsFileTest watchers do not behave...
[vamsas.git] / src / org / vamsas / client / simpleclient / Lock.java
index dfc978e..b49cdf5 100644 (file)
@@ -1,11 +1,16 @@
 package org.vamsas.client.simpleclient;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.nio.channels.FileLock;
 
+import org.apache.commons.logging.LogFactory;
+
 /**
  * transient object representing a file lock
  * This lock should hold for all processes interacting in a session.
@@ -15,6 +20,7 @@ import java.nio.channels.FileLock;
  */
 
 public class Lock {
+  org.apache.commons.logging.Log log = LogFactory.getLog(Lock.class);
   FileLock lock = null;
   RandomAccessFile rafile=null;
   /**
@@ -29,21 +35,25 @@ public class Lock {
     try {
       if (!lockfile.exists())
         if (!lockfile.createNewFile()) {
+          log.warn("Failed to create locked file "+lockfile);
           return;
         }
       
       lock = (rafile=new RandomAccessFile(lockfile,"rw")).getChannel().tryLock();
-      if (lock==null || !lock.isValid())
+      if (lock==null || !lock.isValid()) {
         // failed to get lock. Close the file channel
+        log.debug("failed to get lock for "+lockfile);
         rafile.getChannel().close();
+        lock=null;
+      }
     } catch (FileNotFoundException e) {
-      System.err.println("Error! Couldn't create a lockfile at "
-          + lockfile.getAbsolutePath());
-      e.printStackTrace();
+      //
+      log.debug("Lock failed - normal behaviour for windows locking.");
+      //log.error("Error! Couldn't create a lockfile at "
+      //  + lockfile.getAbsolutePath(), e);
     } catch (IOException e) {
-      System.err.println("Error! Problems with IO when creating a lock on "
-          + lockfile.getAbsolutePath());
-      e.printStackTrace();
+      log.error("Error! Problems with IO when creating a lock on "
+          + lockfile.getAbsolutePath(),e);
     }
   }
   
@@ -55,19 +65,73 @@ public class Lock {
   }
   public void release() {
     try {
-      // TODO: verify that channel.close should be called after release() for rigourous locking. 
-      if (lock!=null && lock.isValid())
-        lock.release();
-      if (rafile!=null && rafile.getChannel().isOpen())
-        rafile.getChannel().close();
+      // TODO: verify that channel.close should be called after release() for rigourous locking.
+      if (rafile!=null && rafile.getChannel()!=null) {
+        if (rafile.getChannel().isOpen()) {
+          if (lock!=null && lock.isValid())
+            lock.release();
+          if (rafile!=null && rafile.getChannel().isOpen())
+            rafile.getChannel().close();
+        }
+      }
     } catch (IOException e) {
-      // TODO Auto-generated catch block
-      e.printStackTrace(System.err);
+      log.warn("Whilst releasing lock",e);
     }
     lock=null;
     rafile=null;
   }
   
+  /**
+   * 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 FileInputStream getFileInputStream(boolean atStart) throws IOException {
+    if (!isLocked())
+      return null;
+    if (atStart)
+      rafile.seek(0);
+    return new FileInputStream(rafile.getFD());
+  }
+  /**
+   * 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 FileOutputStream getFileOutputStream(boolean clear) throws IOException {
+    if (!isLocked())
+      return null;
+    if (clear)
+      rafile.setLength(0);
+    rafile.seek(rafile.length());
+    return new LockedFileOutputStream(rafile.getFD());
+  }
+  /**
+   * return buffered output stream to locked file.
+   * @param clear - true means file is truncated to 0 length before writing 
+   * @return
+   */
+  public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
+    FileOutputStream fos = getFileOutputStream(clear);
+    if (fos!=null)
+      return new BufferedOutputStream(fos);
+    return 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;
+  }
   /* Explicitly release lock (probably don't need to do this!)
    * @see java.lang.Object#finalize()
    */