Coverage Report - org.mule.util.monitor.FileMonitor
 
Classes in this File Line Coverage Branch Coverage Complexity
FileMonitor
0%
0/32
0%
0/12
0
FileMonitor$FileMonitorNotifier
0%
0/25
0%
0/12
0
 
 1  
 /*
 2  
  * $Id: FileMonitor.java 19191 2010-08-25 21:05:23Z tcarlson $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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<File, Long> files;
 36  
     private List<WeakReference<FileListener>> 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<File, Long>();
 47  0
         listeners = new ArrayList<WeakReference<FileListener>>();
 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 (WeakReference<FileListener> reference : listeners)
 101  
         {
 102  0
             FileListener listener = reference.get();
 103  0
             if (listener == fileListener)
 104  
             {
 105  0
                 return;
 106  
             }
 107  0
         }
 108  
 
 109  
         // Use WeakReference to avoid memory leak if this becomes the
 110  
         // sole reference to the object.
 111  0
         listeners.add(new WeakReference<FileListener>(fileListener));
 112  0
     }
 113  
 
 114  
     /**
 115  
      * Remove listener from this file monitor.
 116  
      * 
 117  
      * @param fileListener Listener to remove.
 118  
      */
 119  
     public void removeListener(FileListener fileListener)
 120  
     {
 121  0
         for (Iterator<WeakReference<FileListener>> i = listeners.iterator(); i.hasNext();)
 122  
         {
 123  0
             WeakReference<FileListener> reference = i.next();
 124  0
             FileListener listener = reference.get();
 125  0
             if (listener == fileListener)
 126  
             {
 127  0
                 i.remove();
 128  0
                 break;
 129  
             }
 130  0
         }
 131  0
     }
 132  
 
 133  
     /**
 134  
      * This is the timer thread which is executed every n milliseconds according to
 135  
      * the setting of the file monitor.
 136  
      */
 137  
     public class FileMonitorNotifier extends TimerTask
 138  
     {
 139  
         private ExceptionListener exceptionListener;
 140  
 
 141  
         public FileMonitorNotifier()
 142  0
         {
 143  0
             super();
 144  0
         }
 145  
 
 146  
         public FileMonitorNotifier(ExceptionListener exceptionListener)
 147  0
         {
 148  0
             this.exceptionListener = exceptionListener;
 149  0
         }
 150  
 
 151  
         public void run()
 152  
         {
 153  
             // Loop over the registered files and see which have changed.
 154  
             // Use a copy of the list in case listener wants to alter the
 155  
             // list within its fileChanged method.
 156  0
             Collection<File> fileKeys = new ArrayList<File>(files.keySet());
 157  
 
 158  0
             for (File file : fileKeys)
 159  
             {
 160  0
                 long lastModifiedTime = files.get(file).longValue();
 161  0
                 long newModifiedTime = file.exists() ? file.lastModified() : -1;
 162  
 
 163  
                 // Chek if file has changed
 164  0
                 if (newModifiedTime != lastModifiedTime)
 165  
                 {
 166  
                     // Register new modified time
 167  0
                     files.put(file, new Long(newModifiedTime));
 168  
 
 169  
                     // Notify listeners
 170  0
                     for (Iterator<WeakReference<FileListener>> j = listeners.iterator(); j.hasNext();)
 171  
                     {
 172  0
                         WeakReference<FileListener> reference = j.next();
 173  0
                         FileListener listener = reference.get();
 174  
 
 175  
                         // Remove from list if the back-end object has been GC'd
 176  0
                         if (listener == null)
 177  
                         {
 178  0
                             j.remove();
 179  
                         }
 180  
                         else
 181  
                         {
 182  
                             try
 183  
                             {
 184  0
                                 listener.fileChanged(file);
 185  
                             }
 186  0
                             catch (IOException e)
 187  
                             {
 188  
                                 // TODO MULE-863: What should we do if null?
 189  0
                                 if (exceptionListener != null)
 190  
                                 {
 191  0
                                     exceptionListener.exceptionThrown(e);
 192  
                                 }
 193  0
                             }
 194  
                         }
 195  0
                     }
 196  
                 }
 197  0
             }
 198  0
         }
 199  
     }
 200  
 }