View Javadoc

    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
    27  /***
    28   * <p>A reloading strategy that will reload the configuration every time its
    29   * underlying file is changed.</p>
    30   * <p>This reloading strategy does not actively monitor a configuration file,
    31   * but is triggered by its associated configuration whenever properties are
    32   * accessed. It then checks the configuration file's last modification date
    33   * and causes a reload if this has changed.</p>
    34   * <p>To avoid permanent disc access on successive property lookups a refresh
    35   * delay can be specified. This has the effect that the configuration file's
    36   * last modification date is only checked once in this delay period. The default
    37   * value for this refresh delay is 5 seconds.</p>
    38   * <p>This strategy only works with FileConfiguration instances.</p>
    39   *
    40   * @author Emmanuel Bourg
    41   * @version $Revision: 439648 $, $Date: 2006-09-02 22:42:10 +0200 (Sa, 02 Sep 2006) $
    42   * @since 1.1
    43   */
    44  public class FileChangedReloadingStrategy implements ReloadingStrategy
    45  {
    46      /*** Constant for the jar URL protocol.*/
    47      private static final String JAR_PROTOCOL = "jar";
    48
    49      /*** Constant for the default refresh delay.*/
    50      private static final int DEFAULT_REFRESH_DELAY = 5000;
    51
    52      /*** Stores a reference to the configuration to be monitored.*/
    53      protected FileConfiguration configuration;
    54
    55      /*** The last time the configuration file was modified. */
    56      protected long lastModified;
    57
    58      /*** The last time the file was checked for changes. */
    59      protected long lastChecked;
    60
    61      /*** The minimum delay in milliseconds between checks. */
    62      protected long refreshDelay = DEFAULT_REFRESH_DELAY;
    63
    64      public void setConfiguration(FileConfiguration configuration)
    65      {
    66          this.configuration = configuration;
    67      }
    68
    69      public void init()
    70      {
    71          updateLastModified();
    72      }
    73
    74      public boolean reloadingRequired()
    75      {
    76          boolean reloading = false;
    77
    78          long now = System.currentTimeMillis();
    79
    80          if (now > lastChecked + refreshDelay)
    81          {
    82              lastChecked = now;
    83              if (hasChanged())
    84              {
    85                  reloading = true;
    86              }
    87          }
    88
    89          return reloading;
    90      }
    91
    92      public void reloadingPerformed()
    93      {
    94          updateLastModified();
    95      }
    96
    97      /***
    98       * Return the minimal time in milliseconds between two reloadings.
    99       *
    100      * @return the refresh delay (in milliseconds)
    101      */
    102     public long getRefreshDelay()
    103     {
    104         return refreshDelay;
    105     }
    106
    107     /***
    108      * Set the minimal time between two reloadings.
    109      *
    110      * @param refreshDelay refresh delay in milliseconds
    111      */
    112     public void setRefreshDelay(long refreshDelay)
    113     {
    114         this.refreshDelay = refreshDelay;
    115     }
    116
    117     /***
    118      * Update the last modified time.
    119      */
    120     protected void updateLastModified()
    121     {
    122         File file = getFile();
    123         if (file != null)
    124         {
    125             lastModified = file.lastModified();
    126         }
    127     }
    128
    129     /***
    130      * Check if the configuration has changed since the last time it was loaded.
    131      *
    132      * @return a flag whether the configuration has changed
    133      */
    134     protected boolean hasChanged()
    135     {
    136         File file = getFile();
    137         if (file == null || !file.exists())
    138         {
    139             return false;
    140         }
    141
    142         return file.lastModified() > lastModified;
    143     }
    144
    145     /***
    146      * Returns the file that is monitored by this strategy. Note that the return
    147      * value can be <b>null </b> under some circumstances.
    148      *
    149      * @return the monitored file
    150      */
    151     protected File getFile()
    152     {
    153         return (configuration.getURL() != null) ? fileFromURL(configuration
    154                 .getURL()) : configuration.getFile();
    155     }
    156
    157     /***
    158      * Helper method for transforming a URL into a file object. This method
    159      * handles file: and jar: URLs.
    160      *
    161      * @param url the URL to be converted
    162      * @return the resulting file or <b>null </b>
    163      */
    164     private File fileFromURL(URL url)
    165     {
    166         if (JAR_PROTOCOL.equals(url.getProtocol()))
    167         {
    168             String path = url.getPath();
    169             try
    170             {
    171                 return ConfigurationUtils.fileFromURL(new URL(path.substring(0,
    172                         path.indexOf('!'))));
    173             }
    174             catch (MalformedURLException mex)
    175             {
    176                 return null;
    177             }
    178         }
    179         else
    180         {
    181             return ConfigurationUtils.fileFromURL(url);
    182         }
    183     }
    184 }