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