|
|||||||||||||||||||
| Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
| FileWatcher.java | 37,5% | 53,6% | 45,5% | 48,9% |
|
||||||||||||||
| 1 | /* | |
| 2 | * $Id: FileWatcher.java,v 1.6 2004/08/03 09:01:05 amecky Exp $ | |
| 3 | * | |
| 4 | * FileWatcher.java | |
| 5 | * | |
| 6 | * Created on 26. Juni 2002, 12:12 | |
| 7 | */ | |
| 8 | ||
| 9 | package org.jconfig; | |
| 10 | ||
| 11 | import java.io.File; | |
| 12 | import java.util.Iterator; | |
| 13 | import java.util.List; | |
| 14 | import java.util.Vector; | |
| 15 | ||
| 16 | import org.jconfig.event.FileListener; | |
| 17 | import org.jconfig.event.FileListenerEvent; | |
| 18 | /** | |
| 19 | * A class which implements an event dispatching mechanism to all | |
| 20 | * classes supporting the FileListener interface. This class will | |
| 21 | * notify all FileListeners when the configuration changes. Once | |
| 22 | * the FileWatcher has been shutdown, the class needs to be | |
| 23 | * reinstanciated and restarted. | |
| 24 | * | |
| 25 | * @author Andreas Mecky <andreas.mecky@xcom.de> | |
| 26 | * @author Terry R. Dye <terry.dye@xcom.de> | |
| 27 | */ | |
| 28 | public class FileWatcher extends Thread { | |
| 29 | ||
| 30 | private File file; | |
| 31 | private List fileListenerList; | |
| 32 | private volatile Thread watcher; | |
| 33 | // check every two minutes | |
| 34 | private int interval = 2*1000; | |
| 35 | private long lastmodified; | |
| 36 | ||
| 37 | /** | |
| 38 | * Creates a new instance of FileWatcher by calling the FileWatcher( File ) | |
| 39 | * Constructor. | |
| 40 | * | |
| 41 | * @param filename A String representing the path to the file to be watched. | |
| 42 | */ | |
| 43 | 0 | public FileWatcher( String filename ) { |
| 44 | 0 | this( new File( filename ) ); |
| 45 | } | |
| 46 | ||
| 47 | /** | |
| 48 | * Constructs a FileWatcher watching the specified File | |
| 49 | * | |
| 50 | * @param file The File to be watched | |
| 51 | */ | |
| 52 | 37 | public FileWatcher( File file ) { |
| 53 | 37 | if( file == null ) { |
| 54 | 0 | throw new NullPointerException("File cannot be <null>"); |
| 55 | } | |
| 56 | 37 | this.file = file; |
| 57 | 37 | this.lastmodified = file.lastModified(); |
| 58 | 37 | this.fileListenerList = new Vector(); |
| 59 | } | |
| 60 | ||
| 61 | /** | |
| 62 | * Adds FileListener | |
| 63 | * | |
| 64 | * @param fileListener The FileListener | |
| 65 | */ | |
| 66 | 37 | public void addFileListener( FileListener fileListener ) { |
| 67 | 37 | fileListenerList.add( fileListener ); |
| 68 | } | |
| 69 | ||
| 70 | /** | |
| 71 | * Set the timer interval. The default is 10 seconds | |
| 72 | * | |
| 73 | * @param seconds The number of seconds to set the interval when | |
| 74 | * to check for the changes to the file. | |
| 75 | */ | |
| 76 | 0 | public void setInterval( int seconds ) { |
| 77 | 0 | this.interval = seconds*1000; |
| 78 | } | |
| 79 | ||
| 80 | /** | |
| 81 | * Tell thread to stop watching. Currently once a Thread is started | |
| 82 | * and stopped, a new FileWatcher will be required. | |
| 83 | */ | |
| 84 | 0 | public void stopWatching() { |
| 85 | 0 | this.watcher = null; |
| 86 | } | |
| 87 | ||
| 88 | /** | |
| 89 | * Start the Thread on its journey to scan for changes to the | |
| 90 | * file it is watching. | |
| 91 | */ | |
| 92 | 37 | public void start() { |
| 93 | 37 | watcher = new Thread( this ); |
| 94 | 37 | watcher.setDaemon(true); |
| 95 | 37 | watcher.start(); |
| 96 | } | |
| 97 | ||
| 98 | /** | |
| 99 | * Start the thread to call checkFile() | |
| 100 | */ | |
| 101 | 37 | public void run() { |
| 102 | 37 | Thread thisThread = Thread.currentThread(); |
| 103 | 45 | while (thisThread == watcher) { |
| 104 | 45 | try { |
| 105 | 45 | Thread.sleep(interval); |
| 106 | } catch (InterruptedException e){ | |
| 107 | // can't do much from here with Exception | |
| 108 | 0 | watcher = null; |
| 109 | } | |
| 110 | 8 | checkFile(); |
| 111 | } | |
| 112 | } | |
| 113 | ||
| 114 | /** | |
| 115 | * Retrieve an array of FileListeners. | |
| 116 | * | |
| 117 | * @return FileListeners as array of FileListener | |
| 118 | */ | |
| 119 | 0 | public FileListener[] getFileListeners() { |
| 120 | 0 | return (FileListener[])fileListenerList.toArray(); |
| 121 | } | |
| 122 | ||
| 123 | /* allows us to update the File object, in case we need to. */ | |
| 124 | /** | |
| 125 | * Sets a new File to be watched. This causes the FileWatcher to watch | |
| 126 | * the given File and disregard the File that was used during Construction. | |
| 127 | * | |
| 128 | * @param file The File to be watched | |
| 129 | */ | |
| 130 | 0 | public void setFile( File file ) { |
| 131 | 0 | this.file = file; |
| 132 | } | |
| 133 | ||
| 134 | /* looks at the internal FileListenerList and keeps track of changed info */ | |
| 135 | 8 | private void checkFile() { |
| 136 | 8 | File newFile = file; |
| 137 | 8 | if( newFile.lastModified() > lastmodified ) { |
| 138 | 0 | lastmodified = newFile.lastModified(); |
| 139 | 0 | Iterator iterator = fileListenerList.iterator(); |
| 140 | 0 | while( iterator.hasNext() ) { |
| 141 | 0 | FileListener listener = (FileListener)iterator.next(); |
| 142 | 0 | listener.fileChanged( new FileListenerEvent( newFile ) ); |
| 143 | } | |
| 144 | } | |
| 145 | } | |
| 146 | ||
| 147 | /** | |
| 148 | * Used to test it all | |
| 149 | * | |
| 150 | * @param args None required | |
| 151 | */ | |
| 152 | 0 | public static void main( String args[] ) { |
| 153 | 0 | new FileWatcher( "config.xml" ).start(); |
| 154 | } | |
| 155 | } | |
| 156 | ||
| 157 | /** | |
| 158 | * $Log: FileWatcher.java,v $ | |
| 159 | * Revision 1.6 2004/08/03 09:01:05 amecky | |
| 160 | * *** empty log message *** | |
| 161 | * | |
| 162 | * Revision 1.5 2004/01/27 10:41:37 amecky | |
| 163 | * *** empty log message *** | |
| 164 | * | |
| 165 | * Revision 1.4 2003/07/03 19:45:49 terrydye | |
| 166 | * Parameter checking by FileWatcher constructor. | |
| 167 | * | |
| 168 | * Revision 1.3 2003/07/01 06:54:42 amecky | |
| 169 | * *** empty log message *** | |
| 170 | * | |
| 171 | * Revision 1.2 2003/04/16 20:27:25 terrydye | |
| 172 | * merge from private cvs repository | |
| 173 | * | |
| 174 | * Revision 1.7 2003/02/21 12:43:37 Andreas.Mecky | |
| 175 | * *** empty log message *** | |
| 176 | * | |
| 177 | * Revision 1.6 2002/08/13 15:17:46 Terry.Dye | |
| 178 | * no message | |
| 179 | * | |
| 180 | * Revision 1.5 2002/08/07 15:18:17 Andreas.Mecky | |
| 181 | * no message | |
| 182 | * | |
| 183 | * Revision 1.4 2002/07/05 14:25:09 Terry.Dye | |
| 184 | * Daily changes | |
| 185 | * | |
| 186 | * Revision 1.3 2002/07/01 08:13:58 Terry.Dye | |
| 187 | * *** empty log message *** | |
| 188 | * | |
| 189 | * Revision 1.2 2002/06/28 09:53:25 Terry.Dye | |
| 190 | * Example updated to shutdown thread properly/safely. | |
| 191 | * | |
| 192 | * Revision 1.1 2002/06/26 16:12:43 Terry.Dye | |
| 193 | * Created | |
| 194 | * | |
| 195 | */ |
|
||||||||||