1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 }