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    *     http://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      /** Constant for the key in the parameters map used by this class. */
48      private static final String PARAM_KEY = RESERVED_PARAMETER_PREFIX + "fileBased";
49  
50      /** Property name for the reloading refresh delay. */
51      private static final String PROP_REFRESH_DELAY = "reloadingRefreshDelay";
52  
53      /** Property name of the reloading detector factory. */
54      private static final String PROP_DETECTOR_FACTORY = "reloadingDetectorFactory";
55  
56      /**
57       * Stores the associated file handler for the location of the configuration.
58       */
59      private FileHandler fileHandler;
60  
61      /** The factory for reloading detectors. */
62      private ReloadingDetectorFactory reloadingDetectorFactory;
63  
64      /** The refresh delay for reloading support. */
65      private Long reloadingRefreshDelay;
66  
67      /**
68       * Creates a new instance of {@code FileBasedBuilderParametersImpl} with an uninitialized {@code FileHandler} object.
69       */
70      public FileBasedBuilderParametersImpl() {
71          this(null);
72      }
73  
74      /**
75       * Creates a new instance of {@code FileBasedBuilderParametersImpl} and associates it with the given {@code FileHandler}
76       * object. If the handler is <b>null</b>, a new handler instance is created.
77       *
78       * @param handler the associated {@code FileHandler} (can be <b>null</b>)
79       */
80      public FileBasedBuilderParametersImpl(final FileHandler handler) {
81          fileHandler = handler != null ? handler : new FileHandler();
82      }
83  
84      /**
85       * Creates a new {@code FileBasedBuilderParametersImpl} object from the content of the given map. While
86       * {@code fromParameters()} expects that an object already exists and is stored in the given map, this method creates a
87       * new instance based on the content of the map. The map can contain properties of a {@code FileHandler} and some
88       * additional settings which are stored directly in the newly created object. If the map is <b>null</b>, an
89       * uninitialized instance is returned.
90       *
91       * @param map the map with properties (must not be <b>null</b>)
92       * @return the newly created instance
93       * @throws ClassCastException if the map contains invalid data
94       */
95      public static FileBasedBuilderParametersImpl fromMap(final Map<String, ?> map) {
96          final FileBasedBuilderParametersImpl params = new FileBasedBuilderParametersImpl(FileHandler.fromMap(map));
97          if (map != null) {
98              params.setReloadingRefreshDelay((Long) map.get(PROP_REFRESH_DELAY));
99              params.setReloadingDetectorFactory((ReloadingDetectorFactory) map.get(PROP_DETECTOR_FACTORY));
100         }
101         return params;
102     }
103 
104     /**
105      * Looks up an instance of this class in the specified parameters map. This is equivalent to
106      * {@code fromParameters(params, false};}
107      *
108      * @param params the map with parameters (must not be <b>null</b>
109      * @return the instance obtained from the map or <b>null</b>
110      * @throws IllegalArgumentException if the map is <b>null</b>
111      */
112     public static FileBasedBuilderParametersImpl fromParameters(final Map<String, ?> params) {
113         return fromParameters(params, false);
114     }
115 
116     /**
117      * Looks up an instance of this class in the specified parameters map and optionally creates a new one if none is found.
118      * This method can be used to obtain an instance of this class which has been stored in a parameters map. It is
119      * compatible with the {@code getParameters()} method.
120      *
121      * @param params the map with parameters (must not be <b>null</b>
122      * @param createIfMissing determines the behavior if no instance is found in the map; if <b>true</b>, a new instance
123      *        with default settings is created; if <b>false</b>, <b>null</b> is returned
124      * @return the instance obtained from the map or <b>null</b>
125      * @throws IllegalArgumentException if the map is <b>null</b>
126      */
127     public static FileBasedBuilderParametersImpl fromParameters(final Map<String, ?> params, final boolean createIfMissing) {
128         if (params == null) {
129             throw new IllegalArgumentException("Parameters map must not be null!");
130         }
131 
132         FileBasedBuilderParametersImpl instance = (FileBasedBuilderParametersImpl) params.get(PARAM_KEY);
133         if (instance == null && createIfMissing) {
134             instance = new FileBasedBuilderParametersImpl();
135         }
136         return instance;
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 }