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