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 java.net.URL;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.LinkedList;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.stream.Collectors;
30
31 import org.apache.commons.configuration2.CombinedConfiguration;
32 import org.apache.commons.configuration2.Configuration;
33 import org.apache.commons.configuration2.ConfigurationLookup;
34 import org.apache.commons.configuration2.HierarchicalConfiguration;
35 import org.apache.commons.configuration2.SystemConfiguration;
36 import org.apache.commons.configuration2.XMLConfiguration;
37 import org.apache.commons.configuration2.beanutils.BeanDeclaration;
38 import org.apache.commons.configuration2.beanutils.BeanHelper;
39 import org.apache.commons.configuration2.beanutils.CombinedBeanDeclaration;
40 import org.apache.commons.configuration2.beanutils.XMLBeanDeclaration;
41 import org.apache.commons.configuration2.builder.BasicBuilderParameters;
42 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
43 import org.apache.commons.configuration2.builder.BuilderParameters;
44 import org.apache.commons.configuration2.builder.ConfigurationBuilder;
45 import org.apache.commons.configuration2.builder.ConfigurationBuilderEvent;
46 import org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl;
47 import org.apache.commons.configuration2.builder.FileBasedBuilderProperties;
48 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
49 import org.apache.commons.configuration2.builder.XMLBuilderParametersImpl;
50 import org.apache.commons.configuration2.builder.XMLBuilderProperties;
51 import org.apache.commons.configuration2.event.EventListener;
52 import org.apache.commons.configuration2.ex.ConfigurationException;
53 import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
54 import org.apache.commons.configuration2.interpol.Lookup;
55 import org.apache.commons.configuration2.io.FileSystem;
56 import org.apache.commons.configuration2.resolver.CatalogResolver;
57 import org.apache.commons.configuration2.tree.DefaultExpressionEngineSymbols;
58 import org.apache.commons.configuration2.tree.OverrideCombiner;
59 import org.apache.commons.configuration2.tree.UnionCombiner;
60 import org.xml.sax.EntityResolver;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 public class CombinedConfigurationBuilder extends BasicConfigurationBuilder<CombinedConfiguration> {
210
211
212
213
214
215 public static final String ADDITIONAL_NAME = CombinedConfigurationBuilder.class.getName() + "/ADDITIONAL_CONFIG";
216
217
218 static final String CONFIG_BEAN_FACTORY_NAME = CombinedConfigurationBuilder.class.getName() + ".CONFIG_BEAN_FACTORY_NAME";
219
220
221 static final String ATTR_NAME = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + "name"
222 + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
223
224
225 static final String ATTR_ATNAME = "at";
226
227
228 static final String ATTR_AT_RES = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + ATTR_ATNAME
229 + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
230
231
232 static final String ATTR_AT = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + ATTR_ATNAME + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
233
234
235 static final String ATTR_OPTIONALNAME = "optional";
236
237
238 static final String ATTR_OPTIONAL_RES = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + ATTR_OPTIONALNAME
239 + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
240
241
242 static final String ATTR_OPTIONAL = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + ATTR_OPTIONALNAME
243 + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
244
245
246 static final String ATTR_FORCECREATE = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + "forceCreate"
247 + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
248
249
250 static final String ATTR_RELOAD = DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_START + XMLBeanDeclaration.RESERVED_PREFIX + "reload"
251 + DefaultExpressionEngineSymbols.DEFAULT_ATTRIBUTE_END;
252
253
254
255
256 static final String KEY_SYSTEM_PROPS = "[@systemProperties]";
257
258
259 static final String SEC_HEADER = "header";
260
261
262 static final String KEY_UNION = "additional";
263
264
265 static final String[] CONFIG_SECTIONS = {"additional", "override", SEC_HEADER};
266
267
268
269
270 static final String KEY_OVERRIDE = "override";
271
272
273
274
275 static final String KEY_OVERRIDE_LIST = SEC_HEADER + ".combiner.override.list-nodes.node";
276
277
278
279
280 static final String KEY_ADDITIONAL_LIST = SEC_HEADER + ".combiner.additional.list-nodes.node";
281
282
283
284
285 static final String KEY_CONFIGURATION_PROVIDERS = SEC_HEADER + ".providers.provider";
286
287
288
289
290 static final String KEY_PROVIDER_KEY = XMLBeanDeclaration.ATTR_PREFIX + "tag]";
291
292
293
294
295 static final String KEY_CONFIGURATION_LOOKUPS = SEC_HEADER + ".lookups.lookup";
296
297
298
299
300 static final String KEY_ENTITY_RESOLVER = SEC_HEADER + ".entity-resolver";
301
302
303
304
305 static final String KEY_LOOKUP_KEY = XMLBeanDeclaration.ATTR_PREFIX + "prefix]";
306
307
308
309
310 static final String FILE_SYSTEM = SEC_HEADER + ".fileSystem";
311
312
313
314
315
316 static final String KEY_RESULT = SEC_HEADER + ".result";
317
318
319 static final String KEY_COMBINER = KEY_RESULT + ".nodeCombiner";
320
321
322 static final String EXT_XML = "xml";
323
324
325 private static final String BASIC_BUILDER = "org.apache.commons.configuration2.builder.BasicConfigurationBuilder";
326
327
328 private static final String FILE_BUILDER = "org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder";
329
330
331 private static final String RELOADING_BUILDER = "org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder";
332
333
334 private static final String FILE_PARAMS = "org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl";
335
336
337 private static final ConfigurationBuilderProvider PROPERTIES_PROVIDER = new FileExtensionConfigurationBuilderProvider(FILE_BUILDER, RELOADING_BUILDER,
338 "org.apache.commons.configuration2.XMLPropertiesConfiguration", "org.apache.commons.configuration2.PropertiesConfiguration", EXT_XML,
339 Collections.singletonList(FILE_PARAMS));
340
341
342 private static final ConfigurationBuilderProvider XML_PROVIDER = new BaseConfigurationBuilderProvider(FILE_BUILDER, RELOADING_BUILDER,
343 "org.apache.commons.configuration2.XMLConfiguration", Collections.singletonList("org.apache.commons.configuration2.builder.XMLBuilderParametersImpl"));
344
345
346 private static final BaseConfigurationBuilderProvider JNDI_PROVIDER = new BaseConfigurationBuilderProvider(BASIC_BUILDER, null,
347 "org.apache.commons.configuration2.JNDIConfiguration",
348 Collections.singletonList("org.apache.commons.configuration2.builder.JndiBuilderParametersImpl"));
349
350
351 private static final BaseConfigurationBuilderProvider SYSTEM_PROVIDER = new BaseConfigurationBuilderProvider(BASIC_BUILDER, null,
352 "org.apache.commons.configuration2.SystemConfiguration", Collections.singletonList("org.apache.commons.configuration2.builder.BasicBuilderParameters"));
353
354
355 private static final BaseConfigurationBuilderProvider INI_PROVIDER = new BaseConfigurationBuilderProvider(FILE_BUILDER, RELOADING_BUILDER,
356 "org.apache.commons.configuration2.INIConfiguration", Collections.singletonList(FILE_PARAMS));
357
358
359 private static final BaseConfigurationBuilderProvider ENV_PROVIDER = new BaseConfigurationBuilderProvider(BASIC_BUILDER, null,
360 "org.apache.commons.configuration2.EnvironmentConfiguration",
361 Collections.singletonList("org.apache.commons.configuration2.builder.BasicBuilderParameters"));
362
363
364 private static final BaseConfigurationBuilderProvider PLIST_PROVIDER = new FileExtensionConfigurationBuilderProvider(FILE_BUILDER, RELOADING_BUILDER,
365 "org.apache.commons.configuration2.plist.XMLPropertyListConfiguration", "org.apache.commons.configuration2.plist.PropertyListConfiguration", EXT_XML,
366 Collections.singletonList(FILE_PARAMS));
367
368
369 private static final BaseConfigurationBuilderProvider COMBINED_PROVIDER = new CombinedConfigurationBuilderProvider();
370
371
372 private static final MultiFileConfigurationBuilderProvider MULTI_XML_PROVIDER = new MultiFileConfigurationBuilderProvider(
373 "org.apache.commons.configuration2.XMLConfiguration", "org.apache.commons.configuration2.builder.XMLBuilderParametersImpl");
374
375
376 private static final String[] DEFAULT_TAGS = {"properties", "xml", "hierarchicalXml", "plist", "ini", "system", "env", "jndi", "configuration",
377 "multiFile"};
378
379
380 private static final ConfigurationBuilderProvider[] DEFAULT_PROVIDERS = {PROPERTIES_PROVIDER, XML_PROVIDER, XML_PROVIDER, PLIST_PROVIDER, INI_PROVIDER,
381 SYSTEM_PROVIDER, ENV_PROVIDER, JNDI_PROVIDER, COMBINED_PROVIDER, MULTI_XML_PROVIDER};
382
383
384 private static final Map<String, ConfigurationBuilderProvider> DEFAULT_PROVIDERS_MAP;
385
386
387 private ConfigurationBuilder<? extends HierarchicalConfiguration<?>> definitionBuilder;
388
389
390 private HierarchicalConfiguration<?> definitionConfiguration;
391
392
393 private ConfigurationSourceData sourceData;
394
395
396 private CombinedBuilderParametersImpl currentParameters;
397
398
399 private XMLBuilderParametersImpl currentXMLParameters;
400
401
402 private CombinedConfiguration currentConfiguration;
403
404
405
406
407
408 private ConfigurationInterpolator parentInterpolator;
409
410
411
412
413 public CombinedConfigurationBuilder() {
414 super(CombinedConfiguration.class);
415 }
416
417
418
419
420
421
422
423 public CombinedConfigurationBuilder(final Map<String, Object> params) {
424 super(CombinedConfiguration.class, params);
425 }
426
427
428
429
430
431
432
433
434
435 public CombinedConfigurationBuilder(final Map<String, Object> params, final boolean allowFailOnInit) {
436 super(CombinedConfiguration.class, params, allowFailOnInit);
437 }
438
439
440
441
442
443
444
445 public synchronized ConfigurationBuilder<? extends HierarchicalConfiguration<?>> getDefinitionBuilder() throws ConfigurationException {
446 if (definitionBuilder == null) {
447 definitionBuilder = setupDefinitionBuilder(getParameters());
448 addDefinitionBuilderChangeListener(definitionBuilder);
449 }
450 return definitionBuilder;
451 }
452
453
454
455
456 @Override
457 public CombinedConfigurationBuilder configure(final BuilderParameters... params) {
458 super.configure(params);
459 return this;
460 }
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477 public synchronized ConfigurationBuilder<? extends Configuration> getNamedBuilder(final String name) throws ConfigurationException {
478 if (sourceData == null) {
479 throw new ConfigurationException("Information about child builders" + " has not been setup yet! Call getConfiguration() first.");
480 }
481 final ConfigurationBuilder<? extends Configuration> builder = sourceData.getNamedBuilder(name);
482 if (builder == null) {
483 throw new ConfigurationException("Builder cannot be resolved: " + name);
484 }
485 return builder;
486 }
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502 public synchronized Set<String> builderNames() {
503 if (sourceData == null) {
504 return Collections.emptySet();
505 }
506 return Collections.unmodifiableSet(sourceData.builderNames());
507 }
508
509
510
511
512 @Override
513 public synchronized void resetParameters() {
514 super.resetParameters();
515 definitionBuilder = null;
516 definitionConfiguration = null;
517 currentParameters = null;
518 currentXMLParameters = null;
519
520 if (sourceData != null) {
521 sourceData.cleanUp();
522 sourceData = null;
523 }
524 }
525
526
527
528
529
530
531
532
533
534
535
536
537
538 protected ConfigurationBuilder<? extends HierarchicalConfiguration<?>> setupDefinitionBuilder(final Map<String, Object> params)
539 throws ConfigurationException {
540 final CombinedBuilderParametersImpl cbParams = CombinedBuilderParametersImpl.fromParameters(params);
541 if (cbParams != null) {
542 final ConfigurationBuilder<? extends HierarchicalConfiguration<?>> defBuilder = cbParams.getDefinitionBuilder();
543 if (defBuilder != null) {
544 return defBuilder;
545 }
546
547 if (cbParams.getDefinitionBuilderParameters() != null) {
548 return createXMLDefinitionBuilder(cbParams.getDefinitionBuilderParameters());
549 }
550 }
551
552 final BuilderParameters fileParams = FileBasedBuilderParametersImpl.fromParameters(params);
553 if (fileParams != null) {
554 return createXMLDefinitionBuilder(fileParams);
555 }
556
557 throw new ConfigurationException("No builder for configuration definition specified!");
558 }
559
560
561
562
563
564
565
566
567
568
569 protected ConfigurationBuilder<? extends HierarchicalConfiguration<?>> createXMLDefinitionBuilder(final BuilderParameters builderParams) {
570 return new FileBasedConfigurationBuilder<>(XMLConfiguration.class).configure(builderParams);
571 }
572
573
574
575
576
577
578
579
580
581
582
583 protected HierarchicalConfiguration<?> getDefinitionConfiguration() throws ConfigurationException {
584 if (definitionConfiguration == null) {
585 definitionConfiguration = getDefinitionBuilder().getConfiguration();
586 }
587 return definitionConfiguration;
588 }
589
590
591
592
593
594
595
596
597 protected synchronized Collection<ConfigurationBuilder<? extends Configuration>> getChildBuilders() {
598 return sourceData.getChildBuilders();
599 }
600
601
602
603
604
605
606 @Override
607 protected BeanDeclaration createResultDeclaration(final Map<String, Object> params) throws ConfigurationException {
608 final BeanDeclaration paramsDecl = super.createResultDeclaration(params);
609 final XMLBeanDeclaration resultDecl = new XMLBeanDeclaration(getDefinitionConfiguration(), KEY_RESULT, true, CombinedConfiguration.class.getName());
610 return new CombinedBeanDeclaration(resultDecl, paramsDecl);
611 }
612
613
614
615
616
617
618
619
620
621 @Override
622 protected void initResultInstance(final CombinedConfiguration result) throws ConfigurationException {
623 super.initResultInstance(result);
624
625 currentConfiguration = result;
626 final HierarchicalConfiguration<?> config = getDefinitionConfiguration();
627 if (config.getMaxIndex(KEY_COMBINER) < 0) {
628
629 result.setNodeCombiner(new OverrideCombiner());
630 }
631
632 setUpCurrentParameters();
633 initNodeCombinerListNodes(result, config, KEY_OVERRIDE_LIST);
634 registerConfiguredProviders(config);
635 setUpCurrentXMLParameters();
636 currentXMLParameters.setFileSystem(initFileSystem(config));
637 initSystemProperties(config, getBasePath());
638 registerConfiguredLookups(config, result);
639 configureEntityResolver(config, currentXMLParameters);
640 setUpParentInterpolator(currentConfiguration, config);
641
642 final ConfigurationSourceData data = getSourceData();
643 final boolean createBuilders = data.getChildBuilders().isEmpty();
644 final List<ConfigurationBuilder<? extends Configuration>> overrideBuilders = data.createAndAddConfigurations(result, data.getOverrideSources(),
645 data.overrideBuilders);
646 if (createBuilders) {
647 data.overrideBuilders.addAll(overrideBuilders);
648 }
649 if (!data.getUnionSources().isEmpty()) {
650 final CombinedConfiguration addConfig = createAdditionalsConfiguration(result);
651 result.addConfiguration(addConfig, ADDITIONAL_NAME);
652 initNodeCombinerListNodes(addConfig, config, KEY_ADDITIONAL_LIST);
653 final List<ConfigurationBuilder<? extends Configuration>> unionBuilders = data.createAndAddConfigurations(addConfig, data.unionDeclarations,
654 data.unionBuilders);
655 if (createBuilders) {
656 data.unionBuilders.addAll(unionBuilders);
657 }
658 }
659
660 result.isEmpty();
661 currentConfiguration = null;
662 }
663
664
665
666
667
668
669
670
671
672
673 protected CombinedConfiguration createAdditionalsConfiguration(final CombinedConfiguration resultConfig) {
674 final CombinedConfiguration addConfig = new CombinedConfiguration(new UnionCombiner());
675 addConfig.setListDelimiterHandler(resultConfig.getListDelimiterHandler());
676 return addConfig;
677 }
678
679
680
681
682
683
684
685
686
687
688 protected void registerConfiguredLookups(final HierarchicalConfiguration<?> defConfig, final Configuration resultConfig) throws ConfigurationException {
689 final Map<String, Lookup> lookups = defConfig.configurationsAt(KEY_CONFIGURATION_LOOKUPS).stream().collect(
690 Collectors.toMap(config -> config.getString(KEY_LOOKUP_KEY), config -> (Lookup) fetchBeanHelper().createBean(new XMLBeanDeclaration(config))));
691
692 if (!lookups.isEmpty()) {
693 final ConfigurationInterpolator defCI = defConfig.getInterpolator();
694 if (defCI != null) {
695 defCI.registerLookups(lookups);
696 }
697 resultConfig.getInterpolator().registerLookups(lookups);
698 }
699 }
700
701
702
703
704
705
706
707
708
709
710 protected FileSystem initFileSystem(final HierarchicalConfiguration<?> config) throws ConfigurationException {
711 if (config.getMaxIndex(FILE_SYSTEM) == 0) {
712 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, FILE_SYSTEM);
713 return (FileSystem) fetchBeanHelper().createBean(decl);
714 }
715 return null;
716 }
717
718
719
720
721
722
723
724
725
726 protected void initSystemProperties(final HierarchicalConfiguration<?> config, final String basePath) throws ConfigurationException {
727 final String fileName = config.getString(KEY_SYSTEM_PROPS);
728 if (fileName != null) {
729 try {
730 SystemConfiguration.setSystemProperties(basePath, fileName);
731 } catch (final Exception ex) {
732 throw new ConfigurationException("Error setting system properties from " + fileName, ex);
733 }
734 }
735 }
736
737
738
739
740
741
742
743
744
745 protected void configureEntityResolver(final HierarchicalConfiguration<?> config, final XMLBuilderParametersImpl xmlParams) throws ConfigurationException {
746 if (config.getMaxIndex(KEY_ENTITY_RESOLVER) == 0) {
747 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config, KEY_ENTITY_RESOLVER, true);
748 final EntityResolver resolver = (EntityResolver) fetchBeanHelper().createBean(decl, CatalogResolver.class);
749 final FileSystem fileSystem = xmlParams.getFileHandler().getFileSystem();
750 if (fileSystem != null) {
751 BeanHelper.setProperty(resolver, "fileSystem", fileSystem);
752 }
753 final String basePath = xmlParams.getFileHandler().getBasePath();
754 if (basePath != null) {
755 BeanHelper.setProperty(resolver, "baseDir", basePath);
756 }
757 final ConfigurationInterpolator ci = new ConfigurationInterpolator();
758 ci.registerLookups(fetchPrefixLookups());
759 BeanHelper.setProperty(resolver, "interpolator", ci);
760
761 xmlParams.setEntityResolver(resolver);
762 }
763 }
764
765
766
767
768
769
770
771
772
773 protected ConfigurationBuilderProvider providerForTag(final String tagName) {
774 return currentParameters.providerForTag(tagName);
775 }
776
777
778
779
780
781
782
783
784
785 protected void initChildBuilderParameters(final BuilderParameters params) {
786 initDefaultChildParameters(params);
787
788 if (params instanceof BasicBuilderParameters) {
789 initChildBasicParameters((BasicBuilderParameters) params);
790 }
791 if (params instanceof XMLBuilderProperties<?>) {
792 initChildXMLParameters((XMLBuilderProperties<?>) params);
793 }
794 if (params instanceof FileBasedBuilderProperties<?>) {
795 initChildFileBasedParameters((FileBasedBuilderProperties<?>) params);
796 }
797 if (params instanceof CombinedBuilderParametersImpl) {
798 initChildCombinedParameters((CombinedBuilderParametersImpl) params);
799 }
800 }
801
802
803
804
805
806
807
808 void initChildEventListeners(final BasicConfigurationBuilder<? extends Configuration> dest) {
809 copyEventListeners(dest);
810 }
811
812
813
814
815
816
817
818
819 CombinedConfiguration getConfigurationUnderConstruction() {
820 return currentConfiguration;
821 }
822
823
824
825
826
827
828
829
830 void initBean(final Object bean, final BeanDeclaration decl) {
831 fetchBeanHelper().initBean(bean, decl);
832 }
833
834
835
836
837
838 private void setUpCurrentParameters() {
839 currentParameters = CombinedBuilderParametersImpl.fromParameters(getParameters(), true);
840 currentParameters.registerMissingProviders(DEFAULT_PROVIDERS_MAP);
841 }
842
843
844
845
846
847
848
849
850 private void setUpCurrentXMLParameters() throws ConfigurationException {
851 currentXMLParameters = new XMLBuilderParametersImpl();
852 initDefaultBasePath();
853 }
854
855
856
857
858
859
860
861
862 private void setUpParentInterpolator(final Configuration resultConfig, final Configuration defConfig) {
863 parentInterpolator = new ConfigurationInterpolator();
864 parentInterpolator.addDefaultLookup(new ConfigurationLookup(resultConfig));
865 final ConfigurationInterpolator defInterpolator = defConfig.getInterpolator();
866 if (defInterpolator != null) {
867 defInterpolator.setParentInterpolator(parentInterpolator);
868 }
869 }
870
871
872
873
874
875
876
877
878 private void initDefaultBasePath() throws ConfigurationException {
879 assert currentParameters != null : "Current parameters undefined!";
880 if (currentParameters.getBasePath() != null) {
881 currentXMLParameters.setBasePath(currentParameters.getBasePath());
882 } else {
883 final ConfigurationBuilder<? extends HierarchicalConfiguration<?>> defBuilder = getDefinitionBuilder();
884 if (defBuilder instanceof FileBasedConfigurationBuilder) {
885 @SuppressWarnings("rawtypes")
886 final FileBasedConfigurationBuilder fileBuilder = (FileBasedConfigurationBuilder) defBuilder;
887 final URL url = fileBuilder.getFileHandler().getURL();
888 currentXMLParameters.setBasePath(url != null ? url.toExternalForm() : fileBuilder.getFileHandler().getBasePath());
889 }
890 }
891 }
892
893
894
895
896
897
898
899
900
901
902
903 private void initDefaultChildParameters(final BuilderParameters params) {
904 currentParameters.getChildDefaultParametersManager().initializeParameters(params);
905 }
906
907
908
909
910
911
912
913
914 private void initChildBasicParameters(final BasicBuilderParameters params) {
915 params.setPrefixLookups(fetchPrefixLookups());
916 params.setParentInterpolator(parentInterpolator);
917 if (currentParameters.isInheritSettings()) {
918 params.inheritFrom(getParameters());
919 }
920 }
921
922
923
924
925
926
927
928 private void initChildFileBasedParameters(final FileBasedBuilderProperties<?> params) {
929 params.setBasePath(getBasePath());
930 params.setFileSystem(currentXMLParameters.getFileHandler().getFileSystem());
931 }
932
933
934
935
936
937
938 private void initChildXMLParameters(final XMLBuilderProperties<?> params) {
939 params.setEntityResolver(currentXMLParameters.getEntityResolver());
940 }
941
942
943
944
945
946
947
948
949 private void initChildCombinedParameters(final CombinedBuilderParametersImpl params) {
950 params.registerMissingProviders(currentParameters);
951 params.setBasePath(getBasePath());
952 }
953
954
955
956
957
958
959
960
961 private ConfigurationSourceData getSourceData() throws ConfigurationException {
962 if (sourceData == null) {
963 if (currentParameters == null) {
964 setUpCurrentParameters();
965 setUpCurrentXMLParameters();
966 }
967 sourceData = createSourceData();
968 }
969 return sourceData;
970 }
971
972
973
974
975
976
977
978 private ConfigurationSourceData createSourceData() throws ConfigurationException {
979 final ConfigurationSourceData result = new ConfigurationSourceData();
980 result.initFromDefinitionConfiguration(getDefinitionConfiguration());
981 return result;
982 }
983
984
985
986
987
988
989
990 private String getBasePath() {
991 return currentXMLParameters.getFileHandler().getBasePath();
992 }
993
994
995
996
997
998
999 private void registerConfiguredProviders(final HierarchicalConfiguration<?> defConfig) {
1000 defConfig.configurationsAt(KEY_CONFIGURATION_PROVIDERS).forEach(config -> {
1001 final XMLBeanDeclaration decl = new XMLBeanDeclaration(config);
1002 final String key = config.getString(KEY_PROVIDER_KEY);
1003 currentParameters.registerProvider(key, (ConfigurationBuilderProvider) fetchBeanHelper().createBean(decl));
1004 });
1005 }
1006
1007
1008
1009
1010
1011
1012
1013
1014 private void addDefinitionBuilderChangeListener(final ConfigurationBuilder<? extends HierarchicalConfiguration<?>> defBuilder) {
1015 defBuilder.addEventListener(ConfigurationBuilderEvent.RESET, event -> {
1016 synchronized (this) {
1017 reset();
1018 definitionBuilder = defBuilder;
1019 }
1020 });
1021 }
1022
1023
1024
1025
1026
1027
1028
1029 private Map<String, ? extends Lookup> fetchPrefixLookups() {
1030 final CombinedConfiguration cc = getConfigurationUnderConstruction();
1031 return cc != null ? cc.getInterpolator().getLookups() : null;
1032 }
1033
1034
1035
1036
1037
1038
1039
1040 private Collection<ConfigurationDeclaration> createDeclarations(final Collection<? extends HierarchicalConfiguration<?>> configs) {
1041 return configs.stream().map(c -> new ConfigurationDeclaration(this, c)).collect(Collectors.toList());
1042 }
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052 private static void initNodeCombinerListNodes(final CombinedConfiguration cc, final HierarchicalConfiguration<?> defConfig, final String key) {
1053 defConfig.getList(key).forEach(listNode -> cc.getNodeCombiner().addListNode((String) listNode));
1054 }
1055
1056
1057
1058
1059
1060
1061 private static Map<String, ConfigurationBuilderProvider> createDefaultProviders() {
1062 final Map<String, ConfigurationBuilderProvider> providers = new HashMap<>();
1063 for (int i = 0; i < DEFAULT_TAGS.length; i++) {
1064 providers.put(DEFAULT_TAGS[i], DEFAULT_PROVIDERS[i]);
1065 }
1066 return providers;
1067 }
1068
1069 static {
1070 DEFAULT_PROVIDERS_MAP = createDefaultProviders();
1071 }
1072
1073
1074
1075
1076 private final class ConfigurationSourceData {
1077
1078 private final List<ConfigurationDeclaration> overrideDeclarations;
1079
1080
1081 private final List<ConfigurationDeclaration> unionDeclarations;
1082
1083
1084 private final List<ConfigurationBuilder<? extends Configuration>> overrideBuilders;
1085
1086
1087 private final List<ConfigurationBuilder<? extends Configuration>> unionBuilders;
1088
1089
1090 private final Map<String, ConfigurationBuilder<? extends Configuration>> namedBuilders;
1091
1092
1093 private final Collection<ConfigurationBuilder<? extends Configuration>> allBuilders;
1094
1095
1096 private final EventListener<ConfigurationBuilderEvent> changeListener;
1097
1098
1099
1100
1101 public ConfigurationSourceData() {
1102 overrideDeclarations = new ArrayList<>();
1103 unionDeclarations = new ArrayList<>();
1104 overrideBuilders = new ArrayList<>();
1105 unionBuilders = new ArrayList<>();
1106 namedBuilders = new HashMap<>();
1107 allBuilders = new LinkedList<>();
1108 changeListener = createBuilderChangeListener();
1109 }
1110
1111
1112
1113
1114
1115
1116
1117 public void initFromDefinitionConfiguration(final HierarchicalConfiguration<?> config) throws ConfigurationException {
1118 overrideDeclarations.addAll(createDeclarations(fetchTopLevelOverrideConfigs(config)));
1119 overrideDeclarations.addAll(createDeclarations(config.childConfigurationsAt(KEY_OVERRIDE)));
1120 unionDeclarations.addAll(createDeclarations(config.childConfigurationsAt(KEY_UNION)));
1121 }
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132 public List<ConfigurationBuilder<? extends Configuration>> createAndAddConfigurations(final CombinedConfiguration ccResult,
1133 final List<ConfigurationDeclaration> srcDecl, final List<ConfigurationBuilder<? extends Configuration>> builders) throws ConfigurationException {
1134 final boolean createBuilders = builders.isEmpty();
1135 final List<ConfigurationBuilder<? extends Configuration>> newBuilders;
1136 if (createBuilders) {
1137 newBuilders = new ArrayList<>(srcDecl.size());
1138 } else {
1139 newBuilders = builders;
1140 }
1141
1142 for (int i = 0; i < srcDecl.size(); i++) {
1143 final ConfigurationBuilder<? extends Configuration> b;
1144 if (createBuilders) {
1145 b = createConfigurationBuilder(srcDecl.get(i));
1146 newBuilders.add(b);
1147 } else {
1148 b = builders.get(i);
1149 }
1150 addChildConfiguration(ccResult, srcDecl.get(i), b);
1151 }
1152
1153 return newBuilders;
1154 }
1155
1156
1157
1158
1159 public void cleanUp() {
1160 getChildBuilders().forEach(b -> b.removeEventListener(ConfigurationBuilderEvent.RESET, changeListener));
1161 namedBuilders.clear();
1162 }
1163
1164
1165
1166
1167
1168
1169 public Collection<ConfigurationBuilder<? extends Configuration>> getChildBuilders() {
1170 return allBuilders;
1171 }
1172
1173
1174
1175
1176
1177
1178 public List<ConfigurationDeclaration> getOverrideSources() {
1179 return overrideDeclarations;
1180 }
1181
1182
1183
1184
1185
1186
1187 public List<ConfigurationDeclaration> getUnionSources() {
1188 return unionDeclarations;
1189 }
1190
1191
1192
1193
1194
1195
1196
1197
1198 public ConfigurationBuilder<? extends Configuration> getNamedBuilder(final String name) {
1199 return namedBuilders.get(name);
1200 }
1201
1202
1203
1204
1205
1206
1207 public Set<String> builderNames() {
1208 return namedBuilders.keySet();
1209 }
1210
1211
1212
1213
1214
1215
1216
1217
1218 private ConfigurationBuilder<? extends Configuration> createConfigurationBuilder(final ConfigurationDeclaration decl) throws ConfigurationException {
1219 final ConfigurationBuilderProvider provider = providerForTag(decl.getConfiguration().getRootElementName());
1220 if (provider == null) {
1221 throw new ConfigurationException("Unsupported configuration source: " + decl.getConfiguration().getRootElementName());
1222 }
1223
1224 final ConfigurationBuilder<? extends Configuration> builder = provider.getConfigurationBuilder(decl);
1225 if (decl.getName() != null) {
1226 namedBuilders.put(decl.getName(), builder);
1227 }
1228 allBuilders.add(builder);
1229 builder.addEventListener(ConfigurationBuilderEvent.RESET, changeListener);
1230 return builder;
1231 }
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241 private void addChildConfiguration(final CombinedConfiguration ccResult, final ConfigurationDeclaration decl,
1242 final ConfigurationBuilder<? extends Configuration> builder) throws ConfigurationException {
1243 try {
1244 ccResult.addConfiguration(builder.getConfiguration(), decl.getName(), decl.getAt());
1245 } catch (final ConfigurationException cex) {
1246
1247 if (!decl.isOptional()) {
1248 throw cex;
1249 }
1250 }
1251 }
1252
1253
1254
1255
1256 private EventListener<ConfigurationBuilderEvent> createBuilderChangeListener() {
1257 return event -> resetResult();
1258 }
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268 private List<? extends HierarchicalConfiguration<?>> fetchTopLevelOverrideConfigs(final HierarchicalConfiguration<?> config) {
1269
1270 final List<? extends HierarchicalConfiguration<?>> configs = config.childConfigurationsAt(null);
1271 for (final Iterator<? extends HierarchicalConfiguration<?>> it = configs.iterator(); it.hasNext();) {
1272 final String nodeName = it.next().getRootElementName();
1273 for (final String element : CONFIG_SECTIONS) {
1274 if (element.equals(nodeName)) {
1275 it.remove();
1276 break;
1277 }
1278 }
1279 }
1280 return configs;
1281 }
1282 }
1283 }