001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.configuration2.builder.combined; 018 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.Collections; 022import java.util.Map; 023import java.util.Set; 024 025import org.apache.commons.configuration2.FileBasedConfiguration; 026import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder; 027import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder; 028import org.apache.commons.configuration2.ex.ConfigurationException; 029import org.apache.commons.configuration2.reloading.CombinedReloadingController; 030import org.apache.commons.configuration2.reloading.ReloadingController; 031import org.apache.commons.configuration2.reloading.ReloadingControllerSupport; 032 033/** 034 * <p> 035 * A specialized {@code MultiFileConfigurationBuilder} implementation which adds 036 * support for reloading. 037 * </p> 038 * <p> 039 * This class - as its super class - allows operating on multiple configuration 040 * files whose file names are determined using a file name pattern and a 041 * {@code ConfigurationInterpolator} object. It provides the following 042 * additional features: 043 * </p> 044 * <ul> 045 * <li>Configuration builder for managed configurations have reloading support. 046 * So reloading is possible for all configuration sources loaded by this builder 047 * instance.</li> 048 * <li>A {@link ReloadingController} is provided which can be used to trigger 049 * reload checks on all managed configurations.</li> 050 * </ul> 051 * <p> 052 * Although this builder manages an arbitrary number of child configurations, to 053 * clients only a single configuration is visible - the one selected by the 054 * evaluation of the file name pattern. Builder reset notifications triggered by 055 * the reloading mechanism do not really take this fact into account; they are 056 * not limited to the currently selected child configuration, but occur for each 057 * of the managed configuration. 058 * </p> 059 * 060 * @version $Id: ReloadingMultiFileConfigurationBuilder.java 1790899 2017-04-10 21:56:46Z ggregory $ 061 * @since 2.0 062 * @param <T> the concrete type of {@code Configuration} objects created by this 063 * builder 064 */ 065public class ReloadingMultiFileConfigurationBuilder<T extends FileBasedConfiguration> 066 extends MultiFileConfigurationBuilder<T> implements 067 ReloadingControllerSupport 068{ 069 /** The reloading controller used by this builder. */ 070 private final ReloadingController reloadingController = 071 createReloadingController(); 072 073 /** 074 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} 075 * and sets initialization parameters and a flag whether initialization 076 * failures should be ignored. 077 * 078 * @param resCls the result configuration class 079 * @param params a map with initialization parameters 080 * @param allowFailOnInit a flag whether initialization errors should be 081 * ignored 082 * @throws IllegalArgumentException if the result class is <b>null</b> 083 */ 084 public ReloadingMultiFileConfigurationBuilder(Class<T> resCls, 085 Map<String, Object> params, boolean allowFailOnInit) 086 { 087 super(resCls, params, allowFailOnInit); 088 } 089 090 /** 091 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} 092 * and sets initialization parameters. 093 * 094 * @param resCls the result configuration class 095 * @param params a map with initialization parameters 096 * @throws IllegalArgumentException if the result class is <b>null</b> 097 */ 098 public ReloadingMultiFileConfigurationBuilder(Class<T> resCls, 099 Map<String, Object> params) 100 { 101 super(resCls, params); 102 } 103 104 /** 105 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} 106 * without setting initialization parameters. 107 * 108 * @param resCls the result configuration class 109 * @throws IllegalArgumentException if the result class is <b>null</b> 110 */ 111 public ReloadingMultiFileConfigurationBuilder(Class<T> resCls) 112 { 113 super(resCls); 114 } 115 116 /** 117 * {@inheritDoc} This implementation returns a special 118 * {@code ReloadingController} that delegates to the reloading controllers 119 * of the managed builders created so far. 120 */ 121 @Override 122 public ReloadingController getReloadingController() 123 { 124 return reloadingController; 125 } 126 127 /** 128 * {@inheritDoc} This implementation returns a file-based configuration 129 * builder with reloading support. 130 */ 131 @Override 132 protected FileBasedConfigurationBuilder<T> createManagedBuilder( 133 String fileName, Map<String, Object> params) 134 throws ConfigurationException 135 { 136 return new ReloadingFileBasedConfigurationBuilder<>(getResultClass(), 137 params, isAllowFailOnInit()); 138 } 139 140 /** 141 * Creates the reloading controller used by this builder. This method 142 * creates a specialized {@link CombinedReloadingController} which operates 143 * on the reloading controllers of the managed builders created so far. 144 * 145 * @return the newly created {@code ReloadingController} 146 */ 147 private ReloadingController createReloadingController() 148 { 149 Set<ReloadingController> empty = Collections.emptySet(); 150 return new CombinedReloadingController(empty) 151 { 152 @Override 153 public Collection<ReloadingController> getSubControllers() 154 { 155 Collection<FileBasedConfigurationBuilder<T>> builders = 156 getManagedBuilders().values(); 157 Collection<ReloadingController> controllers = 158 new ArrayList<>(builders.size()); 159 for (FileBasedConfigurationBuilder<T> b : builders) 160 { 161 controllers.add(((ReloadingControllerSupport) b) 162 .getReloadingController()); 163 } 164 return controllers; 165 } 166 }; 167 } 168}