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}