View Javadoc

1   /*
2    * Copyright 2001-2005 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License")
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.configuration.reloading;
18  
19  import java.io.File;
20  import java.net.MalformedURLException;
21  import java.net.URL;
22  
23  import org.apache.commons.configuration.ConfigurationUtils;
24  import org.apache.commons.configuration.FileConfiguration;
25  
26  /***
27   * <p>A reloading strategy that will reload the configuration every time its
28   * underlying file is changed.</p>
29   * <p>This reloading strategy does not actively monitor a configuration file,
30   * but is triggered by its associated configuration whenever properties are
31   * accessed. It then checks the configuration file's last modification date
32   * and causes a reload if this has changed.</p>
33   * <p>To avoid permanent disc access on successive property lookups a refresh
34   * delay can be specified. This has the effect that the configuration file's
35   * last modification date is only checked once in this delay period. The default
36   * value for this refresh delay is 5 seconds.</p>
37   * <p>This strategy only works with FileConfiguration instances.</p>
38   *
39   * @author Emmanuel Bourg
40   * @version $Revision$, $Date: 2005-10-10 21:26:46 +0200 (Mon, 10 Oct 2005) $
41   * @since 1.1
42   */
43  public class FileChangedReloadingStrategy implements ReloadingStrategy
44  {
45      /*** Constant for the jar URL protocol.*/
46      private static final String JAR_PROTOCOL = "jar";
47  
48      /*** Constant for the default refresh delay.*/
49      private static final int DEFAULT_REFRESH_DELAY = 5000;
50  
51      /*** Stores a reference to the configuration to be monitored.*/
52      protected FileConfiguration configuration;
53  
54      /*** The last time the configuration file was modified. */
55      protected long lastModified;
56  
57      /*** The last time the file was checked for changes. */
58      protected long lastChecked;
59  
60      /*** The minimum delay in milliseconds between checks. */
61      protected long refreshDelay = DEFAULT_REFRESH_DELAY;
62  
63      public void setConfiguration(FileConfiguration configuration)
64      {
65          this.configuration = configuration;
66      }
67  
68      public void init()
69      {
70          updateLastModified();
71      }
72  
73      public boolean reloadingRequired()
74      {
75          boolean reloading = false;
76  
77          long now = System.currentTimeMillis();
78  
79          if (now > lastChecked + refreshDelay)
80          {
81              lastChecked = now;
82              if (hasChanged())
83              {
84                  reloading = true;
85              }
86          }
87  
88          return reloading;
89      }
90  
91      public void reloadingPerformed()
92      {
93          updateLastModified();
94      }
95  
96      /***
97       * Return the minimal time in milliseconds between two reloadings.
98       *
99       * @return the refresh delay (in milliseconds)
100      */
101     public long getRefreshDelay()
102     {
103         return refreshDelay;
104     }
105 
106     /***
107      * Set the minimal time between two reloadings.
108      *
109      * @param refreshDelay refresh delay in milliseconds
110      */
111     public void setRefreshDelay(long refreshDelay)
112     {
113         this.refreshDelay = refreshDelay;
114     }
115 
116     /***
117      * Update the last modified time.
118      */
119     protected void updateLastModified()
120     {
121         File file = getFile();
122         if (file != null)
123         {
124             lastModified = file.lastModified();
125         }
126     }
127 
128     /***
129      * Check if the configuration has changed since the last time it was loaded.
130      *
131      * @return a flag whether the configuration has changed
132      */
133     protected boolean hasChanged()
134     {
135         File file = getFile();
136         if (file == null || !file.exists())
137         {
138             return false;
139         }
140 
141         return file.lastModified() > lastModified;
142     }
143 
144     /***
145      * Returns the file that is monitored by this strategy. Note that the return
146      * value can be <b>null </b> under some circumstances.
147      *
148      * @return the monitored file
149      */
150     protected File getFile()
151     {
152         return (configuration.getURL() != null) ? fileFromURL(configuration
153                 .getURL()) : configuration.getFile();
154     }
155 
156     /***
157      * Helper method for transforming a URL into a file object. This method
158      * handles file: and jar: URLs.
159      *
160      * @param url the URL to be converted
161      * @return the resulting file or <b>null </b>
162      */
163     private File fileFromURL(URL url)
164     {
165         if (JAR_PROTOCOL.equals(url.getProtocol()))
166         {
167             String path = url.getPath();
168             try
169             {
170                 return ConfigurationUtils.fileFromURL(new URL(path.substring(0,
171                         path.indexOf('!'))));
172             }
173             catch (MalformedURLException mex)
174             {
175                 return null;
176             }
177         }
178         else
179         {
180             return ConfigurationUtils.fileFromURL(url);
181         }
182     }
183 }