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 public 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 public void testAsEventSourceNonSupportedEx() {
139 assertThrows(ConfigurationRuntimeException.class, () -> ConfigurationUtils.asEventSource(this, false));
140 }
141
142
143
144
145 @Test
146 public void testAsEventSourceSupported() {
147 final XMLConfiguration src = new XMLConfiguration();
148 assertSame(src, ConfigurationUtils.asEventSource(src, true));
149 }
150
151
152
153
154 @Test
155 public 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 public 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 public void testCloneConfigurationNotSupported() {
181 final Configuration myNonCloneableConfig = new NonCloneableConfiguration();
182 assertThrows(ConfigurationRuntimeException.class, () -> ConfigurationUtils.cloneConfiguration(myNonCloneableConfig));
183 }
184
185
186
187
188 @Test
189 public void testCloneConfigurationNull() {
190 assertNull(ConfigurationUtils.cloneConfiguration(null));
191 }
192
193
194
195
196 @Test
197 public 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 public void testCloneIfPossibleNotSupported() {
212 final Long value = 20130116221714L;
213 assertSame(value, ConfigurationUtils.cloneIfPossible(value));
214 }
215
216
217
218
219 @Test
220 public void testCloneIfPossibleNull() {
221 assertNull(ConfigurationUtils.cloneIfPossible(null));
222 }
223
224
225
226
227 @Test
228 public 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 public 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 public void testCloneSynchronizerFailed() {
257 final NonCloneableSynchronizer synchronizer = new NonCloneableSynchronizer();
258 assertThrows(ConfigurationRuntimeException.class, () -> ConfigurationUtils.cloneSynchronizer(synchronizer));
259 }
260
261
262
263
264 @Test
265 public 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 public void testCloneSynchronizerNoOp() {
277 assertSame(NoOpSynchronizer.INSTANCE, ConfigurationUtils.cloneSynchronizer(NoOpSynchronizer.INSTANCE));
278 }
279
280
281
282
283 @Test
284 public void testCloneSynchronizerNull() {
285 assertThrows(IllegalArgumentException.class, () -> ConfigurationUtils.cloneSynchronizer(null));
286 }
287
288
289
290
291 @Test
292 public 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 public 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 public 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 public void testConvertNullToHierarchical() {
327 assertNull(ConfigurationUtils.convertToHierarchical(null));
328 }
329
330
331
332
333 @Test
334 public 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
341 final BaseHierarchicalConfiguration hc = (BaseHierarchicalConfiguration) ConfigurationUtils.convertToHierarchical(conf);
342 for (final Iterator<String> it = conf.getKeys(); it.hasNext();) {
343 final String key = it.next();
344 assertEquals(conf.getProperty(key), hc.getProperty(key), "Wrong value for key " + key);
345 }
346 }
347
348
349
350
351
352 @Test
353 public void testConvertToHierarchicalDelimiters() {
354 final BaseConfiguration conf = new BaseConfiguration();
355 conf.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
356 conf.addProperty("test.key", "1\\,2\\,3");
357 assertEquals("1,2,3", conf.getString("test.key"));
358 final HierarchicalConfiguration<?> hc = ConfigurationUtils.convertToHierarchical(conf);
359 assertEquals("1,2,3", hc.getString("test.key"));
360 }
361
362
363
364
365 @Test
366 public void testConvertToHierarchicalEngine() {
367 final Configuration conf = new BaseConfiguration();
368 conf.addProperty("test(a)", Boolean.TRUE);
369 conf.addProperty("test(b)", Boolean.FALSE);
370 final DefaultExpressionEngine engine = new DefaultExpressionEngine(
371 new DefaultExpressionEngineSymbols.Builder(DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS).setIndexStart("[").setIndexEnd("]").create());
372 final HierarchicalConfiguration<?> hc = ConfigurationUtils.convertToHierarchical(conf, engine);
373 assertTrue(hc.getBoolean("test(a)"));
374 assertFalse(hc.getBoolean("test(b)"));
375 }
376
377
378
379
380
381 @Test
382 public void testConvertToHierarchicalMultiValues() {
383 final BaseConfiguration config = new BaseConfiguration();
384 config.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
385 config.addProperty("test", "1,2,3");
386 final HierarchicalConfiguration<?> hc = ConfigurationUtils.convertToHierarchical(config);
387 assertEquals(1, hc.getInt("test(0)"));
388 assertEquals(2, hc.getInt("test(1)"));
389 assertEquals(3, hc.getInt("test(2)"));
390 }
391
392
393
394
395
396 @Test
397 public void testConvertToHierarchicalOrderOfProperties() {
398 final PropertiesConfiguration config = new PropertiesConfiguration();
399 config.addProperty("x.y.z", true);
400 config.addProperty("x.y", true);
401 @SuppressWarnings("unchecked")
402 final HierarchicalConfiguration<ImmutableNode> hc = (HierarchicalConfiguration<ImmutableNode>) ConfigurationUtils.convertToHierarchical(config);
403 final ImmutableNode rootNode = hc.getNodeModel().getNodeHandler().getRootNode();
404 final ImmutableNode nodeX = rootNode.getChildren().get(0);
405 assertEquals(1, nodeX.getChildren().size());
406 }
407
408 @Test
409 public void testCopy() {
410
411 final Configuration conf1 = new BaseConfiguration();
412 conf1.addProperty("key1", "value1");
413 conf1.addProperty("key2", "value2");
414
415
416 final Configuration conf2 = new BaseConfiguration();
417 conf2.addProperty("key1", "value3");
418 conf2.addProperty("key2", "value4");
419
420
421 ConfigurationUtils.copy(conf1, conf2);
422
423 assertEquals("value1", conf2.getProperty("key1"));
424 assertEquals("value2", conf2.getProperty("key2"));
425 }
426
427
428
429
430 @Test
431 public void testEnableRuntimeExceptions() {
432 final PropertiesConfiguration config = new PropertiesConfiguration() {
433 @Override
434 protected void addPropertyDirect(final String key, final Object value) {
435
436 fireError(ConfigurationErrorEvent.WRITE, ConfigurationEvent.ADD_PROPERTY, key, value, new RuntimeException("A faked exception!"));
437 }
438 };
439 config.clearErrorListeners();
440 ConfigurationUtils.enableRuntimeExceptions(config);
441 assertThrows(ConfigurationRuntimeException.class, () -> config.addProperty("test", "testValue"));
442 }
443
444
445
446
447
448 @Test
449 public void testEnableRuntimeExceptionsInvalid() {
450 final Configuration c = mock(Configuration.class);
451 assertThrows(IllegalArgumentException.class, () -> ConfigurationUtils.enableRuntimeExceptions(c));
452 }
453
454
455
456
457 @Test
458 public void testEnableRuntimeExceptionsNull() {
459 assertThrows(IllegalArgumentException.class, () -> ConfigurationUtils.enableRuntimeExceptions(null));
460 }
461
462
463
464
465 @Test
466 public void testLoadClassCCLNotFound() throws ClassNotFoundException {
467 Thread.currentThread().setContextClassLoader(new ClassLoader() {
468 @Override
469 public Class<?> loadClass(final String name) throws ClassNotFoundException {
470 throw new ClassNotFoundException(name);
471 }
472 });
473 assertEquals(CLS_NAME, ConfigurationUtils.loadClass(CLS_NAME).getName());
474 }
475
476
477
478
479 @Test
480 public void testLoadClassCCLNull() throws ClassNotFoundException {
481 Thread.currentThread().setContextClassLoader(null);
482 assertEquals(CLS_NAME, ConfigurationUtils.loadClass(CLS_NAME).getName());
483 }
484
485
486
487
488 @Test
489 public void testLoadClassFromCCL() throws ClassNotFoundException {
490 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
491 assertEquals(CLS_NAME, ConfigurationUtils.loadClass(CLS_NAME).getName());
492 }
493
494
495
496
497 @Test
498 public void testLoadClassNoExFound() {
499 assertEquals(CLS_NAME, ConfigurationUtils.loadClassNoEx(CLS_NAME).getName());
500 }
501
502
503
504
505 @Test
506 public void testLoadClassNoExNotFound() {
507 assertThrows(ConfigurationRuntimeException.class, () -> ConfigurationUtils.loadClassNoEx("a non existing class!"));
508 }
509
510
511
512
513 @Test
514 public void testLoadClassNotFound() {
515 assertThrows(ClassNotFoundException.class, () -> ConfigurationUtils.loadClass("a non existing class!"));
516 }
517
518 @Test
519 public void testToString() {
520 final Configuration config = new BaseConfiguration();
521 final String lineSeparator = System.lineSeparator();
522
523 assertEquals("", ConfigurationUtils.toString(config));
524
525 config.setProperty("one", "1");
526 assertEquals("one=1", ConfigurationUtils.toString(config));
527
528 config.setProperty("two", "2");
529 assertEquals("one=1" + lineSeparator + "two=2", ConfigurationUtils.toString(config));
530
531 config.clearProperty("one");
532 assertEquals("two=2", ConfigurationUtils.toString(config));
533
534 config.setProperty("one", "1");
535 assertEquals("two=2" + lineSeparator + "one=1", ConfigurationUtils.toString(config));
536 }
537 }