X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=inline;f=src%2Forg%2Fvamsas%2Fclient%2Fsimpleclient%2FFileWatcher.java;h=a3225db0c98f5f9bf98b8d91ff8f6d4fae22f4ca;hb=8c0230fceb94cba911790b1622b030d02eb0e7ac;hp=f486360c11d894eaec966f39d3a119707b0cf2a1;hpb=de5c431d734c37ef35afb58a849a321010df1a99;p=vamsas.git diff --git a/src/org/vamsas/client/simpleclient/FileWatcher.java b/src/org/vamsas/client/simpleclient/FileWatcher.java index f486360..a3225db 100644 --- a/src/org/vamsas/client/simpleclient/FileWatcher.java +++ b/src/org/vamsas/client/simpleclient/FileWatcher.java @@ -5,48 +5,142 @@ package org.vamsas.client.simpleclient; import java.io.File; +import org.vamsas.client.SimpleClient; + /** - * @author jim - * Watches a particular file for its creation, deletion, or modification. + * @author jim Watches a particular file for its creation, deletion, or + * modification. */ public class FileWatcher { - private File subject=null; - private long lastStat; - boolean exists=false; + + private File subject = null; + + private long lastStat[]; + boolean waslocked=false; + boolean exists = false; /** - * Make a watcher for a particular file. - * If the file doesn't exist, the watcher will watch - * for its creation (and indicate a change of state) - * @param subject + * transient lock on subject - can be passed back to calling class + * to preserve new state of file for immediate reading. + */ + private Lock subjectLock = null; + + private void clearLock() { + if (subjectLock!=null) + subjectLock.release(); + subjectLock=null; + } + + private boolean checkLock() { + if (subject!=null && subject.exists()) { + if (subjectLock!=null) { + subjectLock.release(); + } + subjectLock = new Lock(subject); + if (subjectLock.isLocked()) { + // subjectLock.release(); + return false; + } + clearLock(); + return true; + } + return false; + } + + private long[] getStat(File subject) { + return new long[] { subject.lastModified(), subject.length() }; + } + private boolean compStat(long[] stat, long[] newstat) { + if (stat[0]!=newstat[0] || stat[1]!=newstat[1]) + return false; + return true; + } + /** + * Detect changes in file state and release of any + * lock in place during change. + * @return true if file state has changed. Leaves lock in subjectLock (ready to be passed to caller) */ private boolean check() { - if (subject!=null) { + if (subject != null) { if (!subject.exists()) { if (exists) { - exists=false; - return true; - } - return false; - } else { - long newStat=subject.lastModified(); - if (exists && lastStat==newStat) { + if (!waslocked) { + // !checkLock()) { + + exists = false; + // waslocked=false; + return true; + } + } + // locked - state change registered after lock is released return false; + } else { + long[] newStat = getStat(subject); // subject.lastModified(); + if (!checkLock()) { + // file is free to access, return state change + if (!exists || !compStat(lastStat, newStat)) { + waslocked=false; + exists=true; + lastStat=newStat; + return true; + } + // no change + return false; + } else { + waslocked=true; + return false; + } } - lastStat=newStat; - exists=true; - return true; } - } return false; } + /** + * updates internal record of file state when caller has intentionally + * modified subject. (ignores locked-state of subject) + */ + public void setState() { + if (subject!=null) { + if (exists = subject.exists()) { + lastStat = getStat(subject); + waslocked = false; + } + } + } + /** + * Make a watcher for a particular file. If the file doesn't exist, the + * watcher will watch for its creation (and indicate a change of state) + * For locked files, the removal of a lock constitutes a change of + * state if the file was modified. + * + * @param subject + */ public FileWatcher(File subject) { // TODO Auto-generated constructor stub this.subject = subject; - check(); + setState(); } + /** + * Test for change in file state. Only indicates a change + * after any lock on a file has been released. + * @return true if file has been modified. + */ public boolean hasChanged() { - return check(); + boolean res = check(); + clearLock(); + return res; + } + /** + * passes lock back to caller if hasChanged returned true. + * @return + */ + public Lock getChangedState() { + boolean res = check(); + if (res) + return subjectLock; + else { + clearLock(); + return null; + } } }