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