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