001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.configuration;
019    
020    import static org.junit.Assert.assertEquals;
021    import static org.junit.Assert.assertFalse;
022    import static org.junit.Assert.assertNotNull;
023    import static org.junit.Assert.assertNull;
024    import static org.junit.Assert.assertTrue;
025    
026    import java.io.File;
027    import java.util.ArrayList;
028    import java.util.Iterator;
029    import java.util.List;
030    
031    import org.junit.Before;
032    import org.junit.Test;
033    
034    /**
035     * Test loading multiple configurations.
036     *
037     * @version $Id: TestNullCompositeConfiguration.java 1224814 2011-12-26 21:15:53Z oheger $
038     */
039    public class TestNullCompositeConfiguration
040    {
041        protected PropertiesConfiguration conf1;
042        protected PropertiesConfiguration conf2;
043        protected XMLConfiguration xmlConf;
044        protected CompositeConfiguration cc;
045    
046        /** The File that we test with */
047        private String testProperties = ConfigurationAssert.getTestFile("test.properties").getAbsolutePath();
048        private String testProperties2 = ConfigurationAssert.getTestFile("test2.properties").getAbsolutePath();
049        private String testPropertiesXML = ConfigurationAssert.getTestFile("test.xml").getAbsolutePath();
050    
051        @Before
052        public void setUp() throws Exception
053        {
054            cc = new CompositeConfiguration();
055            conf1 = new PropertiesConfiguration(testProperties);
056            conf2 = new PropertiesConfiguration(testProperties2);
057            xmlConf = new XMLConfiguration(new File(testPropertiesXML));
058    
059            cc.setThrowExceptionOnMissing(false);
060        }
061    
062        @Test
063        public void testThrowExceptionOnMissing()
064        {
065            assertFalse("Throw Exception Property is set!", cc.isThrowExceptionOnMissing());
066        }
067    
068        @Test
069        public void testAddRemoveConfigurations() throws Exception
070        {
071            cc.addConfiguration(conf1);
072            assertEquals(2, cc.getNumberOfConfigurations());
073            cc.addConfiguration(conf1);
074            assertEquals(2, cc.getNumberOfConfigurations());
075            cc.addConfiguration(conf2);
076            assertEquals(3, cc.getNumberOfConfigurations());
077            cc.removeConfiguration(conf1);
078            assertEquals(2, cc.getNumberOfConfigurations());
079            cc.clear();
080            assertEquals(1, cc.getNumberOfConfigurations());
081        }
082    
083        @Test
084        public void testGetPropertyWIncludes() throws Exception
085        {
086            cc.addConfiguration(conf1);
087            cc.addConfiguration(conf2);
088            List<Object> l = cc.getList("packages");
089            assertTrue(l.contains("packagea"));
090        }
091    
092        @Test
093        public void testGetProperty() throws Exception
094        {
095            cc.addConfiguration(conf1);
096            cc.addConfiguration(conf2);
097            assertEquals("Make sure we get the property from conf1 first", "test.properties", cc.getString("propertyInOrder"));
098            cc.clear();
099    
100            cc.addConfiguration(conf2);
101            cc.addConfiguration(conf1);
102            assertEquals("Make sure we get the property from conf2 first", "test2.properties", cc.getString("propertyInOrder"));
103        }
104    
105        @Test
106        public void testCantRemoveMemoryConfig() throws Exception
107        {
108            cc.clear();
109            assertEquals(1, cc.getNumberOfConfigurations());
110    
111            Configuration internal = cc.getConfiguration(0);
112            cc.removeConfiguration(internal);
113    
114            assertEquals(1, cc.getNumberOfConfigurations());
115        }
116    
117        @Test
118        public void testGetPropertyMissing() throws Exception
119        {
120            cc.addConfiguration(conf1);
121            cc.addConfiguration(conf2);
122    
123            assertNull("Bogus property is not null!", cc.getString("bogus.property"));
124    
125            assertTrue("Should be false", !cc.getBoolean("test.missing.boolean", false));
126            assertTrue("Should be true", cc.getBoolean("test.missing.boolean.true", true));
127        }
128    
129        @Test
130        public void testMultipleTypesOfConfigs() throws Exception
131        {
132            cc.addConfiguration(conf1);
133            cc.addConfiguration(xmlConf);
134            assertEquals("Make sure we get the property from conf1 first", 1, cc.getInt("test.short"));
135            cc.clear();
136    
137            cc.addConfiguration(xmlConf);
138            cc.addConfiguration(conf1);
139            assertEquals("Make sure we get the property from xml", 8, cc.getInt("test.short"));
140        }
141    
142        @Test
143        public void testPropertyExistsInOnlyOneConfig() throws Exception
144        {
145            cc.addConfiguration(conf1);
146            cc.addConfiguration(xmlConf);
147            assertEquals("value", cc.getString("element"));
148        }
149    
150        /**
151         * Tests getting a default when the key doesn't exist
152         */
153        @Test
154        public void testDefaultValueWhenKeyMissing() throws Exception
155        {
156            cc.addConfiguration(conf1);
157            cc.addConfiguration(xmlConf);
158            assertEquals("default", cc.getString("bogus", "default"));
159            assertTrue(1.4 == cc.getDouble("bogus", 1.4));
160            assertTrue(1.4 == cc.getDouble("bogus", 1.4));
161        }
162    
163        @Test
164        public void testGettingConfiguration() throws Exception
165        {
166            cc.addConfiguration(conf1);
167            cc.addConfiguration(xmlConf);
168            assertEquals(PropertiesConfiguration.class, cc.getConfiguration(0).getClass());
169            assertEquals(XMLConfiguration.class, cc.getConfiguration(1).getClass());
170        }
171    
172        /**
173         * Tests setting values.  These are set in memory mode only!
174         */
175        @Test
176        public void testClearingProperty() throws Exception
177        {
178            cc.addConfiguration(conf1);
179            cc.addConfiguration(xmlConf);
180            cc.clearProperty("test.short");
181            assertTrue("Make sure test.short is gone!", !cc.containsKey("test.short"));
182        }
183    
184        /**
185         * Tests adding values.  Make sure they _DON'T_ override any other properties but add to the
186         * existing properties  and keep sequence
187         */
188        @Test
189        public void testAddingProperty() throws Exception
190        {
191            cc.addConfiguration(conf1);
192            cc.addConfiguration(xmlConf);
193    
194            String[] values = cc.getStringArray("test.short");
195    
196            assertEquals("Number of values before add is wrong!", 1, values.length);
197            assertEquals("First Value before add is wrong", "1", values[0]);
198    
199            cc.addProperty("test.short", "88");
200    
201            values = cc.getStringArray("test.short");
202    
203            assertEquals("Number of values is wrong!", 2, values.length);
204            assertEquals("First Value is wrong", "1", values[0]);
205            assertEquals("Third Value is wrong", "88", values[1]);
206        }
207    
208        /**
209         * Tests setting values.  These are set in memory mode only!
210         */
211        @Test
212        public void testSettingMissingProperty() throws Exception
213        {
214            cc.addConfiguration(conf1);
215            cc.addConfiguration(xmlConf);
216            cc.setProperty("my.new.property", "supernew");
217            assertEquals("supernew", cc.getString("my.new.property"));
218        }
219    
220        /**
221         * Tests retrieving subsets of configurations
222         */
223        @Test
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        @Test
244        public void testSubsetCanResolve() throws Exception
245        {
246            cc = new CompositeConfiguration();
247            final BaseConfiguration config = new BaseConfiguration();
248            config.addProperty("subset.tempfile", "${java.io.tmpdir}/file.tmp");
249            cc.addConfiguration(config);
250            cc.addConfiguration(ConfigurationConverter.getConfiguration(System.getProperties()));
251    
252            Configuration subset = cc.subset("subset");
253            assertEquals(System.getProperty("java.io.tmpdir") + "/file.tmp", subset.getString("tempfile"));
254        }
255    
256        /**
257          * Tests {@code List} parsing.
258          */
259        @Test
260        public void testList() throws Exception
261        {
262            cc.addConfiguration(conf1);
263            cc.addConfiguration(xmlConf);
264    
265            List<Object> packages = cc.getList("packages");
266            // we should get 3 packages here
267            assertEquals(3, packages.size());
268    
269            List<Object> defaultList = new ArrayList<Object>();
270            defaultList.add("1");
271            defaultList.add("2");
272    
273            packages = cc.getList("packages.which.dont.exist", defaultList);
274            // we should get 2 packages here
275            assertEquals(2, packages.size());
276        }
277    
278        /**
279         * Tests {@code String} array parsing.
280         */
281        @Test
282        public void testStringArray() throws Exception
283        {
284            cc.addConfiguration(conf1);
285            cc.addConfiguration(xmlConf);
286    
287            String[] packages = cc.getStringArray("packages");
288            // we should get 3 packages here
289            assertEquals(3, packages.length);
290    
291            packages = cc.getStringArray("packages.which.dont.exist");
292            // we should get 0 packages here
293            assertEquals(0, packages.length);
294        }
295    
296        @Test
297        public void testGetList()
298        {
299            Configuration conf1 = new BaseConfiguration();
300            conf1.addProperty("array", "value1");
301            conf1.addProperty("array", "value2");
302    
303            Configuration conf2 = new BaseConfiguration();
304            conf2.addProperty("array", "value3");
305            conf2.addProperty("array", "value4");
306    
307            cc.addConfiguration(conf1);
308            cc.addConfiguration(conf2);
309    
310            // check the composite 'array' property
311            List<Object> list = cc.getList("array");
312            assertNotNull("null list", list);
313            assertEquals("list size", 2, list.size());
314            assertTrue("'value1' not found in the list", list.contains("value1"));
315            assertTrue("'value2' not found in the list", list.contains("value2"));
316    
317            // add an element to the list in the composite configuration
318            cc.addProperty("array", "value5");
319    
320            // test the new list
321            list = cc.getList("array");
322            assertNotNull("null list", list);
323            assertEquals("list size", 3, list.size());
324            assertTrue("'value1' not found in the list", list.contains("value1"));
325            assertTrue("'value2' not found in the list", list.contains("value2"));
326            assertTrue("'value5' not found in the list", list.contains("value5"));
327        }
328    
329        @Test
330        public void testGetVector()
331        {
332            Configuration conf1 = new BaseConfiguration();
333            conf1.addProperty("array", "value1");
334            conf1.addProperty("array", "value2");
335    
336            Configuration conf2 = new BaseConfiguration();
337            conf2.addProperty("array", "value3");
338            conf2.addProperty("array", "value4");
339    
340            cc.addConfiguration(conf1);
341            cc.addConfiguration(conf2);
342    
343            // add an element to the vector in the composite configuration
344            cc.addProperty("array", "value5");
345    
346            List<Object> list = cc.getList("array");
347            assertEquals("Wrong number of elements", 3, list.size());
348            assertEquals("Wrong element 1", "value1", list.get(0));
349            assertEquals("Wrong element 2", "value2", list.get(1));
350            assertEquals("Wrong element 3", "value5", list.get(2));
351        }
352    
353        /**
354          * Tests {@code getKeys()} preserves the order
355          */
356        @Test
357        public void testGetKeysPreservesOrder() throws Exception
358        {
359            cc.addConfiguration(conf1);
360            List<String> orderedList = new ArrayList<String>();
361            for (Iterator<String> keys = conf1.getKeys(); keys.hasNext();)
362            {
363                orderedList.add(keys.next());
364            }
365            List<String> iteratedList = new ArrayList<String>();
366            for (Iterator<String> keys = cc.getKeys(); keys.hasNext();)
367            {
368                iteratedList.add(keys.next());
369            }
370            assertEquals(orderedList.size(), iteratedList.size());
371            for (int i = 0; i < orderedList.size(); i++)
372            {
373                assertEquals(orderedList.get(i), iteratedList.get(i));
374            }
375        }
376    
377        /**
378          * Tests {@code getKeys(String key)} preserves the order
379          */
380        @Test
381        public void testGetKeys2PreservesOrder() throws Exception
382        {
383            cc.addConfiguration(conf1);
384            List<String> orderedList = new ArrayList<String>();
385            for (Iterator<String> keys = conf1.getKeys("test"); keys.hasNext();)
386            {
387                orderedList.add(keys.next());
388            }
389            List<String> iteratedList = new ArrayList<String>();
390            for (Iterator<String> keys = cc.getKeys("test"); keys.hasNext();)
391            {
392                iteratedList.add(keys.next());
393            }
394            assertEquals(orderedList.size(), iteratedList.size());
395            for (int i = 0; i < orderedList.size(); i++)
396            {
397                assertEquals(orderedList.get(i), iteratedList.get(i));
398            }
399        }
400    
401        @Test
402        public void testGetStringWithDefaults()
403        {
404            BaseConfiguration defaults = new BaseConfiguration();
405            defaults.addProperty("default", "default string");
406    
407            Configuration c = new CompositeConfiguration(defaults);
408    
409            c.addProperty("string", "test string");
410    
411            assertEquals("test string", c.getString("string"));
412    
413            assertNull("XXX should have been null!", c.getString("XXX"));
414    
415            //test defaults
416            assertEquals(
417                "test string",
418                c.getString("string", "some default value"));
419            assertEquals("default string", c.getString("default"));
420            assertEquals(
421                "default string",
422                c.getString("default", "some default value"));
423            assertEquals(
424                "some default value",
425                c.getString("XXX", "some default value"));
426        }
427    
428        @Test
429        public void testCheckingInMemoryConfiguration() throws Exception
430        {
431            String TEST_KEY = "testKey";
432            Configuration defaults = new PropertiesConfiguration();
433            defaults.setProperty(TEST_KEY, "testValue");
434            Configuration testConfiguration = new CompositeConfiguration(defaults);
435            assertTrue(testConfiguration.containsKey(TEST_KEY));
436            assertFalse(testConfiguration.isEmpty());
437            boolean foundTestKey = false;
438            Iterator<String> i = testConfiguration.getKeys();
439            for (; i.hasNext();)
440            {
441                String key = i.next();
442                if (key.equals(TEST_KEY))
443                {
444                    foundTestKey = true;
445                }
446            }
447            assertTrue(foundTestKey);
448            testConfiguration.clearProperty(TEST_KEY);
449            assertFalse(testConfiguration.containsKey(TEST_KEY));
450        }
451    }