Coverage Report - org.apache.commons.configuration.SubsetConfiguration
 
Classes in this File Line Coverage Branch Coverage Complexity
SubsetConfiguration
92%
57/62
100%
13/13
1,462
SubsetConfiguration$1
100%
2/2
N/A
1,462
SubsetConfiguration$2
100%
2/2
N/A
1,462
 
 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.util.Iterator;
 21  
 
 22  
 import org.apache.commons.collections.Transformer;
 23  
 import org.apache.commons.collections.iterators.TransformIterator;
 24  
 
 25  
 /**
 26  
  * <p>A subset of another configuration. The new Configuration object contains
 27  
  * every key from the parent Configuration that starts with prefix. The prefix
 28  
  * is removed from the keys in the subset.</p>
 29  
  * <p>It is usually not necessary to use this class directly. Instead the
 30  
  * <code>{@link Configuration#subset(String)}</code> method should be used,
 31  
  * which will return a correctly initialized instance.</p>
 32  
  *
 33  
  * @author Emmanuel Bourg
 34  
  * @version $Revision: 529531 $, $Date: 2007-04-17 10:52:41 +0200 (Di, 17 Apr 2007) $
 35  
  */
 36  
 public class SubsetConfiguration extends AbstractConfiguration
 37  
 {
 38  
     /** The parent configuration. */
 39  
     protected Configuration parent;
 40  
 
 41  
     /** The prefix used to select the properties. */
 42  
     protected String prefix;
 43  
 
 44  
     /** The prefix delimiter */
 45  
     protected String delimiter;
 46  
 
 47  
     /**
 48  
      * Create a subset of the specified configuration
 49  
      *
 50  
      * @param parent The parent configuration
 51  
      * @param prefix The prefix used to select the properties
 52  
      */
 53  
     public SubsetConfiguration(Configuration parent, String prefix)
 54  21
     {
 55  21
         this.parent = parent;
 56  21
         this.prefix = prefix;
 57  21
     }
 58  
 
 59  
     /**
 60  
      * Create a subset of the specified configuration
 61  
      *
 62  
      * @param parent    The parent configuration
 63  
      * @param prefix    The prefix used to select the properties
 64  
      * @param delimiter The prefix delimiter
 65  
      */
 66  
     public SubsetConfiguration(Configuration parent, String prefix, String delimiter)
 67  65
     {
 68  65
         this.parent = parent;
 69  65
         this.prefix = prefix;
 70  65
         this.delimiter = delimiter;
 71  65
     }
 72  
 
 73  
     /**
 74  
      * Return the key in the parent configuration associated to the specified
 75  
      * key in this subset.
 76  
      *
 77  
      * @param key The key in the subset.
 78  
      * @return the key as to be used by the parent
 79  
      */
 80  
     protected String getParentKey(String key)
 81  
     {
 82  75
         if ("".equals(key) || key == null)
 83  
         {
 84  4
             return prefix;
 85  
         }
 86  
         else
 87  
         {
 88  71
             return delimiter == null ? prefix + key : prefix + delimiter + key;
 89  
         }
 90  
     }
 91  
 
 92  
     /**
 93  
      * Return the key in the subset configuration associated to the specified
 94  
      * key in the parent configuration.
 95  
      *
 96  
      * @param key The key in the parent configuration.
 97  
      * @return the key in the context of this subset configuration
 98  
      */
 99  
     protected String getChildKey(String key)
 100  
     {
 101  110
         if (!key.startsWith(prefix))
 102  
         {
 103  0
             throw new IllegalArgumentException("The parent key '" + key + "' is not in the subset.");
 104  
         }
 105  
         else
 106  
         {
 107  110
             String modifiedKey = null;
 108  110
             if (key.length() == prefix.length())
 109  
             {
 110  4
                 modifiedKey = "";
 111  4
             }
 112  
             else
 113  
             {
 114  106
                 int i = prefix.length() + (delimiter != null ? delimiter.length() : 0);
 115  106
                 modifiedKey = key.substring(i);
 116  
             }
 117  
 
 118  110
             return modifiedKey;
 119  
         }
 120  
     }
 121  
 
 122  
     /**
 123  
      * Return the parent configuation for this subset.
 124  
      *
 125  
      * @return the parent configuration
 126  
      */
 127  
     public Configuration getParent()
 128  
     {
 129  1
         return parent;
 130  
     }
 131  
 
 132  
     /**
 133  
      * Return the prefix used to select the properties in the parent configuration.
 134  
      *
 135  
      * @return the prefix used by this subset
 136  
      */
 137  
     public String getPrefix()
 138  
     {
 139  2
         return prefix;
 140  
     }
 141  
 
 142  
     /**
 143  
      * Set the prefix used to select the properties in the parent configuration.
 144  
      *
 145  
      * @param prefix the prefix
 146  
      */
 147  
     public void setPrefix(String prefix)
 148  
     {
 149  1
         this.prefix = prefix;
 150  1
     }
 151  
 
 152  
     public Configuration subset(String prefix)
 153  
     {
 154  1
         return parent.subset(getParentKey(prefix));
 155  
     }
 156  
 
 157  
     public boolean isEmpty()
 158  
     {
 159  11
         return !getKeys().hasNext();
 160  
     }
 161  
 
 162  
     public boolean containsKey(String key)
 163  
     {
 164  10
         return parent.containsKey(getParentKey(key));
 165  
     }
 166  
 
 167  
     public void addPropertyDirect(String key, Object value)
 168  
     {
 169  10
         parent.addProperty(getParentKey(key), value);
 170  10
     }
 171  
 
 172  
     public void setProperty(String key, Object value)
 173  
     {
 174  7
         parent.setProperty(getParentKey(key), value);
 175  7
     }
 176  
 
 177  
     public void clearProperty(String key)
 178  
     {
 179  1
         parent.clearProperty(getParentKey(key));
 180  1
     }
 181  
 
 182  
     public Object getProperty(String key)
 183  
     {
 184  41
         return parent.getProperty(getParentKey(key));
 185  
     }
 186  
 
 187  
     public Iterator getKeys(String prefix)
 188  
     {
 189  1
         return new TransformIterator(parent.getKeys(getParentKey(prefix)), new Transformer()
 190  
         {
 191  1
             public Object transform(Object obj)
 192  
             {
 193  2
                 return getChildKey((String) obj);
 194  
             }
 195  
         });
 196  
     }
 197  
 
 198  
     public Iterator getKeys()
 199  
     {
 200  31
         return new TransformIterator(parent.getKeys(prefix), new Transformer()
 201  
         {
 202  31
             public Object transform(Object obj)
 203  
             {
 204  104
                 return getChildKey((String) obj);
 205  
             }
 206  
         });
 207  
     }
 208  
 
 209  
     protected Object interpolate(Object base)
 210  
     {
 211  40
         if (delimiter == null && "".equals(prefix))
 212  
         {
 213  20
             return super.interpolate(base);
 214  
         }
 215  
         else
 216  
         {
 217  20
             SubsetConfiguration config = new SubsetConfiguration(parent, "");
 218  20
             return config.interpolate(base);
 219  
         }
 220  
     }
 221  
 
 222  
     protected String interpolate(String base)
 223  
     {
 224  15
         return super.interpolate(base);
 225  
     }
 226  
 
 227  
     /**
 228  
      * {@inheritDoc}
 229  
      *
 230  
      * Change the behaviour of the parent configuration if it supports this feature.
 231  
      */
 232  
     public void setThrowExceptionOnMissing(boolean throwExceptionOnMissing)
 233  
     {
 234  1
         if (parent instanceof AbstractConfiguration)
 235  
         {
 236  1
             ((AbstractConfiguration) parent).setThrowExceptionOnMissing(throwExceptionOnMissing);
 237  1
         }
 238  
         else
 239  
         {
 240  0
             super.setThrowExceptionOnMissing(throwExceptionOnMissing);
 241  
         }
 242  1
     }
 243  
 
 244  
     /**
 245  
      * {@inheritDoc}
 246  
      *
 247  
      * The subset inherits this feature from its parent if it supports this feature.
 248  
      */
 249  
     public boolean isThrowExceptionOnMissing()
 250  
     {
 251  2
         if (parent instanceof AbstractConfiguration)
 252  
         {
 253  2
             return ((AbstractConfiguration) parent).isThrowExceptionOnMissing();
 254  
         }
 255  
         else
 256  
         {
 257  0
             return super.isThrowExceptionOnMissing();
 258  
         }
 259  
     }
 260  
 
 261  
     /**
 262  
      * Returns the list delimiter. This property will be fetched from the parent
 263  
      * configuration if supported.
 264  
      *
 265  
      * @return the list delimiter
 266  
      * @since 1.4
 267  
      */
 268  
     public char getListDelimiter()
 269  
     {
 270  4
         return (parent instanceof AbstractConfiguration) ? ((AbstractConfiguration) parent)
 271  
                 .getListDelimiter()
 272  
                 : super.getListDelimiter();
 273  
     }
 274  
 
 275  
     /**
 276  
      * Sets the list delimiter. If the parent configuration supports this
 277  
      * feature, the delimiter will be set at the parent.
 278  
      *
 279  
      * @param delim the new list delimiter
 280  
      * @since 1.4
 281  
      */
 282  
     public void setListDelimiter(char delim)
 283  
     {
 284  2
         if (parent instanceof AbstractConfiguration)
 285  
         {
 286  2
             ((AbstractConfiguration) parent).setListDelimiter(delim);
 287  2
         }
 288  
         else
 289  
         {
 290  0
             super.setListDelimiter(delim);
 291  
         }
 292  2
     }
 293  
 
 294  
     /**
 295  
      * Returns a flag whether string properties should be checked for list
 296  
      * delimiter characters. This implementation ensures that this flag is kept
 297  
      * in sync with the parent configuration if this object supports this
 298  
      * feature.
 299  
      *
 300  
      * @return the delimiter parsing disabled flag
 301  
      * @since 1.4
 302  
      */
 303  
     public boolean isDelimiterParsingDisabled()
 304  
     {
 305  5
         return (parent instanceof AbstractConfiguration) ? ((AbstractConfiguration) parent)
 306  
                 .isDelimiterParsingDisabled()
 307  
                 : super.isDelimiterParsingDisabled();
 308  
     }
 309  
 
 310  
     /**
 311  
      * Sets a flag whether list parsing is disabled. This implementation will
 312  
      * also set the flag at the parent configuration if this object supports
 313  
      * this feature.
 314  
      *
 315  
      * @param delimiterParsingDisabled the delimiter parsing disabled flag
 316  
      * @since 1.4
 317  
      */
 318  
     public void setDelimiterParsingDisabled(boolean delimiterParsingDisabled)
 319  
     {
 320  2
         if (parent instanceof AbstractConfiguration)
 321  
         {
 322  2
             ((AbstractConfiguration) parent)
 323  
                     .setDelimiterParsingDisabled(delimiterParsingDisabled);
 324  2
         }
 325  
         else
 326  
         {
 327  0
             super.setDelimiterParsingDisabled(delimiterParsingDisabled);
 328  
         }
 329  2
     }
 330  
 }