added automatic channel closure for failed locks. (suggest this class becomes a singl...
[vamsas.git] / src / org / vamsas / client / simpleclient / FileWatcher.java
1 /**
2  * 
3  */
4 package org.vamsas.client.simpleclient;
5
6 import java.io.File;
7
8 import org.vamsas.client.SimpleClient;
9
10 /**
11  * @author jim Watches a particular file for its creation, deletion, or
12  *         modification.
13  */
14 public class FileWatcher {
15
16   private File subject = null;
17
18   private long lastStat[];
19   boolean waslocked=false;
20   boolean exists = false;
21
22   /**
23    * Make a watcher for a particular file. If the file doesn't exist, the
24    * watcher will watch for its creation (and indicate a change of state) 
25    * For locked files, the removal of a lock constitutes a change of 
26    * state if the file was modified.
27    * 
28    * @param subject
29    */
30   private boolean checkLock() {
31     if (subject!=null && subject.exists()) {
32       Lock tl = new Lock(subject);
33       if (tl.isLocked()) {
34         tl.release();
35         return false;
36       }
37       tl.release();
38       return true;
39     }
40     return false;
41   }
42   
43   private long[] getStat(File subject) {
44     return new long[] { subject.lastModified(), subject.length() };
45   }
46   private boolean compStat(long[] stat, long[] newstat) {
47     if (stat[0]!=newstat[0] || stat[1]!=newstat[1])
48       return false;
49     return true;
50   }
51   /**
52    * Detect changes in file state and release of any
53    * lock in place during change.
54    * @return true if file state has changed
55    */
56   private boolean check() {
57     if (subject != null) {
58       if (!subject.exists()) {
59         if (exists) {
60           if (!waslocked) {
61             // !checkLock()) {
62           
63             exists = false;
64             // waslocked=false;
65             return true;
66           }
67         }
68         // locked - state change registered after lock is released
69         return false;
70       } else {
71         long[] newStat = getStat(subject); // subject.lastModified();
72         if (!checkLock()) {
73           // file is free to access, return state change
74           if (!exists || !compStat(lastStat, newStat)) {
75             waslocked=false;
76             exists=true;
77             lastStat=newStat;
78             return true;
79           }
80           // no change
81           return false;
82         } else {
83           waslocked=true;
84           return false;
85         }
86       }
87     }
88     return false;
89   }
90   public void setState() {
91     if (subject!=null) {
92       lastStat = getStat(subject);
93       exists = subject.exists();
94       waslocked = checkLock();
95     }
96   }
97   
98   public FileWatcher(File subject) {
99     // TODO Auto-generated constructor stub
100     this.subject = subject;
101     setState();
102   }
103
104   public boolean hasChanged() {
105     return check();
106   }
107 }