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