View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.configuration2.builder;
18  
19  import java.io.File;
20  import java.net.URL;
21  import java.util.Map;
22  
23  import org.apache.commons.configuration2.io.FileHandler;
24  import org.apache.commons.configuration2.io.FileLocationStrategy;
25  import org.apache.commons.configuration2.io.FileSystem;
26  import org.apache.commons.configuration2.io.URLConnectionOptions;
27  
28  /**
29   * <p>
30   * An implementation of {@code BuilderParameters} which contains parameters related to {@code Configuration}
31   * implementations that are loaded from files.
32   * </p>
33   * <p>
34   * The parameters defined here are interpreted by builder implementations that can deal with file-based configurations.
35   * Note that these parameters are typically no initialization properties of configuration objects (i.e. they are not
36   * passed to set methods after the creation of the result configuration). Rather, the parameters object is stored as a
37   * whole in the builder's map with initialization parameters and can be accessed from there.
38   * </p>
39   * <p>
40   * This class is not thread-safe. It is intended that an instance is constructed and initialized by a single thread
41   * during configuration of a {@code ConfigurationBuilder}.
42   * </p>
43   *
44   * @since 2.0
45   */
46  public class FileBasedBuilderParametersImpl extends BasicBuilderParameters implements FileBasedBuilderProperties<FileBasedBuilderParametersImpl> {
47  
48      /** Constant for the key in the parameters map used by this class. */
49      private static final String PARAM_KEY = RESERVED_PARAMETER_PREFIX + "fileBased";
50  
51      /** Property name for the reloading refresh delay. */
52      private static final String PROP_REFRESH_DELAY = "reloadingRefreshDelay";
53  
54      /** Property name of the reloading detector factory. */
55      private static final String PROP_DETECTOR_FACTORY = "reloadingDetectorFactory";
56  
57      /**
58       * Creates a new {@code FileBasedBuilderParametersImpl} object from the content of the given map. While
59       * {@code fromParameters()} expects that an object already exists and is stored in the given map, this method creates a
60       * new instance based on the content of the map. The map can contain properties of a {@code FileHandler} and some
61       * additional settings which are stored directly in the newly created object. If the map is <strong>null</strong>, an
62       * uninitialized instance is returned.
63       *
64       * @param map the map with properties (must not be <strong>null</strong>)
65       * @return the newly created instance
66       * @throws ClassCastException if the map contains invalid data
67       */
68      public static FileBasedBuilderParametersImpl fromMap(final Map<String, ?> map) {
69          final FileBasedBuilderParametersImpl params = new FileBasedBuilderParametersImpl(FileHandler.fromMap(map));
70          if (map != null) {
71              params.setReloadingRefreshDelay((Long) map.get(PROP_REFRESH_DELAY));
72              params.setReloadingDetectorFactory((ReloadingDetectorFactory) map.get(PROP_DETECTOR_FACTORY));
73          }
74          return params;
75      }
76  
77      /**
78       * Looks up an instance of this class in the specified parameters map. This is equivalent to
79       * {@code fromParameters(params, false};}
80       *
81       * @param params the map with parameters (must not be <strong>null</strong>
82       * @return the instance obtained from the map or <strong>null</strong>
83       * @throws IllegalArgumentException if the map is <strong>null</strong>
84       */
85      public static FileBasedBuilderParametersImpl fromParameters(final Map<String, ?> params) {
86          return fromParameters(params, false);
87      }
88  
89      /**
90       * Looks up an instance of this class in the specified parameters map and optionally creates a new one if none is found.
91       * This method can be used to obtain an instance of this class which has been stored in a parameters map. It is
92       * compatible with the {@code getParameters()} method.
93       *
94       * @param params the map with parameters (must not be <strong>null</strong>
95       * @param createIfMissing determines the behavior if no instance is found in the map; if <strong>true</strong>, a new instance
96       *        with default settings is created; if <strong>false</strong>, <strong>null</strong> is returned
97       * @return the instance obtained from the map or <strong>null</strong>
98       * @throws IllegalArgumentException if the map is <strong>null</strong>
99       */
100     public static FileBasedBuilderParametersImpl fromParameters(final Map<String, ?> params, final boolean createIfMissing) {
101         if (params == null) {
102             throw new IllegalArgumentException("Parameters map must not be null.");
103         }
104 
105         FileBasedBuilderParametersImpl instance = (FileBasedBuilderParametersImpl) params.get(PARAM_KEY);
106         if (instance == null && createIfMissing) {
107             instance = new FileBasedBuilderParametersImpl();
108         }
109         return instance;
110     }
111 
112     /**
113      * Stores the associated file handler for the location of the configuration.
114      */
115     private FileHandler fileHandler;
116 
117     /** The factory for reloading detectors. */
118     private ReloadingDetectorFactory reloadingDetectorFactory;
119 
120     /** The refresh delay for reloading support. */
121     private Long reloadingRefreshDelay;
122 
123     /**
124      * Creates a new instance of {@code FileBasedBuilderParametersImpl} with an uninitialized {@code FileHandler} object.
125      */
126     public FileBasedBuilderParametersImpl() {
127         this(null);
128     }
129 
130     /**
131      * Creates a new instance of {@code FileBasedBuilderParametersImpl} and associates it with the given {@code FileHandler}
132      * object. If the handler is <strong>null</strong>, a new handler instance is created.
133      *
134      * @param handler the associated {@code FileHandler} (can be <strong>null</strong>)
135      */
136     public FileBasedBuilderParametersImpl(final FileHandler handler) {
137         fileHandler = handler != null ? handler : new FileHandler();
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 <strong>null</strong> 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 <strong>null</strong> 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 }