    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 *     https://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.fluent;
    018
    019import java.io.File;
    020import java.net.URL;
    021
    022import org.apache.commons.configuration2.CombinedConfiguration;
    023import org.apache.commons.configuration2.FileBasedConfiguration;
    024import org.apache.commons.configuration2.INIConfiguration;
    025import org.apache.commons.configuration2.PropertiesConfiguration;
    026import org.apache.commons.configuration2.XMLConfiguration;
    027import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
    028import org.apache.commons.configuration2.builder.combined.CombinedConfigurationBuilder;
    029import org.apache.commons.configuration2.ex.ConfigurationException;
    030
    031//@formatter:off
    032/**
    033 * A convenience class which simplifies the creation of standard configurations and their builders.
    034 * <p>
    035 * Complex initializations of configuration builders can be done in a pretty straight-forward way by making use of the
    036 * provided fluent API. However, if only default settings are used (and maybe a configuration file to be loaded has to
    037 * be specified), this approach tends to become a bit verbose. This class was introduced to simplify the creation of
    038 * configuration objects in such cases. It offers a bunch of methods which allow the creation of some standard
    039 * configuration classes with default settings passing in only a minimum required parameters.
    040 * </p>
    041 * <p>
    042 * An an example consider the creation of a {@code PropertiesConfiguration} object from a file. Using a builder, code
    043 * like the following one would have to be written:
    044 * </p>
    045 * <pre>
    046 * Parameters params = new Parameters();
    047 * FileBasedConfigurationBuilder&lt;PropertiesConfiguration&gt; builder =
    048 *   new FileBasedConfigurationBuilder&lt;PropertiesConfiguration&gt;(PropertiesConfiguration.class)
    049 *     .configure(params.fileBased().setFile(new File(&quot;config.properties&quot;)));
    050 * PropertiesConfiguration config = builder.getConfiguration();
    051 * </pre>
    052 * <p>
    053 * With a convenience method of {@code Configurations} the same can be achieved with the following:
    054 * </p>
    055 * <pre>
    056 * Configurations configurations = new Configurations();
    057 * PropertiesConfiguration config = configurations.properties(new File(&quot;config.properties&quot;));
    058 * </pre>
    059 * <p>
    060 * There are similar methods for constructing builder objects from which configurations can then be obtained.
    061 * </p>
    062 * <p>
    063 * This class is thread-safe. A single instance can be created by an application and used in a central way to create
    064 * configuration objects. When an instance is created a {@link Parameters} instance can be passed in. Otherwise, a
    065 * default instance is created. In any case, the {@code Parameters} instance associated with a {@code Configurations}
    066 * object can be used to define default settings for the configurations to be created.
    067 * </p>
    068 *
    069 * @since 2.0
    070 * @see org.apache.commons.configuration2.builder.DefaultParametersManager
    071 */
    072//@formatter:off
    073public class Configurations {
    074
    075    /** The parameters object associated with this instance. */
    076    private final Parameters parameters;
    077
    078    /**
    079     * Creates a new {@code Configurations} instance with default settings.
    080     */
    081    public Configurations() {
    082        this(null);
    083    }
    084
    085    /**
    086     * Creates a new instance of {@code Configurations} and initializes it with the specified {@code Parameters} object.
    087     *
    088     * @param params the {@code Parameters} (may be <strong>null</strong>, then a default instance is created)
    089     */
    090    public Configurations(final Parameters params) {
    091        parameters = params != null ? params : new Parameters();
    092    }
    093
    094    /**
    095     * Creates a {@code CombinedConfiguration} instance from the content of the given file. This is a convenience method
    096     * which can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a
    097     * builder is created).
    098     *
    099     * @param file the file to be loaded
    100     * @return a {@code CombinedConfiguration} object initialized from this file
    101     * @throws ConfigurationException if an error occurred when loading the configuration
    102     */
    103    public CombinedConfiguration combined(final File file) throws ConfigurationException {
    104        return combinedBuilder(file).getConfiguration();
    105    }
    106
    107    /**
    108     * Creates a {@code CombinedConfiguration} instance from the content of the file identified by the given path. This is a
    109     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    110     * the scenes a builder is created).
    111     *
    112     * @param path the path to the file to be loaded
    113     * @return a {@code CombinedConfiguration} object initialized from this URL
    114     * @throws ConfigurationException if an error occurred when loading the configuration
    115     */
    116    public CombinedConfiguration combined(final String path) throws ConfigurationException {
    117        return combinedBuilder(path).getConfiguration();
    118    }
    119
    120    /**
    121     * Creates a {@code CombinedConfiguration} instance from the content of the given URL. This is a convenience method
    122     * which can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a
    123     * builder is created).
    124     *
    125     * @param url the URL to be loaded
    126     * @return a {@code CombinedConfiguration} object initialized from this URL
    127     * @throws ConfigurationException if an error occurred when loading the configuration
    128     */
    129    public CombinedConfiguration combined(final URL url) throws ConfigurationException {
    130        return combinedBuilder(url).getConfiguration();
    131    }
    132
    133    /**
    134     * Creates a builder for a {@code CombinedConfiguration} and initializes it with the given file to be loaded.
    135     *
    136     * @param file the file to be loaded
    137     * @return the newly created {@code CombinedConfigurationBuilder}
    138     */
    139    public CombinedConfigurationBuilder combinedBuilder(final File file) {
    140        return new CombinedConfigurationBuilder().configure(fileParams(file));
    141    }
    142
    143    /**
    144     * Creates a builder for a {@code CombinedConfiguration} and initializes it with the given path to the file to be
    145     * loaded.
    146     *
    147     * @param path the path to the file to be loaded
    148     * @return the newly created {@code CombinedConfigurationBuilder}
    149     */
    150    public CombinedConfigurationBuilder combinedBuilder(final String path) {
    151        return new CombinedConfigurationBuilder().configure(fileParams(path));
    152    }
    153
    154    /**
    155     * Creates a builder for a {@code CombinedConfiguration} and initializes it with the given URL to be loaded.
    156     *
    157     * @param url the URL to be loaded
    158     * @return the newly created {@code CombinedConfigurationBuilder}
    159     */
    160    public CombinedConfigurationBuilder combinedBuilder(final URL url) {
    161        return new CombinedConfigurationBuilder().configure(fileParams(url));
    162    }
    163
    164    /**
    165     * Creates a configured builder for a file-based configuration of the specified type.
    166     *
    167     * @param configClass the configuration class
    168     * @param <T> the type of the configuration to be constructed
    169     * @return the newly created builder
    170     * @since 2.6
    171     */
    172    private <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> createFileBasedBuilder(final Class<T> configClass) {
    173        return new FileBasedConfigurationBuilder<>(configClass);
    174    }
    175
    176    /**
    177     * Creates a configured builder for a file-based configuration of the specified type.
    178     *
    179     * @param configClass the configuration class
    180     * @param params the parameters object for configuring the builder
    181     * @param <T> the type of the configuration to be constructed
    182     * @return the newly created builder
    183     */
    184    private <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> createFileBasedBuilder(final Class<T> configClass,
    185        final FileBasedBuilderParameters params) {
    186        return createFileBasedBuilder(configClass).configure(params);
    187    }
    188
    189    /**
    190     * Creates an instance of the specified file-based configuration class from the content of the given file. This is a
    191     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    192     * the scenes a builder is created).
    193     *
    194     * @param configClass the configuration class
    195     * @param file the file to be loaded
    196     * @param <T> the type of the configuration to be constructed
    197     * @return a {@code FileBasedConfiguration} object initialized from this file
    198     * @throws ConfigurationException if an error occurred when loading the configuration
    199     */
    200    public <T extends FileBasedConfiguration> T fileBased(final Class<T> configClass, final File file) throws ConfigurationException {
    201        return fileBasedBuilder(configClass, file).getConfiguration();
    202    }
    203
    204    /**
    205     * Creates an instance of the specified file-based configuration class from the content of the file identified by the
    206     * given path. This is a convenience method which can be used if no builder is needed for managing the configuration
    207     * object. (Although, behind the scenes a builder is created).
    208     *
    209     * @param configClass the configuration class
    210     * @param path the path to the file to be loaded
    211     * @param <T> the type of the configuration to be constructed
    212     * @return a {@code FileBasedConfiguration} object initialized from this file
    213     * @throws ConfigurationException if an error occurred when loading the configuration
    214     */
    215    public <T extends FileBasedConfiguration> T fileBased(final Class<T> configClass, final String path) throws ConfigurationException {
    216        return fileBasedBuilder(configClass, path).getConfiguration();
    217    }
    218
    219    /**
    220     * Creates an instance of the specified file-based configuration class from the content of the given URL. This is a
    221     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    222     * the scenes a builder is created).
    223     *
    224     * @param configClass the configuration class
    225     * @param url the URL to be loaded
    226     * @param <T> the type of the configuration to be constructed
    227     * @return a {@code FileBasedConfiguration} object initialized from this file
    228     * @throws ConfigurationException if an error occurred when loading the configuration
    229     */
    230    public <T extends FileBasedConfiguration> T fileBased(final Class<T> configClass, final URL url) throws ConfigurationException {
    231        return fileBasedBuilder(configClass, url).getConfiguration();
    232    }
    233
    234    /**
    235     * Creates a {@code FileBasedConfigurationBuilder} for the specified configuration class and initializes it with the
    236     * file to be loaded.
    237     *
    238     * @param configClass the configuration class
    239     * @param file the file to be loaded
    240     * @param <T> the type of the configuration to be constructed
    241     * @return the new {@code FileBasedConfigurationBuilder}
    242     */
    243    public <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> fileBasedBuilder(final Class<T> configClass, final File file) {
    244        return createFileBasedBuilder(configClass, fileParams(file));
    245    }
    246
    247    /**
    248     * Creates a {@code FileBasedConfigurationBuilder} for the specified configuration class and initializes it with the
    249     * path to the file to be loaded.
    250     *
    251     * @param configClass the configuration class
    252     * @param path the path to the file to be loaded
    253     * @param <T> the type of the configuration to be constructed
    254     * @return the new {@code FileBasedConfigurationBuilder}
    255     */
    256    public <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> fileBasedBuilder(final Class<T> configClass, final String path) {
    257        return createFileBasedBuilder(configClass, fileParams(path));
    258    }
    259
    260    /**
    261     * Creates a {@code FileBasedConfigurationBuilder} for the specified configuration class and initializes it with the URL
    262     * to the file to be loaded.
    263     *
    264     * @param configClass the configuration class
    265     * @param url the URL to be loaded
    266     * @param <T> the type of the configuration to be constructed
    267     * @return the new {@code FileBasedConfigurationBuilder}
    268     */
    269    public <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> fileBasedBuilder(final Class<T> configClass, final URL url) {
    270        return createFileBasedBuilder(configClass, fileParams(url));
    271    }
    272
    273    /**
    274     * Convenience method for creating a parameters object for a file-based configuration.
    275     *
    276     * @return the newly created parameters object
    277     */
    278    private FileBasedBuilderParameters fileParams() {
    279        return getParameters().fileBased();
    280    }
    281
    282    /**
    283     * Convenience method for creating a file-based parameters object initialized with the given file.
    284     *
    285     * @param file the file to be loaded
    286     * @return the initialized parameters object
    287     */
    288    private FileBasedBuilderParameters fileParams(final File file) {
    289        return fileParams().setFile(file);
    290    }
    291
    292    /**
    293     * Convenience method for creating a file-based parameters object initialized with the given file path.
    294     *
    295     * @param path the path to the file to be loaded
    296     * @return the initialized parameters object
    297     */
    298    private FileBasedBuilderParameters fileParams(final String path) {
    299        return fileParams().setFileName(path);
    300    }
    301
    302    /**
    303     * Convenience method for creating a file-based parameters object initialized with the given file.
    304     *
    305     * @param url the URL to be loaded
    306     * @return the initialized parameters object
    307     */
    308    private FileBasedBuilderParameters fileParams(final URL url) {
    309        return fileParams().setURL(url);
    310    }
    311
    312    /**
    313     * Gets the {@code Parameters} instance associated with this object.
    314     *
    315     * @return the associated {@code Parameters} object
    316     */
    317    public Parameters getParameters() {
    318        return parameters;
    319    }
    320
    321    /**
    322     * Creates a {@code INIConfiguration} instance from the content of the given file. This is a convenience method which
    323     * can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a builder is
    324     * created).
    325     *
    326     * @param file the file to be loaded
    327     * @return a {@code INIConfiguration} object initialized from this file
    328     * @throws ConfigurationException if an error occurred when loading the configuration
    329     */
    330    public INIConfiguration ini(final File file) throws ConfigurationException {
    331        return iniBuilder(file).getConfiguration();
    332    }
    333
    334    /**
    335     * Creates a {@code INIConfiguration} instance from the content of the file identified by the given path. This is a
    336     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    337     * the scenes a builder is created).
    338     *
    339     * @param path the path to the file to be loaded
    340     * @return a {@code INIConfiguration} object initialized from this file
    341     * @throws ConfigurationException if an error occurred when loading the configuration
    342     */
    343    public INIConfiguration ini(final String path) throws ConfigurationException {
    344        return iniBuilder(path).getConfiguration();
    345    }
    346
    347    /**
    348     * Creates a {@code INIConfiguration} instance from the content of the given URL. This is a convenience method which can
    349     * be used if no builder is needed for managing the configuration object. (Although, behind the scenes a builder is
    350     * created).
    351     *
    352     * @param url the URL to be loaded
    353     * @return a {@code INIConfiguration} object initialized from this file
    354     * @throws ConfigurationException if an error occurred when loading the configuration
    355     */
    356    public INIConfiguration ini(final URL url) throws ConfigurationException {
    357        return iniBuilder(url).getConfiguration();
    358    }
    359
    360    /**
    361     * Creates a builder for a {@code INIConfiguration} and initializes it with the given file to be loaded.
    362     *
    363     * @param file the file to be loaded
    364     * @return the newly created {@code FileBasedConfigurationBuilder}
    365     */
    366    public FileBasedConfigurationBuilder<INIConfiguration> iniBuilder(final File file) {
    367        return fileBasedBuilder(INIConfiguration.class, file);
    368    }
    369
    370    /**
    371     * Creates a builder for a {@code INIConfiguration} and initializes it with the file file identified by the given path.
    372     *
    373     * @param path the path to the file to be loaded
    374     * @return the newly created {@code FileBasedConfigurationBuilder}
    375     */
    376    public FileBasedConfigurationBuilder<INIConfiguration> iniBuilder(final String path) {
    377        return fileBasedBuilder(INIConfiguration.class, path);
    378    }
    379
    380    /**
    381     * Creates a builder for a {@code INIConfiguration} and initializes it with the given URL to be loaded.
    382     *
    383     * @param url the URL to be loaded
    384     * @return the newly created {@code FileBasedConfigurationBuilder}
    385     */
    386    public FileBasedConfigurationBuilder<INIConfiguration> iniBuilder(final URL url) {
    387        return fileBasedBuilder(INIConfiguration.class, url);
    388    }
    389
    390    /**
    391     * Creates a {@code PropertiesConfiguration} instance from the content of the given file. This is a convenience method
    392     * which can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a
    393     * builder is created).
    394     *
    395     * @param file the file to be loaded
    396     * @return a {@code PropertiesConfiguration} object initialized from this file
    397     * @throws ConfigurationException if an error occurred when loading the configuration
    398     */
    399    public PropertiesConfiguration properties(final File file) throws ConfigurationException {
    400        return propertiesBuilder(file).getConfiguration();
    401    }
    402
    403    /**
    404     * Creates a {@code PropertiesConfiguration} instance from the content of the file identified by the given path. This is
    405     * a convenience method which can be used if no builder is needed for managing the configuration object. (Although,
    406     * behind the scenes a builder is created).
    407     *
    408     * @param path the path to the file to be loaded
    409     * @return a {@code PropertiesConfiguration} object initialized from this path
    410     * @throws ConfigurationException if an error occurred when loading the configuration
    411     */
    412    public PropertiesConfiguration properties(final String path) throws ConfigurationException {
    413        return propertiesBuilder(path).getConfiguration();
    414    }
    415
    416    /**
    417     * Creates a {@code PropertiesConfiguration} instance from the content of the given URL. This is a convenience method
    418     * which can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a
    419     * builder is created).
    420     *
    421     * @param url the URL to be loaded
    422     * @return a {@code PropertiesConfiguration} object initialized from this URL
    423     * @throws ConfigurationException if an error occurred when loading the configuration
    424     */
    425    public PropertiesConfiguration properties(final URL url) throws ConfigurationException {
    426        return propertiesBuilder(url).getConfiguration();
    427    }
    428
    429    /**
    430     * Creates a builder for a {@code PropertiesConfiguration}.
    431     *
    432     * @return the newly created {@code FileBasedConfigurationBuilder}
    433     * @since 2.6
    434     */
    435    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder() {
    436        return createFileBasedBuilder(PropertiesConfiguration.class);
    437    }
    438
    439    /**
    440     * Creates a builder for a {@code PropertiesConfiguration} and initializes it with the given file to be loaded.
    441     *
    442     * @param file the file to be loaded
    443     * @return the newly created {@code FileBasedConfigurationBuilder}
    444     */
    445    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder(final File file) {
    446        return fileBasedBuilder(PropertiesConfiguration.class, file);
    447    }
    448
    449    /**
    450     * Creates a builder for a {@code PropertiesConfiguration} and initializes it with the given parameters to be loaded.
    451     *
    452     * @param parameters the parameters to be loaded
    453     * @return the newly created {@code FileBasedConfigurationBuilder}
    454     * @since 2.6
    455     */
    456    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder(final PropertiesBuilderParameters parameters) {
    457        return propertiesBuilder().configure(parameters);
    458    }
    459
    460    /**
    461     * Creates a builder for a {@code PropertiesConfiguration} and initializes it with the given path to the file to be
    462     * loaded.
    463     *
    464     * @param path the path to the file to be loaded
    465     * @return the newly created {@code FileBasedConfigurationBuilder}
    466     */
    467    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder(final String path) {
    468        return fileBasedBuilder(PropertiesConfiguration.class, path);
    469    }
    470
    471    /**
    472     * Creates a builder for a {@code PropertiesConfiguration} and initializes it with the given URL to be loaded.
    473     *
    474     * @param url the URL to be loaded
    475     * @return the newly created {@code FileBasedConfigurationBuilder}
    476     */
    477    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder(final URL url) {
    478        return fileBasedBuilder(PropertiesConfiguration.class, url);
    479    }
    480
    481    /**
    482     * Creates a {@code XMLConfiguration} instance from the content of the given file. This is a convenience method which
    483     * can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a builder is
    484     * created).
    485     *
    486     * @param file the file to be loaded
    487     * @return a {@code XMLConfiguration} object initialized from this file
    488     * @throws ConfigurationException if an error occurred when loading the configuration
    489     */
    490    public XMLConfiguration xml(final File file) throws ConfigurationException {
    491        return xmlBuilder(file).getConfiguration();
    492    }
    493
    494    /**
    495     * Creates a {@code XMLConfiguration} instance from the content of the file identified by the given path. This is a
    496     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    497     * the scenes a builder is created).
    498     *
    499     * @param path the path to the file to be loaded
    500     * @return a {@code XMLConfiguration} object initialized from this file
    501     * @throws ConfigurationException if an error occurred when loading the configuration
    502     */
    503    public XMLConfiguration xml(final String path) throws ConfigurationException {
    504        return xmlBuilder(path).getConfiguration();
    505    }
    506
    507    /**
    508     * Creates a {@code XMLConfiguration} instance from the content of the given URL. This is a convenience method which can
    509     * be used if no builder is needed for managing the configuration object. (Although, behind the scenes a builder is
    510     * created).
    511     *
    512     * @param url the URL to be loaded
    513     * @return a {@code XMLConfiguration} object initialized from this file
    514     * @throws ConfigurationException if an error occurred when loading the configuration
    515     */
    516    public XMLConfiguration xml(final URL url) throws ConfigurationException {
    517        return xmlBuilder(url).getConfiguration();
    518    }
    519
    520    /**
    521     * Creates a builder for a {@code XMLConfiguration} and initializes it with the given file to be loaded.
    522     *
    523     * @param file the file to be loaded
    524     * @return the newly created {@code FileBasedConfigurationBuilder}
    525     */
    526    public FileBasedConfigurationBuilder<XMLConfiguration> xmlBuilder(final File file) {
    527        return fileBasedBuilder(XMLConfiguration.class, file);
    528    }
    529
    530    /**
    531     * Creates a builder for a {@code XMLConfiguration} and initializes it with the given path to the file to be loaded.
    532     *
    533     * @param path the path to the file to be loaded
    534     * @return the newly created {@code FileBasedConfigurationBuilder}
    535     */
    536    public FileBasedConfigurationBuilder<XMLConfiguration> xmlBuilder(final String path) {
    537        return fileBasedBuilder(XMLConfiguration.class, path);
    538    }
    539
    540    /**
    541     * Creates a builder for a {@code XMLConfiguration} and initializes it with the given URL to be loaded.
    542     *
    543     * @param url the URL to be loaded
    544     * @return the newly created {@code FileBasedConfigurationBuilder}
    545     */
    546    public FileBasedConfigurationBuilder<XMLConfiguration> xmlBuilder(final URL url) {
    547        return fileBasedBuilder(XMLConfiguration.class, url);
    548    }
    549
    550}