View Javadoc

    1   /*
    2    * Copyright 2001-2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License")
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package org.apache.commons.configuration;
    18
    19  import java.util.ArrayList;
    20  import java.util.Iterator;
    21  import java.util.LinkedList;
    22  import java.util.List;
    23  import java.util.Vector;
    24
    25  /***
    26   * This Configuration class allows you to add multiple different types of Configuration
    27   * to this CompositeConfiguration.  If you add Configuration1, and then Configuration2,
    28   * any properties shared will mean that Configuration1 will be returned.
    29   * You can add multiple different types or the same type of properties file.
    30   * If Configuration1 doesn't have the property, then Configuration2 will be checked.
    31   *
    32   * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
    33   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    34   * @version $Id: CompositeConfiguration.java,v 1.19 2004/10/05 22:56:58 ebourg Exp $
    35   */
    36  public class CompositeConfiguration extends AbstractConfiguration
    37  {
    38      /*** List holding all the configuration */
    39      private List configList = new LinkedList();
    40
    41      /***
    42       * Configuration that holds in memory stuff.  Inserted as first so any
    43       * setProperty() override anything else added.
    44       */
    45      private Configuration inMemoryConfiguration;
    46
    47      /***
    48       * Creates an empty CompositeConfiguration object which can then
    49       * be added some other Configuration files
    50       */
    51      public CompositeConfiguration()
    52      {
    53          clear();
    54      }
    55
    56      /***
    57       * Creates an CompositeConfiguration object with a specified InMemory
    58       * configuration. This configuration will store any changes made to
    59       * the CompositeConfiguration.
    60       *
    61       * @param inMemoryConfiguration the in memory configuration to use
    62       */
    63      public CompositeConfiguration(Configuration inMemoryConfiguration)
    64      {
    65          configList.clear();
    66          this.inMemoryConfiguration = inMemoryConfiguration;
    67          configList.add(inMemoryConfiguration);
    68      }
    69
    70      /***
    71       * Add a configuration.
    72       *
    73       * @param config the configuration to add
    74       */
    75      public void addConfiguration(Configuration config)
    76      {
    77          if (!configList.contains(config))
    78          {
    79              // As the inMemoryConfiguration contains all manually added keys,
    80              // we must make sure that it is always last. "Normal", non composed
    81              // configuration add their keys at the end of the configuration and
    82              // we want to mimic this behaviour.
    83              configList.add(configList.indexOf(inMemoryConfiguration), config);
    84
    85              if (config instanceof AbstractConfiguration)
    86              {
    87                  ((AbstractConfiguration) config).setThrowExceptionOnMissing(isThrowExceptionOnMissing());
    88              }
    89          }
    90      }
    91
    92      /***
    93       * Remove a configuration. The in memory configuration cannot be removed.
    94       *
    95       * @param config The configuration to remove
    96       */
    97      public void removeConfiguration(Configuration config)
    98      {
    99          // Make sure that you can't remove the inMemoryConfiguration from
    100         // the CompositeConfiguration object
    101         if (!config.equals(inMemoryConfiguration))
    102         {
    103             configList.remove(config);
    104         }
    105     }
    106
    107     /***
    108      * Return the number of configurations.
    109      *
    110      * @return the number of configuration
    111      */
    112     public int getNumberOfConfigurations()
    113     {
    114         return configList.size();
    115     }
    116
    117     /***
    118      * Remove all configuration reinitialize the in memory configuration.
    119      */
    120     public void clear()
    121     {
    122         configList.clear();
    123         // recreate the in memory configuration
    124         inMemoryConfiguration = new BaseConfiguration();
    125         ((BaseConfiguration) inMemoryConfiguration).setThrowExceptionOnMissing(isThrowExceptionOnMissing());
    126         configList.add(inMemoryConfiguration);
    127     }
    128
    129     /***
    130      * Add this property to the inmemory Configuration.
    131      *
    132      * @param key The Key to add the property to.
    133      * @param token The Value to add.
    134      */
    135     protected void addPropertyDirect(String key, Object token)
    136     {
    137         inMemoryConfiguration.addProperty(key, token);
    138     }
    139
    140     /***
    141      * Read property from underlying composite
    142      *
    143      * @param key key to use for mapping
    144      *
    145      * @return object associated with the given configuration key.
    146      */
    147     protected Object getPropertyDirect(String key)
    148     {
    149         Configuration firstMatchingConfiguration = null;
    150         for (Iterator i = configList.iterator(); i.hasNext();)
    151         {
    152             Configuration config = (Configuration) i.next();
    153             if (config.containsKey(key))
    154             {
    155                 firstMatchingConfiguration = config;
    156                 break;
    157             }
    158         }
    159
    160         if (firstMatchingConfiguration != null)
    161         {
    162             return firstMatchingConfiguration.getProperty(key);
    163         }
    164         else
    165         {
    166             return null;
    167         }
    168     }
    169
    170     /***
    171      * {@inheritDoc}
    172      */
    173     public Iterator getKeys()
    174     {
    175         List keys = new ArrayList();
    176         for (Iterator i = configList.iterator(); i.hasNext();)
    177         {
    178             Configuration config = (Configuration) i.next();
    179
    180             Iterator j = config.getKeys();
    181             while (j.hasNext())
    182             {
    183                 String key = (String) j.next();
    184                 if (!keys.contains(key))
    185                 {
    186                     keys.add(key);
    187                 }
    188             }
    189         }
    190
    191         return keys.iterator();
    192     }
    193
    194     /***
    195      * {@inheritDoc}
    196      */
    197     public Iterator getKeys(String key)
    198     {
    199         List keys = new ArrayList();
    200         for (Iterator i = configList.iterator(); i.hasNext();)
    201         {
    202             Configuration config = (Configuration) i.next();
    203
    204             Iterator j = config.getKeys(key);
    205             while (j.hasNext())
    206             {
    207                 String newKey = (String) j.next();
    208                 if (!keys.contains(newKey))
    209                 {
    210                     keys.add(newKey);
    211                 }
    212             }
    213         }
    214
    215         return keys.iterator();
    216     }
    217
    218     /***
    219      * {@inheritDoc}
    220      */
    221     public boolean isEmpty()
    222     {
    223         boolean isEmpty = true;
    224         for (Iterator i = configList.iterator(); i.hasNext();)
    225         {
    226             Configuration config = (Configuration) i.next();
    227             if (!config.isEmpty())
    228             {
    229                 return false;
    230             }
    231         }
    232
    233         return isEmpty;
    234     }
    235
    236     /***
    237      * {@inheritDoc}
    238      */
    239     public Object getProperty(String key)
    240     {
    241         return getPropertyDirect(key);
    242     }
    243
    244     /***
    245      * {@inheritDoc}
    246      */
    247     public void setProperty(String key, Object value)
    248     {
    249         clearProperty(key);
    250         addProperty(key, value);
    251     }
    252
    253     /***
    254      * {@inheritDoc}
    255      */
    256     public void clearProperty(String key)
    257     {
    258         for (Iterator i = configList.iterator(); i.hasNext();)
    259         {
    260             Configuration config = (Configuration) i.next();
    261             config.clearProperty(key);
    262         }
    263     }
    264
    265     /***
    266      * {@inheritDoc}
    267      */
    268     public boolean containsKey(String key)
    269     {
    270         for (Iterator i = configList.iterator(); i.hasNext();)
    271         {
    272             Configuration config = (Configuration) i.next();
    273             if (config.containsKey(key))
    274             {
    275                 return true;
    276             }
    277         }
    278         return false;
    279     }
    280
    281     /***
    282      * {@inheritDoc}
    283      */
    284     public List getList(String key, List defaultValue)
    285     {
    286         List list = new ArrayList();
    287
    288         // add all elements from the first configuration containing the requested key
    289         Iterator it = configList.iterator();
    290         while (it.hasNext() && list.isEmpty())
    291         {
    292             Configuration config = (Configuration) it.next();
    293             if (config != inMemoryConfiguration && config.containsKey(key))
    294             {
    295                 list.addAll(config.getList(key));
    296             }
    297         }
    298
    299         // add all elements from the in memory configuration
    300         list.addAll(inMemoryConfiguration.getList(key));
    301
    302         if (list.isEmpty())
    303         {
    304             return defaultValue;
    305         }
    306
    307         return list;
    308     }
    309
    310     /***
    311      * {@inheritDoc}
    312      */
    313     public Vector getVector(String key, Vector defaultValue)
    314     {
    315         return new Vector(getList(key, defaultValue));
    316     }
    317
    318     /***
    319      * {@inheritDoc}
    320      */
    321     public String[] getStringArray(String key)
    322     {
    323         List list = getList(key);
    324
    325         // interpolate the strings
    326         String[] tokens = new String[list.size()];
    327
    328         for (int i = 0; i < tokens.length; i++)
    329         {
    330             tokens[i] = interpolate(String.valueOf(list.get(i)));
    331         }
    332
    333         return tokens;
    334     }
    335
    336     /***
    337      * Return the configuration at the specified index.
    338      *
    339      * @param index The index of the configuration to retrieve
    340      */
    341     public Configuration getConfiguration(int index)
    342     {
    343         return (Configuration) configList.get(index);
    344     }
    345
    346     /***
    347      * {@inheritDoc}
    348      */
    349     public Configuration getInMemoryConfiguration()
    350     {
    351         return inMemoryConfiguration;
    352     }
    353 }