001/*
002 * $Id: FileWatcher.java,v 1.6 2002/08/13 15:17:46 Terry.Dye Exp $
003 *
004 * FileWatcher.java
005 *
006 * Created on 26. Juni 2002, 12:12
007 */
008
009package org.jconfig;
010
011import org.jconfig.event.FileListener;
012import org.jconfig.event.FileListenerEvent;
013
014import java.io.File;
015
016import java.lang.Thread;
017
018import java.util.Iterator;
019import java.util.List;
020import java.util.Vector;
021/**
022 * A class which implements an event dispatching mechanism to all
023 * classes supporting the FileListener interface. This class will
024 * notify all FileListeners when the configuration changes. Once
025 * the FileWatcher has been shutdown, the class needs to be
026 * reinstanciated and restarted.
027 *
028 * @author Andreas Mecky <andreas.mecky@xcom.de>
029 * @author Terry R. Dye <terry.dye@xcom.de>
030 */
031public class FileWatcher extends Thread {
032
033    private File file;
034    private List fileListenerList;
035    private volatile Thread watcher;
036    private int interval = 10000;
037    private long lastmodified;
038
039    /**
040     * Creates a new instance of FileWatcher by calling the FileWatcher( File )
041     * Constructor.
042     *
043     * @param filename A String representing the path to the file to be watched.
044     */
045    public FileWatcher( String filename ) {
046        this( new File( filename ) );
047    }
048
049    /**
050     * Constructs a FileWatcher watching the specified File
051     *
052     * @param file The File to be watched
053     */
054    public FileWatcher( File file ) {
055        this.file = file;
056        this.lastmodified = file.lastModified();
057        this.fileListenerList = new Vector();
058    }
059
060    /**
061     * Adds FileListener
062     *
063     * @param fileListener The FileListener
064     */
065    public void addFileListener( FileListener fileListener ) {
066        fileListenerList.add( fileListener );
067    }
068
069    /**
070     * Set the timer interval. The default is 10 seconds
071     *
072     * @param seconds The number of seconds to set the interval when
073     * to check for the changes to the file.
074     */
075    public void setInterval( int seconds ) {
076        this.interval = seconds*1000;
077    }
078
079    /**
080     * Tell thread to stop watching. Currently once a Thread is started
081     * and stopped, a new FileWatcher will be required.
082     */
083    public void stopWatching() {
084        this.watcher = null;
085    }
086    
087    /**
088     * Start the Thread on its journey to scan for changes to the 
089     * file it is watching.
090     */
091    public void start() {
092        watcher = new Thread( this );
093        watcher.start();
094    }
095
096    /** 
097     * Start the thread to call checkFile() 
098     */
099    public void run() {
100        Thread thisThread = Thread.currentThread();
101        while (thisThread == watcher) {
102            try {
103                watcher.sleep(interval);
104            } catch (InterruptedException e){
105                // can't do much from here with Exception
106                watcher = null;
107            }
108            checkFile();
109        }
110    }
111    
112    /**
113     * Retrieve an array of FileListeners.
114     *
115     * @return FileListeners as array of FileListener
116     */
117    public FileListener[] getFileListeners() {
118        return (FileListener[])fileListenerList.toArray();
119    }
120    
121    /* allows us to update the File object, in case we need to. */
122    /**
123     * Sets a new File to be watched. This causes the FileWatcher to watch
124     * the given File and disregard the File that was used during Construction.
125     *
126     * @param file The File to be watched
127     */    
128    public void setFile( File file ) {
129        this.file = file;
130    }
131    
132    /* looks at the internal FileListenerList and keeps track of changed info */
133    private void checkFile() {
134        File newFile = file;
135        if( newFile.lastModified() > lastmodified ) {
136            lastmodified = newFile.lastModified();
137            Iterator iterator = fileListenerList.iterator();
138            while( iterator.hasNext() ) {
139                FileListener listener = (FileListener)iterator.next();
140                listener.fileChanged( new FileListenerEvent( newFile ) );
141            }
142        }
143    }
144    
145    /** 
146     * Used to test it all
147     *
148     * @param args None required
149     */
150    public static void main( String args[] ) {
151        new FileWatcher( "config.xml" ).start();
152    }
153}
154
155/**
156 * $Log: FileWatcher.java,v $
157 * Revision 1.6  2002/08/13 15:17:46  Terry.Dye
158 * no message
159 *
160 * Revision 1.5  2002/08/07 15:18:17  Andreas.Mecky
161 * no message
162 *
163 * Revision 1.4  2002/07/05 14:25:09  Terry.Dye
164 * Daily changes
165 *
166 * Revision 1.3  2002/07/01 08:13:58  Terry.Dye
167 * *** empty log message ***
168 *
169 * Revision 1.2  2002/06/28 09:53:25  Terry.Dye
170 * Example updated to shutdown thread properly/safely.
171 *
172 * Revision 1.1  2002/06/26 16:12:43  Terry.Dye
173 * Created
174 *
175 */