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