Clover coverage report -
Coverage timestamp: Fri Nov 19 2004 13:41:51 PST
file stats: LOC: 185   Methods: 15
NCLOC: 149   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
FileSystemWatcher.java 71.4% 81.4% 80% 78.4%
coverage coverage
 1    package photospace.vfs.event;
 2   
 3    import java.io.*;
 4    import java.util.*;
 5    import org.apache.commons.logging.*;
 6   
 7    public class FileSystemWatcher
 8    implements Runnable
 9    {
 10    private static final Log log = LogFactory.getLog(FileSystemWatcher.class);
 11   
 12    private Set roots = new HashSet();
 13    private Set listeners = new HashSet();
 14    private Map snapshot = new HashMap();
 15    private FileFilter filter;
 16    private int sleep = 100;
 17    private Thread watcher;
 18    private boolean running = false;
 19   
 20  1 public void addListener(FileEventListener listener) throws IOException
 21    {
 22  1 listeners.add(listener);
 23    }
 24   
 25  1 public void addRoot(File file) throws IOException
 26    {
 27  0 if (!file.exists()) throw new IllegalArgumentException(file + " does not exist");
 28  1 roots.add(file.getCanonicalFile());
 29    }
 30   
 31  0 public void setRoots(List roots) throws IOException
 32    {
 33  0 this.roots = new HashSet();
 34  0 for (Iterator i = roots.iterator(); i.hasNext();)
 35    {
 36  0 addRoot((File) i.next());
 37    }
 38    }
 39   
 40  0 public void setListeners(List listeners) throws IOException
 41    {
 42  0 this.listeners = new HashSet();
 43  0 for (Iterator i = listeners.iterator(); i.hasNext();)
 44    {
 45  0 addListener((FileEventListener) i.next());
 46    }
 47    }
 48   
 49  1 public void setFilter(FileFilter filter)
 50    {
 51  1 this.filter = filter;
 52    }
 53   
 54  1 public void start()
 55    {
 56  1 log.info("Starting watching " + roots.size() + " filesystems: " + roots);
 57   
 58  1 watcher = new Thread(this);
 59  1 watcher.setPriority(Thread.MIN_PRIORITY);
 60  1 running = true;
 61  1 watcher.start();
 62    }
 63   
 64  0 public void destroy()
 65    {
 66  0 running = false;
 67    }
 68   
 69  1 public void run()
 70    {
 71  1 sleep(sleep);
 72   
 73  1 snapshot = createSnapshot(new ArrayList(roots));
 74   
 75  50 while (running)
 76    {
 77  50 sleep(sleep);
 78   
 79  49 try
 80    {
 81  49 lookForChanges(new ArrayList(roots));
 82   
 83  49 for (Iterator i = new ArrayList(snapshot.keySet()).iterator(); i.hasNext();)
 84    {
 85  85 File file = (File) i.next();
 86  85 if (!file.exists())
 87    {
 88  1 fireEvent(new FileEvent(FileEvent.DELETED, file));
 89  1 snapshot.remove(file);
 90    }
 91    }
 92    }
 93    catch (Exception e)
 94    {
 95  0 log.error("Exception watching filesystem. Sleeping for 30 seconds...", e);
 96  0 sleep(30 * 1000);
 97    }
 98    }
 99    }
 100   
 101  51 private synchronized void sleep(int milliseconds)
 102    {
 103   
 104  51 try { wait(milliseconds); }
 105    //try { Thread.sleep(milliseconds); }
 106    catch (InterruptedException e) { }
 107    }
 108   
 109    /**
 110    * Creates a snapshot of the files in the provided file system roots.
 111    * The snapshot is a Map of File objects to their lastModified date
 112    * as of the time the snapshot was taken.
 113    * @param roots
 114    * @return
 115    */
 116  1 public Map createSnapshot(List roots)
 117    {
 118  1 Map snapshot = new HashMap();
 119  1 collect((File[]) roots.toArray(new File[] {}), snapshot);
 120  1 return snapshot;
 121    }
 122   
 123  2 private void collect(File[] from, Map to)
 124    {
 125  2 for (int i = 0; i < from.length; i++)
 126    {
 127  1 File file = from[i];
 128  1 if (!to.containsKey(file))
 129    {
 130  1 to.put(file, new Long(file.lastModified()));
 131    }
 132   
 133  1 if (file.isDirectory()) collect(file.listFiles(filter), to);
 134    }
 135    }
 136   
 137   
 138  120 private void lookForChanges(List files)
 139    {
 140  120 for (Iterator i = files.iterator(); i.hasNext();)
 141    {
 142  84 File file = (File) i.next();
 143  84 if (!snapshot.containsKey(file))
 144    {
 145  2 fireEvent(new FileEvent(FileEvent.CREATED, file));
 146  2 snapshot.put(file, new Long(file.lastModified()));
 147    }
 148  82 else if (file.lastModified() > ((Long) snapshot.get(file)).longValue())
 149    {
 150  4 fireEvent(new FileEvent(FileEvent.UPDATED, file));
 151  4 snapshot.put(file, new Long(file.lastModified()));
 152    }
 153   
 154  71 if (file.isDirectory()) lookForChanges(Arrays.asList(file.listFiles(filter)));
 155    }
 156    }
 157   
 158  7 private void fireEvent(FileEvent event)
 159    {
 160  7 log.debug(event);
 161   
 162  7 for (Iterator j = listeners.iterator(); j.hasNext();)
 163    {
 164  7 FileEventListener listener = (FileEventListener) j.next();
 165  7 try
 166    {
 167  7 listener.handleFileEvent(event);
 168    }
 169    catch (Throwable t)
 170    {
 171  0 log.error(listener + " threw an exception handling " + event, t);
 172    }
 173    }
 174    }
 175   
 176  1 public void setSleep(int sleep)
 177    {
 178  1 this.sleep = sleep;
 179    }
 180   
 181  3 public Map getSnapshot()
 182    {
 183  3 return snapshot;
 184    }
 185    }