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