remove unnecessary existence checks.
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / NativeLock.java
1 package uk.ac.vamsas.client.simpleclient;
2
3 import java.io.BufferedInputStream;
4 import java.io.BufferedOutputStream;
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.FileNotFoundException;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10 import java.io.OutputStream;
11 import java.io.RandomAccessFile;
12 import java.nio.channels.FileChannel;
13 import java.nio.channels.FileLock;
14 import java.nio.channels.ReadableByteChannel;
15
16 /**
17  * @author JimP
18  *
19  */
20 public class NativeLock extends Lock {
21
22   protected FileLock lock = null;
23
24   /**
25    * @param lockfile
26    * @param block true means thread will block until a lock is obtained.
27    */
28   public NativeLock(File lockfile, boolean block) {
29     super(lockfile);
30     // try and get a lock.
31     lock = null;
32     
33     try {
34       /*if (!lockfile.createNewFile()) {
35           log.warn("Failed to create locked file "+lockfile);
36           return;
37         }
38       */
39       rafile=new RandomAccessFile(lockfile,"rw");
40       if (block)
41         lock = rafile.getChannel().lock();
42       else
43         lock = rafile.getChannel().tryLock();
44       if (lock==null || !lock.isValid()) {
45         // failed to get lock. Close the file channel
46         log.debug("failed to get lock for "+lockfile);
47         rafile.getChannel().close();
48         lock=null;
49       }
50     } catch (FileNotFoundException e) {
51       //
52       log.debug("Lock failed - normal behaviour for windows locking.");
53       //log.error("Error! Couldn't create a lockfile at "
54       //  + lockfile.getAbsolutePath(), e);
55     } catch (IOException e) {
56       log.error("Error! Problems with IO when creating a lock on "
57           + lockfile.getAbsolutePath(),e);
58     } // catch (Exception )
59   }
60
61   public boolean isLocked() {
62     if (lock != null && lock.isValid()) {
63       return true;
64     }
65     return false;
66   }
67
68   public void release() {
69     release(true);
70   }
71
72   public void release(boolean closeChannel) {
73     try {
74       // channel.close should be called before release() for rigourous locking.
75       if (rafile!=null && rafile.getFD().valid() && rafile.getChannel()!=null && lock.isValid()) {
76         if (closeChannel && rafile.getChannel().isOpen()) {
77             rafile.close();
78             rafile=null; 
79         }
80         if (lock!=null && lock.isValid())
81           lock.release();
82         
83       }
84     } catch (IOException e) {
85       log.warn("Whilst releasing lock",e);
86     }
87     lock=null;
88   }
89
90   /**
91    * gets Locked Stream for reading from
92    * @param atStart true to start reading at beginning of file.
93    * @return null if file not locked
94    * @throws IOException
95    */
96   public FileInputStream getFileInputStream(boolean atStart) throws IOException {
97     if (!isLocked())
98       return null;
99     if (atStart)
100       rafile.seek(0);
101     return new FileInputStream(rafile.getFD());
102   }
103
104   /**
105    * gets Locked stream to write to
106    * FileInput always starts at the *end* of the file (after any truncation)
107    * @param clear true means file will be cleared to zero length
108    * @return null if file is not locked
109    * @throws IOException
110    */
111   public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
112     if (!isLocked())
113       return null;
114     if (clear) {
115       rafile.seek(0);
116       rafile.setLength(0);
117     } else
118       rafile.seek(rafile.length());
119     return new LockedFileOutputStream(rafile.getFD());
120   }
121
122   /**
123    * return buffered output stream to locked file.
124    * @param clear - true means file is truncated to 0 length before writing 
125    * @return
126    */
127   public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
128     OutputStream fos = getFileOutputStream(clear);
129     if (fos!=null)
130       return new BufferedOutputStream(fos);
131     return null;
132   }
133   /**
134    * @see uk.ac.vamsas.client.simpleclient.Lock#finalize()
135    */
136   protected void finalize() throws Throwable {
137     release(true); // we explicitly lose the lock here.
138     // log.debug("lock closing through garbage collection ?");
139     super.finalize();
140   }
141
142   /* (non-Javadoc)
143    * @see uk.ac.vamsas.client.simpleclient.Lock#getLength()
144    */
145   public long length() {
146     if (isLocked()){
147       try {
148         return rafile.length();
149       } catch (Exception e) {
150         log.debug("getLength exception:",e);
151       }
152     }
153     return -1;
154   }
155
156   public RandomAccessFile getRaFile() throws IOException {
157     if (isLocked())
158       return rafile;
159     else
160       log.debug("Failed to getRaFile on "+target);
161     return null;
162   }  
163   
164   public FileChannel getRaChannel() throws IOException {
165     if (isLocked())
166       return rafile.getChannel();
167     else
168       log.debug("Failed to getRaChannel on "+target);
169     return null;
170   }
171
172 }