    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.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    /** The parameters object associated with this instance. */
    075    private final Parameters parameters;
    076
    077    /**
    078     * Creates a new {@code Configurations} instance with default settings.
    079     */
    080    public Configurations() {
    081        this(null);
    082    }
    083
    084    /**
    085     * Creates a new instance of {@code Configurations} and initializes it with the specified {@code Parameters} object.
    086     *
    087     * @param params the {@code Parameters} (may be <strong>null</strong>, then a default instance is created)
    088     */
    089    public Configurations(final Parameters params) {
    090        parameters = params != null ? params : new Parameters();
    091    }
    092
    093    /**
    094     * Creates a {@code CombinedConfiguration} instance from the content of the given file. This is a convenience method
    095     * which can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a
    096     * builder is created).
    097     *
    098     * @param file the file to be loaded
    099     * @return a {@code CombinedConfiguration} object initialized from this file
    100     * @throws ConfigurationException if an error occurred when loading the configuration
    101     */
    102    public CombinedConfiguration combined(final File file) throws ConfigurationException {
    103        return combinedBuilder(file).getConfiguration();
    104    }
    105
    106    /**
    107     * Creates a {@code CombinedConfiguration} instance from the content of the file identified by the given path. This is a
    108     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    109     * the scenes a builder is created).
    110     *
    111     * @param path the path to the file to be loaded
    112     * @return a {@code CombinedConfiguration} object initialized from this URL
    113     * @throws ConfigurationException if an error occurred when loading the configuration
    114     */
    115    public CombinedConfiguration combined(final String path) throws ConfigurationException {
    116        return combinedBuilder(path).getConfiguration();
    117    }
    118
    119    /**
    120     * Creates a {@code CombinedConfiguration} instance from the content of the given URL. This is a convenience method
    121     * which can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a
    122     * builder is created).
    123     *
    124     * @param url the URL to be loaded
    125     * @return a {@code CombinedConfiguration} object initialized from this URL
    126     * @throws ConfigurationException if an error occurred when loading the configuration
    127     */
    128    public CombinedConfiguration combined(final URL url) throws ConfigurationException {
    129        return combinedBuilder(url).getConfiguration();
    130    }
    131
    132    /**
    133     * Creates a builder for a {@code CombinedConfiguration} and initializes it with the given file to be loaded.
    134     *
    135     * @param file the file to be loaded
    136     * @return the newly created {@code CombinedConfigurationBuilder}
    137     */
    138    public CombinedConfigurationBuilder combinedBuilder(final File file) {
    139        return new CombinedConfigurationBuilder().configure(fileParams(file));
    140    }
    141
    142    /**
    143     * Creates a builder for a {@code CombinedConfiguration} and initializes it with the given path to the file to be
    144     * loaded.
    145     *
    146     * @param path the path to the file to be loaded
    147     * @return the newly created {@code CombinedConfigurationBuilder}
    148     */
    149    public CombinedConfigurationBuilder combinedBuilder(final String path) {
    150        return new CombinedConfigurationBuilder().configure(fileParams(path));
    151    }
    152
    153    /**
    154     * Creates a builder for a {@code CombinedConfiguration} and initializes it with the given URL to be loaded.
    155     *
    156     * @param url the URL to be loaded
    157     * @return the newly created {@code CombinedConfigurationBuilder}
    158     */
    159    public CombinedConfigurationBuilder combinedBuilder(final URL url) {
    160        return new CombinedConfigurationBuilder().configure(fileParams(url));
    161    }
    162
    163    /**
    164     * Creates a configured builder for a file-based configuration of the specified type.
    165     *
    166     * @param configClass the configuration class
    167     * @param <T> the type of the configuration to be constructed
    168     * @return the newly created builder
    169     * @since 2.6
    170     */
    171    private <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> createFileBasedBuilder(final Class<T> configClass) {
    172        return new FileBasedConfigurationBuilder<>(configClass);
    173    }
    174
    175    /**
    176     * Creates a configured builder for a file-based configuration of the specified type.
    177     *
    178     * @param configClass the configuration class
    179     * @param params the parameters object for configuring the builder
    180     * @param <T> the type of the configuration to be constructed
    181     * @return the newly created builder
    182     */
    183    private <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> createFileBasedBuilder(final Class<T> configClass,
    184        final FileBasedBuilderParameters params) {
    185        return createFileBasedBuilder(configClass).configure(params);
    186    }
    187
    188    /**
    189     * Creates an instance of the specified file-based configuration class from the content of the given file. This is a
    190     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    191     * the scenes a builder is created).
    192     *
    193     * @param configClass the configuration class
    194     * @param file the file to be loaded
    195     * @param <T> the type of the configuration to be constructed
    196     * @return a {@code FileBasedConfiguration} object initialized from this file
    197     * @throws ConfigurationException if an error occurred when loading the configuration
    198     */
    199    public <T extends FileBasedConfiguration> T fileBased(final Class<T> configClass, final File file) throws ConfigurationException {
    200        return fileBasedBuilder(configClass, file).getConfiguration();
    201    }
    202
    203    /**
    204     * Creates an instance of the specified file-based configuration class from the content of the file identified by the
    205     * given path. This is a convenience method which can be used if no builder is needed for managing the configuration
    206     * object. (Although, behind the scenes a builder is created).
    207     *
    208     * @param configClass the configuration class
    209     * @param path the path to the file to be loaded
    210     * @param <T> the type of the configuration to be constructed
    211     * @return a {@code FileBasedConfiguration} object initialized from this file
    212     * @throws ConfigurationException if an error occurred when loading the configuration
    213     */
    214    public <T extends FileBasedConfiguration> T fileBased(final Class<T> configClass, final String path) throws ConfigurationException {
    215        return fileBasedBuilder(configClass, path).getConfiguration();
    216    }
    217
    218    /**
    219     * Creates an instance of the specified file-based configuration class from the content of the given URL. This is a
    220     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    221     * the scenes a builder is created).
    222     *
    223     * @param configClass the configuration class
    224     * @param url the URL to be loaded
    225     * @param <T> the type of the configuration to be constructed
    226     * @return a {@code FileBasedConfiguration} object initialized from this file
    227     * @throws ConfigurationException if an error occurred when loading the configuration
    228     */
    229    public <T extends FileBasedConfiguration> T fileBased(final Class<T> configClass, final URL url) throws ConfigurationException {
    230        return fileBasedBuilder(configClass, url).getConfiguration();
    231    }
    232
    233    /**
    234     * Creates a {@code FileBasedConfigurationBuilder} for the specified configuration class and initializes it with the
    235     * file to be loaded.
    236     *
    237     * @param configClass the configuration class
    238     * @param file the file to be loaded
    239     * @param <T> the type of the configuration to be constructed
    240     * @return the new {@code FileBasedConfigurationBuilder}
    241     */
    242    public <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> fileBasedBuilder(final Class<T> configClass, final File file) {
    243        return createFileBasedBuilder(configClass, fileParams(file));
    244    }
    245
    246    /**
    247     * Creates a {@code FileBasedConfigurationBuilder} for the specified configuration class and initializes it with the
    248     * path to the file to be loaded.
    249     *
    250     * @param configClass the configuration class
    251     * @param path the path to the file to be loaded
    252     * @param <T> the type of the configuration to be constructed
    253     * @return the new {@code FileBasedConfigurationBuilder}
    254     */
    255    public <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> fileBasedBuilder(final Class<T> configClass, final String path) {
    256        return createFileBasedBuilder(configClass, fileParams(path));
    257    }
    258
    259    /**
    260     * Creates a {@code FileBasedConfigurationBuilder} for the specified configuration class and initializes it with the URL
    261     * to the file to be loaded.
    262     *
    263     * @param configClass the configuration class
    264     * @param url the URL to be loaded
    265     * @param <T> the type of the configuration to be constructed
    266     * @return the new {@code FileBasedConfigurationBuilder}
    267     */
    268    public <T extends FileBasedConfiguration> FileBasedConfigurationBuilder<T> fileBasedBuilder(final Class<T> configClass, final URL url) {
    269        return createFileBasedBuilder(configClass, fileParams(url));
    270    }
    271
    272    /**
    273     * Convenience method for creating a parameters object for a file-based configuration.
    274     *
    275     * @return the newly created parameters object
    276     */
    277    private FileBasedBuilderParameters fileParams() {
    278        return getParameters().fileBased();
    279    }
    280
    281    /**
    282     * Convenience method for creating a file-based parameters object initialized with the given file.
    283     *
    284     * @param file the file to be loaded
    285     * @return the initialized parameters object
    286     */
    287    private FileBasedBuilderParameters fileParams(final File file) {
    288        return fileParams().setFile(file);
    289    }
    290
    291    /**
    292     * Convenience method for creating a file-based parameters object initialized with the given file path.
    293     *
    294     * @param path the path to the file to be loaded
    295     * @return the initialized parameters object
    296     */
    297    private FileBasedBuilderParameters fileParams(final String path) {
    298        return fileParams().setFileName(path);
    299    }
    300
    301    /**
    302     * Convenience method for creating a file-based parameters object initialized with the given file.
    303     *
    304     * @param url the URL to be loaded
    305     * @return the initialized parameters object
    306     */
    307    private FileBasedBuilderParameters fileParams(final URL url) {
    308        return fileParams().setURL(url);
    309    }
    310
    311    /**
    312     * Gets the {@code Parameters} instance associated with this object.
    313     *
    314     * @return the associated {@code Parameters} object
    315     */
    316    public Parameters getParameters() {
    317        return parameters;
    318    }
    319
    320    /**
    321     * Creates a {@code INIConfiguration} instance from the content of the given file. This is a convenience method which
    322     * can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a builder is
    323     * created).
    324     *
    325     * @param file the file to be loaded
    326     * @return a {@code INIConfiguration} object initialized from this file
    327     * @throws ConfigurationException if an error occurred when loading the configuration
    328     */
    329    public INIConfiguration ini(final File file) throws ConfigurationException {
    330        return iniBuilder(file).getConfiguration();
    331    }
    332
    333    /**
    334     * Creates a {@code INIConfiguration} instance from the content of the file identified by the given path. This is a
    335     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    336     * the scenes a builder is created).
    337     *
    338     * @param path the path to the file to be loaded
    339     * @return a {@code INIConfiguration} object initialized from this file
    340     * @throws ConfigurationException if an error occurred when loading the configuration
    341     */
    342    public INIConfiguration ini(final String path) throws ConfigurationException {
    343        return iniBuilder(path).getConfiguration();
    344    }
    345
    346    /**
    347     * Creates a {@code INIConfiguration} instance from the content of the given URL. This is a convenience method which can
    348     * be used if no builder is needed for managing the configuration object. (Although, behind the scenes a builder is
    349     * created).
    350     *
    351     * @param url the URL to be loaded
    352     * @return a {@code INIConfiguration} object initialized from this file
    353     * @throws ConfigurationException if an error occurred when loading the configuration
    354     */
    355    public INIConfiguration ini(final URL url) throws ConfigurationException {
    356        return iniBuilder(url).getConfiguration();
    357    }
    358
    359    /**
    360     * Creates a builder for a {@code INIConfiguration} and initializes it with the given file to be loaded.
    361     *
    362     * @param file the file to be loaded
    363     * @return the newly created {@code FileBasedConfigurationBuilder}
    364     */
    365    public FileBasedConfigurationBuilder<INIConfiguration> iniBuilder(final File file) {
    366        return fileBasedBuilder(INIConfiguration.class, file);
    367    }
    368
    369    /**
    370     * Creates a builder for a {@code INIConfiguration} and initializes it with the file file identified by the given path.
    371     *
    372     * @param path the path to the file to be loaded
    373     * @return the newly created {@code FileBasedConfigurationBuilder}
    374     */
    375    public FileBasedConfigurationBuilder<INIConfiguration> iniBuilder(final String path) {
    376        return fileBasedBuilder(INIConfiguration.class, path);
    377    }
    378
    379    /**
    380     * Creates a builder for a {@code INIConfiguration} and initializes it with the given URL to be loaded.
    381     *
    382     * @param url the URL to be loaded
    383     * @return the newly created {@code FileBasedConfigurationBuilder}
    384     */
    385    public FileBasedConfigurationBuilder<INIConfiguration> iniBuilder(final URL url) {
    386        return fileBasedBuilder(INIConfiguration.class, url);
    387    }
    388
    389    /**
    390     * Creates a {@code PropertiesConfiguration} instance from the content of the given file. This is a convenience method
    391     * which can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a
    392     * builder is created).
    393     *
    394     * @param file the file to be loaded
    395     * @return a {@code PropertiesConfiguration} object initialized from this file
    396     * @throws ConfigurationException if an error occurred when loading the configuration
    397     */
    398    public PropertiesConfiguration properties(final File file) throws ConfigurationException {
    399        return propertiesBuilder(file).getConfiguration();
    400    }
    401
    402    /**
    403     * Creates a {@code PropertiesConfiguration} instance from the content of the file identified by the given path. This is
    404     * a convenience method which can be used if no builder is needed for managing the configuration object. (Although,
    405     * behind the scenes a builder is created).
    406     *
    407     * @param path the path to the file to be loaded
    408     * @return a {@code PropertiesConfiguration} object initialized from this path
    409     * @throws ConfigurationException if an error occurred when loading the configuration
    410     */
    411    public PropertiesConfiguration properties(final String path) throws ConfigurationException {
    412        return propertiesBuilder(path).getConfiguration();
    413    }
    414
    415    /**
    416     * Creates a {@code PropertiesConfiguration} instance from the content of the given URL. This is a convenience method
    417     * which can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a
    418     * builder is created).
    419     *
    420     * @param url the URL to be loaded
    421     * @return a {@code PropertiesConfiguration} object initialized from this URL
    422     * @throws ConfigurationException if an error occurred when loading the configuration
    423     */
    424    public PropertiesConfiguration properties(final URL url) throws ConfigurationException {
    425        return propertiesBuilder(url).getConfiguration();
    426    }
    427
    428    /**
    429     * Creates a builder for a {@code PropertiesConfiguration}.
    430     *
    431     * @return the newly created {@code FileBasedConfigurationBuilder}
    432     * @since 2.6
    433     */
    434    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder() {
    435        return createFileBasedBuilder(PropertiesConfiguration.class);
    436    }
    437
    438    /**
    439     * Creates a builder for a {@code PropertiesConfiguration} and initializes it with the given file to be loaded.
    440     *
    441     * @param file the file to be loaded
    442     * @return the newly created {@code FileBasedConfigurationBuilder}
    443     */
    444    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder(final File file) {
    445        return fileBasedBuilder(PropertiesConfiguration.class, file);
    446    }
    447
    448    /**
    449     * Creates a builder for a {@code PropertiesConfiguration} and initializes it with the given parameters to be loaded.
    450     *
    451     * @param parameters the parameters to be loaded
    452     * @return the newly created {@code FileBasedConfigurationBuilder}
    453     * @since 2.6
    454     */
    455    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder(final PropertiesBuilderParameters parameters) {
    456        return propertiesBuilder().configure(parameters);
    457    }
    458
    459    /**
    460     * Creates a builder for a {@code PropertiesConfiguration} and initializes it with the given path to the file to be
    461     * loaded.
    462     *
    463     * @param path the path to the file to be loaded
    464     * @return the newly created {@code FileBasedConfigurationBuilder}
    465     */
    466    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder(final String path) {
    467        return fileBasedBuilder(PropertiesConfiguration.class, path);
    468    }
    469
    470    /**
    471     * Creates a builder for a {@code PropertiesConfiguration} and initializes it with the given URL to be loaded.
    472     *
    473     * @param url the URL to be loaded
    474     * @return the newly created {@code FileBasedConfigurationBuilder}
    475     */
    476    public FileBasedConfigurationBuilder<PropertiesConfiguration> propertiesBuilder(final URL url) {
    477        return fileBasedBuilder(PropertiesConfiguration.class, url);
    478    }
    479
    480    /**
    481     * Creates a {@code XMLConfiguration} instance from the content of the given file. This is a convenience method which
    482     * can be used if no builder is needed for managing the configuration object. (Although, behind the scenes a builder is
    483     * created).
    484     *
    485     * @param file the file to be loaded
    486     * @return a {@code XMLConfiguration} object initialized from this file
    487     * @throws ConfigurationException if an error occurred when loading the configuration
    488     */
    489    public XMLConfiguration xml(final File file) throws ConfigurationException {
    490        return xmlBuilder(file).getConfiguration();
    491    }
    492
    493    /**
    494     * Creates a {@code XMLConfiguration} instance from the content of the file identified by the given path. This is a
    495     * convenience method which can be used if no builder is needed for managing the configuration object. (Although, behind
    496     * the scenes a builder is created).
    497     *
    498     * @param path the path to the file to be loaded
    499     * @return a {@code XMLConfiguration} object initialized from this file
    500     * @throws ConfigurationException if an error occurred when loading the configuration
    501     */
    502    public XMLConfiguration xml(final String path) throws ConfigurationException {
    503        return xmlBuilder(path).getConfiguration();
    504    }
    505
    506    /**
    507     * Creates a {@code XMLConfiguration} instance from the content of the given URL. This is a convenience method which can
    508     * be used if no builder is needed for managing the configuration object. (Although, behind the scenes a builder is
    509     * created).
    510     *
    511     * @param url the URL to be loaded
    512     * @return a {@code XMLConfiguration} object initialized from this file
    513     * @throws ConfigurationException if an error occurred when loading the configuration
    514     */
    515    public XMLConfiguration xml(final URL url) throws ConfigurationException {
    516        return xmlBuilder(url).getConfiguration();
    517    }
    518
    519    /**
    520     * Creates a builder for a {@code XMLConfiguration} and initializes it with the given file to be loaded.
    521     *
    522     * @param file the file to be loaded
    523     * @return the newly created {@code FileBasedConfigurationBuilder}
    524     */
    525    public FileBasedConfigurationBuilder<XMLConfiguration> xmlBuilder(final File file) {
    526        return fileBasedBuilder(XMLConfiguration.class, file);
    527    }
    528
    529    /**
    530     * Creates a builder for a {@code XMLConfiguration} and initializes it with the given path to the file to be loaded.
    531     *
    532     * @param path the path to the file to be loaded
    533     * @return the newly created {@code FileBasedConfigurationBuilder}
    534     */
    535    public FileBasedConfigurationBuilder<XMLConfiguration> xmlBuilder(final String path) {
    536        return fileBasedBuilder(XMLConfiguration.class, path);
    537    }
    538
    539    /**
    540     * Creates a builder for a {@code XMLConfiguration} and initializes it with the given URL to be loaded.
    541     *
    542     * @param url the URL to be loaded
    543     * @return the newly created {@code FileBasedConfigurationBuilder}
    544     */
    545    public FileBasedConfigurationBuilder<XMLConfiguration> xmlBuilder(final URL url) {
    546        return fileBasedBuilder(XMLConfiguration.class, url);
    547    }
    548
    549}