001: package org.enhydra.dm.util.filesys;
002:
003: import java.io.File;
004: import java.io.FileNotFoundException;
005: import java.net.URL;
006: import java.util.Hashtable;
007: import java.util.Timer;
008: import java.util.TimerTask;
009:
010: import org.enhydra.dm.api.util.filesys.FileChangeListener;
011:
012: public class FileMonitor {
013:
014: private static final FileMonitor instance = new FileMonitor();
015:
016: private Timer timer;
017:
018: private Hashtable timerEntries;
019:
020: public static FileMonitor getInstance() {
021: return instance;
022: }
023:
024: protected FileMonitor() {
025: // Create timer, run timer thread as daemon.
026: timer = new Timer(true);
027: timerEntries = new Hashtable();
028: }
029:
030: /**
031: * Associate a monitored file with a FileChangeListener.
032: *
033: * @param listener - listener to notify when the file changed.
034: * @param fileName - name of the file to monitor.
035: * @param period - polling period in milliseconds.
036: */
037: public void addFileChangeListener(FileChangeListener listener,
038: String fileName, long period) throws FileNotFoundException {
039: removeFileChangeListener(listener, fileName);
040: FileMonitorTask task = new FileMonitorTask(listener, fileName);
041: timerEntries.put(fileName + listener.hashCode(), task);
042: timer.schedule(task, period, period);
043: }
044:
045: /**
046: * Remove the listener from the notification list.
047: *
048: * @param listener the listener to be removed.
049: */
050: public void removeFileChangeListener(FileChangeListener listener,
051: String fileName) {
052: FileMonitorTask task = (FileMonitorTask) timerEntries
053: .remove(fileName + listener.hashCode());
054: if (task != null) {
055: task.cancel();
056: }
057: }
058:
059: protected void fireFileChangeEvent(FileChangeListener listener,
060: String fileName) {
061: listener.fileChanged(fileName);
062: }
063:
064: class FileMonitorTask extends TimerTask {
065: FileChangeListener listener;
066:
067: String fileName;
068:
069: File monitoredFile;
070:
071: long lastModified;
072:
073: public FileMonitorTask(FileChangeListener listener,
074: String fileName) throws FileNotFoundException {
075: this .listener = listener;
076: this .fileName = fileName;
077: this .lastModified = 0;
078:
079: monitoredFile = new File(fileName);
080: if (!monitoredFile.exists()) { // but is it on CLASSPATH?
081: URL fileURL = listener.getClass().getClassLoader()
082: .getResource(fileName);
083: if (fileURL != null) {
084: monitoredFile = new File(fileURL.getFile());
085: } else {
086: throw new FileNotFoundException("File Not Found: "
087: + fileName);
088: }
089: }
090: this .lastModified = monitoredFile.lastModified();
091: }
092:
093: public void run() {
094: long lastModified = monitoredFile.lastModified();
095: if (lastModified != this.lastModified) {
096: this.lastModified = lastModified;
097: fireFileChangeEvent(this.listener, this.fileName);
098: }
099: }
100: }
101: }
|