View Javadoc

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