1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.configuration;
19
20 import java.io.Reader;
21 import java.io.Writer;
22 import java.io.File;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.net.URL;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import org.apache.commons.configuration.event.ConfigurationEvent;
30 import org.apache.commons.configuration.event.ConfigurationListener;
31 import org.apache.commons.configuration.reloading.ReloadingStrategy;
32
33 /***
34 * <p>Base class for implementing file based hierarchical configurations.</p>
35 * <p>This class serves an analogous purpose as the
36 * <code>{@link AbstractFileConfiguration}</code> class for non hierarchical
37 * configurations. It behaves in exactly the same way, so please refer to the
38 * documentation of <code>AbstractFileConfiguration</code> for further details.</p>
39 *
40 * @since 1.2
41 *
42 * @author Emmanuel Bourg
43 * @version $Revision: 492216 $, $Date: 2007-01-03 17:51:24 +0100 (Mi, 03 Jan 2007) $
44 */
45 public abstract class AbstractHierarchicalFileConfiguration
46 extends HierarchicalConfiguration
47 implements FileConfiguration, ConfigurationListener
48 {
49 /*** Stores the delegate used for implementing functionality related to the
50 * <code>FileConfiguration</code> interface.
51 */
52 private FileConfigurationDelegate delegate;
53
54 /***
55 * Creates a new instance of
56 * <code>AbstractHierarchicalFileConfiguration</code>.
57 */
58 protected AbstractHierarchicalFileConfiguration()
59 {
60 initialize();
61 }
62
63 /***
64 * Creates a new instance of
65 * <code>AbstractHierarchicalFileConfiguration</code> and copies the
66 * content of the specified configuration into this object.
67 *
68 * @param c the configuration to copy
69 * @since 1.4
70 */
71 protected AbstractHierarchicalFileConfiguration(HierarchicalConfiguration c)
72 {
73 super(c);
74 initialize();
75 }
76
77 /***
78 * Creates and loads the configuration from the specified file.
79 *
80 * @param fileName The name of the plist file to load.
81 * @throws ConfigurationException Error while loading the file
82 */
83 public AbstractHierarchicalFileConfiguration(String fileName) throws ConfigurationException
84 {
85 this();
86
87 delegate.setFileName(fileName);
88
89
90 load();
91 }
92
93 /***
94 * Creates and loads the configuration from the specified file.
95 *
96 * @param file The configuration file to load.
97 * @throws ConfigurationException Error while loading the file
98 */
99 public AbstractHierarchicalFileConfiguration(File file) throws ConfigurationException
100 {
101 this();
102
103 setFile(file);
104
105
106 if (file.exists())
107 {
108 load();
109 }
110 }
111
112 /***
113 * Creates and loads the configuration from the specified URL.
114 *
115 * @param url The location of the configuration file to load.
116 * @throws ConfigurationException Error while loading the file
117 */
118 public AbstractHierarchicalFileConfiguration(URL url) throws ConfigurationException
119 {
120 this();
121
122 setURL(url);
123
124
125 load();
126 }
127
128 /***
129 * Initializes this instance, mainly the internally used delegate object.
130 */
131 private void initialize()
132 {
133 delegate = createDelegate();
134 initDelegate(delegate);
135 }
136
137 protected void addPropertyDirect(String key, Object obj)
138 {
139 super.addPropertyDirect(key, obj);
140 delegate.possiblySave();
141 }
142
143 public void clearProperty(String key)
144 {
145 super.clearProperty(key);
146 delegate.possiblySave();
147 }
148
149 public void clearTree(String key)
150 {
151 super.clearTree(key);
152 delegate.possiblySave();
153 }
154
155 public void setProperty(String key, Object value)
156 {
157 super.setProperty(key, value);
158 delegate.possiblySave();
159 }
160
161 public void load() throws ConfigurationException
162 {
163 delegate.load();
164 }
165
166 public void load(String fileName) throws ConfigurationException
167 {
168 delegate.load(fileName);
169 }
170
171 public void load(File file) throws ConfigurationException
172 {
173 delegate.load(file);
174 }
175
176 public void load(URL url) throws ConfigurationException
177 {
178 delegate.load(url);
179 }
180
181 public void load(InputStream in) throws ConfigurationException
182 {
183 delegate.load(in);
184 }
185
186 public void load(InputStream in, String encoding) throws ConfigurationException
187 {
188 delegate.load(in, encoding);
189 }
190
191 public void save() throws ConfigurationException
192 {
193 delegate.save();
194 }
195
196 public void save(String fileName) throws ConfigurationException
197 {
198 delegate.save(fileName);
199 }
200
201 public void save(File file) throws ConfigurationException
202 {
203 delegate.save(file);
204 }
205
206 public void save(URL url) throws ConfigurationException
207 {
208 delegate.save(url);
209 }
210
211 public void save(OutputStream out) throws ConfigurationException
212 {
213 delegate.save(out);
214 }
215
216 public void save(OutputStream out, String encoding) throws ConfigurationException
217 {
218 delegate.save(out, encoding);
219 }
220
221 public String getFileName()
222 {
223 return delegate.getFileName();
224 }
225
226 public void setFileName(String fileName)
227 {
228 delegate.setFileName(fileName);
229 }
230
231 public String getBasePath()
232 {
233 return delegate.getBasePath();
234 }
235
236 public void setBasePath(String basePath)
237 {
238 delegate.setBasePath(basePath);
239 }
240
241 public File getFile()
242 {
243 return delegate.getFile();
244 }
245
246 public void setFile(File file)
247 {
248 delegate.setFile(file);
249 }
250
251 public URL getURL()
252 {
253 return delegate.getURL();
254 }
255
256 public void setURL(URL url)
257 {
258 delegate.setURL(url);
259 }
260
261 public void setAutoSave(boolean autoSave)
262 {
263 delegate.setAutoSave(autoSave);
264 }
265
266 public boolean isAutoSave()
267 {
268 return delegate.isAutoSave();
269 }
270
271 public ReloadingStrategy getReloadingStrategy()
272 {
273 return delegate.getReloadingStrategy();
274 }
275
276 public void setReloadingStrategy(ReloadingStrategy strategy)
277 {
278 delegate.setReloadingStrategy(strategy);
279 }
280
281 public void reload()
282 {
283 setDetailEvents(false);
284 try
285 {
286 delegate.reload();
287 }
288 finally
289 {
290 setDetailEvents(true);
291 }
292 }
293
294 public String getEncoding()
295 {
296 return delegate.getEncoding();
297 }
298
299 public void setEncoding(String encoding)
300 {
301 delegate.setEncoding(encoding);
302 }
303
304 public boolean containsKey(String key)
305 {
306 reload();
307 return super.containsKey(key);
308 }
309
310 public Iterator getKeys(String prefix)
311 {
312 reload();
313 return super.getKeys(prefix);
314 }
315
316 public Object getProperty(String key)
317 {
318 reload();
319 return super.getProperty(key);
320 }
321
322 public boolean isEmpty()
323 {
324 reload();
325 return super.isEmpty();
326 }
327
328 /***
329 * Fetches a list of nodes, which are selected by the specified key. This
330 * implementation will perform a reload if necessary.
331 *
332 * @param key the key
333 * @return a list with the selected nodes
334 */
335 protected List fetchNodeList(String key)
336 {
337 reload();
338 return super.fetchNodeList(key);
339 }
340
341 /***
342 * Creates the file configuration delegate, i.e. the object that implements
343 * functionality required by the <code>FileConfiguration</code> interface.
344 * This base implementation will return an instance of the
345 * <code>FileConfigurationDelegate</code> class. Derived classes may
346 * override it to create a different delegate object.
347 *
348 * @return the file configuration delegate
349 */
350 protected FileConfigurationDelegate createDelegate()
351 {
352 return new FileConfigurationDelegate();
353 }
354
355 /***
356 * Helper method for initializing the file configuration delegate.
357 *
358 * @param del the delegate
359 */
360 private void initDelegate(FileConfigurationDelegate del)
361 {
362 del.addConfigurationListener(this);
363 }
364
365 /***
366 * Reacts on configuration change events triggered by the delegate. These
367 * events are passed to the registered configuration listeners.
368 *
369 * @param event the triggered event
370 * @since 1.3
371 */
372 public void configurationChanged(ConfigurationEvent event)
373 {
374
375 setDetailEvents(true);
376 try
377 {
378 fireEvent(event.getType(), event.getPropertyName(), event
379 .getPropertyValue(), event.isBeforeUpdate());
380 }
381 finally
382 {
383 setDetailEvents(false);
384 }
385 }
386
387 /***
388 * Returns the file configuration delegate.
389 *
390 * @return the delegate
391 */
392 protected FileConfigurationDelegate getDelegate()
393 {
394 return delegate;
395 }
396
397 /***
398 * Allows to set the file configuration delegate.
399 * @param delegate the new delegate
400 */
401 protected void setDelegate(FileConfigurationDelegate delegate)
402 {
403 this.delegate = delegate;
404 }
405
406 /***
407 * A special implementation of the <code>FileConfiguration</code> interface that is
408 * used internally to implement the <code>FileConfiguration</code> methods
409 * for hierarchical configurations.
410 */
411 protected class FileConfigurationDelegate extends AbstractFileConfiguration
412 {
413 public void load(Reader in) throws ConfigurationException
414 {
415 AbstractHierarchicalFileConfiguration.this.load(in);
416 }
417
418 public void save(Writer out) throws ConfigurationException
419 {
420 AbstractHierarchicalFileConfiguration.this.save(out);
421 }
422
423 public void clear()
424 {
425 AbstractHierarchicalFileConfiguration.this.clear();
426 }
427 }
428 }