Coverage Report - org.mule.util.monitor.FileMonitor
 
Classes in this File Line Coverage Branch Coverage Complexity
FileMonitor
0%
0/33
0%
0/12
2.2
FileMonitor$FileMonitorNotifier
0%
0/26
0%
0/12
2.2
 
 1  
 /*
 2  
  * $Id: FileMonitor.java 7963 2007-08-21 08:53:15Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.util.monitor;
 12  
 
 13  
 import java.beans.ExceptionListener;
 14  
 import java.io.File;
 15  
 import java.io.IOException;
 16  
 import java.lang.ref.WeakReference;
 17  
 import java.util.ArrayList;
 18  
 import java.util.Collection;
 19  
 import java.util.HashMap;
 20  
 import java.util.Iterator;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 import java.util.Timer;
 24  
 import java.util.TimerTask;
 25  
 
 26  
 /**
 27  
  * Class for monitoring changes in disk files. Usage: 1. Implement the FileListener
 28  
  * interface. 2. Create a FileMonitor instance. 3. Add the file(s)/directory(ies) to
 29  
  * listen for. fileChanged() will be called when a monitored file is created, deleted
 30  
  * or its modified time changes.
 31  
  */
 32  0
 public class FileMonitor
 33  
 {
 34  
     private Timer timer;
 35  
     private Map files;
 36  
     private List listeners;
 37  
     private long pollingInterval;
 38  
 
 39  
     /**
 40  
      * Create a file monitor instance with specified polling interval.
 41  
      * 
 42  
      * @param pollingInterval Polling interval in milli seconds.
 43  
      */
 44  
     public FileMonitor(long pollingInterval)
 45  0
     {
 46  0
         files = new HashMap();
 47  0
         listeners = new ArrayList();
 48  0
         timer = new Timer(true);
 49  0
         this.pollingInterval = pollingInterval;
 50  0
     }
 51  
 
 52  
     /**
 53  
      * Stop the file monitor polling.
 54  
      */
 55  
     public void stop()
 56  
     {
 57  0
         timer.cancel();
 58  0
     }
 59  
 
 60  
     public void start()
 61  
     {
 62  0
         timer.schedule(new FileMonitorNotifier(), 0, pollingInterval);
 63  0
     }
 64  
 
 65  
     /**
 66  
      * Add file to listen for. File may be any java.io.File (including a directory)
 67  
      * and may well be a non-existing file in the case where the creating of the file
 68  
      * is to be trepped. <p/> More than one file can be listened for. When the
 69  
      * specified file is created, modified or deleted, listeners are notified.
 70  
      * 
 71  
      * @param file File to listen for.
 72  
      */
 73  
     public void addFile(File file)
 74  
     {
 75  0
         if (!files.containsKey(file))
 76  
         {
 77  0
             long modifiedTime = file.exists() ? file.lastModified() : -1;
 78  0
             files.put(file, new Long(modifiedTime));
 79  
         }
 80  0
     }
 81  
 
 82  
     /**
 83  
      * Remove specified file for listening.
 84  
      * 
 85  
      * @param file File to remove.
 86  
      */
 87  
     public void removeFile(File file)
 88  
     {
 89  0
         files.remove(file);
 90  0
     }
 91  
 
 92  
     /**
 93  
      * Add listener to this file monitor.
 94  
      * 
 95  
      * @param fileListener Listener to add.
 96  
      */
 97  
     public void addListener(FileListener fileListener)
 98  
     {
 99  
         // Don't add if its already there
 100  0
         for (Iterator i = listeners.iterator(); i.hasNext();)
 101  
         {
 102  0
             WeakReference reference = (WeakReference) i.next();
 103  0
             FileListener listener = (FileListener) reference.get();
 104  0
             if (listener == fileListener)
 105  
             {
 106  0
                 return;
 107  
             }
 108  0
         }
 109  
 
 110  
         // Use WeakReference to avoid memory leak if this becomes the
 111  
         // sole reference to the object.
 112  0
         listeners.add(new WeakReference(fileListener));
 113  0
     }
 114  
 
 115  
     /**
 116  
      * Remove listener from this file monitor.
 117  
      * 
 118  
      * @param fileListener Listener to remove.
 119  
      */
 120  
     public void removeListener(FileMonitor fileListener)
 121  
     {
 122  0
         for (Iterator i = listeners.iterator(); i.hasNext();)
 123  
         {
 124  0
             WeakReference reference = (WeakReference) i.next();
 125  0
             FileMonitor listener = (FileMonitor) reference.get();
 126  0
             if (listener == fileListener)
 127  
             {
 128  0
                 i.remove();
 129  0
                 break;
 130  
             }
 131  0
         }
 132  0
     }
 133  
 
 134  
     /**
 135  
      * This is the timer thread which is executed every n milliseconds according to
 136  
      * the setting of the file monitor.
 137  
      */
 138  
     public class FileMonitorNotifier extends TimerTask
 139  
     {
 140  
         private ExceptionListener exceptionListener;
 141  
 
 142  
         public FileMonitorNotifier()
 143  0
         {
 144  0
             super();
 145  0
         }
 146  
 
 147  
         public FileMonitorNotifier(ExceptionListener exceptionListener)
 148  0
         {
 149  0
             this.exceptionListener = exceptionListener;
 150  0
         }
 151  
 
 152  
         public void run()
 153  
         {
 154  
             // Loop over the registered files and see which have changed.
 155  
             // Use a copy of the list in case listener wants to alter the
 156  
             // list within its fileChanged method.
 157  0
             Collection fileKeys = new ArrayList(files.keySet());
 158  
 
 159  0
             for (Iterator i = fileKeys.iterator(); i.hasNext();)
 160  
             {
 161  0
                 File file = (File) i.next();
 162  0
                 long lastModifiedTime = ((Long) files.get(file)).longValue();
 163  0
                 long newModifiedTime = file.exists() ? file.lastModified() : -1;
 164  
 
 165  
                 // Chek if file has changed
 166  0
                 if (newModifiedTime != lastModifiedTime)
 167  
                 {
 168  
                     // Register new modified time
 169  0
                     files.put(file, new Long(newModifiedTime));
 170  
 
 171  
                     // Notify listeners
 172  0
                     for (Iterator j = listeners.iterator(); j.hasNext();)
 173  
                     {
 174  0
                         WeakReference reference = (WeakReference) j.next();
 175  0
                         FileListener listener = (FileListener) reference.get();
 176  
 
 177  
                         // Remove from list if the back-end object has been GC'd
 178  0
                         if (listener == null)
 179  
                         {
 180  0
                             j.remove();
 181  
                         }
 182  
                         else
 183  
                         {
 184  
                             try
 185  
                             {
 186  0
                                 listener.fileChanged(file);
 187  
                             }
 188  0
                             catch (IOException e)
 189  
                             {
 190  
                                 // TODO MULE-863: What should we do if null?
 191  0
                                 if (exceptionListener != null)
 192  
                                 {
 193  0
                                     exceptionListener.exceptionThrown(e);
 194  
                                 }
 195  0
                             }
 196  
                         }
 197  0
                     }
 198  
                 }
 199  0
             }
 200  0
         }
 201  
     }
 202  
 }