Coverage Report - org.apache.commons.configuration.AbstractHierarchicalFileConfiguration
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractHierarchicalFileConfiguration
98%
111/113
100%
1/1
1,019
AbstractHierarchicalFileConfiguration$FileConfigurationDelegate
100%
7/7
N/A
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  
 }