Coverage Report - org.apache.commons.configuration.AbstractHierarchicalFileConfiguration
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractHierarchicalFileConfiguration
98%
109/111
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.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.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: 589380 $, $Date: 2007-10-28 17:37:35 +0100 (So, 28 Okt 2007) $
 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  746
     {
 61  746
         initialize();
 62  746
     }
 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  8
         super(c);
 75  8
         initialize();
 76  8
     }
 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  7
         this();
 87  
         // store the file name
 88  7
         delegate.setFileName(fileName);
 89  
 
 90  
         // load the file
 91  7
         load();
 92  7
     }
 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  132
         this();
 103  
         // set the file and update the url, the base path and the file name
 104  132
         setFile(file);
 105  
 
 106  
         // load the file
 107  132
         if (file.exists())
 108  
         {
 109  131
             load();
 110  
         }
 111  132
     }
 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  1
         this();
 122  
         // set the URL and update the base path and the file name
 123  1
         setURL(url);
 124  
 
 125  
         // load the file
 126  1
         load();
 127  1
     }
 128  
 
 129  
     /**
 130  
      * Initializes this instance, mainly the internally used delegate object.
 131  
      */
 132  
     private void initialize()
 133  
     {
 134  754
         delegate = createDelegate();
 135  754
         initDelegate(delegate);
 136  754
     }
 137  
 
 138  
     protected void addPropertyDirect(String key, Object obj)
 139  
     {
 140  3131
         super.addPropertyDirect(key, obj);
 141  3131
         delegate.possiblySave();
 142  3131
     }
 143  
 
 144  
     public void clearProperty(String key)
 145  
     {
 146  639
         super.clearProperty(key);
 147  639
         delegate.possiblySave();
 148  639
     }
 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  594
         super.setProperty(key, value);
 159  594
         delegate.possiblySave();
 160  594
     }
 161  
 
 162  
     public void load() throws ConfigurationException
 163  
     {
 164  348
         delegate.load();
 165  334
     }
 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  22
         delegate.save(file);
 205  21
     }
 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  104
         delegate.setFileName(fileName);
 230  104
     }
 231  
 
 232  
     public String getBasePath()
 233  
     {
 234  56
         return delegate.getBasePath();
 235  
     }
 236  
 
 237  
     public void setBasePath(String basePath)
 238  
     {
 239  53
         delegate.setBasePath(basePath);
 240  53
     }
 241  
 
 242  
     public File getFile()
 243  
     {
 244  4
         return delegate.getFile();
 245  
     }
 246  
 
 247  
     public void setFile(File file)
 248  
     {
 249  235
         delegate.setFile(file);
 250  235
     }
 251  
 
 252  
     public URL getURL()
 253  
     {
 254  1
         return delegate.getURL();
 255  
     }
 256  
 
 257  
     public void setURL(URL url)
 258  
     {
 259  7
         delegate.setURL(url);
 260  7
     }
 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  3
         return delegate.getReloadingStrategy();
 275  
     }
 276  
 
 277  
     public void setReloadingStrategy(ReloadingStrategy strategy)
 278  
     {
 279  15
         delegate.setReloadingStrategy(strategy);
 280  15
     }
 281  
 
 282  
     public void reload()
 283  
     {
 284  6466
         setDetailEvents(false);
 285  
         try
 286  
         {
 287  6466
             delegate.reload();
 288  
         }
 289  
         finally
 290  
         {
 291  6466
             setDetailEvents(true);
 292  6466
         }
 293  6466
     }
 294  
 
 295  
     public String getEncoding()
 296  
     {
 297  61
         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  841
         reload();
 308  841
         return super.containsKey(key);
 309  
     }
 310  
 
 311  
     public Iterator getKeys(String prefix)
 312  
     {
 313  5
         reload();
 314  5
         return super.getKeys(prefix);
 315  
     }
 316  
 
 317  
     public Object getProperty(String key)
 318  
     {
 319  2098
         reload();
 320  2098
         return super.getProperty(key);
 321  
     }
 322  
 
 323  
     public boolean isEmpty()
 324  
     {
 325  10
         reload();
 326  10
         return super.isEmpty();
 327  
     }
 328  
 
 329  
     /**
 330  
      * Directly adds sub nodes to this configuration. This implementation checks
 331  
      * whether auto save is necessary after executing the operation.
 332  
      *
 333  
      * @param key the key where the nodes are to be added
 334  
      * @param nodes a collection with the nodes to be added
 335  
      * @since 1.5
 336  
      */
 337  
     public void addNodes(String key, Collection nodes)
 338  
     {
 339  3
         super.addNodes(key, nodes);
 340  3
         delegate.possiblySave();
 341  3
     }
 342  
 
 343  
     /**
 344  
      * Fetches a list of nodes, which are selected by the specified key. This
 345  
      * implementation will perform a reload if necessary.
 346  
      *
 347  
      * @param key the key
 348  
      * @return a list with the selected nodes
 349  
      */
 350  
     protected List fetchNodeList(String key)
 351  
     {
 352  3512
         reload();
 353  3512
         return super.fetchNodeList(key);
 354  
     }
 355  
 
 356  
     /**
 357  
      * Reacts on changes of an associated subnode configuration. If the auto
 358  
      * save mechanism is active, the configuration must be saved.
 359  
      *
 360  
      * @param event the event describing the change
 361  
      * @since 1.5
 362  
      */
 363  
     protected void subnodeConfigurationChanged(ConfigurationEvent event)
 364  
     {
 365  4
         delegate.possiblySave();
 366  4
         super.subnodeConfigurationChanged(event);
 367  4
     }
 368  
 
 369  
     /**
 370  
      * Creates the file configuration delegate, i.e. the object that implements
 371  
      * functionality required by the <code>FileConfiguration</code> interface.
 372  
      * This base implementation will return an instance of the
 373  
      * <code>FileConfigurationDelegate</code> class. Derived classes may
 374  
      * override it to create a different delegate object.
 375  
      *
 376  
      * @return the file configuration delegate
 377  
      */
 378  
     protected FileConfigurationDelegate createDelegate()
 379  
     {
 380  385
         return new FileConfigurationDelegate();
 381  
     }
 382  
 
 383  
     /**
 384  
      * Helper method for initializing the file configuration delegate.
 385  
      *
 386  
      * @param del the delegate
 387  
      */
 388  
     private void initDelegate(FileConfigurationDelegate del)
 389  
     {
 390  754
         del.addConfigurationListener(this);
 391  754
     }
 392  
 
 393  
     /**
 394  
      * Reacts on configuration change events triggered by the delegate. These
 395  
      * events are passed to the registered configuration listeners.
 396  
      *
 397  
      * @param event the triggered event
 398  
      * @since 1.3
 399  
      */
 400  
     public void configurationChanged(ConfigurationEvent event)
 401  
     {
 402  
         // deliver reload events to registered listeners
 403  56
         setDetailEvents(true);
 404  
         try
 405  
         {
 406  56
             fireEvent(event.getType(), event.getPropertyName(), event
 407  
                     .getPropertyValue(), event.isBeforeUpdate());
 408  
         }
 409  
         finally
 410  
         {
 411  56
             setDetailEvents(false);
 412  56
         }
 413  56
     }
 414  
 
 415  
     /**
 416  
      * Returns the file configuration delegate.
 417  
      *
 418  
      * @return the delegate
 419  
      */
 420  
     protected FileConfigurationDelegate getDelegate()
 421  
     {
 422  319
         return delegate;
 423  
     }
 424  
 
 425  
     /**
 426  
      * Allows to set the file configuration delegate.
 427  
      * @param delegate the new delegate
 428  
      */
 429  
     protected void setDelegate(FileConfigurationDelegate delegate)
 430  
     {
 431  2
         this.delegate = delegate;
 432  2
     }
 433  
 
 434  
     /**
 435  
      * A special implementation of the <code>FileConfiguration</code> interface that is
 436  
      * used internally to implement the <code>FileConfiguration</code> methods
 437  
      * for hierarchical configurations.
 438  
      */
 439  756
     protected class FileConfigurationDelegate extends AbstractFileConfiguration
 440  
     {
 441  
         public void load(Reader in) throws ConfigurationException
 442  
         {
 443  63
             AbstractHierarchicalFileConfiguration.this.load(in);
 444  63
         }
 445  
 
 446  
         public void save(Writer out) throws ConfigurationException
 447  
         {
 448  57
             AbstractHierarchicalFileConfiguration.this.save(out);
 449  56
         }
 450  
 
 451  
         public void clear()
 452  
         {
 453  28
             AbstractHierarchicalFileConfiguration.this.clear();
 454  28
         }
 455  
     }
 456  
 }