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