import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
+import java.io.File;
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.
- * TODO: currently implemented for local filesystem style locking - need a fallback mechanism for systems without file locks.
* @author jimp
- *
*/
-public class Lock {
- org.apache.commons.logging.Log log = LogFactory.getLog(Lock.class);
- FileLock lock = null;
- RandomAccessFile rafile=null;
+public abstract class Lock {
+ protected org.apache.commons.logging.Log log = LogFactory.getLog(Lock.class);
+ File target = null; // The file that is being locked
+ protected RandomAccessFile rafile=null;
+
/**
* creates a valid Lock (test with <method>isLocked</method>)
* if a lock could be obtained for <param>lockfile</param>
* @param lockfile
*/
- public Lock(java.io.File lockfile) {
- // try and get a lock.
- lock = null;
-
- 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()) {
- // failed to get lock. Close the file channel
- log.debug("failed to get lock for "+lockfile);
- rafile.getChannel().close();
- lock=null;
- }
- } catch (FileNotFoundException e) {
- //
- log.debug("Lock failed - normal behaviour for windows locking.");
- //log.error("Error! Couldn't create a lockfile at "
- // + lockfile.getAbsolutePath(), e);
- } catch (IOException e) {
- log.error("Error! Problems with IO when creating a lock on "
- + lockfile.getAbsolutePath(),e);
- }
- }
-
- boolean isLocked() {
- if (lock != null && lock.isValid()) {
- return true;
- }
- return false;
+ protected Lock(java.io.File lockfile) {
+ target = lockfile;
}
- public void release() {
- release(true);
- }
- public void release(boolean closeChannel) {
- try {
- // channel.close should be called before release() for rigourous locking.
- if (rafile!=null && rafile.getChannel()!=null) {
- if (rafile.getChannel().isOpen()) {
- if (closeChannel && rafile.getChannel().isOpen())
- rafile.getChannel().close();
- if (lock!=null && lock.isValid())
- lock.release();
- }
- }
- } catch (IOException e) {
- log.warn("Whilst releasing lock",e);
- }
- lock=null;
- rafile=null;
- }
-
+ /**
+ *
+ * @return true if lock is held on the target
+ */
+ public abstract boolean isLocked();
+ /**
+ * release lock and close all managed channels to file
+ *
+ */
+ public abstract void release();
+ /**
+ * optionally close the open random access channel on the file when releasing lock
+ * @param closeChannel
+ */
+ public abstract void release(boolean closeChannel);
+
/**
* 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());
- }
+ public abstract FileInputStream getFileInputStream(boolean atStart) throws IOException;
+
/**
* gets Locked stream to write to
* FileInput always starts at the *end* of the file (after any truncation)
* @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());
- }
+ public abstract FileOutputStream getFileOutputStream(boolean clear) throws IOException;
/**
* 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;
+ public abstract BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException;
+
+ protected void finalize() throws Throwable {
+ target=null;
}
-
/**
* return buffered input stream for locked file.
* @param atStart - true means read from begining of file
return new BufferedInputStream(fis);
return null;
}
- /* Explicitly release lock (probably don't need to do this!)
- * @see java.lang.Object#finalize()
- */
- protected void finalize() throws Throwable {
- release(true); // we explicitly lose the lock here.
- // log.debug("lock closing through garbage collection ?");
- super.finalize();
- }
-
}