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 }