1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Set;
25
26 import org.apache.commons.configuration.HierarchicalConfiguration.Node;
27
28 import junit.framework.TestCase;
29
30 /***
31 * Test class for HierarchicalConfiguration.
32 *
33 * @version $Id: TestHierarchicalConfiguration.java 234100 2005-08-20 18:18:16Z oheger $
34 */
35 public class TestHierarchicalConfiguration extends TestCase
36 {
37 private static String[] tables = { "users", "documents" };
38
39 private static String[][] fields =
40 {
41 { "uid", "uname", "firstName", "lastName", "email" },
42 { "docid", "name", "creationDate", "authorID", "version" }
43 };
44
45 private HierarchicalConfiguration config;
46
47 protected void setUp() throws Exception
48 {
49 /***
50 * Initialize the configuration with the following structure:
51 *
52 * tables
53 * table
54 * name
55 * fields
56 * field
57 * name
58 * field
59 * name
60 */
61 config = new HierarchicalConfiguration();
62 HierarchicalConfiguration.Node nodeTables = createNode("tables", null);
63 for(int i = 0; i < tables.length; i++)
64 {
65 HierarchicalConfiguration.Node nodeTable = createNode("table", null);
66 nodeTables.addChild(nodeTable);
67 HierarchicalConfiguration.Node nodeName = createNode("name", tables[i]);
68 nodeTable.addChild(nodeName);
69 HierarchicalConfiguration.Node nodeFields = createNode("fields", null);
70 nodeTable.addChild(nodeFields);
71
72 for (int j = 0; j < fields[i].length; j++)
73 {
74 nodeFields.addChild(createFieldNode(fields[i][j]));
75 }
76 }
77
78 config.getRoot().addChild(nodeTables);
79 }
80
81 public void testSetRoot()
82 {
83 try
84 {
85 config.setRoot(null);
86 fail("Could set null root node!");
87 }
88 catch(IllegalArgumentException iex)
89 {
90
91 }
92
93 config.setRoot(new HierarchicalConfiguration.Node("test"));
94 assertTrue(config.isEmpty());
95 }
96
97 public void testIsEmpty()
98 {
99 assertFalse(config.isEmpty());
100 HierarchicalConfiguration conf2 = new HierarchicalConfiguration();
101 assertTrue(conf2.isEmpty());
102 HierarchicalConfiguration.Node child1 = new HierarchicalConfiguration.Node("child1");
103 HierarchicalConfiguration.Node child2 = new HierarchicalConfiguration.Node("child2");
104 child1.addChild(child2);
105 conf2.getRoot().addChild(child1);
106 assertTrue(conf2.isEmpty());
107 }
108
109 public void testGetProperty()
110 {
111 assertNull(config.getProperty("tables.table.resultset"));
112 assertNull(config.getProperty("tables.table.fields.field"));
113
114 Object prop = config.getProperty("tables.table(0).fields.field.name");
115 assertNotNull(prop);
116 assertTrue(prop instanceof Collection);
117 assertEquals(5, ((Collection) prop).size());
118
119 prop = config.getProperty("tables.table.fields.field.name");
120 assertNotNull(prop);
121 assertTrue(prop instanceof Collection);
122 assertEquals(10, ((Collection) prop).size());
123
124 prop = config.getProperty("tables.table.fields.field(3).name");
125 assertNotNull(prop);
126 assertTrue(prop instanceof Collection);
127 assertEquals(2, ((Collection) prop).size());
128
129 prop = config.getProperty("tables.table(1).fields.field(2).name");
130 assertNotNull(prop);
131 assertEquals("creationDate", prop.toString());
132 }
133
134 public void testSetProperty()
135 {
136 config.setProperty("tables.table(0).name", "resources");
137 assertEquals("resources", config.getString("tables.table(0).name"));
138 config.setProperty("tables.table.name", "tab1,tab2");
139 assertEquals("tab1", config.getString("tables.table(0).name"));
140 assertEquals("tab2", config.getString("tables.table(1).name"));
141
142 config.setProperty("test.items.item", new int[] { 2, 4, 8, 16 });
143 assertEquals(3, config.getMaxIndex("test.items.item"));
144 assertEquals(8, config.getInt("test.items.item(2)"));
145 config.setProperty("test.items.item(2)", new Integer(6));
146 assertEquals(6, config.getInt("test.items.item(2)"));
147 config.setProperty("test.items.item(2)", new int[] { 7, 9, 11 });
148 assertEquals(5, config.getMaxIndex("test.items.item"));
149
150 config.setProperty("test", Boolean.TRUE);
151 config.setProperty("test.items", "01/01/05");
152 assertEquals(5, config.getMaxIndex("test.items.item"));
153 assertTrue(config.getBoolean("test"));
154 assertEquals("01/01/05", config.getProperty("test.items"));
155
156 config.setProperty("test.items.item", new Integer(42));
157 assertEquals(0, config.getMaxIndex("test.items.item"));
158 assertEquals(42, config.getInt("test.items.item"));
159 }
160
161 public void testClearProperty()
162 {
163 config.clearProperty("tables.table(0).fields.field(0).name");
164 assertEquals("uname", config.getProperty("tables.table(0).fields.field(0).name"));
165 config.clearProperty("tables.table(0).name");
166 assertFalse(config.containsKey("tables.table(0).name"));
167 assertEquals("firstName", config.getProperty("tables.table(0).fields.field(1).name"));
168 assertEquals("documents", config.getProperty("tables.table.name"));
169 config.clearProperty("tables.table");
170 assertEquals("documents", config.getProperty("tables.table.name"));
171
172 config.addProperty("test", "first");
173 config.addProperty("test.level", "second");
174 config.clearProperty("test");
175 assertEquals("second", config.getString("test.level"));
176 assertFalse(config.containsKey("test"));
177 }
178
179 public void testClearTree()
180 {
181 Object prop = config.getProperty("tables.table(0).fields.field.name");
182 assertNotNull(prop);
183 config.clearTree("tables.table(0).fields.field(3)");
184 prop = config.getProperty("tables.table(0).fields.field.name");
185 assertNotNull(prop);
186 assertTrue(prop instanceof Collection);
187 assertEquals(4, ((Collection) prop).size());
188
189 config.clearTree("tables.table(0).fields");
190 assertNull(config.getProperty("tables.table(0).fields.field.name"));
191 prop = config.getProperty("tables.table.fields.field.name");
192 assertNotNull(prop);
193 assertTrue(prop instanceof Collection);
194 assertEquals(5, ((Collection) prop).size());
195
196 config.clearTree("tables.table(1)");
197 assertNull(config.getProperty("tables.table.fields.field.name"));
198 }
199
200 public void testContainsKey()
201 {
202 assertTrue(config.containsKey("tables.table(0).name"));
203 assertTrue(config.containsKey("tables.table(1).name"));
204 assertFalse(config.containsKey("tables.table(2).name"));
205
206 assertTrue(config.containsKey("tables.table(0).fields.field.name"));
207 assertFalse(config.containsKey("tables.table(0).fields.field"));
208 config.clearTree("tables.table(0).fields");
209 assertFalse(config.containsKey("tables.table(0).fields.field.name"));
210
211 assertTrue(config.containsKey("tables.table.fields.field.name"));
212 }
213
214 public void testGetKeys()
215 {
216 List keys = new ArrayList();
217 for (Iterator it = config.getKeys(); it.hasNext();)
218 {
219 keys.add(it.next());
220 }
221
222 assertEquals(2, keys.size());
223 assertTrue(keys.contains("tables.table.name"));
224 assertTrue(keys.contains("tables.table.fields.field.name"));
225
226
227 config.addProperty("order.key1", "value1");
228 config.addProperty("order.key2", "value2");
229 config.addProperty("order.key3", "value3");
230
231 Iterator it = config.getKeys("order");
232 assertEquals("1st key", "order.key1", it.next());
233 assertEquals("2nd key", "order.key2", it.next());
234 assertEquals("3rd key", "order.key3", it.next());
235 }
236
237 public void testGetKeysString()
238 {
239
240 config.addProperty("tables.table(0).fields.field(1).type", "VARCHAR");
241 config.addProperty("tables.table(0)[@type]", "system");
242 config.addProperty("tables.table(0).size", "42");
243 config.addProperty("tables.table(0).fields.field(0).size", "128");
244 config.addProperty("connections.connection.param.url", "url1");
245 config.addProperty("connections.connection.param.user", "me");
246 config.addProperty("connections.connection.param.pwd", "secret");
247 config.addProperty("connections.connection(-1).param.url", "url2");
248 config.addProperty("connections.connection(1).param.user", "guest");
249
250 checkKeys("tables.table(1)", new String[] { "name", "fields.field.name" });
251 checkKeys("tables.table(0)",
252 new String[] { "name", "fields.field.name", "tables.table(0)[@type]", "size", "fields.field.type", "fields.field.size" });
253 checkKeys("connections.connection(0).param",
254 new String[] {"url", "user", "pwd" });
255 checkKeys("connections.connection(1).param",
256 new String[] {"url", "user" });
257 }
258
259 public void testAddProperty()
260 {
261 config.addProperty("tables.table(0).fields.field(-1).name", "phone");
262 Object prop = config.getProperty("tables.table(0).fields.field.name");
263 assertNotNull(prop);
264 assertTrue(prop instanceof Collection);
265 assertEquals(6, ((Collection) prop).size());
266
267 config.addProperty("tables.table(0).fields.field.name", "fax");
268 prop = config.getProperty("tables.table.fields.field(5).name");
269 assertNotNull(prop);
270 assertTrue(prop instanceof List);
271 List list = (List) prop;
272 assertEquals("phone", list.get(0));
273 assertEquals("fax", list.get(1));
274
275 config.addProperty("tables.table(-1).name", "config");
276 prop = config.getProperty("tables.table.name");
277 assertNotNull(prop);
278 assertTrue(prop instanceof Collection);
279 assertEquals(3, ((Collection) prop).size());
280 config.addProperty("tables.table(2).fields.field(0).name", "cid");
281 config.addProperty("tables.table(2).fields.field(-1).name",
282 "confName");
283 prop = config.getProperty("tables.table(2).fields.field.name");
284 assertNotNull(prop);
285 assertTrue(prop instanceof Collection);
286 assertEquals(2, ((Collection) prop).size());
287 assertEquals("confName",
288 config.getProperty("tables.table(2).fields.field(1).name"));
289
290 config.addProperty("connection.user", "scott");
291 config.addProperty("connection.passwd", "tiger");
292 assertEquals("tiger", config.getProperty("connection.passwd"));
293
294 ConfigurationKey key = new ConfigurationKey();
295 key.append("tables").append("table").appendIndex(0);
296 key.appendAttribute("tableType");
297 config.addProperty(key.toString(), "system");
298 assertEquals("system", config.getProperty(key.toString()));
299
300 try
301 {
302 config.addProperty(".", "InvalidKey");
303 fail("Could add invalid key!");
304 }
305 catch(IllegalArgumentException iex)
306 {
307
308 }
309 }
310
311 public void testGetMaxIndex()
312 {
313 assertEquals(4, config.getMaxIndex("tables.table(0).fields.field"));
314 assertEquals(4, config.getMaxIndex("tables.table(1).fields.field"));
315 assertEquals(1, config.getMaxIndex("tables.table"));
316 assertEquals(1, config.getMaxIndex("tables.table.name"));
317 assertEquals(0, config.getMaxIndex("tables.table(0).name"));
318 assertEquals(0, config.getMaxIndex("tables.table(1).fields.field(1)"));
319 assertEquals(-1, config.getMaxIndex("tables.table(2).fields"));
320
321 int maxIdx = config.getMaxIndex("tables.table(0).fields.field.name");
322 for(int i = 0; i <= maxIdx; i++)
323 {
324 ConfigurationKey key = new ConfigurationKey("tables.table(0).fields");
325 key.append("field").appendIndex(i).append("name");
326 assertNotNull(config.getProperty(key.toString()));
327 }
328 }
329
330 public void testSubset()
331 {
332
333 Configuration subset = config.subset("tables.table(0)");
334 assertEquals(tables[0], subset.getProperty("name"));
335
336 Object prop = subset.getProperty("fields.field.name");
337 assertNotNull(prop);
338 assertTrue(prop instanceof Collection);
339 assertEquals(5, ((Collection) prop).size());
340
341 for (int i = 0; i < fields[0].length; i++)
342 {
343 ConfigurationKey key = new ConfigurationKey();
344 key.append("fields").append("field").appendIndex(i);
345 key.append("name");
346 assertEquals(fields[0][i], subset.getProperty(key.toString()));
347 }
348
349
350 assertTrue("subset is not empty", config.subset("tables.table(2)").isEmpty());
351
352
353 subset = config.subset("tables.table.fields.field");
354 prop = subset.getProperty("name");
355 assertTrue("prop is not a collection", prop instanceof Collection);
356 assertEquals(10, ((Collection) prop).size());
357
358 assertEquals(fields[0][0], subset.getProperty("name(0)"));
359
360
361 subset = config.subset("tables.table.fields.field.name");
362 assertTrue("subset is not empty", subset.isEmpty());
363 }
364
365 public void testClone()
366 {
367 Configuration copy = (Configuration) config.clone();
368 assertTrue(copy instanceof HierarchicalConfiguration);
369 for (int i = 0; i < tables.length; i++)
370 {
371 assertEquals(tables[i], copy.getString("tables.table(" + i + ").name"));
372 for (int j = 0; j < fields[i].length; j++)
373 {
374 assertEquals(fields[i][j], copy.getString("tables.table(" + i + ").fields.field(" + j + ").name"));
375 }
376 }
377 }
378
379 public void testAddNodes()
380 {
381 Collection nodes = new ArrayList();
382 nodes.add(createFieldNode("birthDate"));
383 nodes.add(createFieldNode("lastLogin"));
384 nodes.add(createFieldNode("language"));
385 config.addNodes("tables.table(0).fields", nodes);
386 assertEquals(7, config.getMaxIndex("tables.table(0).fields.field"));
387 assertEquals("birthDate", config.getString("tables.table(0).fields.field(5).name"));
388 assertEquals("lastLogin", config.getString("tables.table(0).fields.field(6).name"));
389 assertEquals("language", config.getString("tables.table(0).fields.field(7).name"));
390
391 try
392 {
393 config.addNodes(".", nodes);
394 fail("Could use empty key!");
395 }
396 catch(IllegalArgumentException iex)
397 {
398
399 }
400 }
401
402 /***
403 * Tests removing children from a configuration node.
404 */
405 public void testNodeRemove()
406 {
407 HierarchicalConfiguration.Node node = new HierarchicalConfiguration.Node(
408 "parent", "test");
409 assertFalse(node.hasChildren());
410 node.removeChildren();
411 assertFalse(node.remove("child"));
412
413 node.addChild(createNode("test", "test"));
414 assertTrue(node.hasChildren());
415 assertTrue(node.remove("test"));
416 assertFalse(node.hasChildren());
417
418 for (int i = 0; i < 10; i++)
419 {
420 node.addChild(createNode("child" + i, "test" + i));
421 }
422 assertTrue(node.hasChildren());
423 assertFalse(node.remove("child"));
424 assertTrue(node.remove("child2"));
425 assertTrue(node.getChildren("child2").isEmpty());
426
427 HierarchicalConfiguration.Node child = createNode("child0", "testChild");
428 assertFalse(node.remove(child));
429 node.addChild(child);
430 assertTrue(node.remove(child));
431 assertEquals(1, node.getChildren("child0").size());
432 assertEquals("test0", ((HierarchicalConfiguration.Node) node
433 .getChildren("child0").get(0)).getValue());
434
435 assertTrue(node.remove("child0"));
436 assertFalse(node.remove(child));
437
438 node.removeChildren();
439 assertTrue(node.getChildren().isEmpty());
440 assertFalse(node.remove(child));
441 }
442
443 /***
444 * Tests the visitor mechanism.
445 */
446 public void testNodeVisitor()
447 {
448 CountVisitor v = new CountVisitor();
449 config.getRoot().visit(v, null);
450 assertEquals(28, v.beforeCount);
451 assertEquals(v.beforeCount, v.afterCount);
452 }
453
454 /***
455 * Helper method for testing the getKeys(String) method.
456 * @param prefix the key to pass into getKeys()
457 * @param expected the expected result
458 */
459 private void checkKeys(String prefix, String[] expected)
460 {
461 Set values = new HashSet();
462 for(int i = 0; i < expected.length; i++)
463 {
464 values.add((expected[i].startsWith(prefix)) ? expected[i] : prefix + "." + expected[i]);
465 }
466
467 Iterator itKeys = config.getKeys(prefix);
468 while(itKeys.hasNext())
469 {
470 String key = (String) itKeys.next();
471 if(!values.contains(key))
472 {
473 fail("Found unexpected key: " + key);
474 }
475 else
476 {
477 values.remove(key);
478 }
479 }
480
481 assertTrue("Remaining keys " + values, values.isEmpty());
482 }
483
484 /***
485 * Helper method for creating a field node with its children.
486 * @param name the name of the field
487 * @return the field node
488 */
489 private static HierarchicalConfiguration.Node createFieldNode(String name)
490 {
491 HierarchicalConfiguration.Node fld = createNode("field", null);
492 fld.addChild(createNode("name", name));
493 return fld;
494 }
495
496 /***
497 * Helper method for creating a configuration node.
498 * @param name the node's name
499 * @param value the node's value
500 * @return the new node
501 */
502 private static HierarchicalConfiguration.Node createNode(String name, Object value)
503 {
504 HierarchicalConfiguration.Node node = new HierarchicalConfiguration.Node(name);
505 node.setValue(value);
506 return node;
507 }
508
509 /***
510 * A test visitor implementation for checking whether all visitor methods
511 * are correctly called.
512 */
513 static class CountVisitor extends HierarchicalConfiguration.NodeVisitor
514 {
515 public int beforeCount;
516
517 public int afterCount;
518
519 public void visitAfterChildren(Node node, ConfigurationKey key)
520 {
521 super.visitAfterChildren(node, key);
522 afterCount++;
523 }
524
525 public void visitBeforeChildren(Node node, ConfigurationKey key)
526 {
527 super.visitBeforeChildren(node, key);
528 beforeCount++;
529 }
530 }
531 }