1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration2;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
21 import static org.junit.jupiter.api.Assertions.assertNull;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.List;
28
29 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
30 import org.apache.commons.configuration2.ex.ConfigurationRuntimeException;
31 import org.apache.commons.configuration2.tree.DefaultConfigurationKey;
32 import org.apache.commons.configuration2.tree.DefaultExpressionEngine;
33 import org.apache.commons.configuration2.tree.ImmutableNode;
34 import org.apache.commons.configuration2.tree.NodeStructureHelper;
35 import org.junit.jupiter.api.BeforeEach;
36 import org.junit.jupiter.api.Test;
37
38
39
40
41 public class TestHierarchicalConfiguration {
42
43
44 private static final String NEW_NAME = "alteredName";
45
46
47
48
49
50
51 private static DefaultConfigurationKey createConfigurationKey() {
52 return new DefaultConfigurationKey(DefaultExpressionEngine.INSTANCE);
53 }
54
55
56 private BaseHierarchicalConfiguration config;
57
58
59
60
61
62
63
64 private void checkChildConfigurationsAtWithUpdates(final boolean withUpdates, final String expectedName) {
65 final String key = "tables.table(0)";
66 final List<HierarchicalConfiguration<ImmutableNode>> children = withUpdates ? config.childConfigurationsAt(key, true)
67 : config.childConfigurationsAt(key);
68 assertEquals(2, children.size());
69 final HierarchicalConfiguration<ImmutableNode> sub = children.get(0);
70 sub.setProperty(null, NEW_NAME);
71 assertEquals(expectedName, config.getString(key + ".name"));
72 }
73
74
75
76
77
78
79 private void checkConfigurationAtAttributeNode(final boolean withUpdates) {
80 final String key = "tables.table(0)[@type]";
81 config.addProperty(key, "system");
82 assertThrows(ConfigurationRuntimeException.class, () -> config.configurationAt(key, withUpdates));
83 }
84
85
86
87
88
89
90
91
92 private void checkConfigurationsAtWithUpdate(final boolean withUpdates, final String expName) {
93 final String key = "tables.table(1).fields.field";
94 final List<HierarchicalConfiguration<ImmutableNode>> lstFlds = withUpdates ? config.configurationsAt(key, true) : config.configurationsAt(key);
95 checkSubConfigurations(lstFlds);
96 lstFlds.get(0).setProperty("name", NEW_NAME);
97 assertEquals(expName, config.getString("tables.table(1).fields.field(0).name"));
98 }
99
100
101
102
103
104
105 private void checkContent(final Configuration c) {
106 for (int i = 0; i < NodeStructureHelper.tablesLength(); i++) {
107 assertEquals(NodeStructureHelper.table(i), c.getString("tables.table(" + i + ").name"));
108 for (int j = 0; j < NodeStructureHelper.fieldsLength(i); j++) {
109 assertEquals(NodeStructureHelper.field(i, j), c.getString("tables.table(" + i + ").fields.field(" + j + ").name"));
110 }
111 }
112 }
113
114
115
116
117
118
119 private void checkSubConfigurations(final List<? extends ImmutableConfiguration> lstFlds) {
120 assertEquals(NodeStructureHelper.fieldsLength(1), lstFlds.size());
121 for (int i = 0; i < NodeStructureHelper.fieldsLength(1); i++) {
122 final ImmutableConfiguration sub = lstFlds.get(i);
123 assertEquals(NodeStructureHelper.field(1, i), sub.getString("name"), "Wrong field at position " + i);
124 }
125 }
126
127 @BeforeEach
128 public void setUp() throws Exception {
129 final ImmutableNode root = new ImmutableNode.Builder(1).addChild(NodeStructureHelper.ROOT_TABLES_TREE).create();
130 config = new BaseHierarchicalConfiguration();
131 config.getNodeModel().setRootNode(root);
132 }
133
134
135
136
137 @Test
138 void testChildConfigurationsAtNotFound() {
139 assertTrue(config.childConfigurationsAt("not.existing.key").isEmpty());
140 }
141
142
143
144
145 @Test
146 void testChildConfigurationsAtNoUniqueKey() {
147 assertTrue(config.childConfigurationsAt("tables.table").isEmpty());
148 }
149
150
151
152
153 @Test
154 void testChildConfigurationsAtNoUpdates() {
155 checkChildConfigurationsAtWithUpdates(false, NodeStructureHelper.table(0));
156 }
157
158
159
160
161 @Test
162 void testChildConfigurationsAtWithUpdates() {
163 checkChildConfigurationsAtWithUpdates(true, NEW_NAME);
164 }
165
166 @Test
167 void testClone() {
168 final Configuration copy = (Configuration) config.clone();
169 assertInstanceOf(BaseHierarchicalConfiguration.class, copy);
170 config.setProperty("tables.table(0).name", "changed table name");
171 checkContent(copy);
172 }
173
174
175
176
177 @Test
178 void testConfigurationAtAttributeNode() {
179 checkConfigurationAtAttributeNode(false);
180 }
181
182
183
184
185 @Test
186 void testConfigurationAtAttributeNodeWithUpdates() {
187 checkConfigurationAtAttributeNode(true);
188 }
189
190
191
192
193
194 @Test
195 void testConfigurationAtClearAndDetach() {
196 config.addProperty("test.sub.test", "success");
197 config.addProperty("test.other", "check");
198 final HierarchicalConfiguration<ImmutableNode> sub = config.configurationAt("test.sub", true);
199 sub.clear();
200 assertTrue(sub.isEmpty());
201 assertNull(config.getString("test.sub.test"));
202 sub.setProperty("test", "failure!");
203 assertNull(config.getString("test.sub.test"));
204 }
205
206
207
208
209 @Test
210 void testConfigurationAtMultipleNodes() {
211 assertThrows(ConfigurationRuntimeException.class, () -> config.configurationAt("tables.table.name"));
212 }
213
214
215
216
217 @Test
218 void testConfigurationAtMultipleNodesWithUpdates() {
219 assertThrows(ConfigurationRuntimeException.class, () -> config.configurationAt("tables.table.name", true));
220 }
221
222
223
224
225 @Test
226 void testConfigurationAtReadAccess() {
227 final HierarchicalConfiguration<ImmutableNode> subConfig = config.configurationAt("tables.table(1)");
228 assertEquals(NodeStructureHelper.table(1), subConfig.getString("name"));
229 final List<Object> lstFlds = subConfig.getList("fields.field.name");
230
231 final List<String> expected = new ArrayList<>();
232 for (int i = 0; i < NodeStructureHelper.fieldsLength(1); i++) {
233 expected.add(NodeStructureHelper.field(1, i));
234 }
235 assertEquals(expected, lstFlds);
236 }
237
238
239
240
241 @Test
242 void testConfigurationAtUnknownSubTree() {
243 assertThrows(ConfigurationRuntimeException.class, () -> config.configurationAt("non.existing.key"));
244 }
245
246
247
248
249 @Test
250 void testConfigurationAtUnknownSubTreeWithUpdates() {
251 assertThrows(ConfigurationRuntimeException.class, () -> config.configurationAt("non.existing.key", true));
252 }
253
254
255
256
257 @Test
258 void testConfigurationAtUpdateParentConnected() {
259 final HierarchicalConfiguration<ImmutableNode> subConfig = config.configurationAt("tables.table(1)", true);
260 config.setProperty("tables.table(1).fields.field(2).name", "testField");
261 assertEquals("testField", subConfig.getString("fields.field(2).name"));
262 }
263
264
265
266
267 @Test
268 void testConfigurationAtUpdateParentIndependent() {
269 final HierarchicalConfiguration<ImmutableNode> subConfig = config.configurationAt("tables.table(1)");
270 config.setProperty("tables.table(1).fields.field(2).name", "testField");
271 assertEquals(NodeStructureHelper.field(1, 2), subConfig.getString("fields.field(2).name"));
272 }
273
274
275
276
277 @Test
278 void testConfigurationAtUpdateSubConfigConnected() {
279 final HierarchicalConfiguration<ImmutableNode> subConfig = config.configurationAt("tables.table(1)", true);
280 subConfig.setProperty("name", "testTable");
281 assertEquals("testTable", config.getString("tables.table(1).name"));
282 }
283
284
285
286
287 @Test
288 void testConfigurationAtUpdateSubConfigIndependent() {
289 final HierarchicalConfiguration<ImmutableNode> subConfig = config.configurationAt("tables.table(1)");
290 subConfig.setProperty("name", "testTable");
291 assertEquals("testTable", subConfig.getString("name"));
292 assertEquals(NodeStructureHelper.table(1), config.getString("tables.table(1).name"));
293 }
294
295
296
297
298 @Test
299 void testConfigurationAtWithUpdateInitialized() {
300 final String key = "tables.table";
301 config.setListDelimiterHandler(new DefaultListDelimiterHandler(';'));
302 config.setThrowExceptionOnMissing(true);
303 final List<HierarchicalConfiguration<ImmutableNode>> subs = config.configurationsAt(key, true);
304 final BaseHierarchicalConfiguration sub = (BaseHierarchicalConfiguration) subs.get(0);
305 assertEquals(config.getListDelimiterHandler(), sub.getListDelimiterHandler());
306 assertTrue(sub.isThrowExceptionOnMissing());
307 }
308
309
310
311
312 @Test
313 void testConfigurationsAtAttributeKey() {
314 final String attrKey = "tables.table(0)[@type]";
315 config.addProperty(attrKey, "user");
316 assertTrue(config.configurationsAt(attrKey).isEmpty());
317 }
318
319
320
321
322 @Test
323 void testConfigurationsAtEmpty() {
324 assertTrue(config.configurationsAt("unknown.key").isEmpty());
325 }
326
327
328
329
330 @Test
331 void testConfigurationsAtNoUpdate() {
332 checkConfigurationsAtWithUpdate(false, NodeStructureHelper.field(1, 0));
333 }
334
335
336
337
338 @Test
339 void testConfigurationsAtWithUpdates() {
340 checkConfigurationsAtWithUpdate(true, NEW_NAME);
341 }
342
343
344
345
346 @Test
347 void testImmutableChildConfigurationsAt() {
348 final List<ImmutableHierarchicalConfiguration> children = config.immutableChildConfigurationsAt("tables.table(0)");
349 assertEquals(2, children.size());
350 final ImmutableHierarchicalConfiguration c1 = children.get(0);
351 assertEquals("name", c1.getRootElementName());
352 assertEquals(NodeStructureHelper.table(0), c1.getString(null));
353 final ImmutableHierarchicalConfiguration c2 = children.get(1);
354 assertEquals("fields", c2.getRootElementName());
355 assertEquals(NodeStructureHelper.field(0, 0), c2.getString("field(0).name"));
356 }
357
358
359
360
361 @Test
362 void testImmutableConfigurationAt() {
363 final ImmutableHierarchicalConfiguration subConfig = config.immutableConfigurationAt("tables.table(1)");
364 assertEquals(NodeStructureHelper.table(1), subConfig.getString("name"));
365 final List<Object> lstFlds = subConfig.getList("fields.field.name");
366
367 final List<String> expected = new ArrayList<>();
368 for (int i = 0; i < NodeStructureHelper.fieldsLength(1); i++) {
369 expected.add(NodeStructureHelper.field(1, i));
370 }
371 assertEquals(expected, lstFlds);
372 }
373
374
375
376
377 @Test
378 void testImmutableConfigurationAtSupportUpdates() {
379 final String newTableName = NodeStructureHelper.table(1) + "_other";
380 final ImmutableHierarchicalConfiguration subConfig = config.immutableConfigurationAt("tables.table(1)", true);
381 config.addProperty("tables.table(-1).name", newTableName);
382 config.clearTree("tables.table(1)");
383 assertEquals(newTableName, subConfig.getString("name"));
384 }
385
386
387
388
389 @Test
390 void testImmutableConfigurationsAt() {
391 final List<ImmutableHierarchicalConfiguration> lstFlds = config.immutableConfigurationsAt("tables.table(1).fields.field");
392 checkSubConfigurations(lstFlds);
393 }
394
395
396
397
398 @Test
399 void testInitCopy() {
400 final BaseHierarchicalConfiguration copy = new BaseHierarchicalConfiguration(config);
401 checkContent(copy);
402 }
403
404
405
406
407 @Test
408 void testInitCopyNull() {
409 final BaseHierarchicalConfiguration copy = new BaseHierarchicalConfiguration((HierarchicalConfiguration<ImmutableNode>) null);
410 assertTrue(copy.isEmpty());
411 }
412
413
414
415
416 @Test
417 void testInitCopyUpdate() {
418 final BaseHierarchicalConfiguration copy = new BaseHierarchicalConfiguration(config);
419 config.setProperty("tables.table(0).name", "NewTable");
420 checkContent(copy);
421 }
422
423
424
425
426 @Test
427 void testInterpolatedConfiguration() {
428 config.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
429 final BaseHierarchicalConfiguration c = (BaseHierarchicalConfiguration) InterpolationTestHelper.testInterpolatedConfiguration(config);
430
431
432 checkContent(c);
433 }
434
435
436
437
438 @Test
439 void testInterpolatedConfigurationEmpty() {
440 config = new BaseHierarchicalConfiguration();
441 assertTrue(config.interpolatedConfiguration().isEmpty());
442 }
443
444
445
446
447 @Test
448 void testInterpolationSubset() {
449 InterpolationTestHelper.testInterpolationSubset(config);
450 }
451
452
453
454
455 @Test
456 void testInterpolationSubsetMultipleLayers() {
457 config.clear();
458 config.addProperty("var", "value");
459 config.addProperty("prop2.prop[@attr]", "${var}");
460 final Configuration sub1 = config.subset("prop2");
461 final Configuration sub2 = sub1.subset("prop");
462 assertEquals("value", sub2.getString("[@attr]"));
463 }
464
465 @Test
466 void testSubset() {
467
468 Configuration subset = config.subset("tables.table(0)");
469 assertEquals(NodeStructureHelper.table(0), subset.getProperty("name"));
470
471 Object prop = subset.getProperty("fields.field.name");
472 Collection<?> collection = assertInstanceOf(Collection.class, prop);
473 assertEquals(5, collection.size());
474
475 for (int i = 0; i < NodeStructureHelper.fieldsLength(0); i++) {
476 final DefaultConfigurationKey key = createConfigurationKey();
477 key.append("fields").append("field").appendIndex(i);
478 key.append("name");
479 assertEquals(NodeStructureHelper.field(0, i), subset.getProperty(key.toString()));
480 }
481
482
483 assertTrue(config.subset("tables.table(2)").isEmpty());
484
485
486 subset = config.subset("tables.table.fields.field");
487 prop = subset.getProperty("name");
488 collection = assertInstanceOf(Collection.class, prop);
489 int expectedFieldCount = 0;
490 for (int i = 0; i < NodeStructureHelper.tablesLength(); i++) {
491 expectedFieldCount += NodeStructureHelper.fieldsLength(i);
492 }
493 assertEquals(expectedFieldCount, collection.size());
494
495 assertEquals(NodeStructureHelper.field(0, 0), subset.getProperty("name(0)"));
496
497
498 subset = config.subset("tables.table.fields.field.name");
499 assertTrue(subset.isEmpty());
500 }
501
502
503
504
505 @Test
506 void testSubsetAttributeResult() {
507 final String key = "tables.table(0)[@type]";
508 config.addProperty(key, "system");
509 final BaseHierarchicalConfiguration subset = (BaseHierarchicalConfiguration) config.subset(key);
510 assertTrue(subset.getModel().getNodeHandler().getRootNode().getChildren().isEmpty());
511 assertEquals("system", subset.getString("[@type]"));
512 }
513
514
515
516
517
518 @Test
519 void testSubsetMultipleNodesWithValues() {
520 config.setProperty("tables.table(0).fields", "My fields");
521 Configuration subset = config.subset("tables.table.fields");
522 assertEquals("My fields", subset.getString(""));
523 config.setProperty("tables.table(1).fields", "My other fields");
524 subset = config.subset("tables.table.fields");
525 assertNull(subset.getString(""));
526 }
527
528
529
530
531
532 @Test
533 void testSubsetNodeWithValue() {
534 config.setProperty("tables.table(0).fields", "My fields");
535 final Configuration subset = config.subset("tables.table(0).fields");
536 assertEquals(NodeStructureHelper.field(0, 0), subset.getString("field(0).name"));
537 assertEquals("My fields", subset.getString(""));
538 }
539 }