001: /* FileWatchdog.java
002:
003: {{IS_NOTE
004:
005: Purpose:
006: Description:
007: History:
008: 2001/7/25, Tom M. Yeh: Created.
009:
010: }}IS_NOTE
011:
012: Copyright (C) 2001 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.io;
020:
021: import java.io.File;
022:
023: import org.zkoss.mesg.MCommon;
024: import org.zkoss.lang.Threads;
025: import org.zkoss.util.logging.Log;
026:
027: /**
028: * File modification monitor thread. It monitors a gving file in a lowest
029: * priority thread. Then, if it detects any modification, invokes
030: * a giving interface. Note: Callback.onModified is at least called once.
031: *
032: * <p>Caller has to implement the FileWatchdog.Callback interface. Then,<br>
033: * new FileWatchdog(filename, 30000, callback).start();
034: *
035: * <p>This class is extended from Thread, so you could manipulate it as
036: * a normal thread, such as interrupt, suspend, and change priority.
037: *
038: * <p>The watchdog executes at the lowest priority, so it won't affect
039: * much of the system performance.
040: *
041: * @author tomyeh
042: */
043: public class FileWatchdog extends Thread {
044: private static final Log log = Log.lookup(FileWatchdog.class);
045:
046: /** The interface to implement when using a FileWatchdog. */
047: public interface Callback {
048: /** Callbacks when the file is modified.
049: *
050: * @param file the file being monitored
051: */
052: public void onModified(File file) throws Exception;
053: }
054:
055: private File _file;
056: private Callback _callback;
057: private long _delay;
058: private long _lastModified = 0;
059: private boolean _warnedAlready = false;
060: private boolean _ceased = false;
061:
062: /** Constructor.
063: * @param file the file
064: * @param delay the delay in milliseconds to wait between each check
065: * @param callback the callback
066: */
067: public FileWatchdog(File file, long delay, Callback callback) {
068: setup(file, delay, callback);
069: }
070:
071: /** Constructor.
072: * @param filename the filename
073: * @param delay the delay in milliseconds to wait between each check
074: * @param callback the callback
075: */
076: public FileWatchdog(String filename, long delay, Callback callback) {
077: if (filename == null)
078: throw new IllegalArgumentException("null");
079: setup(new File(filename), delay, callback);
080: }
081:
082: private void setup(File file, long delay, Callback callback) {
083: if (file == null || callback == null)
084: throw new IllegalArgumentException("null");
085:
086: _file = file;
087: _delay = delay;
088: _callback = callback;
089:
090: Threads.setPriority(this , Thread.MIN_PRIORITY);
091: Threads.setDaemon(this , true);
092: }
093:
094: //-- Thread --//
095: public void start() {
096: _ceased = false;
097: super .start();
098: }
099:
100: /** Stops the thread. */
101: public void cease() {
102: _ceased = true;
103: }
104:
105: public void run() {
106: do {
107: try {
108: if (_file.exists()) {
109: long l = _file.lastModified();
110: if (l > _lastModified) {
111: if (!_ceased && log.debugable())
112: log.debug(_file + " modified: " + l
113: + " vs " + _lastModified);
114:
115: _lastModified = l;
116: _warnedAlready = false;
117: if (!_ceased)
118: _callback.onModified(_file);
119: }
120: } else if (!_warnedAlready) {
121: if (!_ceased)
122: log.debug(MCommon.FILE_NOT_FOUND, _file
123: .getPath());
124: _warnedAlready = true;
125: }
126: } catch (Exception ex) {
127: if (!_ceased)
128: log.warning(MCommon.FILE_READ_FAILED, _file, ex);
129: return; //no point in continuing
130: }
131:
132: try {
133: if (!_ceased)
134: sleep(_delay);
135: } catch (InterruptedException ex) {
136: System.out.println("The file watchdog is interrupted");
137: break; //interrupted
138: }
139: } while (!_ceased);
140:
141: System.out.println(Thread.currentThread().getName()
142: + ": the file watchdog stops");
143: //Don't use log because LogService depends on it
144: }
145: }
|