View Javadoc

    1   /*
    2    * Copyright 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.Iterator;
    20
    21  import org.apache.commons.collections.Transformer;
    22  import org.apache.commons.collections.iterators.TransformIterator;
    23
    24  /***
    25   * A subset of another configuration. The new Configuration object contains
    26   * every key from the parent Configuration that starts with prefix. The prefix
    27   * is removed from the keys in the subset.
    28   *
    29   * @see Configuration#subset(String)
    30   *
    31   * @author Emmanuel Bourg
    32   * @version $Revision: 1.6 $, $Date: 2004/10/05 21:17:25 $
    33   */
    34  public class SubsetConfiguration extends AbstractConfiguration
    35  {
    36      /*** The parent configuration. */
    37      protected Configuration parent;
    38
    39      /*** The prefix used to select the properties. */
    40      protected String prefix;
    41
    42      /*** The prefix delimiter */
    43      protected String delimiter;
    44
    45      /***
    46       * Create a subset of the specified configuration
    47       *
    48       * @param parent The parent configuration
    49       * @param prefix The prefix used to select the properties
    50       */
    51      public SubsetConfiguration(Configuration parent, String prefix)
    52      {
    53          this.parent = parent;
    54          this.prefix = prefix;
    55      }
    56
    57      /***
    58       * Create a subset of the specified configuration
    59       *
    60       * @param parent    The parent configuration
    61       * @param prefix    The prefix used to select the properties
    62       * @param delimiter The prefix delimiter
    63       */
    64      public SubsetConfiguration(Configuration parent, String prefix, String delimiter)
    65      {
    66          this.parent = parent;
    67          this.prefix = prefix;
    68          this.delimiter = delimiter;
    69      }
    70
    71      /***
    72       * Return the key in the parent configuration associated to the specified
    73       * key in this subset.
    74       *
    75       * @param key The key in the subset.
    76       */
    77      protected String getParentKey(String key)
    78      {
    79          if ("".equals(key) || key == null)
    80          {
    81              return prefix;
    82          }
    83          else
    84          {
    85              return delimiter == null ? prefix + key : prefix + delimiter + key;
    86          }
    87      }
    88
    89      /***
    90       * Return the key in the subset configuration associated to the specified
    91       * key in the parent configuration.
    92       *
    93       * @param key The key in the parent configuration.
    94       */
    95      protected String getChildKey(String key)
    96      {
    97          if (!key.startsWith(prefix))
    98          {
    99              throw new IllegalArgumentException("The parent key '" + key + "' is not in the subset.");
    100         }
    101         else
    102         {
    103             String modifiedKey = null;
    104             if (key.length() == prefix.length())
    105             {
    106                 modifiedKey = "";
    107             }
    108             else
    109             {
    110                 int i = prefix.length() + (delimiter != null ? delimiter.length() : 0);
    111                 modifiedKey = key.substring(i);
    112             }
    113
    114             return modifiedKey;
    115         }
    116     }
    117
    118     /***
    119      * Return the parent configuation for this subset.
    120      */
    121     public Configuration getParent()
    122     {
    123         return parent;
    124     }
    125
    126     /***
    127      * Return the prefix used to select the properties in the parent configuration.
    128      */
    129     public String getPrefix()
    130     {
    131         return prefix;
    132     }
    133
    134     /***
    135      * Set the prefix used to select the properties in the parent configuration.
    136      */
    137     public void setPrefix(String prefix)
    138     {
    139         this.prefix = prefix;
    140     }
    141
    142     /***
    143      * {@inheritDoc}
    144      */
    145     public Configuration subset(String prefix)
    146     {
    147         return parent.subset(getParentKey(prefix));
    148     }
    149
    150     /***
    151      * {@inheritDoc}
    152      */
    153     public boolean isEmpty()
    154     {
    155         return !getKeys().hasNext();
    156     }
    157
    158     /***
    159      * {@inheritDoc}
    160      */
    161     public boolean containsKey(String key)
    162     {
    163         return parent.containsKey(getParentKey(key));
    164     }
    165
    166     /***
    167      * {@inheritDoc}
    168      */
    169     public void addPropertyDirect(String key, Object value)
    170     {
    171         parent.addProperty(getParentKey(key), value);
    172     }
    173
    174     /***
    175      * {@inheritDoc}
    176      */
    177     public void setProperty(String key, Object value)
    178     {
    179         parent.setProperty(getParentKey(key), value);
    180     }
    181
    182     /***
    183      * {@inheritDoc}
    184      */
    185     public void clearProperty(String key)
    186     {
    187         parent.clearProperty(getParentKey(key));
    188     }
    189
    190     /***
    191      * {@inheritDoc}
    192      */
    193     public Object getPropertyDirect(String key)
    194     {
    195         return parent.getProperty(getParentKey(key));
    196     }
    197
    198     /***
    199      * {@inheritDoc}
    200      */
    201     public Iterator getKeys(String prefix)
    202     {
    203         return new TransformIterator(parent.getKeys(getParentKey(prefix)), new Transformer()
    204         {
    205             public Object transform(Object obj)
    206             {
    207                 return getChildKey((String) obj);
    208             }
    209         });
    210     }
    211
    212     /***
    213      * {@inheritDoc}
    214      */
    215     public Iterator getKeys()
    216     {
    217         return new TransformIterator(parent.getKeys(prefix), new Transformer()
    218         {
    219             public Object transform(Object obj)
    220             {
    221                 return getChildKey((String) obj);
    222             }
    223         });
    224     }
    225
    226     /***
    227      * {@inheritDoc}
    228      */
    229     protected String interpolate(String base)
    230     {
    231         if (delimiter == null && "".equals(prefix))
    232         {
    233             return super.interpolate(base);
    234         }
    235         else
    236         {
    237             SubsetConfiguration config = new SubsetConfiguration(parent, "");
    238             return config.interpolate(base);
    239         }
    240     }
    241
    242     /***
    243      * {@inheritDoc}
    244      *
    245      * Change the behaviour of the parent configuration if it supports this feature.
    246      */
    247     public void setThrowExceptionOnMissing(boolean throwExceptionOnMissing)
    248     {
    249         if (parent instanceof AbstractConfiguration)
    250         {
    251             ((AbstractConfiguration) parent).setThrowExceptionOnMissing(throwExceptionOnMissing);
    252         }
    253         else
    254         {
    255             super.setThrowExceptionOnMissing(throwExceptionOnMissing);
    256         }
    257     }
    258
    259     /***
    260      * {@inheritDoc}
    261      *
    262      * The subset inherits this feature from its parent if it supports this feature.
    263      */
    264     public boolean isThrowExceptionOnMissing()
    265     {
    266         if (parent instanceof AbstractConfiguration)
    267         {
    268             return ((AbstractConfiguration) parent).isThrowExceptionOnMissing();
    269         }
    270         else
    271         {
    272             return super.isThrowExceptionOnMissing();
    273         }
    274     }
    275 }