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 * @since 2.0 061 * @param <T> the concrete type of {@code Configuration} objects created by this 062 * builder 063 */ 064public class ReloadingMultiFileConfigurationBuilder<T extends FileBasedConfiguration> 065 extends MultiFileConfigurationBuilder<T> implements 066 ReloadingControllerSupport 067{ 068 /** The reloading controller used by this builder. */ 069 private final ReloadingController reloadingController = 070 createReloadingController(); 071 072 /** 073 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} 074 * and sets initialization parameters and a flag whether initialization 075 * failures should be ignored. 076 * 077 * @param resCls the result configuration class 078 * @param params a map with initialization parameters 079 * @param allowFailOnInit a flag whether initialization errors should be 080 * ignored 081 * @throws IllegalArgumentException if the result class is <b>null</b> 082 */ 083 public ReloadingMultiFileConfigurationBuilder(final Class<T> resCls, 084 final Map<String, Object> params, final boolean allowFailOnInit) 085 { 086 super(resCls, params, allowFailOnInit); 087 } 088 089 /** 090 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} 091 * and sets initialization parameters. 092 * 093 * @param resCls the result configuration class 094 * @param params a map with initialization parameters 095 * @throws IllegalArgumentException if the result class is <b>null</b> 096 */ 097 public ReloadingMultiFileConfigurationBuilder(final Class<T> resCls, 098 final Map<String, Object> params) 099 { 100 super(resCls, params); 101 } 102 103 /** 104 * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder} 105 * without setting initialization parameters. 106 * 107 * @param resCls the result configuration class 108 * @throws IllegalArgumentException if the result class is <b>null</b> 109 */ 110 public ReloadingMultiFileConfigurationBuilder(final Class<T> resCls) 111 { 112 super(resCls); 113 } 114 115 /** 116 * {@inheritDoc} This implementation returns a special 117 * {@code ReloadingController} that delegates to the reloading controllers 118 * of the managed builders created so far. 119 */ 120 @Override 121 public ReloadingController getReloadingController() 122 { 123 return reloadingController; 124 } 125 126 /** 127 * {@inheritDoc} This implementation returns a file-based configuration 128 * builder with reloading support. 129 */ 130 @Override 131 protected FileBasedConfigurationBuilder<T> createManagedBuilder( 132 final String fileName, final Map<String, Object> params) 133 throws ConfigurationException 134 { 135 return new ReloadingFileBasedConfigurationBuilder<>(getResultClass(), 136 params, isAllowFailOnInit()); 137 } 138 139 /** 140 * Creates the reloading controller used by this builder. This method 141 * creates a specialized {@link CombinedReloadingController} which operates 142 * on the reloading controllers of the managed builders created so far. 143 * 144 * @return the newly created {@code ReloadingController} 145 */ 146 private ReloadingController createReloadingController() 147 { 148 final Set<ReloadingController> empty = Collections.emptySet(); 149 return new CombinedReloadingController(empty) 150 { 151 @Override 152 public Collection<ReloadingController> getSubControllers() 153 { 154 final Collection<FileBasedConfigurationBuilder<T>> builders = 155 getManagedBuilders().values(); 156 final Collection<ReloadingController> controllers = 157 new ArrayList<>(builders.size()); 158 for (final FileBasedConfigurationBuilder<T> b : builders) 159 { 160 controllers.add(((ReloadingControllerSupport) b) 161 .getReloadingController()); 162 } 163 return controllers; 164 } 165 }; 166 } 167}