1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.configuration2.builder.combined;
18
19 import java.util.Arrays;
20 import java.util.Collection;
21
22 import org.apache.commons.configuration2.CombinedConfiguration;
23 import org.apache.commons.configuration2.Configuration;
24 import org.apache.commons.configuration2.builder.BasicBuilderParameters;
25 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
26 import org.apache.commons.configuration2.builder.BuilderParameters;
27
28 /**
29 * <p>
30 * A specialized {@code ConfigurationBuilderProvider} implementation which deals with combined configuration builders.
31 * </p>
32 * <p>
33 * This class is used to support {@code <configuration>} elements in configuration definition files. The provider
34 * creates another {@link CombinedConfigurationBuilder} which inherits some of the properties from its parent builder.
35 * </p>
36 *
37 * @since 2.0
38 */
39 public class CombinedConfigurationBuilderProvider extends BaseConfigurationBuilderProvider {
40 /** Constant for the name of the supported builder class. */
41 private static final String BUILDER_CLASS = "org.apache.commons.configuration2.builder.combined.CombinedConfigurationBuilder";
42
43 /** Constant for the name of the supported reloading builder class. */
44 private static final String RELOADING_BUILDER_CLASS = "org.apache.commons.configuration2.builder.combined.ReloadingCombinedConfigurationBuilder";
45
46 /** Constant for the name of the supported configuration class. */
47 private static final String CONFIGURATION_CLASS = "org.apache.commons.configuration2.CombinedConfiguration";
48
49 /** Constant for the combined configuration builder parameters class. */
50 private static final String COMBINED_PARAMS = "org.apache.commons.configuration2.builder.combined.CombinedBuilderParametersImpl";
51
52 /** Constant for the name of the file-based builder parameters class. */
53 private static final String FILE_PARAMS = "org.apache.commons.configuration2.builder.FileBasedBuilderParametersImpl";
54
55 /**
56 * Populates the specified parameters object with properties from the given configuration. This method is used to set
57 * default values for basic properties based on the result configuration of the parent builder.
58 *
59 * @param config the configuration whose properties are to be copied
60 * @param params the target parameters object
61 */
62 private static void setUpBasicParameters(final CombinedConfiguration config, final BasicBuilderParameters params) {
63 params.setListDelimiterHandler(config.getListDelimiterHandler()).setLogger(config.getLogger())
64 .setThrowExceptionOnMissing(config.isThrowExceptionOnMissing()).setConfigurationDecoder(config.getConfigurationDecoder());
65 }
66
67 /**
68 * Creates a new instance of {@code CombinedConfigurationBuilderProvider}.
69 */
70 public CombinedConfigurationBuilderProvider() {
71 super(BUILDER_CLASS, RELOADING_BUILDER_CLASS, CONFIGURATION_CLASS, Arrays.asList(COMBINED_PARAMS, FILE_PARAMS));
72 }
73
74 /**
75 * {@inheritDoc} This implementation creates the result builder object directly, not using reflection. (The
76 * reflection-based approach of the base class does not work here because a combined configuration builder has
77 * constructors with a different signature.) It also performs some additional initializations.
78 */
79 @Override
80 protected BasicConfigurationBuilder<? extends Configuration> createBuilder(final ConfigurationDeclaration decl, final Collection<BuilderParameters> params)
81 throws Exception {
82 final CombinedConfigurationBuilder builder;
83 if (decl.isReload()) {
84 builder = new ReloadingCombinedConfigurationBuilder();
85 } else {
86 builder = new CombinedConfigurationBuilder();
87 }
88 decl.getConfigurationBuilder().initChildEventListeners(builder);
89 return builder;
90 }
91
92 /**
93 * {@inheritDoc} This implementation pre-fills basic parameters from the basic properties of the parent builder's result
94 * configuration.
95 */
96 @Override
97 protected void initializeParameterObjects(final ConfigurationDeclaration decl, final Collection<BuilderParameters> params) throws Exception {
98 // we know that the first object is the combined builder parameters
99 // object
100 final BasicBuilderParameters basicParams = (BasicBuilderParameters) params.iterator().next();
101 setUpBasicParameters(decl.getConfigurationBuilder().getConfigurationUnderConstruction(), basicParams);
102 // now properties set explicitly can be overridden
103 super.initializeParameterObjects(decl, params);
104 }
105 }