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