    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.io.File;
    20  import java.util.ArrayList;
    21  import java.util.Iterator;
    22  import java.util.List;
    23  import java.util.NoSuchElementException;
    24  import java.util.Vector;
    25
    26  import junit.framework.TestCase;
    27
    28  /***
    29   * Test loading multiple configurations.
    30   *
    31   * @version $Id: TestCompositeConfiguration.java,v 1.14 2004/10/05 22:56:58 ebourg Exp $
    32   */
    33  public class TestCompositeConfiguration extends TestCase
    34  {
    35      protected PropertiesConfiguration conf1;
    36      protected PropertiesConfiguration conf2;
    37      protected XMLConfiguration xmlConf;
    38      protected CompositeConfiguration cc;
    39
    40      /***
    41       * The File that we test with
    42       */
    43      private String testProperties = new File("conf/test.properties").getAbsolutePath();
    44      private String testProperties2 = new File("conf/test2.properties").getAbsolutePath();
    45      private String testPropertiesXML = new File("conf/test.xml").getAbsolutePath();
    46
    47      protected void setUp() throws Exception
    48      {
    49          cc = new CompositeConfiguration();
    50          conf1 = new PropertiesConfiguration(testProperties);
    51          conf2 = new PropertiesConfiguration(testProperties2);
    52          xmlConf = new XMLConfiguration(new File(testPropertiesXML));
    53
    54          cc.setThrowExceptionOnMissing(true);
    55      }
    56
    57      public void testThrowExceptionOnMissing()
    58      {
    59          assertTrue("Throw Exception Property is not set!", cc.isThrowExceptionOnMissing());
    60      }
    61
    62      public void testAddRemoveConfigurations() throws Exception
    63      {
    64          cc.addConfiguration(conf1);
    65          assertEquals(2, cc.getNumberOfConfigurations());
    66          cc.addConfiguration(conf1);
    67          assertEquals(2, cc.getNumberOfConfigurations());
    68          cc.addConfiguration(conf2);
    69          assertEquals(3, cc.getNumberOfConfigurations());
    70          cc.removeConfiguration(conf1);
    71          assertEquals(2, cc.getNumberOfConfigurations());
    72          cc.clear();
    73          assertEquals(1, cc.getNumberOfConfigurations());
    74      }
    75
    76      public void testGetPropertyWIncludes() throws Exception
    77      {
    78          cc.addConfiguration(conf1);
    79          cc.addConfiguration(conf2);
    80          List l = cc.getList("packages");
    81          assertTrue(l.contains("packagea"));
    82
    83          Vector v = cc.getVector("packages");
    84          assertTrue(v.contains("packagea"));
    85      }
    86
    87      public void testGetProperty() throws Exception
    88      {
    89          cc.addConfiguration(conf1);
    90          cc.addConfiguration(conf2);
    91          assertEquals("Make sure we get the property from conf1 first", "test.properties", cc.getString("propertyInOrder"));
    92          cc.clear();
    93
    94          cc.addConfiguration(conf2);
    95          cc.addConfiguration(conf1);
    96          assertEquals("Make sure we get the property from conf2 first", "test2.properties", cc.getString("propertyInOrder"));
    97      }
    98
    99      public void testCantRemoveMemoryConfig() throws Exception
    100     {
    101         cc.clear();
    102         assertEquals(1, cc.getNumberOfConfigurations());
    103
    104         Configuration internal = cc.getConfiguration(0);
    105         cc.removeConfiguration(internal);
    106
    107         assertEquals(1, cc.getNumberOfConfigurations());
    108     }
    109
    110     public void testGetPropertyMissing() throws Exception
    111     {
    112         cc.addConfiguration(conf1);
    113         cc.addConfiguration(conf2);
    114         try
    115         {
    116             assertNull(cc.getString("bogus.property"));
    117             fail("Should have thrown a NoSuchElementException");
    118         }
    119         catch (NoSuchElementException nsee)
    120         {
    121             assertTrue(nsee.getMessage().indexOf("bogus.property") > -1);
    122         }
    123
    124         assertTrue("Should be false", !cc.getBoolean("test.missing.boolean", false));
    125         assertTrue("Should be true", cc.getBoolean("test.missing.boolean.true", true));
    126     }
    127
    128     /***
    129      * Tests <code>List</code> parsing.
    130      */
    131     public void testMultipleTypesOfConfigs() throws Exception
    132     {
    133         cc.addConfiguration(conf1);
    134         cc.addConfiguration(xmlConf);
    135         assertEquals("Make sure we get the property from conf1 first", 1, cc.getInt("test.short"));
    136         cc.clear();
    137
    138         cc.addConfiguration(xmlConf);
    139         cc.addConfiguration(conf1);
    140         assertEquals("Make sure we get the property from xml", 8, cc.getInt("test.short"));
    141     }
    142
    143     /***
    144      * Tests <code>List</code> parsing.
    145      */
    146     public void testPropertyExistsInOnlyOneConfig() throws Exception
    147     {
    148         cc.addConfiguration(conf1);
    149         cc.addConfiguration(xmlConf);
    150         assertEquals("value", cc.getString("element"));
    151     }
    152
    153     /***
    154      * Tests getting a default when the key doesn't exist
    155      */
    156     public void testDefaultValueWhenKeyMissing() throws Exception
    157     {
    158         cc.addConfiguration(conf1);
    159         cc.addConfiguration(xmlConf);
    160         assertEquals("default", cc.getString("bogus", "default"));
    161         assertTrue(1.4 == cc.getDouble("bogus", 1.4));
    162         assertTrue(1.4 == cc.getDouble("bogus", 1.4));
    163     }
    164
    165     /***
    166      * Tests <code>List</code> parsing.
    167      */
    168     public void testGettingConfiguration() throws Exception
    169     {
    170         cc.addConfiguration(conf1);
    171         cc.addConfiguration(xmlConf);
    172         assertEquals(PropertiesConfiguration.class, cc.getConfiguration(0).getClass());
    173         assertEquals(XMLConfiguration.class, cc.getConfiguration(1).getClass());
    174     }
    175
    176     /***
    177      * Tests setting values.  These are set in memory mode only!
    178      */
    179     public void testClearingProperty() throws Exception
    180     {
    181         cc.addConfiguration(conf1);
    182         cc.addConfiguration(xmlConf);
    183         cc.clearProperty("test.short");
    184         assertTrue("Make sure test.short is gone!", !cc.containsKey("test.short"));
    185     }
    186
    187     /***
    188      * Tests adding values.  Make sure they _DON'T_ override any other properties but add to the
    189      * existing properties  and keep sequence
    190      */
    191     public void testAddingProperty() throws Exception
    192     {
    193         cc.addConfiguration(conf1);
    194         cc.addConfiguration(xmlConf);
    195
    196         String[] values = cc.getStringArray("test.short");
    197
    198         assertEquals("Number of values before add is wrong!", 1, values.length);
    199         assertEquals("First Value before add is wrong", "1", values[0]);
    200
    201         cc.addProperty("test.short", "88");
    202
    203         values = cc.getStringArray("test.short");
    204
    205         assertEquals("Number of values is wrong!", 2, values.length);
    206         assertEquals("First Value is wrong", "1", values[0]);
    207         assertEquals("Third Value is wrong", "88", values[1]);
    208     }
    209
    210     /***
    211      * Tests setting values.  These are set in memory mode only!
    212      */
    213     public void testSettingMissingProperty() throws Exception
    214     {
    215         cc.addConfiguration(conf1);
    216         cc.addConfiguration(xmlConf);
    217         cc.setProperty("my.new.property", "supernew");
    218         assertEquals("supernew", cc.getString("my.new.property"));
    219     }
    220
    221     /***
    222      * Tests retrieving subsets of configurations
    223      */
    224     public void testGettingSubset() throws Exception
    225     {
    226         cc.addConfiguration(conf1);
    227         cc.addConfiguration(xmlConf);
    228
    229         Configuration subset = null;
    230         subset = cc.subset("test");
    231         assertNotNull(subset);
    232         assertFalse("Shouldn't be empty", subset.isEmpty());
    233         assertEquals("Make sure the initial loaded configs subset overrides any later add configs subset", "1", subset.getString("short"));
    234
    235         cc.setProperty("test.short", "43");
    236         subset = cc.subset("test");
    237         assertEquals("Make sure the initial loaded configs subset overrides any later add configs subset", "43", subset.getString("short"));
    238     }
    239
    240     /***
    241      * Tests subsets and still can resolve elements
    242      */
    243     public void testSubsetCanResolve() throws Exception
    244     {
    245         cc = new CompositeConfiguration();
    246         final BaseConfiguration config = new BaseConfiguration();
    247         config.addProperty("subset.tempfile", "${java.io.tmpdir}/file.tmp");
    248         cc.addConfiguration(config);
    249         cc.addConfiguration(ConfigurationConverter.getConfiguration(System.getProperties()));
    250
    251         Configuration subset = cc.subset("subset");
    252         assertEquals(System.getProperty("java.io.tmpdir") + "/file.tmp", subset.getString("tempfile"));
    253     }
    254
    255     /***
    256      * Tests <code>List</code> parsing.
    257      */
    258     public void testList() throws Exception
    259     {
    260         cc.addConfiguration(conf1);
    261         cc.addConfiguration(xmlConf);
    262
    263         List packages = cc.getList("packages");
    264         // we should get 3 packages here
    265         assertEquals(3, packages.size());
    266
    267         Vector vpackages = cc.getVector("packages");
    268         // we should get 3 packages here
    269         assertEquals(3, vpackages.size());
    270
    271         List defaultList = new ArrayList();
    272         defaultList.add("1");
    273         defaultList.add("2");
    274
    275         packages = cc.getList("packages.which.dont.exist", defaultList);
    276         // we should get 2 packages here
    277         assertEquals(2, packages.size());
    278
    279         Vector defaultVector = new Vector();
    280         defaultVector.add("1");
    281         defaultVector.add("2");
    282
    283         vpackages = cc.getVector("packages.which.dont.exist", defaultVector);
    284         // we should get 2 packages here
    285         assertEquals(2, vpackages.size());
    286     }
    287
    288     /***
    289      * Tests <code>String</code> array parsing.
    290      */
    291     public void testStringArray() throws Exception
    292     {
    293         cc.addConfiguration(conf1);
    294         cc.addConfiguration(xmlConf);
    295
    296         String[] packages = cc.getStringArray("packages");
    297         // we should get 3 packages here
    298         assertEquals(3, packages.length);
    299
    300         packages = cc.getStringArray("packages.which.dont.exist");
    301         // we should get 0 packages here
    302         assertEquals(0, packages.length);
    303     }
    304
    305     public void testGetList()
    306     {
    307         Configuration conf1 = new BaseConfiguration();
    308         conf1.addProperty("array", "value1");
    309         conf1.addProperty("array", "value2");
    310
    311         Configuration conf2 = new BaseConfiguration();
    312         conf2.addProperty("array", "value3");
    313         conf2.addProperty("array", "value4");
    314
    315         cc.addConfiguration(conf1);
    316         cc.addConfiguration(conf2);
    317
    318         // check the composite 'array' property
    319         List list = cc.getList("array");
    320         assertNotNull("null list", list);
    321         assertEquals("list size", 2, list.size());
    322         assertTrue("'value1' not found in the list", list.contains("value1"));
    323         assertTrue("'value2' not found in the list", list.contains("value2"));
    324
    325         // add an element to the list in the composite configuration
    326         cc.addProperty("array", "value5");
    327
    328         // test the new list
    329         list = cc.getList("array");
    330         assertNotNull("null list", list);
    331         assertEquals("list size", 3, list.size());
    332         assertTrue("'value1' not found in the list", list.contains("value1"));
    333         assertTrue("'value2' not found in the list", list.contains("value2"));
    334         assertTrue("'value5' not found in the list", list.contains("value5"));
    335     }
    336
    337     public void testGetVector()
    338     {
    339         Configuration conf1 = new BaseConfiguration();
    340         conf1.addProperty("array", "value1");
    341         conf1.addProperty("array", "value2");
    342
    343         Configuration conf2 = new BaseConfiguration();
    344         conf2.addProperty("array", "value3");
    345         conf2.addProperty("array", "value4");
    346
    347         cc.addConfiguration(conf1);
    348         cc.addConfiguration(conf2);
    349
    350         // check the composite 'array' property
    351         Vector vector = cc.getVector("array");
    352         assertNotNull("null vector", vector);
    353         assertEquals("vector size", 2, vector.size());
    354         assertTrue("'value1' not found in the vector", vector.contains("value1"));
    355         assertTrue("'value2' not found in the vector", vector.contains("value2"));
    356
    357         // add an element to the vector in the composite configuration
    358         cc.addProperty("array", "value5");
    359
    360         List list = cc.getList("array");
    361
    362         for (Iterator it = list.iterator(); it.hasNext();)
    363         {
    364             Object value = it.next();
    365         }
    366
    367         Vector lVector = cc.getVector("array");
    368
    369         for (Iterator it = lVector.iterator(); it.hasNext();)
    370         {
    371             Object value = it.next();
    372         }
    373
    374         // test the new vector
    375         vector = cc.getVector("array");
    376         assertNotNull("null vector", vector);
    377         assertEquals("vector size", 3, vector.size());
    378         assertTrue("'value1' not found in the vector", vector.contains("value1"));
    379         assertTrue("'value2' not found in the vector", vector.contains("value2"));
    380         assertTrue("'value5' not found in the vector", vector.contains("value5"));
    381     }
    382
    383     /***
    384      * Tests <code>getKeys</code> preserves the order
    385      */
    386     public void testGetKeysPreservesOrder() throws Exception
    387     {
    388         cc.addConfiguration(conf1);
    389         List orderedList = new ArrayList();
    390         for (Iterator keys = conf1.getKeys(); keys.hasNext();)
    391         {
    392             orderedList.add(keys.next());
    393         }
    394         List iteratedList = new ArrayList();
    395         for (Iterator keys = cc.getKeys(); keys.hasNext();)
    396         {
    397             iteratedList.add(keys.next());
    398         }
    399         assertEquals(orderedList.size(), iteratedList.size());
    400         for (int i = 0; i < orderedList.size(); i++)
    401         {
    402             assertEquals(orderedList.get(i), iteratedList.get(i));
    403         }
    404     }
    405
    406     /***
    407      * Tests <code>getKeys(String key)</code> preserves the order
    408      */
    409     public void testGetKeys2PreservesOrder() throws Exception
    410     {
    411         cc.addConfiguration(conf1);
    412         List orderedList = new ArrayList();
    413         for (Iterator keys = conf1.getKeys("test"); keys.hasNext();)
    414         {
    415             orderedList.add(keys.next());
    416         }
    417         List iteratedList = new ArrayList();
    418         for (Iterator keys = cc.getKeys("test"); keys.hasNext();)
    419         {
    420             iteratedList.add(keys.next());
    421         }
    422         assertEquals(orderedList.size(), iteratedList.size());
    423         for (int i = 0; i < orderedList.size(); i++)
    424         {
    425             assertEquals(orderedList.get(i), iteratedList.get(i));
    426         }
    427     }
    428
    429     public void testGetStringWithDefaults()
    430     {
    431         BaseConfiguration defaults = new BaseConfiguration();
    432         defaults.addProperty("default", "default string");
    433
    434         CompositeConfiguration c = new CompositeConfiguration(defaults);
    435         c.setThrowExceptionOnMissing(cc.isThrowExceptionOnMissing());
    436         c.addProperty("string", "test string");
    437
    438         assertEquals("test string", c.getString("string"));
    439         try
    440         {
    441             c.getString("XXX");
    442             fail("Should throw NoSuchElementException exception");
    443         }
    444         catch (NoSuchElementException e)
    445         {
    446             //ok
    447         }
    448         catch (Exception e)
    449         {
    450             fail("Should throw NoSuchElementException exception, not " + e);
    451         }
    452
    453         //test defaults
    454         assertEquals("test string", c.getString("string", "some default value"));
    455         assertEquals("default string", c.getString("default"));
    456         assertEquals("default string", c.getString("default", "some default value"));
    457         assertEquals("some default value", c.getString("XXX", "some default value"));
    458     }
    459
    460     public void testCheckingInMemoryConfiguration() throws Exception
    461     {
    462         String TEST_KEY = "testKey";
    463         Configuration defaults = new PropertiesConfiguration();
    464         defaults.setProperty(TEST_KEY, "testValue");
    465         Configuration testConfiguration = new CompositeConfiguration(defaults);
    466         assertTrue(testConfiguration.containsKey(TEST_KEY));
    467         assertFalse(testConfiguration.isEmpty());
    468         boolean foundTestKey = false;
    469         Iterator i = testConfiguration.getKeys();
    470         //assertTrue(i instanceof IteratorChain);
    471         //IteratorChain ic = (IteratorChain)i;
    472         //assertEquals(2,i.size());
    473         for (; i.hasNext();)
    474         {
    475             String key = (String) i.next();
    476             if (key.equals(TEST_KEY))
    477             {
    478                 foundTestKey = true;
    479             }
    480         }
    481         assertTrue(foundTestKey);
    482         testConfiguration.clearProperty(TEST_KEY);
    483         assertFalse(testConfiguration.containsKey(TEST_KEY));
    484     }
    485
    486     public void testStringArrayInterpolation()
    487     {
    488         CompositeConfiguration config = new CompositeConfiguration();
    489         config.addProperty("base", "foo");
    490         config.addProperty("list", "${base}.bar1");
    491         config.addProperty("list", "${base}.bar2");
    492         config.addProperty("list", "${base}.bar3");
    493
    494         String[] array = config.getStringArray("list");
    495         assertEquals("size", 3, array.length);
    496         assertEquals("1st element", "foo.bar1", array[0]);
    497         assertEquals("2nd element", "foo.bar2", array[1]);
    498         assertEquals("3rd element", "foo.bar3", array[2]);
    499     }
    500 }