1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.configuration2;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertNotSame;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertSame;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27 import static org.junit.jupiter.api.Assertions.assertTrue;
28 import static org.mockito.Mockito.mock;
29
30 import java.util.ArrayList;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Map;
34
35 import org.apache.commons.configuration2.builder.XMLBuilderParametersImpl;
36 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
37 import org.apache.commons.configuration2.event.ConfigurationErrorEvent;
38 import org.apache.commons.configuration2.event.ConfigurationEvent;
39 import org.apache.commons.configuration2.event.EventListener;
40 import org.apache.commons.configuration2.event.EventSource;
41 import org.apache.commons.configuration2.ex.ConfigurationRuntimeException;
42 import org.apache.commons.configuration2.sync.NoOpSynchronizer;
43 import org.apache.commons.configuration2.tree.DefaultExpressionEngine;
44 import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols;
45 import org.apache.commons.configuration2.tree.ExpressionEngine;
46 import org.apache.commons.configuration2.tree.ImmutableNode;
47 import org.junit.jupiter.api.AfterEach;
48 import org.junit.jupiter.api.BeforeEach;
49 import org.junit.jupiter.api.Test;
50
51
52
53
54 public class TestConfigurationUtils {
55
56
57
58 private static final class CloneableSynchronizer extends NonCloneableSynchronizer implements Cloneable {
59
60 private final boolean cloned;
61
62
63
64
65
66
67 public CloneableSynchronizer(final boolean clone) {
68 cloned = clone;
69 }
70
71 @Override
72 public Object clone() {
73 return new CloneableSynchronizer(true);
74 }
75
76
77
78
79
80
81 public boolean isCloned() {
82 return cloned;
83 }
84 }
85
86
87
88
89 private static class NonCloneableSynchronizer extends SynchronizerTestImpl {
90 }
91
92
93 private static final String CLS_NAME = "org.apache.commons.configuration2.PropertiesConfiguration";
94
95
96 private ClassLoader ccl;
97
98 @BeforeEach
99 public void setUp() throws Exception {
100 ccl = Thread.currentThread().getContextClassLoader();
101 }
102
103 @AfterEach
104 public void tearDown() throws Exception {
105 Thread.currentThread().setContextClassLoader(ccl);
106 }
107
108 @Test
109 void testAppend() {
110
111 final Configuration conf1 = new BaseConfiguration();
112 conf1.addProperty("key1", "value1");
113 conf1.addProperty("key2", "value2");
114
115
116 final Configuration conf2 = new BaseConfiguration();
117 conf2.addProperty("key1", "value3");
118 conf2.addProperty("key2", "value4");
119
120
121 ConfigurationUtils.append(conf1, conf2);
122
123 List<Object> expected = new ArrayList<>();
124 expected.add("value3");
125 expected.add("value1");
126 assertEquals(expected, conf2.getList("key1"));
127
128 expected = new ArrayList<>();
129 expected.add("value4");
130 expected.add("value2");
131 assertEquals(expected, conf2.getList("key2"));
132 }
133
134
135
136
137 @Test
138 void testAsEventSourceNonSupportedEx() {
139 assertThrows(ConfigurationRuntimeException.class, () -> ConfigurationUtils.asEventSource(this, false));
140 }
141
142
143
144
145 @Test
146 void testAsEventSourceSupported() {
147 final XMLConfiguration src = new XMLConfiguration();
148 assertSame(src, ConfigurationUtils.asEventSource(src, true));
149 }
150
151
152
153
154 @Test
155 void testAsEventSourceUnsupportedMock() {
156 @SuppressWarnings("unchecked")
157 final EventListener<ConfigurationEvent> cl = mock(EventListener.class);
158 final EventSource source = ConfigurationUtils.asEventSource(this, true);
159 source.addEventListener(ConfigurationEvent.ANY, cl);
160 assertFalse(source.removeEventListener(ConfigurationEvent.ANY, cl));
161 source.addEventListener(ConfigurationEvent.ANY, null);
162 }
163
164
165
166
167 @Test
168 void testCloneConfiguration() {
169 final BaseHierarchicalConfiguration conf = new BaseHierarchicalConfiguration();
170 conf.addProperty("test", "yes");
171 final BaseHierarchicalConfiguration copy = (BaseHierarchicalConfiguration) ConfigurationUtils.cloneConfiguration(conf);
172 assertNotSame(conf, copy);
173 assertEquals("yes", copy.getString("test"));
174 }
175
176
177
178
179 @Test
180 void testCloneConfigurationNotSupported() {
181 final Configuration myNonCloneableConfig = new NonCloneableConfiguration();
182 assertThrows(ConfigurationRuntimeException.class, () -> ConfigurationUtils.cloneConfiguration(myNonCloneableConfig));
183 }
184
185
186
187
188 @Test
189 void testCloneConfigurationNull() {
190 assertNull(ConfigurationUtils.cloneConfiguration(null));
191 }
192
193
194
195
196 @Test
197 void testCloneIfPossibleError() {
198 final XMLBuilderParametersImpl params = new XMLBuilderParametersImpl() {
199 @Override
200 public XMLBuilderParametersImpl clone() {
201 throw new ConfigurationRuntimeException();
202 }
203 };
204 assertSame(params, ConfigurationUtils.cloneIfPossible(params));
205 }
206
207
208
209
210 @Test
211 void testCloneIfPossibleNotSupported() {
212 final Long value = 20130116221714L;
213 assertSame(value, ConfigurationUtils.cloneIfPossible(value));
214 }
215
216
217
218
219 @Test
220 void testCloneIfPossibleNull() {
221 assertNull(ConfigurationUtils.cloneIfPossible(null));
222 }
223
224
225
226
227 @Test
228 void testCloneIfPossibleSupported() {
229 final XMLBuilderParametersImpl params = new XMLBuilderParametersImpl();
230 params.setPublicID("testID");
231 params.setSchemaValidation(true);
232 final XMLBuilderParametersImpl clone = (XMLBuilderParametersImpl) ConfigurationUtils.cloneIfPossible(params);
233 assertNotSame(params, clone);
234 final Map<String, Object> map = clone.getParameters();
235 for (final Map.Entry<String, Object> e : params.getParameters().entrySet()) {
236 if (!e.getKey().startsWith("config-")) {
237 assertEquals(e.getValue(), map.get(e.getKey()), "Wrong value for field " + e.getKey());
238 }
239 }
240 }
241
242
243
244
245 @Test
246 void testCloneSynchronizerClone() {
247 final CloneableSynchronizer sync = new CloneableSynchronizer(false);
248 final CloneableSynchronizer sync2 = (CloneableSynchronizer) ConfigurationUtils.cloneSynchronizer(sync);
249 assertTrue(sync2.isCloned());
250 }
251
252
253
254
255 @Test
256 void testCloneSynchronizerFailed() {
257 final NonCloneableSynchronizer synchronizer = new NonCloneableSynchronizer();
258 assertThrows(ConfigurationRuntimeException.class, () -> ConfigurationUtils.cloneSynchronizer(synchronizer));
259 }
260
261
262
263
264 @Test
265 void testCloneSynchronizerNewInstance() {
266 final SynchronizerTestImpl sync = new SynchronizerTestImpl();
267 final SynchronizerTestImpl sync2 = (SynchronizerTestImpl) ConfigurationUtils.cloneSynchronizer(sync);
268 assertNotNull(sync2);
269 assertNotSame(sync, sync2);
270 }
271
272
273
274
275 @Test
276 void testCloneSynchronizerNoOp() {
277 assertSame(NoOpSynchronizer.INSTANCE, ConfigurationUtils.cloneSynchronizer(NoOpSynchronizer.INSTANCE));
278 }
279
280
281
282
283 @Test
284 void testCloneSynchronizerNull() {
285 assertThrows(IllegalArgumentException.class, () -> ConfigurationUtils.cloneSynchronizer(null));
286 }
287
288
289
290
291 @Test
292 void testConvertHierarchicalToHierarchical() {
293 final Configuration conf = new BaseHierarchicalConfiguration();
294 conf.addProperty("test", "yes");
295 assertSame(conf, ConfigurationUtils.convertToHierarchical(conf));
296 }
297
298
299
300
301 @Test
302 void testConvertHierarchicalToHierarchicalEngine() {
303 final BaseHierarchicalConfiguration hc = new BaseHierarchicalConfiguration();
304 final ExpressionEngine engine = new DefaultExpressionEngine(DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS);
305 assertSame(hc, ConfigurationUtils.convertToHierarchical(hc, engine));
306 assertSame(engine, hc.getExpressionEngine());
307 }
308
309
310
311
312
313 @Test
314 void testConvertHierarchicalToHierarchicalNullEngine() {
315 final BaseHierarchicalConfiguration hc = new BaseHierarchicalConfiguration();
316 final ExpressionEngine engine = new DefaultExpressionEngine(DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS);
317 hc.setExpressionEngine(engine);
318 assertSame(hc, ConfigurationUtils.convertToHierarchical(hc, null));
319 assertSame(engine, hc.getExpressionEngine());
320 }
321
322
323
324
325 @Test
326 void testConvertNullToHierarchical() {
327 assertNull(ConfigurationUtils.convertToHierarchical(null));
328 }
329
330
331
332
333 @Test
334 void testConvertToHierarchical() {
335 final Configuration conf = new BaseConfiguration();
336 for (int i = 0; i < 10; i++) {
337 conf.addProperty("test" + i, "value" + i);
338 conf.addProperty("test.list", "item" + i);
339 }
340 final BaseHierarchicalConfiguration hc = (BaseHierarchicalConfiguration) ConfigurationUtils.convertToHierarchical(conf);
341 for (final Iterator<String> it = conf.getKeys(); it.hasNext();) {
342 final String key = it.next();
343 assertEquals(conf.getProperty(key), hc.getProperty(key), "Wrong value for key " + key);
344 }
345 }
346
347
348
349
350
351 @Test
352 void testConvertToHierarchicalDelimiters() {
353 final BaseConfiguration conf = new BaseConfiguration();
354 conf.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
355 conf.addProperty("test.key", "1\\,2\\,3");
356 assertEquals("1,2,3", conf.getString("test.key"));
357 final HierarchicalConfiguration<?> hc = ConfigurationUtils.convertToHierarchical(conf);
358 assertEquals("1,2,3", hc.getString("test.key"));
359 }
360
361
362
363
364 @Test
365 void testConvertToHierarchicalEngine() {
366 final Configuration conf = new BaseConfiguration();
367 conf.addProperty("test(a)", Boolean.TRUE);
368 conf.addProperty("test(b)", Boolean.FALSE);
369 final DefaultExpressionEngine engine = new DefaultExpressionEngine(
370 new DefaultExpressionEngineSymbols.Builder(DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS).setIndexStart("[").setIndexEnd("]").create());
371 final HierarchicalConfiguration<?> hc = ConfigurationUtils.convertToHierarchical(conf, engine);
372 assertTrue(hc.getBoolean("test(a)"));
373 assertFalse(hc.getBoolean("test(b)"));
374 }
375
376
377
378
379
380 @Test
381 void testConvertToHierarchicalMultiValues() {
382 final BaseConfiguration config = new BaseConfiguration();
383 config.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
384 config.addProperty("test", "1,2,3");
385 final HierarchicalConfiguration<?> hc = ConfigurationUtils.convertToHierarchical(config);
386 assertEquals(1, hc.getInt("test(0)"));
387 assertEquals(2, hc.getInt("test(1)"));
388 assertEquals(3, hc.getInt("test(2)"));
389 }
390
391
392
393
394
395 @Test
396 void testConvertToHierarchicalOrderOfProperties() {
397 final PropertiesConfiguration config = new PropertiesConfiguration();
398 config.addProperty("x.y.z", true);
399 config.addProperty("x.y", true);
400 @SuppressWarnings("unchecked")
401 final HierarchicalConfiguration<ImmutableNode> hc = (HierarchicalConfiguration<ImmutableNode>) ConfigurationUtils.convertToHierarchical(config);
402 final ImmutableNode rootNode = hc.getNodeModel().getNodeHandler().getRootNode();
403 final ImmutableNode nodeX = rootNode.getChildren().get(0);
404 assertEquals(1, nodeX.getChildren().size());
405 }
406
407 @Test
408 void testCopy() {
409
410 final Configuration conf1 = new BaseConfiguration();
411 conf1.addProperty("key1", "value1");
412 conf1.addProperty("key2", "value2");
413
414 final Configuration conf2 = new BaseConfiguration();
415 conf2.addProperty("key1", "value3");
416 conf2.addProperty("key2", "value4");
417
418 ConfigurationUtils.copy(conf1, conf2);
419 assertEquals("value1", conf2.getProperty("key1"));
420 assertEquals("value2", conf2.getProperty("key2"));
421 }
422
423
424
425
426 @Test
427 void testEnableRuntimeExceptions() {
428 final PropertiesConfiguration config = new PropertiesConfiguration() {
429 @Override
430 protected void addPropertyDirect(final String key, final Object value) {
431
432 fireError(ConfigurationErrorEvent.WRITE, ConfigurationEvent.ADD_PROPERTY, key, value, new RuntimeException("A faked exception!"));
433 }
434 };
435 config.clearErrorListeners();
436 ConfigurationUtils.enableRuntimeExceptions(config);
437 assertThrows(ConfigurationRuntimeException.class, () -> config.addProperty("test", "testValue"));
438 }
439
440
441
442
443
444 @Test
445 void testEnableRuntimeExceptionsInvalid() {
446 final Configuration c = mock(Configuration.class);
447 assertThrows(IllegalArgumentException.class, () -> ConfigurationUtils.enableRuntimeExceptions(c));
448 }
449
450
451
452
453 @Test
454 void testEnableRuntimeExceptionsNull() {
455 assertThrows(IllegalArgumentException.class, () -> ConfigurationUtils.enableRuntimeExceptions(null));
456 }
457
458
459
460
461 @Test
462 void testLoadClassCCLNotFound() throws ClassNotFoundException {
463 Thread.currentThread().setContextClassLoader(new ClassLoader() {
464 @Override
465 public Class<?> loadClass(final String name) throws ClassNotFoundException {
466 throw new ClassNotFoundException(name);
467 }
468 });
469 assertEquals(CLS_NAME, ConfigurationUtils.loadClass(CLS_NAME).getName());
470 }
471
472
473
474
475 @Test
476 void testLoadClassCCLNull() throws ClassNotFoundException {
477 Thread.currentThread().setContextClassLoader(null);
478 assertEquals(CLS_NAME, ConfigurationUtils.loadClass(CLS_NAME).getName());
479 }
480
481
482
483
484 @Test
485 void testLoadClassFromCCL() throws ClassNotFoundException {
486 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
487 assertEquals(CLS_NAME, ConfigurationUtils.loadClass(CLS_NAME).getName());
488 }
489
490
491
492
493 @Test
494 void testLoadClassNoExFound() {
495 assertEquals(CLS_NAME, ConfigurationUtils.loadClassNoEx(CLS_NAME).getName());
496 }
497
498
499
500
501 @Test
502 void testLoadClassNoExNotFound() {
503 assertThrows(ConfigurationRuntimeException.class, () -> ConfigurationUtils.loadClassNoEx("a non existing class!"));
504 }
505
506
507
508
509 @Test
510 void testLoadClassNotFound() {
511 assertThrows(ClassNotFoundException.class, () -> ConfigurationUtils.loadClass("a non existing class!"));
512 }
513
514 @Test
515 void testToString() {
516 final Configuration config = new BaseConfiguration();
517 final String lineSeparator = System.lineSeparator();
518
519 assertEquals("", ConfigurationUtils.toString(config));
520
521 config.setProperty("one", "1");
522 assertEquals("one=1", ConfigurationUtils.toString(config));
523
524 config.setProperty("two", "2");
525 assertEquals("one=1" + lineSeparator + "two=2", ConfigurationUtils.toString(config));
526
527 config.clearProperty("one");
528 assertEquals("two=2", ConfigurationUtils.toString(config));
529
530 config.setProperty("one", "1");
531 assertEquals("two=2" + lineSeparator + "one=1", ConfigurationUtils.toString(config));
532 }
533 }