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