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