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; 018 019import java.io.File; 020import java.net.URL; 021import java.util.Map; 022 023import org.apache.commons.configuration2.io.FileHandler; 024import org.apache.commons.configuration2.io.FileLocationStrategy; 025import org.apache.commons.configuration2.io.FileSystem; 026 027/** 028 * <p> 029 * An implementation of {@code BuilderParameters} which contains parameters 030 * related to {@code Configuration} implementations that are loaded from files. 031 * </p> 032 * <p> 033 * The parameters defined here are interpreted by builder implementations that 034 * can deal with file-based configurations. Note that these parameters are 035 * typically no initialization properties of configuration objects (i.e. they 036 * are not passed to set methods after the creation of the result 037 * configuration). Rather, the parameters object is stored as a whole in the 038 * builder's map with initialization parameters and can be accessed from there. 039 * </p> 040 * <p> 041 * This class is not thread-safe. It is intended that an instance is constructed 042 * and initialized by a single thread during configuration of a 043 * {@code ConfigurationBuilder}. 044 * </p> 045 * 046 * @since 2.0 047 */ 048public class FileBasedBuilderParametersImpl extends BasicBuilderParameters 049 implements FileBasedBuilderProperties<FileBasedBuilderParametersImpl> 050{ 051 /** Constant for the key in the parameters map used by this class. */ 052 private static final String PARAM_KEY = RESERVED_PARAMETER_PREFIX 053 + "fileBased"; 054 055 /** Property name for the reloading refresh delay. */ 056 private static final String PROP_REFRESH_DELAY = "reloadingRefreshDelay"; 057 058 /** Property name of the reloading detector factory. */ 059 private static final String PROP_DETECTOR_FACTORY = 060 "reloadingDetectorFactory"; 061 062 /** 063 * Stores the associated file handler for the location of the configuration. 064 */ 065 private FileHandler fileHandler; 066 067 /** The factory for reloading detectors. */ 068 private ReloadingDetectorFactory reloadingDetectorFactory; 069 070 /** The refresh delay for reloading support. */ 071 private Long reloadingRefreshDelay; 072 073 /** 074 * Creates a new instance of {@code FileBasedBuilderParametersImpl} with an 075 * uninitialized {@code FileHandler} object. 076 */ 077 public FileBasedBuilderParametersImpl() 078 { 079 this(null); 080 } 081 082 /** 083 * Creates a new instance of {@code FileBasedBuilderParametersImpl} and 084 * associates it with the given {@code FileHandler} object. If the handler 085 * is <b>null</b>, a new handler instance is created. 086 * 087 * @param handler the associated {@code FileHandler} (can be <b>null</b>) 088 */ 089 public FileBasedBuilderParametersImpl(final FileHandler handler) 090 { 091 fileHandler = handler != null ? handler : new FileHandler(); 092 } 093 094 /** 095 * Looks up an instance of this class in the specified parameters map. This 096 * is equivalent to {@code fromParameters(params, false};} 097 * 098 * @param params the map with parameters (must not be <b>null</b> 099 * @return the instance obtained from the map or <b>null</b> 100 * @throws IllegalArgumentException if the map is <b>null</b> 101 */ 102 public static FileBasedBuilderParametersImpl fromParameters( 103 final Map<String, ?> params) 104 { 105 return fromParameters(params, false); 106 } 107 108 /** 109 * Looks up an instance of this class in the specified parameters map and 110 * optionally creates a new one if none is found. This method can be used to 111 * obtain an instance of this class which has been stored in a parameters 112 * map. It is compatible with the {@code getParameters()} method. 113 * 114 * @param params the map with parameters (must not be <b>null</b> 115 * @param createIfMissing determines the behavior if no instance is found in 116 * the map; if <b>true</b>, a new instance with default settings is 117 * created; if <b>false</b>, <b>null</b> is returned 118 * @return the instance obtained from the map or <b>null</b> 119 * @throws IllegalArgumentException if the map is <b>null</b> 120 */ 121 public static FileBasedBuilderParametersImpl fromParameters( 122 final Map<String, ?> params, final boolean createIfMissing) 123 { 124 if (params == null) 125 { 126 throw new IllegalArgumentException( 127 "Parameters map must not be null!"); 128 } 129 130 FileBasedBuilderParametersImpl instance = 131 (FileBasedBuilderParametersImpl) params.get(PARAM_KEY); 132 if (instance == null && createIfMissing) 133 { 134 instance = new FileBasedBuilderParametersImpl(); 135 } 136 return instance; 137 } 138 139 /** 140 * Creates a new {@code FileBasedBuilderParametersImpl} object from the 141 * content of the given map. While {@code fromParameters()} expects that an 142 * object already exists and is stored in the given map, this method creates 143 * a new instance based on the content of the map. The map can contain 144 * properties of a {@code FileHandler} and some additional settings which 145 * are stored directly in the newly created object. If the map is 146 * <b>null</b>, an uninitialized instance is returned. 147 * 148 * @param map the map with properties (must not be <b>null</b>) 149 * @return the newly created instance 150 * @throws ClassCastException if the map contains invalid data 151 */ 152 public static FileBasedBuilderParametersImpl fromMap(final Map<String, ?> map) 153 { 154 final FileBasedBuilderParametersImpl params = 155 new FileBasedBuilderParametersImpl(FileHandler.fromMap(map)); 156 if (map != null) 157 { 158 params.setReloadingRefreshDelay((Long) map.get(PROP_REFRESH_DELAY)); 159 params.setReloadingDetectorFactory((ReloadingDetectorFactory) map 160 .get(PROP_DETECTOR_FACTORY)); 161 } 162 return params; 163 } 164 165 /** 166 * {@inheritDoc} This implementation takes some properties defined in this 167 * class into account. 168 */ 169 @Override 170 public void inheritFrom(final Map<String, ?> source) 171 { 172 super.inheritFrom(source); 173 174 final FileBasedBuilderParametersImpl srcParams = fromParameters(source); 175 if (srcParams != null) 176 { 177 setFileSystem(srcParams.getFileHandler().getFileSystem()); 178 setLocationStrategy( 179 srcParams.getFileHandler().getLocationStrategy()); 180 if (srcParams.getFileHandler().getEncoding() != null) 181 { 182 setEncoding(srcParams.getFileHandler().getEncoding()); 183 } 184 if (srcParams.getReloadingDetectorFactory() != null) 185 { 186 setReloadingDetectorFactory( 187 srcParams.getReloadingDetectorFactory()); 188 } 189 if (srcParams.getReloadingRefreshDelay() != null) 190 { 191 setReloadingRefreshDelay(srcParams.getReloadingRefreshDelay()); 192 } 193 } 194 } 195 196 /** 197 * Returns the {@code FileHandler} managed by this object. This object is 198 * updated every time the file location is changed. 199 * 200 * @return the managed {@code FileHandler} 201 */ 202 public FileHandler getFileHandler() 203 { 204 return fileHandler; 205 } 206 207 /** 208 * Returns the refresh delay for reload operations. Result may be 209 * <b>null</b> if this value has not been set. 210 * 211 * @return the reloading refresh delay 212 */ 213 public Long getReloadingRefreshDelay() 214 { 215 return reloadingRefreshDelay; 216 } 217 218 @Override 219 public FileBasedBuilderParametersImpl setReloadingRefreshDelay( 220 final Long reloadingRefreshDelay) 221 { 222 this.reloadingRefreshDelay = reloadingRefreshDelay; 223 return this; 224 } 225 226 /** 227 * Returns the {@code ReloadingDetectorFactory}. Result may be <b>null</b> 228 * which means that the default factory is to be used. 229 * 230 * @return the {@code ReloadingDetectorFactory} 231 */ 232 public ReloadingDetectorFactory getReloadingDetectorFactory() 233 { 234 return reloadingDetectorFactory; 235 } 236 237 @Override 238 public FileBasedBuilderParametersImpl setReloadingDetectorFactory( 239 final ReloadingDetectorFactory reloadingDetectorFactory) 240 { 241 this.reloadingDetectorFactory = reloadingDetectorFactory; 242 return this; 243 } 244 245 @Override 246 public FileBasedBuilderParametersImpl setFile(final File file) 247 { 248 getFileHandler().setFile(file); 249 return this; 250 } 251 252 @Override 253 public FileBasedBuilderParametersImpl setURL(final URL url) 254 { 255 getFileHandler().setURL(url); 256 return this; 257 } 258 259 @Override 260 public FileBasedBuilderParametersImpl setPath(final String path) 261 { 262 getFileHandler().setPath(path); 263 return this; 264 } 265 266 @Override 267 public FileBasedBuilderParametersImpl setFileName(final String name) 268 { 269 getFileHandler().setFileName(name); 270 return this; 271 } 272 273 @Override 274 public FileBasedBuilderParametersImpl setBasePath(final String path) 275 { 276 getFileHandler().setBasePath(path); 277 return this; 278 } 279 280 @Override 281 public FileBasedBuilderParametersImpl setFileSystem(final FileSystem fs) 282 { 283 getFileHandler().setFileSystem(fs); 284 return this; 285 } 286 287 @Override 288 public FileBasedBuilderParametersImpl setLocationStrategy( 289 final FileLocationStrategy strategy) 290 { 291 getFileHandler().setLocationStrategy(strategy); 292 return this; 293 } 294 295 @Override 296 public FileBasedBuilderParametersImpl setEncoding(final String enc) 297 { 298 getFileHandler().setEncoding(enc); 299 return this; 300 } 301 302 /** 303 * {@inheritDoc} This implementation returns a map which contains this 304 * object itself under a specific key. The static {@code fromParameters()} 305 * method can be used to extract an instance from a parameters map. Of 306 * course, the properties inherited from the base class are also added to 307 * the result map. 308 */ 309 @Override 310 public Map<String, Object> getParameters() 311 { 312 final Map<String, Object> params = super.getParameters(); 313 params.put(PARAM_KEY, this); 314 return params; 315 } 316 317 /** 318 * {@inheritDoc} This implementation also creates a copy of the 319 * {@code FileHandler}. 320 */ 321 @Override 322 public FileBasedBuilderParametersImpl clone() 323 { 324 final FileBasedBuilderParametersImpl copy = 325 (FileBasedBuilderParametersImpl) super.clone(); 326 copy.fileHandler = 327 new FileHandler(fileHandler.getContent(), fileHandler); 328 return copy; 329 } 330}