##### Coverage Report - org.apache.commons.configuration.AbstractHierarchicalFileConfiguration

Classes in this File | Line Coverage | Branch Coverage | Complexity
AbstractHierarchicalFileConfiguration |
98% | 111/113
100% | 1/1
| 1.0188679245283019;1,019
AbstractHierarchicalFileConfiguration$FileConfigurationDelegate |
100% | 7/7
N/A | N/A
| 1.0188679245283019;1,019

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