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.util.ArrayList;
21 import java.util.Collection;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Set;
26
27 import org.apache.commons.collections.CollectionUtils;
28 import org.apache.commons.configuration.HierarchicalConfiguration.Node;
29 import org.apache.commons.configuration.event.ConfigurationEvent;
30 import org.apache.commons.configuration.event.ConfigurationListener;
31 import org.apache.commons.configuration.tree.DefaultConfigurationNode;
32 import org.apache.commons.configuration.tree.DefaultExpressionEngine;
33 import org.apache.commons.configuration.tree.ExpressionEngine;
34
35 import junit.framework.TestCase;
36
37 /***
38 * Test class for HierarchicalConfiguration.
39 *
40 * @version $Id: TestHierarchicalConfiguration.java 525488 2007-04-04 10:46:33Z oheger $
41 */
42 public class TestHierarchicalConfiguration extends TestCase
43 {
44 private static String[] tables = { "users", "documents" };
45
46 private static String[][] fields =
47 {
48 { "uid", "uname", "firstName", "lastName", "email" },
49 { "docid", "name", "creationDate", "authorID", "version" }
50 };
51
52 private HierarchicalConfiguration config;
53
54 protected void setUp() throws Exception
55 {
56 /***
57 * Initialize the configuration with the following structure:
58 *
59 * tables
60 * table
61 * name
62 * fields
63 * field
64 * name
65 * field
66 * name
67 */
68 config = new HierarchicalConfiguration();
69 HierarchicalConfiguration.Node nodeTables = createNode("tables", null);
70 for(int i = 0; i < tables.length; i++)
71 {
72 HierarchicalConfiguration.Node nodeTable = createNode("table", null);
73 nodeTables.addChild(nodeTable);
74 HierarchicalConfiguration.Node nodeName = createNode("name", tables[i]);
75 nodeTable.addChild(nodeName);
76 HierarchicalConfiguration.Node nodeFields = createNode("fields", null);
77 nodeTable.addChild(nodeFields);
78
79 for (int j = 0; j < fields[i].length; j++)
80 {
81 nodeFields.addChild(createFieldNode(fields[i][j]));
82 }
83 }
84
85 config.getRoot().addChild(nodeTables);
86 }
87
88 public void testSetRoot()
89 {
90 try
91 {
92 config.setRoot(null);
93 fail("Could set null root node!");
94 }
95 catch(IllegalArgumentException iex)
96 {
97
98 }
99
100 config.setRoot(new HierarchicalConfiguration.Node("test"));
101 assertTrue(config.isEmpty());
102 }
103
104 public void testSetRootNode()
105 {
106 config.setRootNode(new DefaultConfigurationNode("testNode"));
107 assertNotSame("Same root node", config.getRootNode(), config.getRoot());
108 assertEquals("Wrong name of root node", "testNode", config.getRoot().getName());
109
110 config.setRootNode(new HierarchicalConfiguration.Node("test"));
111 assertSame("Wrong root node", config.getRootNode(), config.getRoot());
112 }
113
114 public void testSetRootNodeNull()
115 {
116 try
117 {
118 config.setRootNode(null);
119 fail("Could set null root node!");
120 }
121 catch(IllegalArgumentException iex)
122 {
123
124 }
125 }
126
127 public void testIsEmpty()
128 {
129 assertFalse(config.isEmpty());
130 HierarchicalConfiguration conf2 = new HierarchicalConfiguration();
131 assertTrue(conf2.isEmpty());
132 HierarchicalConfiguration.Node child1 = new HierarchicalConfiguration.Node("child1");
133 HierarchicalConfiguration.Node child2 = new HierarchicalConfiguration.Node("child2");
134 child1.addChild(child2);
135 conf2.getRoot().addChild(child1);
136 assertTrue(conf2.isEmpty());
137 }
138
139 public void testGetProperty()
140 {
141 assertNull(config.getProperty("tables.table.resultset"));
142 assertNull(config.getProperty("tables.table.fields.field"));
143
144 Object prop = config.getProperty("tables.table(0).fields.field.name");
145 assertNotNull(prop);
146 assertTrue(prop instanceof Collection);
147 assertEquals(5, ((Collection) prop).size());
148
149 prop = config.getProperty("tables.table.fields.field.name");
150 assertNotNull(prop);
151 assertTrue(prop instanceof Collection);
152 assertEquals(10, ((Collection) prop).size());
153
154 prop = config.getProperty("tables.table.fields.field(3).name");
155 assertNotNull(prop);
156 assertTrue(prop instanceof Collection);
157 assertEquals(2, ((Collection) prop).size());
158
159 prop = config.getProperty("tables.table(1).fields.field(2).name");
160 assertNotNull(prop);
161 assertEquals("creationDate", prop.toString());
162 }
163
164 public void testSetProperty()
165 {
166 config.setProperty("tables.table(0).name", "resources");
167 assertEquals("resources", config.getString("tables.table(0).name"));
168 config.setProperty("tables.table.name", "tab1,tab2");
169 assertEquals("tab1", config.getString("tables.table(0).name"));
170 assertEquals("tab2", config.getString("tables.table(1).name"));
171
172 config.setProperty("test.items.item", new int[] { 2, 4, 8, 16 });
173 assertEquals(3, config.getMaxIndex("test.items.item"));
174 assertEquals(8, config.getInt("test.items.item(2)"));
175 config.setProperty("test.items.item(2)", new Integer(6));
176 assertEquals(6, config.getInt("test.items.item(2)"));
177 config.setProperty("test.items.item(2)", new int[] { 7, 9, 11 });
178 assertEquals(5, config.getMaxIndex("test.items.item"));
179
180 config.setProperty("test", Boolean.TRUE);
181 config.setProperty("test.items", "01/01/05");
182 assertEquals(5, config.getMaxIndex("test.items.item"));
183 assertTrue(config.getBoolean("test"));
184 assertEquals("01/01/05", config.getProperty("test.items"));
185
186 config.setProperty("test.items.item", new Integer(42));
187 assertEquals(0, config.getMaxIndex("test.items.item"));
188 assertEquals(42, config.getInt("test.items.item"));
189 }
190
191 public void testClearProperty()
192 {
193 config.clearProperty("tables.table(0).fields.field(0).name");
194 assertEquals("uname", config.getProperty("tables.table(0).fields.field(0).name"));
195 config.clearProperty("tables.table(0).name");
196 assertFalse(config.containsKey("tables.table(0).name"));
197 assertEquals("firstName", config.getProperty("tables.table(0).fields.field(1).name"));
198 assertEquals("documents", config.getProperty("tables.table.name"));
199 config.clearProperty("tables.table");
200 assertEquals("documents", config.getProperty("tables.table.name"));
201
202 config.addProperty("test", "first");
203 config.addProperty("test.level", "second");
204 config.clearProperty("test");
205 assertEquals("second", config.getString("test.level"));
206 assertFalse(config.containsKey("test"));
207 }
208
209 public void testClearTree()
210 {
211 Object prop = config.getProperty("tables.table(0).fields.field.name");
212 assertNotNull(prop);
213 config.clearTree("tables.table(0).fields.field(3)");
214 prop = config.getProperty("tables.table(0).fields.field.name");
215 assertNotNull(prop);
216 assertTrue(prop instanceof Collection);
217 assertEquals(4, ((Collection) prop).size());
218
219 config.clearTree("tables.table(0).fields");
220 assertNull(config.getProperty("tables.table(0).fields.field.name"));
221 prop = config.getProperty("tables.table.fields.field.name");
222 assertNotNull(prop);
223 assertTrue(prop instanceof Collection);
224 assertEquals(5, ((Collection) prop).size());
225
226 config.clearTree("tables.table(1)");
227 assertNull(config.getProperty("tables.table.fields.field.name"));
228 }
229
230 /***
231 * Tests removing more complex node structures.
232 */
233 public void testClearTreeComplex()
234 {
235 final int count = 5;
236
237 for (int idx = 0; idx < count; idx++)
238 {
239 config.addProperty("indexList.index(-1)[@default]", Boolean.FALSE);
240 config.addProperty("indexList.index[@name]", "test" + idx);
241 config.addProperty("indexList.index.dir", "testDir" + idx);
242 }
243 assertEquals("Wrong number of nodes", count - 1, config
244 .getMaxIndex("indexList.index[@name]"));
245
246
247 boolean found = false;
248 for (int idx = 0; true; idx++)
249 {
250 String name = config.getString("indexList.index(" + idx
251 + ")[@name]");
252 if (name == null)
253 {
254 break;
255 }
256 if ("test3".equals(name))
257 {
258 assertEquals("Wrong dir", "testDir3", config
259 .getString("indexList.index(" + idx + ").dir"));
260 config.clearTree("indexList.index(" + idx + ")");
261 found = true;
262 }
263 }
264 assertTrue("Key to remove not found", found);
265 assertEquals("Wrong number of nodes after remove", count - 2, config
266 .getMaxIndex("indexList.index[@name]"));
267 assertEquals("Wrong number of dir nodes after remove", count - 2,
268 config.getMaxIndex("indexList.index.dir"));
269
270
271 for (int idx = 0; true; idx++)
272 {
273 String name = config.getString("indexList.index(" + idx
274 + ")[@name]");
275 if (name == null)
276 {
277 break;
278 }
279 if ("test3".equals(name))
280 {
281 fail("Key was not removed!");
282 }
283 }
284 }
285
286 public void testContainsKey()
287 {
288 assertTrue(config.containsKey("tables.table(0).name"));
289 assertTrue(config.containsKey("tables.table(1).name"));
290 assertFalse(config.containsKey("tables.table(2).name"));
291
292 assertTrue(config.containsKey("tables.table(0).fields.field.name"));
293 assertFalse(config.containsKey("tables.table(0).fields.field"));
294 config.clearTree("tables.table(0).fields");
295 assertFalse(config.containsKey("tables.table(0).fields.field.name"));
296
297 assertTrue(config.containsKey("tables.table.fields.field.name"));
298 }
299
300 public void testGetKeys()
301 {
302 List keys = new ArrayList();
303 for (Iterator it = config.getKeys(); it.hasNext();)
304 {
305 keys.add(it.next());
306 }
307
308 assertEquals(2, keys.size());
309 assertTrue(keys.contains("tables.table.name"));
310 assertTrue(keys.contains("tables.table.fields.field.name"));
311
312
313 config.addProperty("order.key1", "value1");
314 config.addProperty("order.key2", "value2");
315 config.addProperty("order.key3", "value3");
316
317 Iterator it = config.getKeys("order");
318 assertEquals("1st key", "order.key1", it.next());
319 assertEquals("2nd key", "order.key2", it.next());
320 assertEquals("3rd key", "order.key3", it.next());
321 }
322
323 public void testGetKeysString()
324 {
325
326 config.addProperty("tables.table(0).fields.field(1).type", "VARCHAR");
327 config.addProperty("tables.table(0)[@type]", "system");
328 config.addProperty("tables.table(0).size", "42");
329 config.addProperty("tables.table(0).fields.field(0).size", "128");
330 config.addProperty("connections.connection.param.url", "url1");
331 config.addProperty("connections.connection.param.user", "me");
332 config.addProperty("connections.connection.param.pwd", "secret");
333 config.addProperty("connections.connection(-1).param.url", "url2");
334 config.addProperty("connections.connection(1).param.user", "guest");
335
336 checkKeys("tables.table(1)", new String[] { "name", "fields.field.name" });
337 checkKeys("tables.table(0)",
338 new String[] { "name", "fields.field.name", "tables.table(0)[@type]", "size", "fields.field.type", "fields.field.size" });
339 checkKeys("connections.connection(0).param",
340 new String[] {"url", "user", "pwd" });
341 checkKeys("connections.connection(1).param",
342 new String[] {"url", "user" });
343 }
344
345 public void testAddProperty()
346 {
347 config.addProperty("tables.table(0).fields.field(-1).name", "phone");
348 Object prop = config.getProperty("tables.table(0).fields.field.name");
349 assertNotNull(prop);
350 assertTrue(prop instanceof Collection);
351 assertEquals(6, ((Collection) prop).size());
352
353 config.addProperty("tables.table(0).fields.field.name", "fax");
354 prop = config.getProperty("tables.table.fields.field(5).name");
355 assertNotNull(prop);
356 assertTrue(prop instanceof List);
357 List list = (List) prop;
358 assertEquals("phone", list.get(0));
359 assertEquals("fax", list.get(1));
360
361 config.addProperty("tables.table(-1).name", "config");
362 prop = config.getProperty("tables.table.name");
363 assertNotNull(prop);
364 assertTrue(prop instanceof Collection);
365 assertEquals(3, ((Collection) prop).size());
366 config.addProperty("tables.table(2).fields.field(0).name", "cid");
367 config.addProperty("tables.table(2).fields.field(-1).name",
368 "confName");
369 prop = config.getProperty("tables.table(2).fields.field.name");
370 assertNotNull(prop);
371 assertTrue(prop instanceof Collection);
372 assertEquals(2, ((Collection) prop).size());
373 assertEquals("confName",
374 config.getProperty("tables.table(2).fields.field(1).name"));
375
376 config.addProperty("connection.user", "scott");
377 config.addProperty("connection.passwd", "tiger");
378 assertEquals("tiger", config.getProperty("connection.passwd"));
379
380 ConfigurationKey key = new ConfigurationKey();
381 key.append("tables").append("table").appendIndex(0);
382 key.appendAttribute("tableType");
383 config.addProperty(key.toString(), "system");
384 assertEquals("system", config.getProperty(key.toString()));
385
386 try
387 {
388 config.addProperty(".", "InvalidKey");
389 fail("Could add invalid key!");
390 }
391 catch(IllegalArgumentException iex)
392 {
393
394 }
395 }
396
397 public void testGetMaxIndex()
398 {
399 assertEquals(4, config.getMaxIndex("tables.table(0).fields.field"));
400 assertEquals(4, config.getMaxIndex("tables.table(1).fields.field"));
401 assertEquals(1, config.getMaxIndex("tables.table"));
402 assertEquals(1, config.getMaxIndex("tables.table.name"));
403 assertEquals(0, config.getMaxIndex("tables.table(0).name"));
404 assertEquals(0, config.getMaxIndex("tables.table(1).fields.field(1)"));
405 assertEquals(-1, config.getMaxIndex("tables.table(2).fields"));
406
407 int maxIdx = config.getMaxIndex("tables.table(0).fields.field.name");
408 for(int i = 0; i <= maxIdx; i++)
409 {
410 ConfigurationKey key = new ConfigurationKey("tables.table(0).fields");
411 key.append("field").appendIndex(i).append("name");
412 assertNotNull(config.getProperty(key.toString()));
413 }
414 }
415
416 public void testSubset()
417 {
418
419 Configuration subset = config.subset("tables.table(0)");
420 assertEquals(tables[0], subset.getProperty("name"));
421
422 Object prop = subset.getProperty("fields.field.name");
423 assertNotNull(prop);
424 assertTrue(prop instanceof Collection);
425 assertEquals(5, ((Collection) prop).size());
426
427 for (int i = 0; i < fields[0].length; i++)
428 {
429 ConfigurationKey key = new ConfigurationKey();
430 key.append("fields").append("field").appendIndex(i);
431 key.append("name");
432 assertEquals(fields[0][i], subset.getProperty(key.toString()));
433 }
434
435
436 assertTrue("subset is not empty", config.subset("tables.table(2)").isEmpty());
437
438
439 subset = config.subset("tables.table.fields.field");
440 prop = subset.getProperty("name");
441 assertTrue("prop is not a collection", prop instanceof Collection);
442 assertEquals(10, ((Collection) prop).size());
443
444 assertEquals(fields[0][0], subset.getProperty("name(0)"));
445
446
447 subset = config.subset("tables.table.fields.field.name");
448 assertTrue("subset is not empty", subset.isEmpty());
449 }
450
451 /***
452 * Tests the configurationAt() method to obtain a configuration for a sub
453 * tree.
454 */
455 public void testConfigurationAt()
456 {
457 HierarchicalConfiguration subConfig = config
458 .configurationAt("tables.table(1)");
459 assertEquals("Wrong table name", tables[1], subConfig.getString("name"));
460 List lstFlds = subConfig.getList("fields.field.name");
461 assertEquals("Wrong number of fields", fields[1].length, lstFlds.size());
462 for (int i = 0; i < fields[1].length; i++)
463 {
464 assertEquals("Wrong field at position " + i, fields[1][i], lstFlds
465 .get(i));
466 }
467
468 subConfig.setProperty("name", "testTable");
469 assertEquals("Change not visible in parent", "testTable", config
470 .getString("tables.table(1).name"));
471 config.setProperty("tables.table(1).fields.field(2).name", "testField");
472 assertEquals("Change not visible in sub config", "testField", subConfig
473 .getString("fields.field(2).name"));
474 }
475
476 /***
477 * Tests the configurationAt() method when the passed in key does not exist.
478 */
479 public void testConfigurationAtUnknownSubTree()
480 {
481 try
482 {
483 config.configurationAt("non.existing.key");
484 fail("Could obtain sub config for unknown key!");
485 }
486 catch (IllegalArgumentException iex)
487 {
488
489 }
490 }
491
492 /***
493 * Tests the configurationAt() method when the passed in key selects
494 * multiple nodes. This should cause an exception.
495 */
496 public void testConfigurationAtMultipleNodes()
497 {
498 try
499 {
500 config.configurationAt("tables.table.name");
501 fail("Could create sub config with non unique key!");
502 }
503 catch (IllegalArgumentException iex)
504 {
505
506 }
507 }
508
509 /***
510 * Tests the configurationsAt() method.
511 */
512 public void testConfigurationsAt()
513 {
514 List lstFlds = config.configurationsAt("tables.table(1).fields.field");
515 assertEquals("Wrong size of fields", fields[1].length, lstFlds.size());
516 for (int i = 0; i < fields[1].length; i++)
517 {
518 HierarchicalConfiguration sub = (HierarchicalConfiguration) lstFlds
519 .get(i);
520 assertEquals("Wrong field at position " + i, fields[1][i], sub
521 .getString("name"));
522 }
523 }
524
525 /***
526 * Tests the configurationsAt() method when the passed in key does not
527 * select any sub nodes.
528 */
529 public void testConfigurationsAtEmpty()
530 {
531 assertTrue("List is not empty", config.configurationsAt("unknown.key")
532 .isEmpty());
533 }
534
535 public void testClone()
536 {
537 Configuration copy = (Configuration) config.clone();
538 assertTrue(copy instanceof HierarchicalConfiguration);
539 checkContent(copy);
540 }
541
542 /***
543 * Tests whether registered event handlers are handled correctly when a
544 * configuration is cloned. They should not be registered at the clone.
545 */
546 public void testCloneWithEventListeners()
547 {
548 config.addConfigurationListener(new ConfigurationListener()
549 {
550 public void configurationChanged(ConfigurationEvent event)
551 {
552
553 }
554 });
555 HierarchicalConfiguration copy = (HierarchicalConfiguration) config
556 .clone();
557 assertTrue("Event listener registered at clone", copy
558 .getConfigurationListeners().isEmpty());
559 }
560
561 public void testAddNodes()
562 {
563 Collection nodes = new ArrayList();
564 nodes.add(createFieldNode("birthDate"));
565 nodes.add(createFieldNode("lastLogin"));
566 nodes.add(createFieldNode("language"));
567 config.addNodes("tables.table(0).fields", nodes);
568 assertEquals(7, config.getMaxIndex("tables.table(0).fields.field"));
569 assertEquals("birthDate", config.getString("tables.table(0).fields.field(5).name"));
570 assertEquals("lastLogin", config.getString("tables.table(0).fields.field(6).name"));
571 assertEquals("language", config.getString("tables.table(0).fields.field(7).name"));
572 }
573
574 /***
575 * Tests the addNodes() method when the provided key does not exist. In
576 * this case, a new node (or even a complete new branch) will be created.
577 */
578 public void testAddNodesForNonExistingKey()
579 {
580 Collection nodes = new ArrayList();
581 nodes.add(createNode("usr", "scott"));
582 Node nd = createNode("pwd", "tiger");
583 nd.setAttribute(true);
584 nodes.add(nd);
585 config.addNodes("database.connection.settings", nodes);
586
587 assertEquals("Usr node not found", "scott", config.getString("database.connection.settings.usr"));
588 assertEquals("Pwd node not found", "tiger", config.getString("database.connection.settings[@pwd]"));
589 }
590
591 /***
592 * Tests the addNodes() method when the new nodes should be added to an
593 * attribute node. This is not allowed.
594 */
595 public void testAddNodesWithAttributeKey()
596 {
597 Collection nodes = new ArrayList();
598 nodes.add(createNode("testNode", "yes"));
599 try
600 {
601 config.addNodes("database.connection[@settings]", nodes);
602 fail("Could add nodes to an attribute node!");
603 }
604 catch(IllegalArgumentException iex)
605 {
606
607 }
608 }
609
610 /***
611 * Tests removing children from a configuration node.
612 */
613 public void testNodeRemove()
614 {
615 HierarchicalConfiguration.Node node = new HierarchicalConfiguration.Node(
616 "parent", "test");
617 assertFalse(node.hasChildren());
618 node.removeChildren();
619 assertFalse(node.remove("child"));
620
621 node.addChild(createNode("test", "test"));
622 assertTrue(node.hasChildren());
623 assertTrue(node.remove("test"));
624 assertFalse(node.hasChildren());
625
626 for (int i = 0; i < 10; i++)
627 {
628 node.addChild(createNode("child" + i, "test" + i));
629 }
630 assertTrue(node.hasChildren());
631 assertFalse(node.remove("child"));
632 assertTrue(node.remove("child2"));
633 assertTrue(node.getChildren("child2").isEmpty());
634
635 HierarchicalConfiguration.Node child = createNode("child0", "testChild");
636 assertFalse(node.remove(child));
637 node.addChild(child);
638 assertTrue(node.remove(child));
639 assertEquals(1, node.getChildren("child0").size());
640 assertEquals("test0", ((HierarchicalConfiguration.Node) node
641 .getChildren("child0").get(0)).getValue());
642
643 assertTrue(node.remove("child0"));
644 assertFalse(node.remove(child));
645
646 node.removeChildren();
647 assertTrue(node.getChildren().isEmpty());
648 assertFalse(node.remove(child));
649 }
650
651 /***
652 * Tests the visitor mechanism.
653 */
654 public void testNodeVisitor()
655 {
656 CountVisitor v = new CountVisitor();
657 config.getRoot().visit(v, null);
658 assertEquals(28, v.beforeCount);
659 assertEquals(v.beforeCount, v.afterCount);
660 }
661
662 /***
663 * Tests setting a custom expression engine, which uses a slightly different
664 * syntax.
665 */
666 public void testSetExpressionEngine()
667 {
668 config.setExpressionEngine(null);
669 assertNotNull("Expression engine is null", config.getExpressionEngine());
670 assertSame("Default engine is not used", HierarchicalConfiguration
671 .getDefaultExpressionEngine(), config.getExpressionEngine());
672
673 config.setExpressionEngine(createAlternativeExpressionEngine());
674 checkAlternativeSyntax();
675 }
676
677 /***
678 * Tests setting the default expression engine. This should impact all
679 * configuration instances that do not have their own engine.
680 */
681 public void testSetDefaultExpressionEngine()
682 {
683 ExpressionEngine engineOld = HierarchicalConfiguration.getDefaultExpressionEngine();
684 HierarchicalConfiguration
685 .setDefaultExpressionEngine(createAlternativeExpressionEngine());
686 checkAlternativeSyntax();
687 HierarchicalConfiguration.setDefaultExpressionEngine(engineOld);
688 }
689
690 /***
691 * Tests setting the default expression engine to null. This should not be
692 * allowed.
693 */
694 public void testSetDefaultExpressionEngineNull()
695 {
696 try
697 {
698 HierarchicalConfiguration.setDefaultExpressionEngine(null);
699 fail("Could set default expression engine to null!");
700 }
701 catch (IllegalArgumentException iex)
702 {
703
704 }
705 }
706
707 /***
708 * Tests the copy constructor.
709 */
710 public void testInitCopy()
711 {
712 HierarchicalConfiguration copy = new HierarchicalConfiguration(config);
713 checkContent(copy);
714 }
715
716 /***
717 * Tests whether the nodes of a copied configuration are independent from
718 * the source configuration.
719 */
720 public void testInitCopyUpdate()
721 {
722 HierarchicalConfiguration copy = new HierarchicalConfiguration(config);
723 config.setProperty("tables.table(0).name", "NewTable");
724 checkContent(copy);
725 }
726
727 /***
728 * Tests interpolation facilities.
729 */
730 public void testInterpolation()
731 {
732 config.addProperty("base.dir", "/home/foo");
733 config.addProperty("test.absolute.dir.dir1", "${base.dir}/path1");
734 config.addProperty("test.absolute.dir.dir2", "${base.dir}/path2");
735 config.addProperty("test.absolute.dir.dir3", "${base.dir}/path3");
736
737 Configuration sub = config.subset("test.absolute.dir");
738 for (int i = 1; i < 4; i++)
739 {
740 assertEquals("Wrong interpolation in parent", "/home/foo/path" + i,
741 config.getString("test.absolute.dir.dir" + i));
742 assertEquals("Wrong interpolation in subnode",
743 "/home/foo/path" + i, sub.getString("dir" + i));
744 }
745 }
746
747 /***
748 * Tests the copy constructor when a null reference is passed.
749 */
750 public void testInitCopyNull()
751 {
752 HierarchicalConfiguration copy = new HierarchicalConfiguration(null);
753 assertTrue("Configuration not empty", copy.isEmpty());
754 }
755
756 /***
757 * Helper method for testing the getKeys(String) method.
758 *
759 * @param prefix the key to pass into getKeys()
760 * @param expected the expected result
761 */
762 private void checkKeys(String prefix, String[] expected)
763 {
764 Set values = new HashSet();
765 for(int i = 0; i < expected.length; i++)
766 {
767 values.add((expected[i].startsWith(prefix)) ? expected[i] : prefix + "." + expected[i]);
768 }
769
770 Iterator itKeys = config.getKeys(prefix);
771 while(itKeys.hasNext())
772 {
773 String key = (String) itKeys.next();
774 if(!values.contains(key))
775 {
776 fail("Found unexpected key: " + key);
777 }
778 else
779 {
780 values.remove(key);
781 }
782 }
783
784 assertTrue("Remaining keys " + values, values.isEmpty());
785 }
786
787 /***
788 * Helper method for checking keys using an alternative syntax.
789 */
790 private void checkAlternativeSyntax()
791 {
792 assertNull(config.getProperty("tables/table/resultset"));
793 assertNull(config.getProperty("tables/table/fields/field"));
794
795 Object prop = config.getProperty("tables/table[0]/fields/field/name");
796 assertNotNull(prop);
797 assertTrue(prop instanceof Collection);
798 assertEquals(5, ((Collection) prop).size());
799
800 prop = config.getProperty("tables/table/fields/field/name");
801 assertNotNull(prop);
802 assertTrue(prop instanceof Collection);
803 assertEquals(10, ((Collection) prop).size());
804
805 prop = config.getProperty("tables/table/fields/field[3]/name");
806 assertNotNull(prop);
807 assertTrue(prop instanceof Collection);
808 assertEquals(2, ((Collection) prop).size());
809
810 prop = config.getProperty("tables/table[1]/fields/field[2]/name");
811 assertNotNull(prop);
812 assertEquals("creationDate", prop.toString());
813
814 Set keys = new HashSet();
815 CollectionUtils.addAll(keys, config.getKeys());
816 assertEquals("Wrong number of defined keys", 2, keys.size());
817 assertTrue("Key not found", keys.contains("tables/table/name"));
818 assertTrue("Key not found", keys
819 .contains("tables/table/fields/field/name"));
820 }
821
822 /***
823 * Checks the content of the passed in configuration object. Used by some
824 * tests that copy a configuration.
825 *
826 * @param c the configuration to check
827 */
828 private void checkContent(Configuration c)
829 {
830 for (int i = 0; i < tables.length; i++)
831 {
832 assertEquals(tables[i], c.getString("tables.table(" + i + ").name"));
833 for (int j = 0; j < fields[i].length; j++)
834 {
835 assertEquals(fields[i][j], c.getString("tables.table(" + i
836 + ").fields.field(" + j + ").name"));
837 }
838 }
839 }
840
841 private ExpressionEngine createAlternativeExpressionEngine()
842 {
843 DefaultExpressionEngine engine = new DefaultExpressionEngine();
844 engine.setPropertyDelimiter("/");
845 engine.setIndexStart("[");
846 engine.setIndexEnd("]");
847 return engine;
848 }
849
850 /***
851 * Helper method for creating a field node with its children.
852 *
853 * @param name the name of the field
854 * @return the field node
855 */
856 private static HierarchicalConfiguration.Node createFieldNode(String name)
857 {
858 HierarchicalConfiguration.Node fld = createNode("field", null);
859 fld.addChild(createNode("name", name));
860 return fld;
861 }
862
863 /***
864 * Helper method for creating a configuration node.
865 * @param name the node's name
866 * @param value the node's value
867 * @return the new node
868 */
869 private static HierarchicalConfiguration.Node createNode(String name, Object value)
870 {
871 HierarchicalConfiguration.Node node = new HierarchicalConfiguration.Node(name);
872 node.setValue(value);
873 return node;
874 }
875
876 /***
877 * A test visitor implementation for checking whether all visitor methods
878 * are correctly called.
879 */
880 static class CountVisitor extends HierarchicalConfiguration.NodeVisitor
881 {
882 public int beforeCount;
883
884 public int afterCount;
885
886 public void visitAfterChildren(Node node, ConfigurationKey key)
887 {
888 super.visitAfterChildren(node, key);
889 afterCount++;
890 }
891
892 public void visitBeforeChildren(Node node, ConfigurationKey key)
893 {
894 super.visitBeforeChildren(node, key);
895 beforeCount++;
896 }
897 }
898 }