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 * http://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.Collection; 20 import java.util.Collections; 21 import java.util.Map; 22 import java.util.Set; 23 import java.util.stream.Collectors; 24 25 import org.apache.commons.configuration2.FileBasedConfiguration; 26 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder; 27 import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder; 28 import org.apache.commons.configuration2.ex.ConfigurationException; 29 import org.apache.commons.configuration2.reloading.CombinedReloadingController; 30 import org.apache.commons.configuration2.reloading.ReloadingController; 31 import org.apache.commons.configuration2.reloading.ReloadingControllerSupport; 32 33 /** 34 * <p> 35 * A specialized {@code MultiFileConfigurationBuilder} implementation which adds support for reloading. 36 * </p> 37 * <p> 38 * This class - as its super class - allows operating on multiple configuration files whose file names are determined 39 * using a file name pattern and a {@code ConfigurationInterpolator} object. It provides the following additional 40 * features: 41 * </p> 42 * <ul> 43 * <li>Configuration builder for managed configurations have reloading support. So reloading is possible for all 44 * configuration sources loaded by this builder instance.</li> 45 * <li>A {@link ReloadingController} is provided which can be used to trigger reload checks on all managed 46 * configurations.</li> 47 * </ul> 48 * <p> 49 * Although this builder manages an arbitrary number of child configurations, to clients only a single configuration is 50 * visible - the one selected by the evaluation of the file name pattern. Builder reset notifications triggered by the 51 * reloading mechanism do not really take this fact into account; they are not limited to the currently selected child 52 * configuration, but occur for each of the managed configuration. 53 * </p> 54 * 55 * @since 2.0 56 * @param <T> the concrete type of {@code Configuration} objects created by this builder 57 */ 58 public class ReloadingMultiFileConfigurationBuilder<T extends FileBasedConfiguration> extends MultiFileConfigurationBuilder<T> 59 implements ReloadingControllerSupport { 60 /** The reloading controller used by this builder. */ 61 private final ReloadingController reloadingController = createReloadingController(); 62 63 /** 64 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} and sets initialization parameters and a 65 * flag whether initialization failures should be ignored. 66 * 67 * @param resCls the result configuration class 68 * @param params a map with initialization parameters 69 * @param allowFailOnInit a flag whether initialization errors should be ignored 70 * @throws IllegalArgumentException if the result class is <b>null</b> 71 */ 72 public ReloadingMultiFileConfigurationBuilder(final Class<T> resCls, final Map<String, Object> params, final boolean allowFailOnInit) { 73 super(resCls, params, allowFailOnInit); 74 } 75 76 /** 77 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} and sets initialization parameters. 78 * 79 * @param resCls the result configuration class 80 * @param params a map with initialization parameters 81 * @throws IllegalArgumentException if the result class is <b>null</b> 82 */ 83 public ReloadingMultiFileConfigurationBuilder(final Class<T> resCls, final Map<String, Object> params) { 84 super(resCls, params); 85 } 86 87 /** 88 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} without setting initialization parameters. 89 * 90 * @param resCls the result configuration class 91 * @throws IllegalArgumentException if the result class is <b>null</b> 92 */ 93 public ReloadingMultiFileConfigurationBuilder(final Class<T> resCls) { 94 super(resCls); 95 } 96 97 /** 98 * {@inheritDoc} This implementation returns a special {@code ReloadingController} that delegates to the reloading 99 * controllers of the managed builders created so far. 100 */ 101 @Override 102 public ReloadingController getReloadingController() { 103 return reloadingController; 104 } 105 106 /** 107 * {@inheritDoc} This implementation returns a file-based configuration builder with reloading support. 108 */ 109 @Override 110 protected FileBasedConfigurationBuilder<T> createManagedBuilder(final String fileName, final Map<String, Object> params) throws ConfigurationException { 111 return new ReloadingFileBasedConfigurationBuilder<>(getResultClass(), params, isAllowFailOnInit()); 112 } 113 114 /** 115 * Creates the reloading controller used by this builder. This method creates a specialized 116 * {@link CombinedReloadingController} which operates on the reloading controllers of the managed builders created so 117 * far. 118 * 119 * @return the newly created {@code ReloadingController} 120 */ 121 private ReloadingController createReloadingController() { 122 final Set<ReloadingController> empty = Collections.emptySet(); 123 return new CombinedReloadingController(empty) { 124 @Override 125 public Collection<ReloadingController> getSubControllers() { 126 return getManagedBuilders().values().stream().map(b -> ((ReloadingControllerSupport) b).getReloadingController()).collect(Collectors.toList()); 127 } 128 }; 129 } 130 }