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