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