minimally debugged idFactory and vorbaId mechanism. Inelegant!
[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
9 /**
10  * @author jim Watches a particular file for its creation, deletion, or
11  *         modification.
12  */
13 public class FileWatcher {
14
15   private File subject = null;
16
17   private long lastStat[];
18   boolean waslocked=false;
19   boolean exists = false;
20   /**
21    * transient lock on subject - can be passed back to calling class
22    * to preserve new state of file for immediate reading.
23    */
24   private Lock subjectLock = null;
25   
26   private void clearLock() {
27     if (subjectLock!=null)
28       subjectLock.release();
29     subjectLock=null;
30   }
31   
32   private boolean checkLock() {
33     if (subject!=null && subject.exists()) {
34       if (subjectLock!=null) {
35         subjectLock.release();
36       }
37       subjectLock = new Lock(subject);
38       if (subjectLock.isLocked()) {
39         // subjectLock.release();
40         return false;
41       }
42       clearLock();
43       return true;
44     }
45     return false;
46   }
47   
48   private long[] getStat(File subject) {
49     return new long[] { subject.lastModified(), subject.length() };
50   }
51   private boolean compStat(long[] stat, long[] newstat) {
52     if (stat[0]!=newstat[0] || stat[1]!=newstat[1])
53       return false;
54     return true;
55   }
56   /**
57    * Detect changes in file state and release of any
58    * lock in place during change.
59    * @return true if file state has changed. Leaves lock in subjectLock (ready to be passed to caller)
60    */
61   private boolean check() {
62     if (subject != null) {
63       if (!subject.exists()) {
64         if (exists) {
65           if (!waslocked) {
66             // !checkLock()) {
67           
68             exists = false;
69             // waslocked=false;
70             return true;
71           }
72         }
73         // locked - state change registered after lock is released
74         return false;
75       } else {
76         long[] newStat = getStat(subject); // subject.lastModified();
77         if (!checkLock()) {
78           // file is free to access, return state change
79           if (!exists || !compStat(lastStat, newStat)) {
80             waslocked=false;
81             exists=true;
82             lastStat=newStat;
83             return true;
84           }
85           // no change
86           return false;
87         } else {
88           waslocked=true;
89           return false;
90         }
91       }
92     }
93     return false;
94   }
95   /**
96    * updates internal record of file state when caller has intentionally
97    * modified subject. (ignores locked-state of subject)
98    */
99   public void setState() {
100     if (subject!=null) {
101       if (exists = subject.exists()) {
102         lastStat = getStat(subject);
103         waslocked = false;
104       }
105     }
106   }
107   
108   /**
109    * Make a watcher for a particular file. If the file doesn't exist, the
110    * watcher will watch for its creation (and indicate a change of state) 
111    * For locked files, the removal of a lock constitutes a change of 
112    * state if the file was modified.
113    * 
114    * @param subject
115    */
116   
117   public FileWatcher(File subject) {
118     // TODO Auto-generated constructor stub
119     this.subject = subject;
120     setState();
121   }
122   /**
123    * Test for change in file state. Only indicates a change 
124    * after any lock on a file has been released.
125    * @return true if file has been modified.
126    */
127   public boolean hasChanged() {
128     boolean res = check();
129     clearLock();
130     return res;
131   }
132   /**
133    * passes lock back to caller if hasChanged returned true.
134    * @return
135    */
136   public Lock getChangedState() {
137     boolean res = check();
138     if (res)
139       return subjectLock;
140     else {
141       clearLock();
142       return null;
143     }
144   }
145 }