001: package org.jzonic.jlo;
002:
003: import org.jzonic.jlo.events.FileListener;
004: import org.jzonic.jlo.events.FileListenerEvent;
005:
006: import java.io.File;
007: import java.util.HashMap;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.Vector;
011:
012: /**
013: * A class which implements an event dispatching mechanism to all
014: * classes supporting the FileListener interface. This class will
015: * notify all FileListeners when the configuration changes. Once
016: * the FileWatcher has been shutdown, the class needs to be
017: * reinstanciated and restarted.
018: *
019: * @author Andreas Mecky <andreas.mecky@xcom.de>
020: * @author Terry R. Dye <terry.dye@xcom.de>
021: */
022: public class FileWatcher extends Thread {
023:
024: private HashMap fileMap;
025: private HashMap fileListenerList;
026: private HashMap configMap;
027: private volatile Thread watcher;
028: private int interval = 1000;
029: private boolean running = true;
030:
031: /**
032: * Creates a new instance of FileWatcher by calling the FileWatcher( File )
033: * Constructor.
034: *
035: * @param filename A String representing the path to the file to be watched.
036: */
037: public FileWatcher() {
038: fileMap = new HashMap();
039: configMap = new HashMap();
040: fileListenerList = new HashMap();
041: setDaemon(true);
042: start();
043: }
044:
045: public void addFile(String fileName) {
046: File file = new File(fileName);
047: if (file.exists()) {
048: long lastModified = file.lastModified();
049: fileMap.put(fileName, new Long(lastModified));
050: }
051: }
052:
053: /**
054: * Adds FileListener
055: *
056: * @param fileListener The FileListener
057: */
058: public void addFileListener(FileListener fileListener,
059: String configurationName) {
060: if (!configMap.containsValue(configurationName)) {
061: List all = (List) fileListenerList.get(configurationName);
062: if (all == null) {
063: all = new Vector();
064: }
065: all.add(fileListener);
066: fileListenerList.put(configurationName, all);
067: String fn = configurationName;
068: if (configurationName.equals("Default")) {
069: fn = "jlo_logging.xml";
070: } else {
071: fn += "_logging.xml";
072: }
073: ClassLoader cl = getClass().getClassLoader();
074: java.net.URL url = cl.getResource(fn);
075: if (url != null) {
076: File file = new File(url.getFile());
077: addFile(file.getAbsolutePath());
078: configMap.put(file, configurationName);
079: }
080: }
081: }
082:
083: /**
084: * Set the timer interval. The default is 10 seconds
085: *
086: * @param seconds The number of seconds to set the interval when
087: * to check for the changes to the file.
088: */
089: public void setInterval(int seconds) {
090: this .interval = seconds * 1000;
091: }
092:
093: /**
094: * Tell thread to stop watching. Currently once a Thread is started
095: * and stopped, a new FileWatcher will be required.
096: */
097: public void stopWatching() {
098: this .watcher = null;
099: }
100:
101: /**
102: * Start the Thread on its journey to scan for changes to the
103: * file it is watching.
104: */
105: public void start() {
106: watcher = new Thread(this );
107: watcher.setDaemon(true);
108: watcher.start();
109: }
110:
111: /**
112: * Start the thread to call checkFile()
113: */
114: public void run() {
115: Thread this Thread = Thread.currentThread();
116: //while (thisThread == watcher) {
117: while (running) {
118: try {
119: Thread.sleep(interval);
120: } catch (InterruptedException e) {
121: // can't do much from here with Exception
122: watcher = null;
123: }
124: Iterator it = fileMap.keySet().iterator();
125: while (it.hasNext()) {
126: String fileName = (String) it.next();
127: long lastModified = ((Long) fileMap.get(fileName))
128: .longValue();
129: lastModified = checkFile(fileName, lastModified);
130: fileMap.put(fileName, new Long(lastModified));
131: }
132: }
133: }
134:
135: /**
136: * Retrieve an array of FileListeners.
137: *
138: * @return FileListeners as array of FileListener
139: */
140: public FileListener[] getFileListeners() {
141: //return (FileListener[])fileListenerList.toArray();
142: //FIXME: fix the bug and get all listeners
143: return null;
144: }
145:
146: private long checkFile(String fileName, long lm) {
147: File newFile = new File(fileName);
148: if (newFile.lastModified() > lm) {
149: lm = newFile.lastModified();
150: String configName = (String) configMap.get(newFile);
151: List all = (List) fileListenerList.get(configName);
152: Iterator iterator = all.iterator();
153: while (iterator.hasNext()) {
154: FileListener listener = (FileListener) iterator.next();
155: listener.fileChanged(new FileListenerEvent(newFile,
156: configName));
157: }
158: }
159: return lm;
160: }
161: }
|