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