1 package org.vamsas.client.simpleclient;
3 import java.io.BufferedInputStream;
4 import java.io.BufferedOutputStream;
5 import java.io.FileInputStream;
6 import java.io.FileNotFoundException;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.RandomAccessFile;
10 import java.nio.channels.FileLock;
12 import org.apache.commons.logging.LogFactory;
15 * transient object representing a file lock
16 * This lock should hold for all processes interacting in a session.
17 * TODO: currently implemented for local filesystem style locking - need a fallback mechanism for systems without file locks.
23 org.apache.commons.logging.Log log = LogFactory.getLog(Lock.class);
25 RandomAccessFile rafile=null;
27 * creates a valid Lock (test with <method>isLocked</method>)
28 * if a lock could be obtained for <param>lockfile</param>
31 public Lock(java.io.File lockfile) {
32 // try and get a lock.
36 if (!lockfile.exists())
37 if (!lockfile.createNewFile()) {
38 log.warn("Failed to create locked file "+lockfile);
42 lock = (rafile=new RandomAccessFile(lockfile,"rw")).getChannel().tryLock();
43 if (lock==null || !lock.isValid()) {
44 // failed to get lock. Close the file channel
45 log.debug("failed to get lock for "+lockfile);
46 rafile.getChannel().close();
49 } catch (FileNotFoundException e) {
51 log.debug("Lock failed - normal behaviour for windows locking.");
52 //log.error("Error! Couldn't create a lockfile at "
53 // + lockfile.getAbsolutePath(), e);
54 } catch (IOException e) {
55 log.error("Error! Problems with IO when creating a lock on "
56 + lockfile.getAbsolutePath(),e);
61 if (lock != null && lock.isValid()) {
66 public void release() {
69 public void release(boolean closeChannel) {
71 // channel.close should be called before release() for rigourous locking.
72 if (rafile!=null && rafile.getChannel()!=null) {
73 if (rafile.getChannel().isOpen()) {
74 if (closeChannel && rafile.getChannel().isOpen())
75 rafile.getChannel().close();
76 if (lock!=null && lock.isValid())
80 } catch (IOException e) {
81 log.warn("Whilst releasing lock",e);
88 * gets Locked Stream for reading from
89 * @param atStart true to start reading at beginning of file.
90 * @return null if file not locked
93 public FileInputStream getFileInputStream(boolean atStart) throws IOException {
98 return new FileInputStream(rafile.getFD());
101 * gets Locked stream to write to
102 * FileInput always starts at the *end* of the file (after any truncation)
103 * @param clear true means file will be cleared to zero length
104 * @return null if file is not locked
105 * @throws IOException
107 public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
112 rafile.seek(rafile.length());
113 return new LockedFileOutputStream(rafile.getFD());
116 * return buffered output stream to locked file.
117 * @param clear - true means file is truncated to 0 length before writing
120 public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
121 FileOutputStream fos = getFileOutputStream(clear);
123 return new BufferedOutputStream(fos);
128 * return buffered input stream for locked file.
129 * @param atStart - true means read from begining of file
130 * @return null if file is not locked.
132 public BufferedInputStream getBufferedInputStream(boolean atStart) throws IOException {
133 FileInputStream fis = getFileInputStream(atStart);
135 return new BufferedInputStream(fis);
138 /* Explicitly release lock (probably don't need to do this!)
139 * @see java.lang.Object#finalize()
141 protected void finalize() throws Throwable {
142 release(true); // we explicitly lose the lock here.
143 // log.debug("lock closing through garbage collection ?");