    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *     https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.configuration2;
    018
    019import java.math.BigDecimal;
    020import java.math.BigInteger;
    021import java.time.Duration;
    022import java.util.Collection;
    023import java.util.ConcurrentModificationException;
    024import java.util.Iterator;
    025import java.util.LinkedHashSet;
    026import java.util.List;
    027import java.util.Map;
    028import java.util.NoSuchElementException;
    029import java.util.Objects;
    030import java.util.Properties;
    031import java.util.Set;
    032import java.util.function.BiConsumer;
    033
    034import org.apache.commons.configuration2.convert.PropertyConverter;
    035import org.apache.commons.configuration2.ex.ConversionException;
    036import org.apache.commons.lang3.tuple.ImmutablePair;
    037
    038/**
    039 * <p>
    040 * The main interface for accessing configuration data in a read-only fashion.
    041 * </p>
    042 * <p>
    043 * The major part of the methods defined in this interface deals with accessing properties of various data types. There
    044 * is a generic {@code getProperty()} method, which returns the value of the queried property in its raw data type.
    045 * Other getter methods try to convert this raw data type into a specific data type. If this fails, a
    046 * {@code ConversionException} will be thrown.
    047 * </p>
    048 * <p>
    049 * For most of the property getter methods an overloaded version exists that allows to specify a default value, which
    050 * will be returned if the queried property cannot be found in the configuration. The behavior of the methods that do
    051 * not take a default value in case of a missing property is not defined by this interface and depends on a concrete
    052 * implementation. E.g. the {@link AbstractConfiguration} class, which is the base class of most configuration
    053 * implementations provided by this package, per default returns <strong>null</strong> if a property is not found, but provides
    054 * the {@link AbstractConfiguration#setThrowExceptionOnMissing(boolean) setThrowExceptionOnMissing()} method, with which
    055 * it can be configured to throw a {@code NoSuchElementException} exception in that case. (Note that getter methods for
    056 * primitive types in {@code AbstractConfiguration} always throw an exception for missing properties because there is no
    057 * way of overloading the return value.)
    058 * </p>
    059 *
    060 * @since 2.0
    061 */
    062public interface ImmutableConfiguration {
    063    /**
    064     * Checks if the configuration contains the specified key.
    065     *
    066     * @param key the key whose presence in this configuration is to be tested
    067     * @return {@code true} if the configuration contains a value for this key, {@code false} otherwise
    068     */
    069    boolean containsKey(String key);
    070
    071    /**
    072     * Tests whether this configuration contains one or more matches to this value. This operation stops at first
    073     * match but may be more expensive than the {@link #containsKey containsKey} method.
    074     *
    075     * @param value value whose presence in this configuration is to be tested
    076     * @return {@code true} if this configuration maps one or more keys to the specified value, false otherwise.
    077     * @since 2.11.0
    078     */
    079    default boolean containsValue(final Object value) {
    080        final Iterator<String> keys = getKeys();
    081        while (keys.hasNext()) {
    082            if (Objects.equals(value, getProperty(keys.next()))) {
    083                return true;
    084            }
    085        }
    086        return false;
    087    }
    088
    089    /**
    090     * Returns a {@link Set} view of the mappings contained in this configuration.
    091     *
    092     * @return a set view of the mappings contained in this configuration.
    093     * @since 2.13.0
    094     */
    095    default Set<Map.Entry<String, Object>> entrySet() {
    096        final LinkedHashSet<Map.Entry<String, Object>> set = new LinkedHashSet<>(size());
    097        getKeys().forEachRemaining(k -> set.add(ImmutablePair.of(k, getProperty(k))));
    098        return set;
    099    }
    100
    101    /**
    102     * Performs the given action for each entry in this configuration until all entries have been processed or the action throws an exception. Unless otherwise
    103     * specified by the implementing class, actions are performed in the order of entry set iteration (if an iteration order is specified.) Exceptions thrown by
    104     * the action are relayed to the caller.
    105     *
    106     * <pre> {@code
    107     * for (Map.Entry<K, V> entry : map.entrySet())
    108     *     action.accept(entry.getKey(), entry.getValue());
    109     * }</pre>
    110     * <p>
    111     * The default implementation makes no guarantees about synchronization or atomicity properties of this method. Any implementation providing atomicity
    112     * guarantees must override this method and document its concurrency properties.
    113     * </p>
    114     *
    115     * @param action The action to be performed for each entry.
    116     * @throws NullPointerException            if the specified action is null.
    117     * @throws ConcurrentModificationException if an entry is found to be removed during iteration.
    118     * @since 2.13.0
    119     */
    120    default void forEach(final BiConsumer<String, Object> action) {
    121        Objects.requireNonNull(action);
    122        for (final Map.Entry<String, Object> entry : entrySet()) {
    123            String k;
    124            Object v;
    125            try {
    126                k = entry.getKey();
    127                v = entry.getValue();
    128            } catch (final IllegalStateException e) {
    129                // this usually means the entry is no longer in the map.
    130                throw new ConcurrentModificationException(e);
    131            }
    132            action.accept(k, v);
    133        }
    134    }
    135
    136    /**
    137     * Gets an object of the specified type associated with the given configuration key. If the key doesn't map to an
    138     * existing object, the method returns null unless {@link AbstractConfiguration#isThrowExceptionOnMissing()} is set to
    139     * {@code true}.
    140     *
    141     * @param <T> the target type of the value
    142     * @param cls the target class of the value
    143     * @param key the key of the value
    144     * @return the value of the requested type for the key
    145     * @throws java.util.NoSuchElementException if the key doesn't map to an existing object and
    146     *         {@code throwExceptionOnMissing=true}
    147     * @throws org.apache.commons.configuration2.ex.ConversionException if the value is not compatible with the requested
    148     *         type
    149     * @since 2.0
    150     */
    151    <T> T get(Class<T> cls, String key);
    152
    153    /**
    154     * Gets an object of the specified type associated with the given configuration key using a default value. If the key
    155     * doesn't map to an existing object, the default value is returned.
    156     *
    157     * @param <T> the target type of the value
    158     * @param cls the target class of the value
    159     * @param key the key of the value
    160     * @param defaultValue the default value
    161     * @return the value of the requested type for the key
    162     * @throws org.apache.commons.configuration2.ex.ConversionException if the value is not compatible with the requested
    163     *         type
    164     *
    165     * @since 2.0
    166     */
    167    <T> T get(Class<T> cls, String key, T defaultValue);
    168
    169    /**
    170     * Gets an array of typed objects associated with the given configuration key. If the key doesn't map to an existing
    171     * object, an empty list is returned.
    172     *
    173     * @param cls the type expected for the elements of the array
    174     * @param key The configuration key.
    175     * @return The associated array if the key is found, and the value compatible with the type specified.
    176     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not
    177     *         compatible with a list of the specified class.
    178     *
    179     * @since 2.0
    180     */
    181    Object getArray(Class<?> cls, String key);
    182
    183    /**
    184     * Gets an array of typed objects associated with the given configuration key. If the key doesn't map to an existing
    185     * object, the default value is returned.
    186     *
    187     * @param cls the type expected for the elements of the array
    188     * @param key the configuration key.
    189     * @param defaultValue the default value
    190     * @return The associated array if the key is found, and the value compatible with the type specified.
    191     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not
    192     *         compatible with an array of the specified class.
    193     * @throws IllegalArgumentException if the default value is not an array of the specified type
    194     * @since 2.0
    195     * @deprecated This method should not be used any more because its signature does not allow type-safe invocations; use
    196     *             {@link #get(Class, String, Object)} instead which offers the same functionality; for instance, to query
    197     *             for an array of ints use {@code int[] result = config.get(int[].class, "myArrayKey", someDefault);}.
    198     */
    199    @Deprecated
    200    Object getArray(Class<?> cls, String key, Object defaultValue);
    201
    202    /**
    203     * Gets a {@link BigDecimal} associated with the given configuration key.
    204     *
    205     * @param key The configuration key.
    206     * @return The associated BigDecimal if key is found and has valid format
    207     */
    208    BigDecimal getBigDecimal(String key);
    209
    210    /**
    211     * Gets a {@link BigDecimal} associated with the given configuration key. If the key doesn't map to an existing object,
    212     * the default value is returned.
    213     *
    214     * @param key The configuration key.
    215     * @param defaultValue The default value.
    216     * @return The associated BigDecimal if key is found and has valid format, default value otherwise.
    217     */
    218    BigDecimal getBigDecimal(String key, BigDecimal defaultValue);
    219
    220    /**
    221     * Gets a {@link BigInteger} associated with the given configuration key.
    222     *
    223     * @param key The configuration key.
    224     * @return The associated BigInteger if key is found and has valid format
    225     */
    226    BigInteger getBigInteger(String key);
    227
    228    /**
    229     * Gets a {@link BigInteger} associated with the given configuration key. If the key doesn't map to an existing object,
    230     * the default value is returned.
    231     *
    232     * @param key The configuration key.
    233     * @param defaultValue The default value.
    234     * @return The associated BigInteger if key is found and has valid format, default value otherwise.
    235     */
    236    BigInteger getBigInteger(String key, BigInteger defaultValue);
    237
    238    /**
    239     * Gets a boolean associated with the given configuration key.
    240     *
    241     * @param key The configuration key.
    242     * @return The associated boolean.
    243     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    244     *         Boolean.
    245     */
    246    boolean getBoolean(String key);
    247
    248    /**
    249     * Gets a boolean associated with the given configuration key. If the key doesn't map to an existing object, the default
    250     * value is returned.
    251     *
    252     * @param key The configuration key.
    253     * @param defaultValue The default value.
    254     * @return The associated boolean.
    255     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    256     *         Boolean.
    257     */
    258    boolean getBoolean(String key, boolean defaultValue);
    259
    260    /**
    261     * Gets a {@link Boolean} associated with the given configuration key.
    262     *
    263     * @param key The configuration key.
    264     * @param defaultValue The default value.
    265     * @return The associated boolean if key is found and has valid format, default value otherwise.
    266     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    267     *         Boolean.
    268     */
    269    Boolean getBoolean(String key, Boolean defaultValue);
    270
    271    /**
    272     * Gets a byte associated with the given configuration key.
    273     *
    274     * @param key The configuration key.
    275     * @return The associated byte.
    276     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    277     *         Byte.
    278     */
    279    byte getByte(String key);
    280
    281    /**
    282     * Gets a byte associated with the given configuration key. If the key doesn't map to an existing object, the default
    283     * value is returned.
    284     *
    285     * @param key The configuration key.
    286     * @param defaultValue The default value.
    287     * @return The associated byte.
    288     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    289     *         Byte.
    290     */
    291    byte getByte(String key, byte defaultValue);
    292
    293    /**
    294     * Gets a {@link Byte} associated with the given configuration key.
    295     *
    296     * @param key The configuration key.
    297     * @param defaultValue The default value.
    298     * @return The associated byte if key is found and has valid format, default value otherwise.
    299     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    300     *         Byte.
    301     */
    302    Byte getByte(String key, Byte defaultValue);
    303
    304    /**
    305     * Gets a collection of typed objects associated with the given configuration key. This method works like
    306     * {@link #getCollection(Class, String, Collection, Collection)} passing in <strong>null</strong> as default value.
    307     *
    308     * @param <T> the element type of the result list
    309     * @param cls the element class of the result list
    310     * @param key the configuration key
    311     * @param target the target collection (may be <strong>null</strong>)
    312     * @return the collection to which data was added
    313     * @throws org.apache.commons.configuration2.ex.ConversionException if the conversion is not possible
    314     * @since 2.0
    315     */
    316    <T> Collection<T> getCollection(Class<T> cls, String key, Collection<T> target);
    317
    318    /**
    319     * Gets a collection of typed objects associated with the given configuration key using the values in the specified
    320     * default collection if the key does not map to an existing object. This method is similar to {@code getList()},
    321     * however, it allows specifying a target collection. Results are added to this collection. This is useful if the data
    322     * retrieved should be added to a specific kind of collection, for example a set to remove duplicates. The return value is as
    323     * follows:
    324     * <ul>
    325     * <li>If the key does not map to an existing object and the default value is <strong>null</strong>, the method returns
    326     * <strong>null</strong>.</li>
    327     * <li>If the target collection is not <strong>null</strong> and data has been added (either from the resolved property value or
    328     * from the default collection), the target collection is returned.</li>
    329     * <li>If the target collection is <strong>null</strong> and data has been added (either from the resolved property value or from
    330     * the default collection), return value is the target collection created by this method.</li>
    331     * </ul>
    332     *
    333     * @param <T> the element type of the result list
    334     * @param cls the element class of the result list
    335     * @param key the configuration key
    336     * @param target the target collection (may be <strong>null</strong>)
    337     * @param defaultValue the default value (may be <strong>null</strong>)
    338     * @return the collection to which data was added
    339     * @throws org.apache.commons.configuration2.ex.ConversionException if the conversion is not possible
    340     * @since 2.0
    341     */
    342    <T> Collection<T> getCollection(Class<T> cls, String key, Collection<T> target, Collection<T> defaultValue);
    343
    344    /**
    345     * Gets a double associated with the given configuration key.
    346     *
    347     * @param key The configuration key.
    348     * @return The associated double.
    349     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    350     *         Double.
    351     */
    352    double getDouble(String key);
    353
    354    /**
    355     * Gets a double associated with the given configuration key. If the key doesn't map to an existing object, the default
    356     * value is returned.
    357     *
    358     * @param key The configuration key.
    359     * @param defaultValue The default value.
    360     * @return The associated double.
    361     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    362     *         Double.
    363     */
    364    double getDouble(String key, double defaultValue);
    365
    366    /**
    367     * Gets a {@link Double} associated with the given configuration key.
    368     *
    369     * @param key The configuration key.
    370     * @param defaultValue The default value.
    371     * @return The associated double if key is found and has valid format, default value otherwise.
    372     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    373     *         Double.
    374     */
    375    Double getDouble(String key, Double defaultValue);
    376
    377    /**
    378     * Gets a {@link Duration} associated with the given configuration key.
    379     *
    380     * @param key The configuration key.
    381     * @return The associated Duration if key is found and has valid format, default value otherwise.
    382     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    383     *         Duration.
    384     * @since 2.8.0
    385     */
    386    default Duration getDuration(final String key) {
    387        final String string = getString(key);
    388        if (string == null) {
    389            throw new NoSuchElementException(key);
    390        }
    391        return PropertyConverter.toDuration(string);
    392    }
    393
    394    /**
    395     * Gets a {@link Duration} associated with the given configuration key.
    396     *
    397     * @param key The configuration key.
    398     * @param defaultValue The default value.
    399     * @return The associated Duration if key is found and has valid format, default value otherwise.
    400     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    401     *         Duration.
    402     * @since 2.8.0
    403     */
    404    default Duration getDuration(final String key, final Duration defaultValue) {
    405        final Object value = getProperty(key);
    406        return value == null ? defaultValue : PropertyConverter.toDuration(value);
    407    }
    408
    409    /**
    410     * Gets the value of a string property that is stored in encoded form in this configuration using a default
    411     * {@code ConfigurationDecoder}. This method works like the method with the same name, but it uses a default
    412     * {@code ConfigurationDecoder} associated with this configuration. It depends on a specific implementation how this
    413     * default decoder is obtained.
    414     *
    415     * @param key the configuration key
    416     * @return the plain string value of the specified encoded property
    417     */
    418    String getEncodedString(String key);
    419
    420    /**
    421     * Gets the value of a string property that is stored in encoded form in this configuration. This method obtains the
    422     * value of the string property identified by the given key. This value is then passed to the provided
    423     * {@code ConfigurationDecoder}. The value returned by the {@code ConfigurationDecoder} is passed to the caller. If the
    424     * key is not associated with a value, the decoder is not invoked; depending on this configuration's settings either
    425     * <strong>null</strong> is returned or an exception is thrown.
    426     *
    427     * @param key the configuration key
    428     * @param decoder the {@code ConfigurationDecoder} (must not be <strong>null</strong>)
    429     * @return the plain string value of the specified encoded property
    430     * @throws IllegalArgumentException if a <strong>null</strong> decoder is passed
    431     */
    432    String getEncodedString(String key, ConfigurationDecoder decoder);
    433
    434    /**
    435     * Gets an enum associated with the given configuration key.
    436     *
    437     * @param <T> The enum type whose constant is to be returned.
    438     * @param enumType the {@code Class} object of the enum type from which to return a constant
    439     * @param key The configuration key.
    440     * @return The associated enum.
    441     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    442     *         String.
    443     * @since 2.8.0
    444     */
    445    default <T extends Enum<T>> T getEnum(final String key, final Class<T> enumType) {
    446        try {
    447            return Enum.valueOf(enumType, getString(key));
    448        } catch (final IllegalArgumentException e) {
    449            throw new ConversionException(e);
    450        }
    451    }
    452
    453    /**
    454     * Gets the enum associated with the given configuration key. If the key doesn't map to an existing object, the default
    455     * value is returned.
    456     *
    457     * @param <T> The enum type whose constant is to be returned.
    458     * @param key The configuration key.
    459     * @param enumType the {@code Class} object of the enum type from which to return a constant
    460     * @param defaultValue The default value.
    461     * @return The associated enum if key is found and has valid format, default value otherwise.
    462     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    463     *         Enum.
    464     * @since 2.8.0
    465     */
    466    default <T extends Enum<T>> T getEnum(final String key, final Class<T> enumType, final T defaultValue) {
    467        final String strValue = getString(key, null);
    468        if (strValue == null) {
    469            return defaultValue;
    470        }
    471        try {
    472            return Enum.valueOf(enumType, strValue);
    473        } catch (final IllegalArgumentException e) {
    474            throw new ConversionException(e);
    475        }
    476    }
    477
    478    /**
    479     * Gets a float associated with the given configuration key.
    480     *
    481     * @param key The configuration key.
    482     * @return The associated float.
    483     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    484     *         Float.
    485     */
    486    float getFloat(String key);
    487
    488    /**
    489     * Gets a float associated with the given configuration key. If the key doesn't map to an existing object, the default
    490     * value is returned.
    491     *
    492     * @param key The configuration key.
    493     * @param defaultValue The default value.
    494     * @return The associated float.
    495     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    496     *         Float.
    497     */
    498    float getFloat(String key, float defaultValue);
    499
    500    /**
    501     * Gets a {@link Float} associated with the given configuration key. If the key doesn't map to an existing object, the
    502     * default value is returned.
    503     *
    504     * @param key The configuration key.
    505     * @param defaultValue The default value.
    506     * @return The associated float if key is found and has valid format, default value otherwise.
    507     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    508     *         Float.
    509     */
    510    Float getFloat(String key, Float defaultValue);
    511
    512    /**
    513     * Gets a int associated with the given configuration key.
    514     *
    515     * @param key The configuration key.
    516     * @return The associated int.
    517     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    518     *         Integer.
    519     */
    520    int getInt(String key);
    521
    522    /**
    523     * Gets a int associated with the given configuration key. If the key doesn't map to an existing object, the default
    524     * value is returned.
    525     *
    526     * @param key The configuration key.
    527     * @param defaultValue The default value.
    528     * @return The associated int.
    529     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    530     *         Integer.
    531     */
    532    int getInt(String key, int defaultValue);
    533
    534    /**
    535     * Gets an {@link Integer} associated with the given configuration key. If the key doesn't map to an existing object,
    536     * the default value is returned.
    537     *
    538     * @param key The configuration key.
    539     * @param defaultValue The default value.
    540     * @return The associated int if key is found and has valid format, default value otherwise.
    541     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    542     *         Integer.
    543     */
    544    Integer getInteger(String key, Integer defaultValue);
    545
    546    /**
    547     * Gets the list of the keys contained in the configuration. The returned iterator can be used to obtain all defined
    548     * keys. It does not allow removing elements from this configuration via its {@code remove()} method. Note that the keys
    549     * of this configuration are returned in a form, so that they can be directly evaluated; escaping of special characters
    550     * (if necessary) has already been performed.
    551     *
    552     * @return An Iterator.
    553     */
    554    Iterator<String> getKeys();
    555
    556    /**
    557     * Gets the list of the keys contained in the configuration that match the specified prefix. For instance, if the
    558     * configuration contains the following keys:<br>
    559     * {@code db.user, db.pwd, db.url, window.xpos, window.ypos},<br>
    560     * an invocation of {@code getKeys("db");}<br>
    561     * will return the keys below:<br>
    562     * {@code db.user, db.pwd, db.url}.<br>
    563     * Note that the prefix itself is included in the result set if there is a matching key. The exact behavior - how the
    564     * prefix is actually interpreted - depends on a concrete implementation.
    565     *
    566     * @param prefix The prefix to test against.
    567     * @return An Iterator of keys that match the prefix.
    568     * @see #getKeys()
    569     */
    570    Iterator<String> getKeys(String prefix);
    571
    572    /**
    573     * Gets the list of the keys contained in the configuration that match the specified prefix. For instance, if the
    574     * configuration contains the following keys:<br>
    575     * {@code db@user, db@pwd, db@url, window.xpos, window.ypos},<br>
    576     * an invocation of {@code getKeys("db","@");}<br>
    577     * will return the keys below:<br>
    578     * {@code db@user, db@pwd, db@url}.<br>
    579     * Note that the prefix itself is included in the result set if there is a matching key. The exact behavior - how the
    580     * prefix is actually interpreted - depends on a concrete implementation.
    581     *
    582     * @param prefix The prefix to test against.
    583     * @param delimiter The prefix delimiter.
    584     * @return An Iterator of keys that match the prefix.
    585     * @see #getKeys()
    586     * @since 2.10.0
    587     */
    588    default Iterator<String> getKeys(final String prefix, final String delimiter) {
    589        return null;
    590    }
    591
    592    /**
    593     * Gets a list of typed objects associated with the given configuration key returning a null if the key doesn't map to
    594     * an existing object.
    595     *
    596     * @param <T> the type expected for the elements of the list
    597     * @param cls the class expected for the elements of the list
    598     * @param key The configuration key.
    599     * @return The associated list if the key is found.
    600     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not
    601     *         compatible with a list of the specified class.
    602     *
    603     * @since 2.0
    604     */
    605    <T> List<T> getList(Class<T> cls, String key);
    606
    607    /**
    608     * Gets a list of typed objects associated with the given configuration key returning the specified default value if the
    609     * key doesn't map to an existing object. This method recursively retrieves all values stored for the passed in key,
    610     * i.e. if one of these values is again a complex object like an array or a collection (which may be the case for some
    611     * concrete subclasses), all values are extracted and added to the resulting list - performing a type conversion if
    612     * necessary.
    613     *
    614     * @param <T> the type expected for the elements of the list
    615     * @param cls the class expected for the elements of the list
    616     * @param key the configuration key.
    617     * @param defaultValue the default value.
    618     * @return The associated List.
    619     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not
    620     *         compatible with a list of the specified class.
    621     *
    622     * @since 2.0
    623     */
    624    <T> List<T> getList(Class<T> cls, String key, List<T> defaultValue);
    625
    626    /**
    627     * Gets a List of the values associated with the given configuration key. This method is different from the generic
    628     * {@code getList()} method in that it does not recursively obtain all values stored for the specified property key.
    629     * Rather, only the first level of the hierarchy is processed. So the resulting list may contain complex objects like
    630     * arrays or collections - depending on the storage structure used by a concrete subclass. If the key doesn't map to an
    631     * existing object, an empty List is returned.
    632     *
    633     * @param key The configuration key.
    634     * @return The associated List.
    635     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    636     *         List.
    637     */
    638    List<Object> getList(String key);
    639
    640    /**
    641     * Gets a List of strings associated with the given configuration key. If the key doesn't map to an existing object, the
    642     * default value is returned.
    643     *
    644     * @param key The configuration key.
    645     * @param defaultValue The default value.
    646     * @return The associated List of strings.
    647     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    648     *         List.
    649     * @see #getList(Class, String, List)
    650     */
    651    List<Object> getList(String key, List<?> defaultValue);
    652
    653    /**
    654     * Gets a long associated with the given configuration key.
    655     *
    656     * @param key The configuration key.
    657     * @return The associated long.
    658     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    659     *         Long.
    660     */
    661    long getLong(String key);
    662
    663    /**
    664     * Gets a long associated with the given configuration key. If the key doesn't map to an existing object, the default
    665     * value is returned.
    666     *
    667     * @param key The configuration key.
    668     * @param defaultValue The default value.
    669     * @return The associated long.
    670     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    671     *         Long.
    672     */
    673    long getLong(String key, long defaultValue);
    674
    675    /**
    676     * Gets a {@link Long} associated with the given configuration key. If the key doesn't map to an existing object, the
    677     * default value is returned.
    678     *
    679     * @param key The configuration key.
    680     * @param defaultValue The default value.
    681     * @return The associated long if key is found and has valid format, default value otherwise.
    682     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    683     *         Long.
    684     */
    685    Long getLong(String key, Long defaultValue);
    686
    687    /**
    688     * Gets a list of properties associated with the given configuration key. This method expects the given key to have an
    689     * arbitrary number of String values, each of which is of the form {@code key=value}. These strings are split at the
    690     * equals sign, and the key parts will become keys of the returned {@code Properties} object, the value parts become
    691     * values.
    692     *
    693     * @param key The configuration key.
    694     * @return The associated properties if key is found.
    695     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    696     *         String/List.
    697     * @throws IllegalArgumentException if one of the tokens is malformed (does not contain an equals sign).
    698     */
    699    Properties getProperties(String key);
    700
    701    /**
    702     * Gets a property from the configuration. This is the most basic get method for retrieving values of properties. In a
    703     * typical implementation of the {@code Configuration} interface the other get methods (that return specific data types)
    704     * will internally make use of this method. On this level variable substitution is not yet performed. The returned
    705     * object is an internal representation of the property value for the passed in key. It is owned by the
    706     * {@code Configuration} object. So a caller should not modify this object. It cannot be guaranteed that this object
    707     * will stay constant over time (i.e. further update operations on the configuration may change its internal state).
    708     *
    709     * @param key property to retrieve
    710     * @return the value to which this configuration maps the specified key, or null if the configuration contains no
    711     *         mapping for this key.
    712     */
    713    Object getProperty(String key);
    714
    715    /**
    716     * Gets a short associated with the given configuration key.
    717     *
    718     * @param key The configuration key.
    719     * @return The associated short.
    720     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    721     *         Short.
    722     */
    723    short getShort(String key);
    724
    725    /**
    726     * Gets a short associated with the given configuration key.
    727     *
    728     * @param key The configuration key.
    729     * @param defaultValue The default value.
    730     * @return The associated short.
    731     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    732     *         Short.
    733     */
    734    short getShort(String key, short defaultValue);
    735
    736    /**
    737     * Gets a {@link Short} associated with the given configuration key. If the key doesn't map to an existing object, the
    738     * default value is returned.
    739     *
    740     * @param key The configuration key.
    741     * @param defaultValue The default value.
    742     * @return The associated short if key is found and has valid format, default value otherwise.
    743     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    744     *         Short.
    745     */
    746    Short getShort(String key, Short defaultValue);
    747
    748    /**
    749     * Gets a string associated with the given configuration key.
    750     *
    751     * @param key The configuration key.
    752     * @return The associated string.
    753     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    754     *         String.
    755     */
    756    String getString(String key);
    757
    758    /**
    759     * Gets a string associated with the given configuration key. If the key doesn't map to an existing object, the default
    760     * value is returned.
    761     *
    762     * @param key The configuration key.
    763     * @param defaultValue The default value.
    764     * @return The associated string if key is found and has valid format, default value otherwise.
    765     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    766     *         String.
    767     */
    768    String getString(String key, String defaultValue);
    769
    770    /**
    771     * Gets an array of strings associated with the given configuration key. If the key doesn't map to an existing object an
    772     * empty array is returned
    773     *
    774     * @param key The configuration key.
    775     * @return The associated string array if key is found.
    776     * @throws org.apache.commons.configuration2.ex.ConversionException is thrown if the key maps to an object that is not a
    777     *         String/List of Strings.
    778     */
    779    String[] getStringArray(String key);
    780
    781    /**
    782     * Return a decorator immutable Configuration containing every key from the current Configuration that starts with the
    783     * specified prefix. The prefix is removed from the keys in the subset. For example, if the configuration contains the
    784     * following properties:
    785     *
    786     * <pre>
    787     *    prefix.number = 1
    788     *    prefix.string = Apache
    789     *    prefixed.foo = bar
    790     *    prefix = Jakarta
    791     * </pre>
    792     *
    793     * the immutable Configuration returned by {@code subset("prefix")} will contain the properties:
    794     *
    795     * <pre>
    796     *    number = 1
    797     *    string = Apache
    798     *    = Jakarta
    799     * </pre>
    800     *
    801     * (The key for the value "Jakarta" is an empty string)
    802     *
    803     * @param prefix The prefix used to select the properties.
    804     * @return a subset immutable configuration
    805     */
    806    ImmutableConfiguration immutableSubset(String prefix);
    807
    808    /**
    809     * Checks if the configuration is empty.
    810     *
    811     * @return {@code true} if the configuration contains no property, {@code false} otherwise.
    812     */
    813    boolean isEmpty();
    814
    815    /**
    816     * Returns the number of keys stored in this configuration. Note that a concrete implementation is not guaranteed to be
    817     * efficient; for some implementations it may be expensive to determine the size. Especially, if you just want to check
    818     * whether a configuration is empty, it is preferable to use the {@link #isEmpty()} method.
    819     *
    820     * @return the number of keys stored in this configuration
    821     */
    822    int size();
    823
    824}