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.Vector;
24  
25  import junit.framework.TestCase;
26  
27  /***
28   * Test loading multiple configurations.
29   *
30   * @version $Id: TestNullCompositeConfiguration.java,v 1.2 2004/09/22 17:17:30 ebourg Exp $
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          Vector v = cc.getVector("packages");
81          assertTrue(v.contains("packagea"));
82      }
83      
84      public void testGetProperty() throws Exception
85      {
86          cc.addConfiguration(conf1);
87          cc.addConfiguration(conf2);
88          assertEquals("Make sure we get the property from conf1 first", "test.properties", cc.getString("propertyInOrder"));
89          cc.clear();
90  
91          cc.addConfiguration(conf2);
92          cc.addConfiguration(conf1);
93          assertEquals("Make sure we get the property from conf2 first", "test2.properties", cc.getString("propertyInOrder"));
94      }
95  
96      public void testCantRemoveMemoryConfig() throws Exception
97      {
98          cc.clear();
99          assertEquals(1, cc.getNumberOfConfigurations());
100 
101         Configuration internal = cc.getConfiguration(0);
102         cc.removeConfiguration(internal);
103 
104         assertEquals(1, cc.getNumberOfConfigurations());
105 
106     }
107 
108     public void testGetPropertyMissing() throws Exception
109     {
110         cc.addConfiguration(conf1);
111         cc.addConfiguration(conf2);
112 
113         assertNull("Bogus property is not null!", cc.getString("bogus.property"));
114 
115         assertTrue("Should be false", !cc.getBoolean("test.missing.boolean", false));
116         assertTrue("Should be true", cc.getBoolean("test.missing.boolean.true", true));
117 
118     }
119 
120     /***
121      * Tests <code>List</code> parsing.
122      */
123     public void testMultipleTypesOfConfigs() throws Exception
124     {
125         cc.addConfiguration(conf1);
126         cc.addConfiguration(xmlConf);
127         assertEquals("Make sure we get the property from conf1 first", 1, cc.getInt("test.short"));
128         cc.clear();
129 
130         cc.addConfiguration(xmlConf);
131         cc.addConfiguration(conf1);
132         assertEquals("Make sure we get the property from xml", 8, cc.getInt("test.short"));
133     }
134 
135     /***
136      * Tests <code>List</code> parsing.
137      */
138     public void testPropertyExistsInOnlyOneConfig() throws Exception
139     {
140         cc.addConfiguration(conf1);
141         cc.addConfiguration(xmlConf);
142         assertEquals("value", cc.getString("element"));
143     }
144 
145     /***
146      * Tests getting a default when the key doesn't exist
147      */
148     public void testDefaultValueWhenKeyMissing() throws Exception
149     {
150         cc.addConfiguration(conf1);
151         cc.addConfiguration(xmlConf);
152         assertEquals("default", cc.getString("bogus", "default"));
153         assertTrue(1.4 == cc.getDouble("bogus", 1.4));
154         assertTrue(1.4 == cc.getDouble("bogus", 1.4));
155     }
156 
157     /***
158      * Tests <code>List</code> parsing.
159      */
160     public void testGettingConfiguration() throws Exception
161     {
162         cc.addConfiguration(conf1);
163         cc.addConfiguration(xmlConf);
164         assertEquals(PropertiesConfiguration.class, cc.getConfiguration(0).getClass());
165         assertEquals(XMLConfiguration.class, cc.getConfiguration(1).getClass());
166     }
167 
168     /***
169      * Tests setting values.  These are set in memory mode only!
170      */
171     public void testClearingProperty() throws Exception
172     {
173         cc.addConfiguration(conf1);
174         cc.addConfiguration(xmlConf);
175         cc.clearProperty("test.short");
176         assertTrue("Make sure test.short is gone!", !cc.containsKey("test.short"));
177     }
178 
179     /***
180      * Tests adding values.  Make sure they _DON'T_ override any other properties but add to the
181      * existing properties  and keep sequence
182      */
183     public void testAddingProperty() throws Exception
184     {
185         cc.addConfiguration(conf1);
186         cc.addConfiguration(xmlConf);
187 
188         String[] values = cc.getStringArray("test.short");
189 
190         assertEquals("Number of values before add is wrong!", 1, values.length);
191         assertEquals("First Value before add is wrong", "1", values[0]);
192 
193         cc.addProperty("test.short", "88");
194 
195         values = cc.getStringArray("test.short");
196 
197         assertEquals("Number of values is wrong!", 2, values.length);
198         assertEquals("First Value is wrong", "1", values[0]);
199         assertEquals("Third Value is wrong", "88", values[1]);
200     }
201 
202     /***
203      * Tests setting values.  These are set in memory mode only!
204      */
205     public void testSettingMissingProperty() throws Exception
206     {
207         cc.addConfiguration(conf1);
208         cc.addConfiguration(xmlConf);
209         cc.setProperty("my.new.property", "supernew");
210         assertEquals("supernew", cc.getString("my.new.property"));
211     }
212 
213     /***
214      * Tests retrieving subsets of configurations
215      */
216     public void testGettingSubset() throws Exception
217     {
218         cc.addConfiguration(conf1);
219         cc.addConfiguration(xmlConf);
220 
221         Configuration subset = null;
222         subset = cc.subset("test");
223         assertNotNull(subset);
224         assertFalse("Shouldn't be empty", subset.isEmpty());
225         assertEquals("Make sure the initial loaded configs subset overrides any later add configs subset", "1", subset.getString("short"));
226 
227         cc.setProperty("test.short", "43");
228         subset = cc.subset("test");
229         assertEquals("Make sure the initial loaded configs subset overrides any later add configs subset", "43", subset.getString("short"));
230     }
231 
232     /***
233      * Tests subsets and still can resolve elements
234      */
235     public void testSubsetCanResolve() throws Exception
236     {
237         cc = new CompositeConfiguration();
238         final BaseConfiguration config = new BaseConfiguration();
239         config.addProperty("subset.tempfile", "${java.io.tmpdir}/file.tmp");
240         cc.addConfiguration(config);
241         cc.addConfiguration(ConfigurationConverter.getConfiguration(System.getProperties()));
242 
243         Configuration subset = cc.subset("subset");
244         assertEquals(System.getProperty("java.io.tmpdir") + "/file.tmp", subset.getString("tempfile"));
245     }
246 
247     /***
248       * Tests <code>List</code> parsing.
249       */
250     public void testList() throws Exception
251     {
252         cc.addConfiguration(conf1);
253         cc.addConfiguration(xmlConf);
254 
255         List packages = cc.getList("packages");
256         // we should get 3 packages here
257         assertEquals(3, packages.size());
258 
259         Vector vpackages = cc.getVector("packages");
260         // we should get 3 packages here
261         assertEquals(3, vpackages.size());
262 
263         List defaultList = new ArrayList();
264         defaultList.add("1");
265         defaultList.add("2");
266 
267         packages = cc.getList("packages.which.dont.exist", defaultList);
268         // we should get 2 packages here
269         assertEquals(2, packages.size());
270 
271         Vector defaultVector = new Vector();
272         defaultVector.add("1");
273         defaultVector.add("2");
274 
275         vpackages = cc.getVector("packages.which.dont.exist", defaultVector);
276         // we should get 2 packages here
277         assertEquals(2, vpackages.size());
278     }
279 
280     /***
281       * Tests <code>String</code> array parsing.
282       */
283     public void testStringArray() throws Exception
284     {
285         cc.addConfiguration(conf1);
286         cc.addConfiguration(xmlConf);
287 
288         String[] packages = cc.getStringArray("packages");
289         // we should get 3 packages here
290         assertEquals(3, packages.length);
291 
292         packages = cc.getStringArray("packages.which.dont.exist");
293         // we should get 0 packages here
294         assertEquals(0, packages.length);
295     }
296 
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 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     public void testGetVector()
330     {
331         Configuration conf1 = new BaseConfiguration();
332         conf1.addProperty("array", "value1");
333         conf1.addProperty("array", "value2");
334 
335         Configuration conf2 = new BaseConfiguration();
336         conf2.addProperty("array", "value3");
337         conf2.addProperty("array", "value4");
338 
339         cc.addConfiguration(conf1);
340         cc.addConfiguration(conf2);
341 
342         // check the composite 'array' property
343         Vector vector = cc.getVector("array");
344         assertNotNull("null vector", vector);
345         assertEquals("vector size", 2, vector.size());
346         assertTrue("'value1' not found in the vector", vector.contains("value1"));
347         assertTrue("'value2' not found in the vector", vector.contains("value2"));
348 
349         // add an element to the vector in the composite configuration
350         cc.addProperty("array", "value5");
351 
352         List list = cc.getList("array");
353         
354         for (Iterator it = list.iterator(); it.hasNext(); )
355         {
356             Object value = it.next();
357             System.out.println(value.getClass().getName() + " -> " + value);
358         }
359 
360         Vector lVector = cc.getVector("array");
361         
362         for (Iterator it = lVector.iterator(); it.hasNext(); )
363         {
364             Object value = it.next();
365             System.out.println(value.getClass().getName() + " -> " + value);
366         }
367 
368         // test the new vector
369         vector = cc.getVector("array");
370         assertNotNull("null vector", vector);
371         assertEquals("vector size", 3, vector.size());
372         assertTrue("'value1' not found in the vector", vector.contains("value1"));
373         assertTrue("'value2' not found in the vector", vector.contains("value2"));
374         assertTrue("'value5' not found in the vector", vector.contains("value5"));
375     }
376 
377     /***
378       * Tests <code>getKeys</code> preserves the order
379       */
380     public void testGetKeysPreservesOrder() throws Exception
381     {
382         cc.addConfiguration(conf1);
383         List orderedList = new ArrayList();
384         for (Iterator keys = conf1.getKeys();keys.hasNext();){
385             orderedList.add(keys.next());
386         }
387         List iteratedList = new ArrayList();
388         for (Iterator keys = cc.getKeys();keys.hasNext();){
389             iteratedList.add(keys.next());
390         }
391         assertEquals(orderedList.size(),iteratedList.size());
392         for (int i =0;i<orderedList.size();i++){
393             assertEquals(orderedList.get(i),iteratedList.get(i));
394         }        
395     }    
396 
397     /***
398       * Tests <code>getKeys(String key)</code> preserves the order
399       */
400     public void testGetKeys2PreservesOrder() throws Exception
401     {
402         cc.addConfiguration(conf1);
403         List orderedList = new ArrayList();
404         for (Iterator keys = conf1.getKeys("test");keys.hasNext();){
405             orderedList.add(keys.next());
406         }
407         List iteratedList = new ArrayList();
408         for (Iterator keys = cc.getKeys("test");keys.hasNext();){
409             iteratedList.add(keys.next());
410         }
411         assertEquals(orderedList.size(),iteratedList.size());
412         for (int i =0;i<orderedList.size();i++){
413             assertEquals(orderedList.get(i),iteratedList.get(i));
414         }        
415     }        
416     
417     public void testGetStringWithDefaults()
418     {
419         BaseConfiguration defaults = new BaseConfiguration();
420         defaults.addProperty("default", "default string");
421 
422         Configuration c = new CompositeConfiguration(defaults);
423         
424         c.addProperty("string", "test string");
425 
426         assertEquals("test string", c.getString("string"));
427 
428         assertNull("XXX should have been null!", c.getString("XXX"));
429 
430         //test defaults
431         assertEquals(
432             "test string",
433             c.getString("string", "some default value"));
434         assertEquals("default string", c.getString("default"));
435         assertEquals(
436             "default string",
437             c.getString("default", "some default value"));
438         assertEquals(
439             "some default value",
440             c.getString("XXX", "some default value"));
441     }
442     
443     public void testCheckingInMemoryConfiguration() throws Exception
444     {
445         String TEST_KEY = "testKey";
446         Configuration defaults = new PropertiesConfiguration();
447         defaults.setProperty(TEST_KEY,"testValue");
448         Configuration testConfiguration = new CompositeConfiguration(defaults);
449         assertTrue(testConfiguration.containsKey(TEST_KEY));
450         assertFalse(testConfiguration.isEmpty());
451         boolean foundTestKey = false;
452         Iterator i = testConfiguration.getKeys();
453         //assertTrue(i instanceof IteratorChain);
454         //IteratorChain ic = (IteratorChain)i;
455         //assertEquals(2,i.size());
456         for (;i.hasNext();){
457             String key = (String)i.next();
458             if(key.equals(TEST_KEY)){
459                 foundTestKey = true;
460             }
461         }
462         assertTrue(foundTestKey);
463         testConfiguration.clearProperty(TEST_KEY);
464         assertFalse(testConfiguration.containsKey(TEST_KEY));
465     }    
466 }