1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration2.builder.combined;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
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.junit.jupiter.api.Assertions.fail;
29 import static org.mockito.Mockito.mock;
30
31 import java.io.File;
32 import java.io.IOException;
33 import java.net.URL;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.HashSet;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Set;
42 import java.util.concurrent.CountDownLatch;
43
44 import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
45 import org.apache.commons.configuration2.CombinedConfiguration;
46 import org.apache.commons.configuration2.Configuration;
47 import org.apache.commons.configuration2.ConfigurationAssert;
48 import org.apache.commons.configuration2.ConfigurationDecoder;
49 import org.apache.commons.configuration2.DynamicCombinedConfiguration;
50 import org.apache.commons.configuration2.HierarchicalConfiguration;
51 import org.apache.commons.configuration2.PropertiesConfiguration;
52 import org.apache.commons.configuration2.XMLConfiguration;
53 import org.apache.commons.configuration2.XMLPropertiesConfiguration;
54 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
55 import org.apache.commons.configuration2.builder.BuilderEventListenerImpl;
56 import org.apache.commons.configuration2.builder.ConfigurationBuilder;
57 import org.apache.commons.configuration2.builder.ConfigurationBuilderEvent;
58 import org.apache.commons.configuration2.builder.CopyObjectDefaultHandler;
59 import org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl;
60 import org.apache.commons.configuration2.builder.FileBasedBuilderProperties;
61 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
62 import org.apache.commons.configuration2.builder.PropertiesBuilderParametersImpl;
63 import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
64 import org.apache.commons.configuration2.builder.XMLBuilderParametersImpl;
65 import org.apache.commons.configuration2.builder.XMLBuilderProperties;
66 import org.apache.commons.configuration2.builder.fluent.CombinedBuilderParameters;
67 import org.apache.commons.configuration2.builder.fluent.FileBasedBuilderParameters;
68 import org.apache.commons.configuration2.builder.fluent.Parameters;
69 import org.apache.commons.configuration2.builder.fluent.XMLBuilderParameters;
70 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
71 import org.apache.commons.configuration2.convert.ListDelimiterHandler;
72 import org.apache.commons.configuration2.event.ConfigurationEvent;
73 import org.apache.commons.configuration2.event.Event;
74 import org.apache.commons.configuration2.event.EventListener;
75 import org.apache.commons.configuration2.ex.ConfigurationException;
76 import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
77 import org.apache.commons.configuration2.interpol.Lookup;
78 import org.apache.commons.configuration2.io.DefaultFileSystem;
79 import org.apache.commons.configuration2.io.FileHandler;
80 import org.apache.commons.configuration2.io.FileLocatorUtils;
81 import org.apache.commons.configuration2.io.FileSystem;
82 import org.apache.commons.configuration2.reloading.ReloadingController;
83 import org.apache.commons.configuration2.reloading.ReloadingControllerSupport;
84 import org.apache.commons.configuration2.resolver.CatalogResolver;
85 import org.apache.commons.configuration2.tree.DefaultExpressionEngine;
86 import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols;
87 import org.apache.commons.configuration2.tree.ImmutableNode;
88 import org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine;
89 import org.junit.jupiter.api.AfterEach;
90 import org.junit.jupiter.api.BeforeEach;
91 import org.junit.jupiter.api.Test;
92
93
94
95
96 public class TestCombinedConfigurationBuilder {
97
98
99
100
101 public static class BuilderProviderTestImpl implements ConfigurationBuilderProvider {
102
103
104 private String propertyKey;
105
106 @Override
107 public ConfigurationBuilder<? extends Configuration> getConfigurationBuilder(final ConfigurationDeclaration decl) throws ConfigurationException {
108 final BaseHierarchicalConfiguration config = new BaseHierarchicalConfiguration();
109 config.addProperty(getPropertyKey(), Boolean.TRUE);
110 return new ConstantConfigurationBuilder(config);
111 }
112
113 public String getPropertyKey() {
114 return propertyKey;
115 }
116
117 public void setPropertyKey(final String propertyKey) {
118 this.propertyKey = propertyKey;
119 }
120 }
121
122
123
124
125
126 public static class CombinedConfigurationTestImpl extends CombinedConfiguration {
127 }
128
129
130
131
132 private static final class ConstantConfigurationBuilder extends BasicConfigurationBuilder<BaseHierarchicalConfiguration> {
133 private final BaseHierarchicalConfiguration configuration;
134
135 public ConstantConfigurationBuilder(final BaseHierarchicalConfiguration conf) {
136 super(BaseHierarchicalConfiguration.class);
137 configuration = conf;
138 }
139
140 @Override
141 public BaseHierarchicalConfiguration getConfiguration() throws ConfigurationException {
142 return configuration;
143 }
144 }
145
146
147
148
149 public static class EntityResolverWithPropertiesTestImpl extends CatalogResolver {
150
151
152 private String baseDirectory;
153
154
155 private FileSystem fileSystem;
156
157
158 private ConfigurationInterpolator interpolator;
159
160 public String getBaseDir() {
161 return baseDirectory;
162 }
163
164 public FileSystem getFileSystem() {
165 return fileSystem;
166 }
167
168 public ConfigurationInterpolator getInterpolator() {
169 return interpolator;
170 }
171
172 @Override
173 public void setBaseDir(final String baseDir) {
174 super.setBaseDir(baseDir);
175 baseDirectory = baseDir;
176 }
177
178 @Override
179 public void setFileSystem(final FileSystem fileSystem) {
180 super.setFileSystem(fileSystem);
181 this.fileSystem = fileSystem;
182 }
183
184 @Override
185 public void setInterpolator(final ConfigurationInterpolator interpolator) {
186 super.setInterpolator(interpolator);
187 this.interpolator = interpolator;
188 }
189 }
190
191
192
193
194
195 public static class FileSystemTestImpl extends DefaultFileSystem {
196 }
197
198
199
200
201 private static final class ReadThread extends Thread {
202
203
204 private final CombinedConfiguration config;
205
206
207 private final CountDownLatch startLatch;
208
209
210 private Boolean value;
211
212 public ReadThread(final CombinedConfiguration cc, final CountDownLatch latch) {
213 config = cc;
214 startLatch = latch;
215 }
216
217 @Override
218 public void run() {
219 try {
220 startLatch.await();
221 value = config.getBoolean("configuration.loaded");
222 } catch (final InterruptedException iex) {
223
224 }
225 }
226
227
228
229
230 public void verify() {
231 try {
232 join();
233 } catch (final InterruptedException iex) {
234 fail("Waiting was interrupted: " + iex);
235 }
236 assertEquals(Boolean.TRUE, value);
237 }
238 }
239
240
241
242
243
244 public static class TestLookup implements Lookup {
245 private final Map<String, String> map = new HashMap<>();
246
247 public TestLookup() {
248 map.put("test_file_xml", "test.xml");
249 map.put("test_file_combine", "testcombine1.xml");
250 map.put("test_key", "test.value");
251 }
252
253 @Override
254 public String lookup(final String key) {
255 return map.get(key);
256 }
257 }
258
259
260 private static final File TEST_FILE = ConfigurationAssert.getTestFile("testDigesterConfiguration.xml");
261
262
263 private static final String TEST_SUB_XML = "test.xml";
264
265
266 private static final String BUILDER_NAME = "subBuilderName";
267
268
269
270
271 private static final String MULTI_FILE_PROPERTY = "Id";
272
273
274
275
276
277
278 private static void checkCombinedConfigAttrs(final CombinedConfiguration cc) {
279 final ListDelimiterHandler handler = cc.getListDelimiterHandler();
280 assertInstanceOf(DefaultListDelimiterHandler.class, handler);
281 assertEquals(',', ((DefaultListDelimiterHandler) handler).getDelimiter());
282 }
283
284
285
286
287
288
289
290
291 protected static BasicConfigurationBuilder<? extends BaseHierarchicalConfiguration> createDefinitionBuilder(final BaseHierarchicalConfiguration defConfig) {
292 return new ConstantConfigurationBuilder(defConfig);
293 }
294
295
296
297
298
299
300
301
302
303 protected static BaseHierarchicalConfiguration createDefinitionConfig(final String tag, final Map<String, Object> attrs) {
304 final BaseHierarchicalConfiguration defConfig = new BaseHierarchicalConfiguration();
305 final String prefix = "override." + tag;
306 for (final Map.Entry<String, Object> e : attrs.entrySet()) {
307 defConfig.addProperty(prefix + "[@" + e.getKey() + "]", e.getValue());
308 }
309 return defConfig;
310 }
311
312
313
314
315
316
317
318 private static XMLBuilderParameters prepareParamsForInheritanceTest(final Parameters params) {
319 final DefaultExpressionEngineSymbols symbols = new DefaultExpressionEngineSymbols.Builder(DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS)
320 .setPropertyDelimiter("/").create();
321 final DefaultExpressionEngine engine = new DefaultExpressionEngine(symbols);
322 final DefaultListDelimiterHandler listDelimiterHandler = new DefaultListDelimiterHandler(',');
323 return params.xml().setExpressionEngine(engine).setListDelimiterHandler(listDelimiterHandler).setFile(TEST_FILE);
324 }
325
326
327
328
329
330
331 private static void switchToMultiFile(final String key) {
332 System.setProperty(MULTI_FILE_PROPERTY, key);
333 }
334
335
336 protected Parameters parameters;
337
338
339 protected CombinedConfigurationBuilder builder;
340
341
342
343
344
345
346 private CombinedConfiguration checkConfiguration() throws ConfigurationException {
347 final CombinedConfiguration compositeConfiguration = builder.getConfiguration();
348
349 assertEquals(3, compositeConfiguration.getNumberOfConfigurations());
350 assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
351 assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration.getConfiguration(1).getClass());
352 assertEquals(XMLConfiguration.class, compositeConfiguration.getConfiguration(2).getClass());
353
354
355 final PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
356 assertNotNull(pc);
357
358
359 checkProperties(compositeConfiguration);
360 return compositeConfiguration;
361 }
362
363
364
365
366
367
368
369 private void checkFileSystem(final File fsFile) throws ConfigurationException {
370 builder.configure(createParameters().setFile(fsFile));
371 builder.getConfiguration();
372 final FileBasedConfigurationBuilder<? extends Configuration> xmlBuilder = (FileBasedConfigurationBuilder<? extends Configuration>) builder
373 .getNamedBuilder("xml");
374 assertInstanceOf(FileSystemTestImpl.class, xmlBuilder.getFileHandler().getFileSystem());
375 }
376
377
378
379
380
381
382
383
384 private void checkMultiFile(final String key, final CombinedConfiguration config, final int rows) {
385 switchToMultiFile(key);
386 assertEquals(rows, config.getInt("rowsPerPage"));
387 }
388
389
390
391
392
393
394 private void checkProperties(final Configuration compositeConfiguration) {
395 assertTrue(compositeConfiguration.getBoolean("test.boolean"));
396 assertEquals("I'm complex!", compositeConfiguration.getProperty("element2.subelement.subsubelement"));
397 assertEquals("value1", compositeConfiguration.getProperty("key1"));
398 }
399
400
401
402
403
404
405
406
407 private CombinedConfiguration createMultiFileConfig(final String fileName) throws ConfigurationException {
408 final File testFile = ConfigurationAssert.getTestFile(fileName);
409 builder.configure(createParameters().setFile(testFile));
410 final CombinedConfiguration config = builder.getConfiguration();
411 assertInstanceOf(DynamicCombinedConfiguration.class, config);
412 return config;
413 }
414
415
416
417
418
419
420 protected FileBasedBuilderParameters createParameters() {
421 return parameters.fileBased();
422 }
423
424
425
426
427
428
429
430
431 private BasicConfigurationBuilder<? extends HierarchicalConfiguration<ImmutableNode>> prepareSubBuilderTest(final Map<String, Object> attrs) {
432 attrs.put("fileName", TEST_SUB_XML);
433 attrs.put("config-name", BUILDER_NAME);
434 final BaseHierarchicalConfiguration defConfig = createDefinitionConfig("xml", attrs);
435 final BasicConfigurationBuilder<? extends HierarchicalConfiguration<ImmutableNode>> defBuilder = createDefinitionBuilder(defConfig);
436 builder.configure(new CombinedBuilderParametersImpl().setDefinitionBuilder(defBuilder));
437 return defBuilder;
438 }
439
440 @BeforeEach
441 public void setUp() throws Exception {
442 System.setProperty("java.naming.factory.initial", "org.apache.commons.configuration2.MockInitialContextFactory");
443 System.setProperty("test_file_xml", TEST_SUB_XML);
444 System.setProperty("test_file_combine", "testcombine1.xml");
445 parameters = new Parameters();
446 builder = new CombinedConfigurationBuilder();
447 }
448
449 @AfterEach
450 public void tearDown() throws Exception {
451 System.getProperties().remove(MULTI_FILE_PROPERTY);
452 }
453
454
455
456
457 @Test
458 void testBasePathForChildConfigurations() throws ConfigurationException {
459 final BaseHierarchicalConfiguration defConfig = new BaseHierarchicalConfiguration();
460 defConfig.addProperty("properties[@fileName]", "test.properties");
461 final File deepDir = new File(ConfigurationAssert.TEST_DIR, "config/deep");
462 builder.configure(
463 new CombinedBuilderParametersImpl().setBasePath(deepDir.getAbsolutePath()).setDefinitionBuilder(new ConstantConfigurationBuilder(defConfig)));
464 final CombinedConfiguration config = builder.getConfiguration();
465 assertEquals("somevalue", config.getString("somekey"));
466 }
467
468
469
470
471 @Test
472 void testBuilderNames() throws ConfigurationException {
473 builder.configure(createParameters().setFile(TEST_FILE));
474 builder.getConfiguration();
475 final Set<String> names = builder.builderNames();
476 assertEquals(new HashSet<>(Arrays.asList("props", "xml")), names);
477 }
478
479
480
481
482 @Test
483 void testBuilderNamesBeforeConfigurationAccess() {
484 assertEquals(Collections.emptySet(), builder.builderNames());
485 builder.configure(createParameters().setFile(TEST_FILE));
486 assertEquals(Collections.emptySet(), builder.builderNames());
487 }
488
489
490
491
492 @Test
493 void testBuilderNamesManipulate() throws ConfigurationException {
494 builder.configure(createParameters().setFile(TEST_FILE));
495 builder.getConfiguration();
496 final Set<String> names = builder.builderNames();
497 assertThrows(UnsupportedOperationException.class, () -> names.add(BUILDER_NAME));
498 }
499
500
501
502
503
504 @Test
505 void testChildBuildersAreInitializedOnlyOnce() throws ConfigurationException {
506 builder.configure(createParameters().setFile(TEST_FILE));
507 builder.getConfiguration();
508 builder.resetResult();
509 builder.getConfiguration();
510 final Collection<ConfigurationBuilder<? extends Configuration>> childBuilders = builder.getChildBuilders();
511 assertEquals(3, childBuilders.size());
512 }
513
514
515
516
517 @Test
518 void testCombinedConfigurationAttributes() throws ConfigurationException {
519 final File initFile = ConfigurationAssert.getTestFile("testCCResultInitialization.xml");
520 builder.configure(createParameters().setFile(initFile));
521 final CombinedConfiguration cc = builder.getConfiguration();
522 checkCombinedConfigAttrs(cc);
523 final CombinedConfiguration cc2 = (CombinedConfiguration) cc.getConfiguration(CombinedConfigurationBuilder.ADDITIONAL_NAME);
524 checkCombinedConfigAttrs(cc2);
525 }
526
527
528
529
530 @Test
531 void testCombinedConfigurationListNodes() throws ConfigurationException {
532 final File initFile = ConfigurationAssert.getTestFile("testCCResultInitialization.xml");
533 builder.configure(createParameters().setFile(initFile));
534 final CombinedConfiguration cc = builder.getConfiguration();
535 Set<String> listNodes = cc.getNodeCombiner().getListNodes();
536 assertEquals(new HashSet<>(Arrays.asList("table", "list")), listNodes);
537
538 final CombinedConfiguration cca = (CombinedConfiguration) cc.getConfiguration(CombinedConfigurationBuilder.ADDITIONAL_NAME);
539 listNodes = cca.getNodeCombiner().getListNodes();
540 assertEquals(Collections.emptySet(), listNodes);
541 }
542
543
544
545
546 @Test
547 void testCombinedConfigurationNoAdditional() throws ConfigurationException {
548 builder.configure(createParameters().setFile(TEST_FILE));
549 final CombinedConfiguration cc = builder.getConfiguration();
550 assertNull(cc.getConfiguration(CombinedConfigurationBuilder.ADDITIONAL_NAME));
551 }
552
553
554
555
556 @Test
557 void testConcurrentReadAccessWithoutSynchronizer() throws ConfigurationException {
558 builder.configure(createParameters().setFile(TEST_FILE));
559 final CombinedConfiguration config = builder.getConfiguration();
560 final int threadCount = 32;
561 final CountDownLatch startLatch = new CountDownLatch(1);
562 final ReadThread[] threads = new ReadThread[threadCount];
563 for (int i = 0; i < threadCount; i++) {
564 threads[i] = new ReadThread(config, startLatch);
565 threads[i].start();
566 }
567
568 startLatch.countDown();
569 for (final ReadThread t : threads) {
570 t.verify();
571 }
572 }
573
574
575
576
577 @Test
578 void testConfigurationBuilderProvider() throws ConfigurationException {
579 final BaseHierarchicalConfiguration defConfig = new BaseHierarchicalConfiguration();
580 defConfig.addProperty("override.configuration[@fileName]", TEST_FILE.getAbsolutePath());
581 builder.configure(new CombinedBuilderParametersImpl().setDefinitionBuilder(new ConstantConfigurationBuilder(defConfig)));
582 final CombinedConfiguration cc = builder.getConfiguration();
583 assertEquals(1, cc.getNumberOfConfigurations());
584 checkProperties(cc);
585 }
586
587
588
589
590 @Test
591 void testConfigurationBuilderProviderInheritBasePath() throws ConfigurationException {
592 final File envFile = ConfigurationAssert.getTestFile("testCCEnvProperties.xml");
593 final String basePath = ConfigurationAssert.OUT_DIR.getAbsolutePath();
594 builder.configure(new CombinedBuilderParametersImpl().setBasePath(basePath).setDefinitionBuilderParameters(createParameters().setFile(envFile)));
595 builder.getConfiguration();
596 final CombinedBuilderParametersImpl params = new CombinedBuilderParametersImpl();
597 builder.initChildBuilderParameters(params);
598 assertEquals(basePath, params.getBasePath());
599 }
600
601
602
603
604
605 @Test
606 void testConfigurationBuilderProviderInheritBasicProperties() throws ConfigurationException {
607 final File testFile = ConfigurationAssert.getTestFile("testCCCombinedChildBuilder.xml");
608 final ListDelimiterHandler listHandler = new DefaultListDelimiterHandler('*');
609 final ConfigurationDecoder decoder = mock(ConfigurationDecoder.class);
610 builder.configure(new CombinedBuilderParametersImpl().setDefinitionBuilderParameters(new XMLBuilderParametersImpl().setFile(testFile))
611 .setListDelimiterHandler(listHandler).setConfigurationDecoder(decoder));
612 final CombinedConfiguration cc = builder.getConfiguration();
613 final CombinedConfiguration cc2 = (CombinedConfiguration) cc.getConfiguration("subcc");
614 assertFalse(cc2.isThrowExceptionOnMissing());
615 assertEquals(listHandler, cc2.getListDelimiterHandler());
616 assertEquals(decoder, cc2.getConfigurationDecoder());
617 }
618
619
620
621
622 @Test
623 void testConfigurationBuilderProviderInheritCustomProviders() throws ConfigurationException {
624 builder.configure(createParameters().setFile(ConfigurationAssert.getTestFile("testCCCustomProvider.xml")));
625 builder.getConfiguration();
626 final CombinedBuilderParametersImpl ccparams = new CombinedBuilderParametersImpl();
627 builder.initChildBuilderParameters(ccparams);
628 assertNotNull(ccparams.providerForTag("test"));
629 }
630
631
632
633
634 @Test
635 void testConfigurationBuilderProviderInheritEventListeners() throws ConfigurationException {
636 @SuppressWarnings("unchecked")
637 final EventListener<Event> l1 = mock(EventListener.class);
638 @SuppressWarnings("unchecked")
639 final EventListener<ConfigurationEvent> l2 = mock(EventListener.class);
640
641 final File testFile = ConfigurationAssert.getTestFile("testCCCombinedChildBuilder.xml");
642 builder.configure(new XMLBuilderParametersImpl().setFile(testFile));
643 builder.addEventListener(Event.ANY, l1);
644 builder.addEventListener(ConfigurationEvent.ANY, l2);
645 final CombinedConfiguration cc = builder.getConfiguration();
646 final CombinedConfiguration cc2 = (CombinedConfiguration) cc.getConfiguration("subcc");
647 final Collection<EventListener<? super ConfigurationEvent>> listeners = cc2.getEventListeners(ConfigurationEvent.ANY);
648 assertTrue(listeners.contains(l1));
649 assertTrue(listeners.contains(l2));
650 final Collection<EventListener<? super Event>> eventListeners = cc2.getEventListeners(Event.ANY);
651 assertEquals(1, eventListeners.size());
652 assertTrue(eventListeners.contains(l1));
653 }
654
655
656
657
658 @Test
659 void testConfigureEntityResolverWithProperties() throws ConfigurationException {
660 final HierarchicalConfiguration<ImmutableNode> config = new BaseHierarchicalConfiguration();
661 config.addProperty("header.entity-resolver[@config-class]", EntityResolverWithPropertiesTestImpl.class.getName());
662 final XMLBuilderParametersImpl xmlParams = new XMLBuilderParametersImpl();
663 final FileSystem fs = mock(FileSystem.class);
664 final String baseDir = ConfigurationAssert.OUT_DIR_NAME;
665 xmlParams.setBasePath(baseDir);
666 xmlParams.setFileSystem(fs);
667 builder.configureEntityResolver(config, xmlParams);
668 final EntityResolverWithPropertiesTestImpl resolver = (EntityResolverWithPropertiesTestImpl) xmlParams.getEntityResolver();
669 assertSame(fs, resolver.getFileSystem());
670 assertSame(baseDir, resolver.getBaseDir());
671 }
672
673
674
675
676 @Test
677 void testConfigureResult() {
678 final CombinedConfigurationBuilder configuredBuilder = builder.configure(createParameters().setFile(TEST_FILE));
679 assertSame(builder, configuredBuilder);
680 }
681
682
683
684
685 @Test
686 void testCustomBuilderProvider() throws ConfigurationException {
687 final String tagName = "myTestTag";
688 final BaseHierarchicalConfiguration dataConf = new BaseHierarchicalConfiguration();
689 dataConf.addProperty(tagName, Boolean.TRUE);
690 final Map<String, Object> attrs = new HashMap<>();
691 attrs.put("config-name", BUILDER_NAME);
692 attrs.put("config-at", "tests");
693 builder.configure(new CombinedBuilderParametersImpl().setDefinitionBuilder(createDefinitionBuilder(createDefinitionConfig(tagName, attrs)))
694 .registerProvider(tagName, decl -> new ConstantConfigurationBuilder(dataConf)));
695 final CombinedConfiguration cc = builder.getConfiguration();
696 assertEquals(dataConf, cc.getConfiguration(BUILDER_NAME));
697 assertEquals(Boolean.TRUE, cc.getProperty("tests." + tagName));
698 }
699
700
701
702
703 @Test
704 void testCustomEntityResolver() throws ConfigurationException {
705 final File resolverFile = ConfigurationAssert.getTestFile("testCCEntityResolver.xml");
706 builder.configure(createParameters().setFile(resolverFile));
707 final CombinedConfiguration cc = builder.getConfiguration();
708 final XMLConfiguration xmlConf = (XMLConfiguration) cc.getConfiguration("xml");
709 final EntityResolverWithPropertiesTestImpl resolver = (EntityResolverWithPropertiesTestImpl) xmlConf.getEntityResolver();
710 assertFalse(resolver.getInterpolator().getLookups().isEmpty());
711 }
712
713
714
715
716 @Test
717 void testCustomFileSystem() throws ConfigurationException {
718 checkFileSystem(ConfigurationAssert.getTestFile("testCCFileSystem.xml"));
719 }
720
721
722
723
724 @Test
725 void testCustomFileSystemForSubConfig() throws ConfigurationException {
726 checkFileSystem(ConfigurationAssert.getTestFile("testCCFileSystemSubConfig.xml"));
727 }
728
729
730
731
732 @Test
733 void testCustomLookup() throws ConfigurationException {
734 final File testFile = ConfigurationAssert.getTestFile("testCCLookup.xml");
735 builder.configure(createParameters().setFile(testFile));
736 final CombinedConfiguration cc = builder.getConfiguration();
737 assertTrue(cc.getInterpolator().getLookups().containsKey("test"));
738 final Configuration xmlConf = cc.getConfiguration("xml");
739 assertTrue(xmlConf.getInterpolator().getLookups().containsKey("test"));
740 }
741
742
743
744
745 @Test
746 void testCustomResultConfiguration() throws ConfigurationException {
747 final File testFile = ConfigurationAssert.getTestFile("testCCResultClass.xml");
748 final ListDelimiterHandler listHandler = new DefaultListDelimiterHandler('.');
749 builder.configure(new CombinedBuilderParametersImpl().setDefinitionBuilderParameters(new XMLBuilderParametersImpl().setFile(testFile))
750 .setListDelimiterHandler(listHandler).setThrowExceptionOnMissing(false));
751 final CombinedConfiguration cc = builder.getConfiguration();
752 assertInstanceOf(CombinedConfigurationTestImpl.class, cc);
753 assertTrue(cc.isThrowExceptionOnMissing());
754 assertEquals(listHandler, cc.getListDelimiterHandler());
755 }
756
757
758
759
760
761 @Test
762 void testDefaultBasePathFromDefinitionBuilder() throws ConfigurationException, IOException {
763 final String testFile = "testCCSystemProperties.xml";
764 builder.configure(new CombinedBuilderParametersImpl()
765 .setDefinitionBuilderParameters(createParameters().setBasePath(ConfigurationAssert.TEST_DIR.getAbsolutePath()).setFileName(testFile)));
766 builder.getConfiguration();
767 final XMLBuilderParametersImpl xmlParams = new XMLBuilderParametersImpl();
768 builder.initChildBuilderParameters(xmlParams);
769 final File basePathFile = FileLocatorUtils.fileFromURL(new URL(xmlParams.getFileHandler().getBasePath()));
770 assertEquals(ConfigurationAssert.getTestFile(testFile).getAbsoluteFile(), basePathFile);
771 }
772
773
774
775
776 @Test
777 void testDefaultBasePathInParameters() throws ConfigurationException {
778 final File testFile = ConfigurationAssert.getTestFile("testCCSystemProperties.xml");
779 final String basePath = ConfigurationAssert.OUT_DIR.getAbsolutePath();
780 builder.configure(new CombinedBuilderParametersImpl().setBasePath(basePath).setDefinitionBuilderParameters(createParameters().setFile(testFile)));
781 builder.getConfiguration();
782 final XMLBuilderParametersImpl xmlParams = new XMLBuilderParametersImpl();
783 builder.initChildBuilderParameters(xmlParams);
784 assertEquals(basePath, xmlParams.getFileHandler().getBasePath());
785 }
786
787
788
789
790 @Test
791 void testEnvironmentProperties() throws ConfigurationException {
792 final File envFile = ConfigurationAssert.getTestFile("testCCEnvProperties.xml");
793 builder.configure(createParameters().setFile(envFile));
794 final CombinedConfiguration cc = builder.getConfiguration();
795 assertFalse(cc.isEmpty());
796
797
798
799
800 cc.setInterpolator(null);
801
802
803 for (final Map.Entry<String, String> e : System.getenv().entrySet()) {
804 assertEquals(e.getValue(), cc.getString(e.getKey()), "Wrong value for property: " + e.getKey());
805 }
806 }
807
808
809
810
811 @Test
812 void testGetChildBuilders() throws ConfigurationException {
813 builder.configure(createParameters().setFile(TEST_FILE));
814 builder.getConfiguration();
815 final Collection<ConfigurationBuilder<? extends Configuration>> childBuilders = builder.getChildBuilders();
816 assertEquals(3, childBuilders.size());
817 }
818
819
820
821
822 @Test
823 void testGetNamedBuilder() throws ConfigurationException {
824 builder.configure(createParameters().setFile(TEST_FILE));
825 builder.getConfiguration();
826 final ConfigurationBuilder<? extends Configuration> propBuilder = builder.getNamedBuilder("props");
827 assertInstanceOf(FileBasedConfigurationBuilder.class, propBuilder);
828 assertInstanceOf(PropertiesConfiguration.class, propBuilder.getConfiguration());
829 }
830
831
832
833
834 @Test
835 void testGetNamedBuilderBeforeConfigurationAccess() {
836 builder.configure(createParameters().setFile(TEST_FILE));
837 assertThrows(ConfigurationException.class, () -> builder.getNamedBuilder("nonExistingBuilder"));
838 }
839
840
841
842
843 @Test
844 void testGetNamedBuilderUnknown() throws ConfigurationException {
845 builder.configure(createParameters().setFile(TEST_FILE));
846 builder.getConfiguration();
847 assertThrows(ConfigurationException.class, () -> builder.getNamedBuilder("nonExistingBuilder"));
848 }
849
850
851
852
853 @Test
854 void testInheritProperties() throws ConfigurationException {
855 final Parameters params = new Parameters();
856 final XMLBuilderParameters xmlParams = prepareParamsForInheritanceTest(params);
857 builder.configure(xmlParams);
858 final CombinedConfiguration config = builder.getConfiguration();
859
860 List<String> list = config.getList(String.class, "test/mixed/array");
861 assertTrue(list.size() > 2);
862 final String[] stringArray = config.getStringArray("test/mixed/array");
863 assertTrue(stringArray.length > 2);
864 final XMLConfiguration xmlConfig = (XMLConfiguration) config.getConfiguration("xml");
865 list = xmlConfig.getList(String.class, "split/list1");
866 assertEquals(3, list.size());
867 }
868
869
870
871
872 @Test
873 void testINIConfiguration() throws ConfigurationException {
874 final File multiFile = ConfigurationAssert.getTestFile("testDigesterConfiguration3.xml");
875 builder.configure(new CombinedBuilderParametersImpl().setDefinitionBuilderParameters(createParameters().setFile(multiFile)));
876 final CombinedConfiguration cc = builder.getConfiguration();
877 assertEquals("yes", cc.getString("testini.loaded"));
878 }
879
880
881
882
883
884 @Test
885 void testInitChildBuilderParametersDefaultChildProperties() throws ConfigurationException {
886 final Long defRefresh = 60000L;
887 final Long xmlRefresh = 30000L;
888 builder.configure(parameters.combined().setDefinitionBuilderParameters(parameters.fileBased().setFile(TEST_FILE))
889 .registerChildDefaultsHandler(FileBasedBuilderProperties.class,
890 new CopyObjectDefaultHandler(new FileBasedBuilderParametersImpl().setReloadingRefreshDelay(defRefresh).setThrowExceptionOnMissing(true)))
891 .registerChildDefaultsHandler(XMLBuilderProperties.class, new CopyObjectDefaultHandler(
892 new XMLBuilderParametersImpl().setValidating(false).setExpressionEngine(new XPathExpressionEngine()).setReloadingRefreshDelay(xmlRefresh))));
893 builder.getConfiguration();
894 final XMLBuilderParametersImpl params = new XMLBuilderParametersImpl();
895 builder.initChildBuilderParameters(params);
896 assertInstanceOf(XPathExpressionEngine.class, params.getParameters().get("expressionEngine"));
897 assertEquals(Boolean.FALSE, params.getParameters().get("validating"));
898 assertEquals(xmlRefresh, params.getReloadingRefreshDelay());
899 assertEquals(Boolean.TRUE, params.getParameters().get("throwExceptionOnMissing"));
900
901 final PropertiesBuilderParametersImpl params2 = new PropertiesBuilderParametersImpl();
902 builder.initChildBuilderParameters(params2);
903 assertEquals(defRefresh, params2.getReloadingRefreshDelay());
904 }
905
906
907
908
909
910 @Test
911 void testInterpolationOverMultipleSources() throws ConfigurationException {
912 final File testFile = ConfigurationAssert.getTestFile("testInterpolationBuilder.xml");
913 builder.configure(createParameters().setFile(testFile));
914 final CombinedConfiguration combConfig = builder.getConfiguration();
915 assertEquals("abc-product", combConfig.getString("products.product.desc"));
916 final XMLConfiguration xmlConfig = (XMLConfiguration) combConfig.getConfiguration("test");
917 assertEquals("abc-product", xmlConfig.getString("products/product/desc"));
918 final HierarchicalConfiguration<ImmutableNode> subConfig = xmlConfig.configurationAt("products/product[@name='abc']", true);
919 assertEquals("abc-product", subConfig.getString("desc"));
920 }
921
922
923
924
925 @Test
926 void testJndiConfiguration() throws ConfigurationException {
927 final File multiFile = ConfigurationAssert.getTestFile("testDigesterConfiguration3.xml");
928 builder.configure(new CombinedBuilderParametersImpl().setDefinitionBuilderParameters(createParameters().setFile(multiFile)));
929 final CombinedConfiguration cc = builder.getConfiguration();
930 assertTrue(cc.getBoolean("test.onlyinjndi"));
931 }
932
933
934
935
936 @Test
937 void testLoadAdditional() throws ConfigurationException {
938 final File additonalFile = ConfigurationAssert.getTestFile("testDigesterConfiguration2.xml");
939 builder.configure(createParameters().setFile(additonalFile));
940 final CombinedConfiguration compositeConfiguration = builder.getConfiguration();
941 assertEquals(2, compositeConfiguration.getNumberOfConfigurations());
942
943
944 Object prop = compositeConfiguration.getProperty("tables.table.name");
945 Collection<?> collection = assertInstanceOf(Collection.class, prop);
946 assertEquals(3, collection.size());
947 assertEquals("users", compositeConfiguration.getProperty("tables.table(0).name"));
948 assertEquals("documents", compositeConfiguration.getProperty("tables.table(1).name"));
949 assertEquals("tasks", compositeConfiguration.getProperty("tables.table(2).name"));
950
951 prop = compositeConfiguration.getProperty("tables.table.fields.field.name");
952 collection = assertInstanceOf(Collection.class, prop);
953 assertEquals(17, collection.size());
954
955 assertEquals("smtp.mydomain.org", compositeConfiguration.getString("mail.host.smtp"));
956 assertEquals("pop3.mydomain.org", compositeConfiguration.getString("mail.host.pop"));
957
958
959 assertEquals("masterOfPost", compositeConfiguration.getString("mail.account.user"));
960 assertEquals("topsecret", compositeConfiguration.getString("mail.account.psswd"));
961
962
963 assertEquals("enhanced factory", compositeConfiguration.getString("test.configuration"));
964 }
965
966
967
968
969 @Test
970 void testLoadConfiguration() throws ConfigurationException {
971 builder.configure(createParameters().setFile(TEST_FILE));
972 checkConfiguration();
973 }
974
975
976
977
978 @Test
979 void testLoadOptional() throws Exception {
980 final File optionalFile = ConfigurationAssert.getTestFile("testDigesterOptionalConfiguration.xml");
981 builder.configure(createParameters().setFile(optionalFile));
982 final Configuration config = builder.getConfiguration();
983 assertTrue(config.getBoolean("test.boolean"));
984 assertEquals("value", config.getProperty("element"));
985 }
986
987
988
989
990 @Test
991 void testLoadOptionalForceCreate() throws ConfigurationException {
992 final String name = "optionalConfig";
993 final Map<String, Object> attrs = new HashMap<>();
994 attrs.put("fileName", "nonExisting.xml");
995 attrs.put("config-name", name);
996 attrs.put("config-optional", Boolean.TRUE);
997 attrs.put("config-forceCreate", Boolean.TRUE);
998 final BaseHierarchicalConfiguration defConfig = createDefinitionConfig("xml", attrs);
999 final BasicConfigurationBuilder<? extends BaseHierarchicalConfiguration> defBuilder = createDefinitionBuilder(defConfig);
1000 builder.configure(new CombinedBuilderParametersImpl().setDefinitionBuilder(defBuilder));
1001 final CombinedConfiguration cc = builder.getConfiguration();
1002 assertEquals(1, cc.getNumberOfConfigurations());
1003 assertInstanceOf(XMLConfiguration.class, cc.getConfiguration(name));
1004 }
1005
1006
1007
1008
1009
1010 @Test
1011 void testLoadOptionalWithException() {
1012 final File optionalExFile = ConfigurationAssert.getTestFile("testDigesterOptionalConfigurationEx.xml");
1013 builder.configure(createParameters().setFile(optionalExFile));
1014 assertThrows(ConfigurationException.class, builder::getConfiguration);
1015 }
1016
1017
1018
1019
1020 @Test
1021 void testMultiTenentConfiguration() throws ConfigurationException {
1022 final CombinedConfiguration config = createMultiFileConfig("testCCMultiTenent.xml");
1023 checkMultiFile("1001", config, 15);
1024 checkMultiFile("1002", config, 25);
1025 checkMultiFile("1003", config, 35);
1026 checkMultiFile("1004", config, 50);
1027 }
1028
1029
1030
1031
1032 @Test
1033 void testMultiTenentConfigurationProperties() throws ConfigurationException {
1034 final CombinedConfiguration config = createMultiFileConfig("testCCMultiTenent.xml");
1035 switchToMultiFile("1001");
1036 final HierarchicalConfiguration<?> multiConf = (HierarchicalConfiguration<?>) config.getConfiguration("clientConfig");
1037 assertInstanceOf(XPathExpressionEngine.class, multiConf.getExpressionEngine());
1038 assertEquals("#808080", config.getString("colors.background"));
1039 assertEquals("#000000", multiConf.getString("colors/text"));
1040 }
1041
1042
1043
1044
1045 @Test
1046 void testMultiTenentConfigurationReloading() throws ConfigurationException, InterruptedException {
1047 final CombinedConfiguration config = createMultiFileConfig("testCCMultiTenentReloading.xml");
1048 final File outFile = ConfigurationAssert.getOutFile("MultiFileReloadingTest.xml");
1049 switchToMultiFile(outFile.getAbsolutePath());
1050 final XMLConfiguration reloadConfig = new XMLConfiguration();
1051 final FileHandler handler = new FileHandler(reloadConfig);
1052 handler.setFile(outFile);
1053 final String key = "test.reload";
1054 reloadConfig.setProperty(key, "no");
1055 handler.save();
1056 try {
1057 assertEquals("no", config.getString(key));
1058 final ConfigurationBuilder<? extends Configuration> childBuilder = builder.getNamedBuilder("clientConfig");
1059 final ReloadingControllerSupport reloadingControllerSupport = assertInstanceOf(ReloadingControllerSupport.class, childBuilder);
1060 final ReloadingController ctrl = reloadingControllerSupport.getReloadingController();
1061 ctrl.checkForReloading(null);
1062 final BuilderEventListenerImpl listener = new BuilderEventListenerImpl();
1063 childBuilder.addEventListener(ConfigurationBuilderEvent.RESET, listener);
1064 reloadConfig.setProperty(key, "yes");
1065 handler.save();
1066
1067 int attempts = 10;
1068 boolean changeDetected;
1069 do {
1070 changeDetected = ctrl.checkForReloading(null);
1071 if (!changeDetected) {
1072 Thread.sleep(1000);
1073 handler.save(outFile);
1074 }
1075 } while (!changeDetected && --attempts > 0);
1076 assertTrue(changeDetected);
1077 assertEquals("yes", builder.getConfiguration().getString(key));
1078 final ConfigurationBuilderEvent event = listener.nextEvent(ConfigurationBuilderEvent.RESET);
1079 listener.assertNoMoreEvents();
1080 final BasicConfigurationBuilder<?> multiBuilder = (BasicConfigurationBuilder<?>) event.getSource();
1081 childBuilder.removeEventListener(ConfigurationBuilderEvent.RESET, listener);
1082 multiBuilder.resetResult();
1083 listener.assertNoMoreEvents();
1084 } finally {
1085 assertTrue(outFile.delete());
1086 }
1087 }
1088
1089
1090
1091
1092 @Test
1093 void testNoDefinitionBuilder() {
1094 assertThrows(ConfigurationException.class, builder::getConfiguration);
1095 }
1096
1097
1098
1099
1100 @Test
1101 void testProviderInDefinitionConfig() throws ConfigurationException {
1102 builder.configure(createParameters().setFile(ConfigurationAssert.getTestFile("testCCCustomProvider.xml")));
1103 final CombinedConfiguration cc = builder.getConfiguration();
1104 assertTrue(cc.getBoolean("testKey"));
1105 }
1106
1107
1108
1109
1110 @Test
1111 void testReactOnSubBuilderChange() throws ConfigurationException {
1112 final Map<String, Object> attrs = new HashMap<>();
1113 prepareSubBuilderTest(attrs);
1114 final CombinedConfiguration cc = builder.getConfiguration();
1115 final BasicConfigurationBuilder<?> subBuilder = (BasicConfigurationBuilder<?>) builder.getNamedBuilder(BUILDER_NAME);
1116 subBuilder.reset();
1117 assertNotSame(cc, builder.getConfiguration());
1118 }
1119
1120
1121
1122
1123 @Test
1124 void testReloadingBuilder() throws ConfigurationException {
1125 final Map<String, Object> attrs = new HashMap<>();
1126 attrs.put("config-reload", Boolean.TRUE);
1127 prepareSubBuilderTest(attrs);
1128 builder.getConfiguration();
1129 assertInstanceOf(ReloadingFileBasedConfigurationBuilder.class, builder.getNamedBuilder(BUILDER_NAME));
1130 }
1131
1132
1133
1134
1135 @Test
1136 void testRemoveSubBuilderListener() throws ConfigurationException {
1137 final Map<String, Object> attrs = new HashMap<>();
1138 prepareSubBuilderTest(attrs);
1139 builder.getConfiguration();
1140 final BasicConfigurationBuilder<?> subBuilder = (BasicConfigurationBuilder<?>) builder.getNamedBuilder(BUILDER_NAME);
1141 builder.reset();
1142 prepareSubBuilderTest(attrs);
1143 final CombinedConfiguration cc = builder.getConfiguration();
1144 final BasicConfigurationBuilder<?> subBuilder2 = (BasicConfigurationBuilder<?>) builder.getNamedBuilder(BUILDER_NAME);
1145 assertNotSame(subBuilder, subBuilder2);
1146 subBuilder.reset();
1147 assertSame(cc, builder.getConfiguration());
1148 }
1149
1150
1151
1152
1153 @Test
1154 void testResetBuilder() throws ConfigurationException {
1155 final Map<String, Object> attrs = new HashMap<>();
1156 final BasicConfigurationBuilder<? extends HierarchicalConfiguration<ImmutableNode>> defBuilder = prepareSubBuilderTest(attrs);
1157 final CombinedConfiguration cc = builder.getConfiguration();
1158 final ConfigurationBuilder<? extends Configuration> subBuilder = builder.getNamedBuilder(BUILDER_NAME);
1159 defBuilder.reset();
1160 final CombinedConfiguration cc2 = builder.getConfiguration();
1161 assertNotSame(cc, cc2);
1162 final ConfigurationBuilder<? extends Configuration> subBuilder2 = builder.getNamedBuilder(BUILDER_NAME);
1163 assertNotSame(subBuilder, subBuilder2);
1164 }
1165
1166
1167
1168
1169
1170 @Test
1171 void testRootNodeInitializedAfterCreation() throws ConfigurationException {
1172 builder.configure(createParameters().setFile(TEST_FILE));
1173 final CombinedConfiguration cc = builder.getConfiguration();
1174 assertNotNull(cc.getNodeModel().getNodeHandler().getRootNode());
1175 }
1176
1177
1178
1179
1180 @Test
1181 void testSuppressChildBuilderPropertyInheritance() throws ConfigurationException {
1182 final Parameters params = new Parameters();
1183 final CombinedBuilderParameters combinedParams = params.combined().setInheritSettings(false);
1184 builder.configure(combinedParams, prepareParamsForInheritanceTest(params));
1185 final CombinedConfiguration config = builder.getConfiguration();
1186
1187 final XMLConfiguration xmlConfig = (XMLConfiguration) config.getConfiguration("xml");
1188 final List<String> list = xmlConfig.getList(String.class, "split.list1");
1189 assertEquals(1, list.size());
1190 }
1191
1192
1193
1194
1195
1196 @Test
1197 void testSystemProperties() throws ConfigurationException {
1198 final File systemFile = ConfigurationAssert.getTestFile("testCCSystemProperties.xml");
1199 builder.configure(createParameters().setFile(systemFile));
1200 final CombinedConfiguration cc = builder.getConfiguration();
1201 assertTrue(cc.containsKey("user.name"));
1202 assertEquals("value1", System.getProperty("key1"));
1203 }
1204 }