Coverage Report - org.apache.commons.configuration.reloading.FileChangedReloadingStrategy
 
Classes in this File Line Coverage Branch Coverage Complexity
FileChangedReloadingStrategy
85%
40/47
78%
22/28
2,417
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 package org.apache.commons.configuration.reloading;
 19  
 
 20  
 import java.io.File;
 21  
 import java.net.MalformedURLException;
 22  
 import java.net.URL;
 23  
 
 24  
 import org.apache.commons.configuration.ConfigurationUtils;
 25  
 import org.apache.commons.configuration.FileConfiguration;
 26  
 import org.apache.commons.logging.Log;
 27  
 import org.apache.commons.logging.LogFactory;
 28  
 
 29  
 /**
 30  
  * <p>A reloading strategy that will reload the configuration every time its
 31  
  * underlying file is changed.</p>
 32  
  * <p>This reloading strategy does not actively monitor a configuration file,
 33  
  * but is triggered by its associated configuration whenever properties are
 34  
  * accessed. It then checks the configuration file's last modification date
 35  
  * and causes a reload if this has changed.</p>
 36  
  * <p>To avoid permanent disc access on successive property lookups a refresh
 37  
  * delay can be specified. This has the effect that the configuration file's
 38  
  * last modification date is only checked once in this delay period. The default
 39  
  * value for this refresh delay is 5 seconds.</p>
 40  
  * <p>This strategy only works with FileConfiguration instances.</p>
 41  
  *
 42  
  * @author Emmanuel Bourg
 43  
  * @version $Id: org.apache.commons.configuration.reloading.FileChangedReloadingStrategy.html 901807 2014-03-16 10:49:30Z oheger $
 44  
  * @since 1.1
 45  
  */
 46  96
 public class FileChangedReloadingStrategy implements ReloadingStrategy
 47  
 {
 48  
     /** Constant for the jar URL protocol.*/
 49  
     private static final String JAR_PROTOCOL = "jar";
 50  
 
 51  
     /** Constant for the default refresh delay.*/
 52  
     private static final int DEFAULT_REFRESH_DELAY = 5000;
 53  
 
 54  
     /** Stores a reference to the configuration to be monitored.*/
 55  
     protected FileConfiguration configuration;
 56  
 
 57  
     /** The last time the configuration file was modified. */
 58  
     protected long lastModified;
 59  
 
 60  
     /** The last time the file was checked for changes. */
 61  
     protected long lastChecked;
 62  
 
 63  
     /** The minimum delay in milliseconds between checks. */
 64  96
     protected long refreshDelay = DEFAULT_REFRESH_DELAY;
 65  
 
 66  
     /** A flag whether a reload is required.*/
 67  
     private boolean reloading;
 68  
 
 69  
     /** The Log to use for diagnostic messages */
 70  96
     private Log logger = LogFactory.getLog(FileChangedReloadingStrategy.class);
 71  
 
 72  
     public void setConfiguration(FileConfiguration configuration)
 73  
     {
 74  97
         this.configuration = configuration;
 75  97
     }
 76  
 
 77  
     public void init()
 78  
     {
 79  85
         updateLastModified();
 80  85
     }
 81  
 
 82  
     public boolean reloadingRequired()
 83  
     {
 84  412294
         if (!reloading)
 85  
         {
 86  412293
             long now = System.currentTimeMillis();
 87  
 
 88  412293
             if (now > lastChecked + refreshDelay)
 89  
             {
 90  70
                 lastChecked = now;
 91  70
                 if (hasChanged())
 92  
                 {
 93  10
                     if (logger.isDebugEnabled())
 94  
                     {
 95  0
                         logger.debug("File change detected: " + getName());
 96  
                     }
 97  10
                     reloading = true;
 98  
                 }
 99  
             }
 100  
         }
 101  
 
 102  412294
         return reloading;
 103  
     }
 104  
 
 105  
     public void reloadingPerformed()
 106  
     {
 107  13726
         updateLastModified();
 108  13738
     }
 109  
 
 110  
     /**
 111  
      * Return the minimal time in milliseconds between two reloadings.
 112  
      *
 113  
      * @return the refresh delay (in milliseconds)
 114  
      */
 115  
     public long getRefreshDelay()
 116  
     {
 117  18
         return refreshDelay;
 118  
     }
 119  
 
 120  
     /**
 121  
      * Set the minimal time between two reloadings.
 122  
      *
 123  
      * @param refreshDelay refresh delay in milliseconds
 124  
      */
 125  
     public void setRefreshDelay(long refreshDelay)
 126  
     {
 127  67
         this.refreshDelay = refreshDelay;
 128  67
     }
 129  
 
 130  
     /**
 131  
      * Update the last modified time.
 132  
      */
 133  
     protected void updateLastModified()
 134  
     {
 135  13114
         File file = getFile();
 136  13522
         if (file != null)
 137  
         {
 138  13719
             lastModified = file.lastModified();
 139  
         }
 140  13831
         reloading = false;
 141  13830
     }
 142  
 
 143  
     /**
 144  
      * Check if the configuration has changed since the last time it was loaded.
 145  
      *
 146  
      * @return a flag whether the configuration has changed
 147  
      */
 148  
     protected boolean hasChanged()
 149  
     {
 150  69
         File file = getFile();
 151  69
         if (file == null || !file.exists())
 152  
         {
 153  5
             if (logger.isWarnEnabled() && lastModified != 0)
 154  
             {
 155  1
                 logger.warn("File was deleted: " + getName(file));
 156  1
                 lastModified = 0;
 157  
             }
 158  5
             return false;
 159  
         }
 160  
 
 161  64
         return file.lastModified() > lastModified;
 162  
     }
 163  
 
 164  
     /**
 165  
      * Returns the file that is monitored by this strategy. Note that the return
 166  
      * value can be <b>null </b> under some circumstances.
 167  
      *
 168  
      * @return the monitored file
 169  
      */
 170  
     protected File getFile()
 171  
     {
 172  13062
         return (configuration.getURL() != null) ? fileFromURL(configuration
 173  
                 .getURL()) : configuration.getFile();
 174  
     }
 175  
 
 176  
     /**
 177  
      * Helper method for transforming a URL into a file object. This method
 178  
      * handles file: and jar: URLs.
 179  
      *
 180  
      * @param url the URL to be converted
 181  
      * @return the resulting file or <b>null </b>
 182  
      */
 183  
     private File fileFromURL(URL url)
 184  
     {
 185  13172
         if (JAR_PROTOCOL.equals(url.getProtocol()))
 186  
         {
 187  2
             String path = url.getPath();
 188  
             try
 189  
             {
 190  2
                 return ConfigurationUtils.fileFromURL(new URL(path.substring(0,
 191  
                         path.indexOf('!'))));
 192  
             }
 193  0
             catch (MalformedURLException mex)
 194  
             {
 195  0
                 return null;
 196  
             }
 197  
         }
 198  
         else
 199  
         {
 200  13632
             return ConfigurationUtils.fileFromURL(url);
 201  
         }
 202  
     }
 203  
 
 204  
     private String getName()
 205  
     {
 206  0
         return getName(getFile());
 207  
     }
 208  
 
 209  
     private String getName(File file)
 210  
     {
 211  1
         String name = configuration.getURL().toString();
 212  1
         if (name == null)
 213  
         {
 214  0
             if (file != null)
 215  
             {
 216  0
                 name = file.getAbsolutePath();
 217  
             }
 218  
             else
 219  
             {
 220  0
                 name = "base: " + configuration.getBasePath()
 221  
                        + "file: " + configuration.getFileName();
 222  
             }
 223  
         }
 224  1
         return name;
 225  
     }
 226  
 }