8cb680860bea2f95dba9b88e804eba27c2cde7d1
[vamsas.git] / src / org / vamsas / client / simpleclient / FileLock.java
1 package org.vamsas.client.simpleclient;
2
3 import java.io.BufferedOutputStream;
4 import java.io.File;
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
11 public class FileLock extends Lock {
12   File _lock = null;
13   protected static String _LockSuffix="lck";
14   /**
15    * call to clear up a filelock file after its been made
16    *
17    */
18   private void tidy() {
19     if (_lock!=null) {
20       _lock.delete();
21       _lock=null;
22     }
23   }
24   /**
25    * @param lockfile
26    */
27   public FileLock(File lockfile) {
28     super(lockfile);
29     // try and get a lock.
30     try {
31       _lock = new File(lockfile.getParentFile(), lockfile.getName()+"."+_LockSuffix);
32       if (_lock.exists() || !_lock.createNewFile()) {
33         log.debug("Failed to get lock for "+lockfile+" using lockfile "+_lock);
34         _lock=null;
35         return;
36       }
37       _lock.deleteOnExit(); // safe - all locks should be removed on finalization.
38       // create target file ready to be written to if necessary.
39       if (!lockfile.exists())
40         if (!lockfile.createNewFile()) {
41           log.warn("Failed to create locked file "+lockfile);
42           return;
43         }
44       openRaFile();
45     } catch (FileNotFoundException e) {
46       //
47       log.debug("FileLock failed with target="+lockfile+" and lockfile suffix of "+_LockSuffix);
48       //log.error("Error! Couldn't create a lockfile at "
49       //  + lockfile.getAbsolutePath(), e);
50     } catch (IOException e) {
51       log.error("Error! Problems with IO when creating a lock on "
52           + lockfile.getAbsolutePath(),e);
53     }
54   }
55   
56   private boolean openRaFile() throws IOException {
57     if (target==null)
58       return false;
59     if (_lock==null || !_lock.exists())
60       return false;
61     if (rafile==null)
62       rafile=new RandomAccessFile(target,"rw");
63     return (rafile.getChannel()!=null) && rafile.getChannel().isOpen();
64   }
65   
66   public boolean isLocked() {
67     if (_lock != null) {
68       if (_lock.exists())
69         return true;
70       _lock=null;
71       if (log.isDebugEnabled())
72         log.debug("Lockfile "+_lock+" unexpectedly deleted ?");
73     }
74     return false;
75   }
76   
77   public void release() {
78     release(true);
79   }
80   
81   public void release(boolean closeChannel) {
82     if (_lock==null)
83       return;
84     if (closeChannel) {
85       if (rafile!=null) 
86         try {
87           rafile.close();
88         } catch (Exception e) {
89           log.debug("Unexpected exception whilst closing RandomAccessFile on "+target, e);
90         }
91         rafile=null; 
92     }
93     tidy();
94   }
95   
96   public FileInputStream getFileInputStream(boolean atStart) throws IOException {
97     if (!isLocked())
98       return null;
99     openRaFile();
100     if (atStart)
101       rafile.seek(0);
102     return new FileInputStream(rafile.getFD());
103   }
104   
105   
106   public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
107     if (!isLocked())
108       return null;
109     openRaFile();
110     if (clear)
111       rafile.setLength(0);
112     else
113       rafile.seek(rafile.length());
114     return new LockedFileOutputStream(rafile.getFD());
115   }
116   
117   
118   public BufferedOutputStream getBufferedOutputStream(boolean clear) throws IOException {
119     FileOutputStream fos = getFileOutputStream(clear);
120     if (fos!=null)
121       return new BufferedOutputStream(fos);
122     return null;
123   }
124   
125   protected void finalize() throws Throwable {
126     release(true); // we explicitly lose the lock here.
127     super.finalize();
128   }
129   
130 }