X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Forg%2Fvamsas%2Fclient%2Fsimpleclient%2FNativeLock.java;fp=src%2Forg%2Fvamsas%2Fclient%2Fsimpleclient%2FNativeLock.java;h=96d9b6b90741ff54e2d2f0b21673bf63aeb9ec82;hb=d4199f5cfea3a90baeb956c4beaa2f3e8c0597c6;hp=0000000000000000000000000000000000000000;hpb=f40af7ef35b8599c22df9a4495dcc49531324f95;p=vamsas.git diff --git a/src/org/vamsas/client/simpleclient/NativeLock.java b/src/org/vamsas/client/simpleclient/NativeLock.java new file mode 100644 index 0000000..96d9b6b --- /dev/null +++ b/src/org/vamsas/client/simpleclient/NativeLock.java @@ -0,0 +1,129 @@ +package org.vamsas.client.simpleclient; + +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; + +public class NativeLock extends Lock { + + protected FileLock lock = null; + + /** + * @param lockfile + */ + public NativeLock(File lockfile) { + super(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); + } + } + + public boolean isLocked() { + if (lock != null && lock.isValid()) { + return true; + } + return false; + } + + 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.getFD().valid() && rafile.getChannel()!=null && lock.isValid()) { + if (closeChannel && rafile.getChannel().isOpen()) { + rafile.close(); + rafile=null; + } + if (lock!=null && lock.isValid()) + lock.release(); + + } + } catch (IOException e) { + log.warn("Whilst releasing lock",e); + } + lock=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; + } + /** + * @see org.vamsas.client.simpleclient.Lock#finalize() + */ + protected void finalize() throws Throwable { + release(true); // we explicitly lose the lock here. + // log.debug("lock closing through garbage collection ?"); + super.finalize(); + } + +}