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: 606798 $, $Date: 2007-12-25 20:05:58 +0100 (Di, 25 Dez 2007) $
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 /*** A flag whether a reload is required.*/
65 private boolean reloading;
66
67 public void setConfiguration(FileConfiguration configuration)
68 {
69 this.configuration = configuration;
70 }
71
72 public void init()
73 {
74 updateLastModified();
75 }
76
77 public boolean reloadingRequired()
78 {
79 if (!reloading)
80 {
81 long now = System.currentTimeMillis();
82
83 if (now > lastChecked + refreshDelay)
84 {
85 lastChecked = now;
86 if (hasChanged())
87 {
88 reloading = true;
89 }
90 }
91 }
92
93 return reloading;
94 }
95
96 public void reloadingPerformed()
97 {
98 updateLastModified();
99 }
100
101 /***
102 * Return the minimal time in milliseconds between two reloadings.
103 *
104 * @return the refresh delay (in milliseconds)
105 */
106 public long getRefreshDelay()
107 {
108 return refreshDelay;
109 }
110
111 /***
112 * Set the minimal time between two reloadings.
113 *
114 * @param refreshDelay refresh delay in milliseconds
115 */
116 public void setRefreshDelay(long refreshDelay)
117 {
118 this.refreshDelay = refreshDelay;
119 }
120
121 /***
122 * Update the last modified time.
123 */
124 protected void updateLastModified()
125 {
126 File file = getFile();
127 if (file != null)
128 {
129 lastModified = file.lastModified();
130 }
131 reloading = false;
132 }
133
134 /***
135 * Check if the configuration has changed since the last time it was loaded.
136 *
137 * @return a flag whether the configuration has changed
138 */
139 protected boolean hasChanged()
140 {
141 File file = getFile();
142 if (file == null || !file.exists())
143 {
144 return false;
145 }
146
147 return file.lastModified() > lastModified;
148 }
149
150 /***
151 * Returns the file that is monitored by this strategy. Note that the return
152 * value can be <b>null </b> under some circumstances.
153 *
154 * @return the monitored file
155 */
156 protected File getFile()
157 {
158 return (configuration.getURL() != null) ? fileFromURL(configuration
159 .getURL()) : configuration.getFile();
160 }
161
162 /***
163 * Helper method for transforming a URL into a file object. This method
164 * handles file: and jar: URLs.
165 *
166 * @param url the URL to be converted
167 * @return the resulting file or <b>null </b>
168 */
169 private File fileFromURL(URL url)
170 {
171 if (JAR_PROTOCOL.equals(url.getProtocol()))
172 {
173 String path = url.getPath();
174 try
175 {
176 return ConfigurationUtils.fileFromURL(new URL(path.substring(0,
177 path.indexOf('!'))));
178 }
179 catch (MalformedURLException mex)
180 {
181 return null;
182 }
183 }
184 else
185 {
186 return ConfigurationUtils.fileFromURL(url);
187 }
188 }
189 }