package edu.mbl.jif.imaging.nav.util;
import java.io.IOException;
import java.util.List;
import name.pachler.nio.file.*;
import name.pachler.nio.file.ext.ExtendedWatchEventModifier;
/**
* Watch for file changes in a directory...
*
* Uses: http://jpathwatch.wordpress.com/ jpathwatch is open source under the GNU General Public
* License with Classpath Exception.
*
* @author GBH
*/
public class PathWatcher {
WatchKey watchingKey;
WatchService watchService;
WatchingThread watchingThread;
PathWatcherObserver oneWhoCares;
public PathWatcher(PathWatcherObserver oneWhoCares) {
this.oneWhoCares = oneWhoCares;
}
public void setWatchedPath(String path, boolean recursive) {
Path watchedPath = Paths.get(path);
try {
if (recursive) {
WatchEvent.Kind<?>[] events = new WatchEvent.Kind<?>[]{
StandardWatchEventKind.ENTRY_CREATE, StandardWatchEventKind.ENTRY_DELETE};
watchingKey = watchedPath.register(watchService, events, ExtendedWatchEventModifier.FILE_TREE);
} else {
watchingKey = watchedPath.register(watchService,
StandardWatchEventKind.ENTRY_CREATE, StandardWatchEventKind.ENTRY_DELETE);
}
} catch (UnsupportedOperationException uox) {
System.err.println("file watching not supported!");
// handle this error here
} catch (IOException iox) {
System.err.println("I/O errors");
// handle this error here
}
}
public void startWatching(String path, boolean recursive) {
stopWatching();
if (watchService == null) {
watchService = FileSystems.getDefault().newWatchService();
}
setWatchedPath(path, recursive);
new WatchingThread().start();
//System.out.println("started WatchingThread");
}
class WatchingThread extends Thread {
public void run() {
while (watchService != null) {
// take() will block until a file has been created/deleted
WatchKey signalledKey;
try {
signalledKey = watchService.take();
} catch (InterruptedException ix) {
// we'll ignore being interrupted
continue;
} catch (ClosedWatchServiceException cwse) {
// other thread closed watch service
//System.out.println("watch service closed, terminating.");
break;
}
// get list of events from key
List<WatchEvent<?>> list = signalledKey.pollEvents();
// VERY IMPORTANT! call reset() AFTER pollEvents() to allow the
// key to be reported again by the watch service
signalledKey.reset();
// we'll simply print what has happened; real applications
// will do something more sensible here
for (WatchEvent e : list) {
String message = "";
if (e.kind() == StandardWatchEventKind.ENTRY_CREATE) {
Path context = (Path) e.context();
oneWhoCares.fileCreated(context.toString());
message = context.toString() + " created";
} else if (e.kind() == StandardWatchEventKind.ENTRY_DELETE) {
Path context = (Path) e.context();
oneWhoCares.fileDeleted(context.toString());
message = context.toString() + " deleted";
} else if (e.kind() == StandardWatchEventKind.OVERFLOW) {
message = "OVERFLOW: more changes happened than we could retreive";
}
System.out.println(message);
System.out.flush();
}
}
//System.out.println("Watching stopped.");
}
}
public void stopWatching() {
if (watchService != null) {
try {
watchService.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
watchService = null;
}
/* Usage:
PathWatcher w = new PathWatcher();
w.startWatching("/SciSoft");
...
w.startWatching("/Temp");
...
w.stopWatching();
*/
// test...
static class Cares implements PathWatcherObserver {
@Override
public void fileCreated(String file) {
System.out.println("Created = " + file);
}
@Override
public void fileDeleted(String file) {
System.out.println("Deleted = " + file);
}
}
public static void main(String[] args) {
Cares cares = new Cares();
PathWatcher w = new PathWatcher(cares);
//w.simple();
System.out.println("watching /SciSoft...");
w.startWatching("/SciSoft", true);
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
}
System.out.println("watching /Temp...");
//w.stopWatching();
w.startWatching("/Temp", false);
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
}
w.stopWatching();
System.out.println("end");
}
}