View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.commons.configuration;
    19
    20  import java.awt.Color;
    21  import java.io.Serializable;
    22  import java.lang.reflect.Array;
    23  import java.math.BigDecimal;
    24  import java.math.BigInteger;
    25  import java.net.URL;
    26  import java.util.ArrayList;
    27  import java.util.Calendar;
    28  import java.util.Collection;
    29  import java.util.Date;
    30  import java.util.Iterator;
    31  import java.util.List;
    32  import java.util.Locale;
    33  import java.util.NoSuchElementException;
    34
    35  import org.apache.commons.lang.ClassUtils;
    36  import org.apache.commons.lang.StringUtils;
    37
    38  /***
    39   * Decorator providing additional getters for any Configuration. This extended
    40   * Configuration supports more types:
    41   * <ul>
    42   *   <li>{@link java.net.URL}</li>
    43   *   <li>{@link java.util.Locale}</li>
    44   *   <li>{@link java.util.Date}</li>
    45   *   <li>{@link java.util.Calendar}</li>
    46   *   <li>{@link java.awt.Color}</li>
    47   *   <li>{@link java.net.InetAddress}</li>
    48   *   <li>{@link javax.mail.internet.InternetAddress} (requires Javamail in the classpath)</li>
    49   *   <li>{@link java.lang.Enum} (Java 5 enumeration types)</li>
    50   * </ul>
    51   *
    52   * Lists and arrays are available for all types.
    53   *
    54   * <h4>Example</h4>
    55   *
    56   * Configuration file <tt>config.properties</tt>:
    57   * <pre>
    58   * title.color = #0000FF
    59   * remote.host = 192.168.0.53
    60   * default.locales = fr,en,de
    61   * email.contact = ebourg@apache.org, oheger@apache.org
    62   * </pre>
    63   *
    64   * Usage:
    65   *
    66   * <pre>
    67   * DataConfiguration config = new DataConfiguration(new PropertiesConfiguration("config.properties"));
    68   *
    69   * // retrieve a property using a specialized getter
    70   * Color color = config.getColor("title.color");
    71   *
    72   * // retrieve a property using a generic getter
    73   * InetAddress host = (InetAddress) config.get(InetAddress.class, "remote.host");
    74   * Locale[] locales = (Locale[]) config.getArray(Locale.class, "default.locales");
    75   * List contacts = config.getList(InternetAddress.class, "email.contact");
    76   * </pre>
    77   *
    78   * <h4>Dates</h4>
    79   *
    80   * Date objects are expected to be formatted with the pattern <tt>yyyy-MM-dd HH:mm:ss</tt>.
    81   * This default format can be changed by specifying another format in the
    82   * getters, or by putting a date format in the configuration under the key
    83   * <tt>org.apache.commons.configuration.format.date</tt>.
    84   *
    85   * @author <a href="ebourg@apache.org">Emmanuel Bourg</a>
    86   * @version $Revision: 589380 $, $Date: 2007-10-28 17:37:35 +0100 (So, 28 Okt 2007) $
    87   * @since 1.1
    88   */
    89  public class DataConfiguration extends AbstractConfiguration implements Serializable
    90  {
    91      /*** The key of the property storing the user defined date format. */
    92      public static final String DATE_FORMAT_KEY = "org.apache.commons.configuration.format.date";
    93
    94      /*** The default format for dates. */
    95      public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    96
    97      /***
    98       * The serial version UID.
    99       */
    100     private static final long serialVersionUID = -69011336405718640L;
    101
    102     /*** Stores the wrapped configuration.*/
    103     protected Configuration configuration;
    104
    105     /***
    106      * Creates a new instance of <code>DataConfiguration</code> and sets the
    107      * wrapped configuration.
    108      *
    109      * @param configuration the wrapped configuration
    110      */
    111     public DataConfiguration(Configuration configuration)
    112     {
    113         this.configuration = configuration;
    114     }
    115
    116     /***
    117      * Return the configuration decorated by this DataConfiguration.
    118      *
    119      * @return the wrapped configuration
    120      */
    121     public Configuration getConfiguration()
    122     {
    123         return configuration;
    124     }
    125
    126     public Object getProperty(String key)
    127     {
    128         return configuration.getProperty(key);
    129     }
    130
    131     protected void addPropertyDirect(String key, Object obj)
    132     {
    133         if (configuration instanceof AbstractConfiguration)
    134         {
    135             ((AbstractConfiguration) configuration).addPropertyDirect(key, obj);
    136         }
    137         else
    138         {
    139             configuration.addProperty(key, obj);
    140         }
    141     }
    142
    143     public boolean isEmpty()
    144     {
    145         return configuration.isEmpty();
    146     }
    147
    148     public boolean containsKey(String key)
    149     {
    150         return configuration.containsKey(key);
    151     }
    152
    153     public void clearProperty(String key)
    154     {
    155         configuration.clearProperty(key);
    156     }
    157
    158     public Iterator getKeys()
    159     {
    160         return configuration.getKeys();
    161     }
    162
    163     /***
    164      * Get an object of the specified type associated with the given
    165      * configuration key. If the key doesn't map to an existing object, the
    166      * method returns null unless {@link #isThrowExceptionOnMissing()} is set
    167      * to <tt>true</tt>.
    168      *
    169      * @param cls the target type of the value
    170      * @param key the key of the value
    171      *
    172      * @return the value of the requested type for the key
    173      *
    174      * @throws NoSuchElementException if the key doesn't map to an existing
    175      *     object and <tt>throwExceptionOnMissing=true</tt>
    176      * @throws ConversionException if the value is not compatible with the requested type
    177      *
    178      * @since 1.5
    179      */
    180     public Object get(Class cls, String key)
    181     {
    182         Object value = get(cls, key, null);
    183         if (value != null)
    184         {
    185             return value;
    186         }
    187         else if (isThrowExceptionOnMissing())
    188         {
    189             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
    190         }
    191         else
    192         {
    193             return null;
    194         }
    195     }
    196
    197     /***
    198      * Get an object of the specified type associated with the given
    199      * configuration key. If the key doesn't map to an existing object, the
    200      * default value is returned.
    201      *
    202      * @param cls          the target type of the value
    203      * @param key          the key of the value
    204      * @param defaultValue the default value
    205      *
    206      * @return the value of the requested type for the key
    207      *
    208      * @throws ConversionException if the value is not compatible with the requested type
    209      *
    210      * @since 1.5
    211      */
    212     public Object get(Class cls, String key, Object defaultValue)
    213     {
    214         Object value = resolveContainerStore(key);
    215
    216         if (value == null)
    217         {
    218             return defaultValue;
    219         }
    220         else
    221         {
    222             try
    223             {
    224                 if (Date.class.equals(cls) || Calendar.class.equals(cls))
    225                 {
    226                     return PropertyConverter.to(cls, interpolate(value), new String[] {getDefaultDateFormat()});
    227                 }
    228                 else
    229                 {
    230                     return PropertyConverter.to(cls, interpolate(value), null);
    231                 }
    232             }
    233             catch (ConversionException e)
    234             {
    235                 throw new ConversionException('\'' + key + "' doesn't map to a " + cls, e);
    236             }
    237         }
    238     }
    239
    240     /***
    241      * Get a list of typed objects associated with the given configuration key.
    242      * If the key doesn't map to an existing object, an empty list is returned.
    243      *
    244      * @param cls the type expected for the elements of the list
    245      * @param key The configuration key.
    246      * @return The associated list if the key is found.
    247      *
    248      * @throws ConversionException is thrown if the key maps to an object that
    249      *     is not compatible with a list of the specified class.
    250      *
    251      * @since 1.5
    252      */
    253     public List getList(Class cls, String key)
    254     {
    255         return getList(cls, key, new ArrayList());
    256     }
    257
    258     /***
    259      * Get a list of typed objects associated with the given configuration key.
    260      * If the key doesn't map to an existing object, the default value is
    261      * returned.
    262      *
    263      * @param cls the      type expected for the elements of the list
    264      * @param key          the configuration key.
    265      * @param defaultValue the default value.
    266      * @return The associated List.
    267      *
    268      * @throws ConversionException is thrown if the key maps to an object that
    269      *     is not compatible with a list of the specified class.
    270      *
    271      * @since 1.5
    272      */
    273     public List getList(Class cls, String key, List defaultValue)
    274     {
    275         Object value = getProperty(key);
    276         Class valueClass = value != null ? value.getClass() : null;
    277
    278         List list;
    279
    280         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
    281         {
    282             // the value is null or is an empty string
    283             list = defaultValue;
    284         }
    285         else
    286         {
    287             list = new ArrayList();
    288
    289             Object[] params = null;
    290             if (cls.equals(Date.class) || cls.equals(Calendar.class))
    291             {
    292                 params = new Object[] {getDefaultDateFormat()};
    293             }
    294
    295             try
    296             {
    297                 if (valueClass.isArray())
    298                 {
    299                     // get the class of the objects contained in the array
    300                     Class arrayType = valueClass.getComponentType();
    301                     int length = Array.getLength(value);
    302
    303                     if (arrayType.equals(cls)
    304                             || (arrayType.isPrimitive() && cls.equals(ClassUtils.primitiveToWrapper(arrayType))))
    305                     {
    306                         // the value is an array of the specified type, or an array
    307                         // of the primitive type derived from the specified type
    308                         for (int i = 0; i < length; i++)
    309                         {
    310                             list.add(Array.get(value, i));
    311                         }
    312                     }
    313                     else
    314                     {
    315                         // attempt to convert the elements of the array
    316                         for (int i = 0; i < length; i++)
    317                         {
    318                             list.add(PropertyConverter.to(cls, interpolate(Array.get(value, i)), params));
    319                         }
    320                     }
    321                 }
    322                 else if (value instanceof Collection)
    323                 {
    324                     Collection values = (Collection) value;
    325
    326                     Iterator it = values.iterator();
    327                     while (it.hasNext())
    328                     {
    329                         list.add(PropertyConverter.to(cls, interpolate(it.next()), params));
    330                     }
    331                 }
    332                 else
    333                 {
    334                     // attempt to convert a single value
    335                     list.add(PropertyConverter.to(cls, interpolate(value), params));
    336                 }
    337             }
    338             catch (ConversionException e)
    339             {
    340                 throw new ConversionException("'" + key + "' doesn't map to a list of " + cls, e);
    341             }
    342         }
    343
    344         return list;
    345     }
    346
    347     /***
    348      * Get an array of typed objects associated with the given configuration key.
    349      * If the key doesn't map to an existing object, an empty list is returned.
    350      *
    351      * @param cls the type expected for the elements of the array
    352      * @param key The configuration key.
    353      * @return The associated array if the key is found, and the value compatible with the type specified.
    354      *
    355      * @throws ConversionException is thrown if the key maps to an object that
    356      *     is not compatible with a list of the specified class.
    357      *
    358      * @since 1.5
    359      */
    360     public Object getArray(Class cls, String key)
    361     {
    362         return getArray(cls, key, Array.newInstance(cls, 0));
    363     }
    364
    365     /***
    366      * Get an array of typed objects associated with the given configuration key.
    367      * If the key doesn't map to an existing object, the default value is returned.
    368      *
    369      * @param cls          the type expected for the elements of the array
    370      * @param key          the configuration key.
    371      * @param defaultValue the default value
    372      * @return The associated array if the key is found, and the value compatible with the type specified.
    373      *
    374      * @throws ConversionException is thrown if the key maps to an object that
    375      *     is not compatible with an array of the specified class.
    376      * @throws IllegalArgumentException if the default value is not an array of the specified type
    377      *
    378      * @since 1.5
    379      */
    380     public Object getArray(Class cls, String key, Object defaultValue)
    381     {
    382         // check the type of the default value
    383         if (defaultValue != null
    384                 && (!defaultValue.getClass().isArray() || !cls
    385                         .isAssignableFrom(defaultValue.getClass()
    386                                 .getComponentType())))
    387         {
    388             throw new IllegalArgumentException(
    389                     "The type of the default value (" + defaultValue.getClass()
    390                             + ")" + " is not an array of the specified class ("
    391                             + cls + ")");
    392         }
    393
    394         if (cls.isPrimitive())
    395         {
    396             return getPrimitiveArray(cls, key, defaultValue);
    397         }
    398
    399         List list = getList(cls, key);
    400         if (list.isEmpty())
    401         {
    402             return defaultValue;
    403         }
    404         else
    405         {
    406             return list.toArray((Object[]) Array.newInstance(cls, list.size()));
    407         }
    408     }
    409
    410     /***
    411      * Get an array of primitive values associated with the given configuration key.
    412      * If the key doesn't map to an existing object, the default value is returned.
    413      *
    414      * @param cls          the primitive type expected for the elements of the array
    415      * @param key          the configuration key.
    416      * @param defaultValue the default value
    417      * @return The associated array if the key is found, and the value compatible with the type specified.
    418      *
    419      * @throws ConversionException is thrown if the key maps to an object that
    420      *     is not compatible with an array of the specified class.
    421      *
    422      * @since 1.5
    423      */
    424     private Object getPrimitiveArray(Class cls, String key, Object defaultValue)
    425     {
    426         Object value = getProperty(key);
    427         Class valueClass = value != null ? value.getClass() : null;
    428
    429         Object array;
    430
    431         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
    432         {
    433             // the value is null or is an empty string
    434             array = defaultValue;
    435         }
    436         else
    437         {
    438             if (valueClass.isArray())
    439             {
    440                 // get the class of the objects contained in the array
    441                 Class arrayType = valueClass.getComponentType();
    442                 int length = Array.getLength(value);
    443
    444                 if (arrayType.equals(cls))
    445                 {
    446                     // the value is an array of the same primitive type
    447                     array = value;
    448                 }
    449                 else if (arrayType.equals(ClassUtils.primitiveToWrapper(cls)))
    450                 {
    451                     // the value is an array of the wrapper type derived from the specified primitive type
    452                     array = Array.newInstance(cls, length);
    453
    454                     for (int i = 0; i < length; i++)
    455                     {
    456                         Array.set(array, i, Array.get(value, i));
    457                     }
    458                 }
    459                 else
    460                 {
    461                     throw new ConversionException('\'' + key + "' (" + arrayType + ")"
    462                             + " doesn't map to a compatible array of " + cls);
    463                 }
    464             }
    465             else if (value instanceof Collection)
    466             {
    467                 Collection values = (Collection) value;
    468
    469                 array = Array.newInstance(cls, values.size());
    470
    471                 Iterator it = values.iterator();
    472                 int i = 0;
    473                 while (it.hasNext())
    474                 {
    475                     Array.set(array, i++, PropertyConverter.to(cls, interpolate(it.next()), null));
    476                 }
    477             }
    478             else
    479             {
    480                 try
    481                 {
    482                     // attempt to convert a single value
    483                     Object convertedValue = PropertyConverter.to(cls, interpolate(value), null);
    484
    485                     // create an array of one element
    486                     array = Array.newInstance(cls, 1);
    487                     Array.set(array, 0, convertedValue);
    488                 }
    489                 catch (ConversionException e)
    490                 {
    491                     throw new ConversionException('\'' + key + "' doesn't map to an array of " + cls, e);
    492                 }
    493             }
    494         }
    495
    496         return array;
    497     }
    498
    499     /***
    500      * Get a list of Boolean objects associated with the given
    501      * configuration key. If the key doesn't map to an existing object
    502      * an empty list is returned.
    503      *
    504      * @param key The configuration key.
    505      * @return The associated Boolean list if the key is found.
    506      *
    507      * @throws ConversionException is thrown if the key maps to an
    508      *         object that is not a list of booleans.
    509      */
    510     public List getBooleanList(String key)
    511     {
    512         return getBooleanList(key, new ArrayList());
    513     }
    514
    515     /***
    516      * Get a list of Boolean objects associated with the given
    517      * configuration key. If the key doesn't map to an existing object,
    518      * the default value is returned.
    519      *
    520      * @param key The configuration key.
    521      * @param defaultValue The default value.
    522      * @return The associated List of Booleans.
    523      *
    524      * @throws ConversionException is thrown if the key maps to an
    525      *         object that is not a list of booleans.
    526      */
    527     public List getBooleanList(String key, List defaultValue)
    528     {
    529          return getList(Boolean.class, key, defaultValue);
    530     }
    531
    532     /***
    533      * Get an array of boolean primitives associated with the given
    534      * configuration key. If the key doesn't map to an existing object
    535      * an empty array is returned.
    536      *
    537      * @param key The configuration key.
    538      * @return The associated boolean array if the key is found.
    539      *
    540      * @throws ConversionException is thrown if the key maps to an
    541      *         object that is not a list of booleans.
    542      */
    543     public boolean[] getBooleanArray(String key)
    544     {
    545         return (boolean[]) getArray(Boolean.TYPE, key);
    546     }
    547
    548     /***
    549      * Get an array of boolean primitives associated with the given
    550      * configuration key. If the key doesn't map to an existing object,
    551      * the default value is returned.
    552      *
    553      * @param key          The configuration key.
    554      * @param defaultValue The default value.
    555      * @return The associated boolean array if the key is found.
    556      *
    557      * @throws ConversionException is thrown if the key maps to an
    558      *         object that is not a list of booleans.
    559      */
    560     public boolean[] getBooleanArray(String key, boolean[] defaultValue)
    561     {
    562         return (boolean[]) getArray(Boolean.TYPE, key, defaultValue);
    563     }
    564
    565     /***
    566      * Get a list of Byte objects associated with the given configuration key.
    567      * If the key doesn't map to an existing object an empty list is returned.
    568      *
    569      * @param key The configuration key.
    570      * @return The associated Byte list if the key is found.
    571      *
    572      * @throws ConversionException is thrown if the key maps to an
    573      *         object that is not a list of bytes.
    574      */
    575     public List getByteList(String key)
    576     {
    577         return getByteList(key, new ArrayList());
    578     }
    579
    580     /***
    581      * Get a list of Byte objects associated with the given configuration key.
    582      * If the key doesn't map to an existing object, the default value is
    583      * returned.
    584      *
    585      * @param key The configuration key.
    586      * @param defaultValue The default value.
    587      * @return The associated List of Bytes.
    588      *
    589      * @throws ConversionException is thrown if the key maps to an
    590      *         object that is not a list of bytes.
    591      */
    592     public List getByteList(String key, List defaultValue)
    593     {
    594         return getList(Byte.class, key, defaultValue);
    595     }
    596
    597     /***
    598      * Get an array of byte primitives associated with the given
    599      * configuration key. If the key doesn't map to an existing object
    600      * an empty array is returned.
    601      *
    602      * @param key The configuration key.
    603      * @return The associated byte array if the key is found.
    604      *
    605      * @throws ConversionException is thrown if the key maps to an
    606      *         object that is not a list of bytes.
    607      */
    608     public byte[] getByteArray(String key)
    609     {
    610         return getByteArray(key, new byte[0]);
    611     }
    612
    613     /***
    614      * Get an array of byte primitives associated with the given
    615      * configuration key. If the key doesn't map to an existing object
    616      * an empty array is returned.
    617      *
    618      * @param key The configuration key.
    619      * @param defaultValue the default value, which will be returned if the property is not found
    620      * @return The associated byte array if the key is found.
    621      *
    622      * @throws ConversionException is thrown if the key maps to an
    623      *         object that is not a list of bytes.
    624      */
    625     public byte[] getByteArray(String key, byte[] defaultValue)
    626     {
    627         return (byte[]) getArray(Byte.TYPE, key, defaultValue);
    628     }
    629
    630     /***
    631      * Get a list of Short objects associated with the given configuration key.
    632      * If the key doesn't map to an existing object an empty list is returned.
    633      *
    634      * @param key The configuration key.
    635      * @return The associated Short list if the key is found.
    636      *
    637      * @throws ConversionException is thrown if the key maps to an
    638      *         object that is not a list of shorts.
    639      */
    640     public List getShortList(String key)
    641     {
    642         return getShortList(key, new ArrayList());
    643     }
    644
    645     /***
    646      * Get a list of Short objects associated with the given configuration key.
    647      * If the key doesn't map to an existing object, the default value is
    648      * returned.
    649      *
    650      * @param key The configuration key.
    651      * @param defaultValue The default value.
    652      * @return The associated List of Shorts.
    653      *
    654      * @throws ConversionException is thrown if the key maps to an
    655      *         object that is not a list of shorts.
    656      */
    657     public List getShortList(String key, List defaultValue)
    658     {
    659         return getList(Short.class, key, defaultValue);
    660     }
    661
    662     /***
    663      * Get an array of short primitives associated with the given
    664      * configuration key. If the key doesn't map to an existing object
    665      * an empty array is returned.
    666      *
    667      * @param key The configuration key.
    668      * @return The associated short array if the key is found.
    669      *
    670      * @throws ConversionException is thrown if the key maps to an
    671      *         object that is not a list of shorts.
    672      */
    673     public short[] getShortArray(String key)
    674     {
    675         return getShortArray(key, new short[0]);
    676     }
    677
    678     /***
    679      * Get an array of short primitives associated with the given
    680      * configuration key. If the key doesn't map to an existing object
    681      * an empty array is returned.
    682      *
    683      * @param key The configuration key.
    684      * @param defaultValue the default value, which will be returned if the property is not found
    685      * @return The associated short array if the key is found.
    686      *
    687      * @throws ConversionException is thrown if the key maps to an
    688      *         object that is not a list of shorts.
    689      */
    690     public short[] getShortArray(String key, short[] defaultValue)
    691     {
    692         return (short[]) getArray(Short.TYPE, key, defaultValue);
    693     }
    694
    695     /***
    696      * Get a list of Integer objects associated with the given
    697      * configuration key. If the key doesn't map to an existing object
    698      * an empty list is returned.
    699      *
    700      * @param key The configuration key.
    701      * @return The associated Integer list if the key is found.
    702      *
    703      * @throws ConversionException is thrown if the key maps to an
    704      *         object that is not a list of integers.
    705      */
    706     public List getIntegerList(String key)
    707     {
    708         return getIntegerList(key, new ArrayList());
    709     }
    710
    711     /***
    712      * Get a list of Integer objects associated with the given
    713      * configuration key. If the key doesn't map to an existing object,
    714      * the default value is returned.
    715      *
    716      * @param key The configuration key.
    717      * @param defaultValue The default value.
    718      * @return The associated List of Integers.
    719      *
    720      * @throws ConversionException is thrown if the key maps to an
    721      *         object that is not a list of integers.
    722      */
    723     public List getIntegerList(String key, List defaultValue)
    724     {
    725         return getList(Integer.class, key, defaultValue);
    726     }
    727
    728     /***
    729      * Get an array of int primitives associated with the given
    730      * configuration key. If the key doesn't map to an existing object
    731      * an empty array is returned.
    732      *
    733      * @param key The configuration key.
    734      * @return The associated int array if the key is found.
    735      *
    736      * @throws ConversionException is thrown if the key maps to an
    737      *         object that is not a list of integers.
    738      */
    739     public int[] getIntArray(String key)
    740     {
    741         return getIntArray(key, new int[0]);
    742     }
    743
    744     /***
    745      * Get an array of int primitives associated with the given
    746      * configuration key. If the key doesn't map to an existing object
    747      * an empty array is returned.
    748      *
    749      * @param key The configuration key.
    750      * @param defaultValue the default value, which will be returned if the property is not found
    751      * @return The associated int array if the key is found.
    752      *
    753      * @throws ConversionException is thrown if the key maps to an
    754      *         object that is not a list of integers.
    755      */
    756     public int[] getIntArray(String key, int[] defaultValue)
    757     {
    758         return (int[]) getArray(Integer.TYPE, key, defaultValue);
    759     }
    760
    761     /***
    762      * Get a list of Long objects associated with the given configuration key.
    763      * If the key doesn't map to an existing object an empty list is returned.
    764      *
    765      * @param key The configuration key.
    766      * @return The associated Long list if the key is found.
    767      *
    768      * @throws ConversionException is thrown if the key maps to an
    769      *         object that is not a list of longs.
    770      */
    771     public List getLongList(String key)
    772     {
    773         return getLongList(key, new ArrayList());
    774     }
    775
    776     /***
    777      * Get a list of Long objects associated with the given configuration key.
    778      * If the key doesn't map to an existing object, the default value is
    779      * returned.
    780      *
    781      * @param key The configuration key.
    782      * @param defaultValue The default value.
    783      * @return The associated List of Longs.
    784      *
    785      * @throws ConversionException is thrown if the key maps to an
    786      *         object that is not a list of longs.
    787      */
    788     public List getLongList(String key, List defaultValue)
    789     {
    790         return getList(Long.class, key, defaultValue);
    791     }
    792
    793     /***
    794      * Get an array of long primitives associated with the given
    795      * configuration key. If the key doesn't map to an existing object
    796      * an empty array is returned.
    797      *
    798      * @param key The configuration key.
    799      * @return The associated long array if the key is found.
    800      *
    801      * @throws ConversionException is thrown if the key maps to an
    802      *         object that is not a list of longs.
    803      */
    804     public long[] getLongArray(String key)
    805     {
    806         return getLongArray(key, new long[0]);
    807     }
    808
    809     /***
    810      * Get an array of long primitives associated with the given
    811      * configuration key. If the key doesn't map to an existing object
    812      * an empty array is returned.
    813      *
    814      * @param key The configuration key.
    815      * @param defaultValue the default value, which will be returned if the property is not found
    816      * @return The associated long array if the key is found.
    817      *
    818      * @throws ConversionException is thrown if the key maps to an
    819      *         object that is not a list of longs.
    820      */
    821     public long[] getLongArray(String key, long[] defaultValue)
    822     {
    823         return (long[]) getArray(Long.TYPE, key, defaultValue);
    824     }
    825
    826     /***
    827      * Get a list of Float objects associated with the given configuration key.
    828      * If the key doesn't map to an existing object an empty list is returned.
    829      *
    830      * @param key The configuration key.
    831      * @return The associated Float list if the key is found.
    832      *
    833      * @throws ConversionException is thrown if the key maps to an
    834      *         object that is not a list of floats.
    835      */
    836     public List getFloatList(String key)
    837     {
    838         return getFloatList(key, new ArrayList());
    839     }
    840
    841     /***
    842      * Get a list of Float objects associated with the given
    843      * configuration key. If the key doesn't map to an existing object,
    844      * the default value is returned.
    845      *
    846      * @param key The configuration key.
    847      * @param defaultValue The default value.
    848      * @return The associated List of Floats.
    849      *
    850      * @throws ConversionException is thrown if the key maps to an
    851      *         object that is not a list of floats.
    852      */
    853     public List getFloatList(String key, List defaultValue)
    854     {
    855         return getList(Float.class, key, defaultValue);
    856     }
    857
    858     /***
    859      * Get an array of float primitives associated with the given
    860      * configuration key. If the key doesn't map to an existing object
    861      * an empty array is returned.
    862      *
    863      * @param key The configuration key.
    864      * @return The associated float array if the key is found.
    865      *
    866      * @throws ConversionException is thrown if the key maps to an
    867      *         object that is not a list of floats.
    868      */
    869     public float[] getFloatArray(String key)
    870     {
    871         return getFloatArray(key, new float[0]);
    872     }
    873
    874     /***
    875      * Get an array of float primitives associated with the given
    876      * configuration key. If the key doesn't map to an existing object
    877      * an empty array is returned.
    878      *
    879      * @param key The configuration key.
    880      * @param defaultValue the default value, which will be returned if the property is not found
    881      * @return The associated float array if the key is found.
    882      *
    883      * @throws ConversionException is thrown if the key maps to an
    884      *         object that is not a list of floats.
    885      */
    886     public float[] getFloatArray(String key, float[] defaultValue)
    887     {
    888         return (float[]) getArray(Float.TYPE, key, defaultValue);
    889     }
    890
    891     /***
    892      * Get a list of Double objects associated with the given
    893      * configuration key. If the key doesn't map to an existing object
    894      * an empty list is returned.
    895      *
    896      * @param key The configuration key.
    897      * @return The associated Double list if the key is found.
    898      *
    899      * @throws ConversionException is thrown if the key maps to an
    900      *         object that is not a list of doubles.
    901      */
    902     public List getDoubleList(String key)
    903     {
    904         return getDoubleList(key, new ArrayList());
    905     }
    906
    907     /***
    908      * Get a list of Double objects associated with the given
    909      * configuration key. If the key doesn't map to an existing object,
    910      * the default value is returned.
    911      *
    912      * @param key The configuration key.
    913      * @param defaultValue The default value.
    914      * @return The associated List of Doubles.
    915      *
    916      * @throws ConversionException is thrown if the key maps to an
    917      *         object that is not a list of doubles.
    918      */
    919     public List getDoubleList(String key, List defaultValue)
    920     {
    921         return getList(Double.class, key, defaultValue);
    922     }
    923
    924     /***
    925      * Get an array of double primitives associated with the given
    926      * configuration key. If the key doesn't map to an existing object
    927      * an empty array is returned.
    928      *
    929      * @param key The configuration key.
    930      * @return The associated double array if the key is found.
    931      *
    932      * @throws ConversionException is thrown if the key maps to an
    933      *         object that is not a list of doubles.
    934      */
    935     public double[] getDoubleArray(String key)
    936     {
    937         return getDoubleArray(key, new double[0]);
    938     }
    939
    940     /***
    941      * Get an array of double primitives associated with the given
    942      * configuration key. If the key doesn't map to an existing object
    943      * an empty array is returned.
    944      *
    945      * @param key The configuration key.
    946      * @param defaultValue the default value, which will be returned if the property is not found
    947      * @return The associated double array if the key is found.
    948      *
    949      * @throws ConversionException is thrown if the key maps to an
    950      *         object that is not a list of doubles.
    951      */
    952     public double[] getDoubleArray(String key, double[] defaultValue)
    953     {
    954         return (double[]) getArray(Double.TYPE, key, defaultValue);
    955     }
    956
    957     /***
    958      * Get a list of BigIntegers associated with the given configuration key.
    959      * If the key doesn't map to an existing object an empty list is returned.
    960      *
    961      * @param key The configuration key.
    962      * @return The associated BigInteger list if the key is found.
    963      *
    964      * @throws ConversionException is thrown if the key maps to an
    965      *         object that is not a list of BigIntegers.
    966      */
    967     public List getBigIntegerList(String key)
    968     {
    969         return getBigIntegerList(key, new ArrayList());
    970     }
    971
    972     /***
    973      * Get a list of BigIntegers associated with the given configuration key.
    974      * If the key doesn't map to an existing object, the default value is
    975      * returned.
    976      *
    977      * @param key The configuration key.
    978      * @param defaultValue The default value.
    979      * @return The associated List of BigIntegers.
    980      *
    981      * @throws ConversionException is thrown if the key maps to an
    982      *         object that is not a list of BigIntegers.
    983      */
    984     public List getBigIntegerList(String key, List defaultValue)
    985     {
    986         return getList(BigInteger.class, key, defaultValue);
    987     }
    988
    989     /***
    990      * Get an array of BigIntegers associated with the given
    991      * configuration key. If the key doesn't map to an existing object
    992      * an empty array is returned.
    993      *
    994      * @param key The configuration key.
    995      * @return The associated BigInteger array if the key is found.
    996      *
    997      * @throws ConversionException is thrown if the key maps to an
    998      *         object that is not a list of BigIntegers.
    999      */
    1000     public BigInteger[] getBigIntegerArray(String key)
    1001     {
    1002         return getBigIntegerArray(key, new BigInteger[0]);
    1003     }
    1004
    1005     /***
    1006      * Get an array of BigIntegers associated with the given
    1007      * configuration key. If the key doesn't map to an existing object
    1008      * an empty array is returned.
    1009      *
    1010      * @param key The configuration key.
    1011      * @param defaultValue the default value, which will be returned if the property is not found
    1012      * @return The associated BigInteger array if the key is found.
    1013      *
    1014      * @throws ConversionException is thrown if the key maps to an
    1015      *         object that is not a list of BigIntegers.
    1016      */
    1017     public BigInteger[] getBigIntegerArray(String key, BigInteger[] defaultValue)
    1018     {
    1019         return (BigInteger[]) getArray(BigInteger.class, key, defaultValue);
    1020     }
    1021
    1022     /***
    1023      * Get a list of BigDecimals associated with the given configuration key.
    1024      * If the key doesn't map to an existing object an empty list is returned.
    1025      *
    1026      * @param key The configuration key.
    1027      * @return The associated BigDecimal list if the key is found.
    1028      *
    1029      * @throws ConversionException is thrown if the key maps to an
    1030      *         object that is not a list of BigDecimals.
    1031      */
    1032     public List getBigDecimalList(String key)
    1033     {
    1034         return getBigDecimalList(key, new ArrayList());
    1035     }
    1036
    1037     /***
    1038      * Get a list of BigDecimals associated with the given configuration key.
    1039      * If the key doesn't map to an existing object, the default value is
    1040      * returned.
    1041      *
    1042      * @param key The configuration key.
    1043      * @param defaultValue The default value.
    1044      * @return The associated List of BigDecimals.
    1045      *
    1046      * @throws ConversionException is thrown if the key maps to an
    1047      *         object that is not a list of BigDecimals.
    1048      */
    1049     public List getBigDecimalList(String key, List defaultValue)
    1050     {
    1051         return getList(BigDecimal.class, key, defaultValue);
    1052     }
    1053
    1054     /***
    1055      * Get an array of BigDecimals associated with the given
    1056      * configuration key. If the key doesn't map to an existing object
    1057      * an empty array is returned.
    1058      *
    1059      * @param key The configuration key.
    1060      * @return The associated BigDecimal array if the key is found.
    1061      *
    1062      * @throws ConversionException is thrown if the key maps to an
    1063      *         object that is not a list of BigDecimals.
    1064      */
    1065     public BigDecimal[] getBigDecimalArray(String key)
    1066     {
    1067         return getBigDecimalArray(key, new BigDecimal[0]);
    1068     }
    1069
    1070     /***
    1071      * Get an array of BigDecimals associated with the given
    1072      * configuration key. If the key doesn't map to an existing object
    1073      * an empty array is returned.
    1074      *
    1075      * @param key The configuration key.
    1076      * @param defaultValue the default value, which will be returned if the property is not found
    1077      * @return The associated BigDecimal array if the key is found.
    1078      *
    1079      * @throws ConversionException is thrown if the key maps to an
    1080      *         object that is not a list of BigDecimals.
    1081      */
    1082     public BigDecimal[] getBigDecimalArray(String key, BigDecimal[] defaultValue)
    1083     {
    1084         return (BigDecimal[]) getArray(BigDecimal.class, key, defaultValue);
    1085     }
    1086
    1087     /***
    1088      * Get an URL associated with the given configuration key.
    1089      *
    1090      * @param key The configuration key.
    1091      * @return The associated URL.
    1092      *
    1093      * @throws ConversionException is thrown if the key maps to an
    1094      *         object that is not an URL.
    1095      */
    1096     public URL getURL(String key)
    1097     {
    1098         return (URL) get(URL.class, key);
    1099     }
    1100
    1101     /***
    1102      * Get an URL associated with the given configuration key.
    1103      * If the key doesn't map to an existing object, the default value
    1104      * is returned.
    1105      *
    1106      * @param key          The configuration key.
    1107      * @param defaultValue The default value.
    1108      * @return The associated URL.
    1109      *
    1110      * @throws ConversionException is thrown if the key maps to an
    1111      *         object that is not an URL.
    1112      */
    1113     public URL getURL(String key, URL defaultValue)
    1114     {
    1115         return (URL) get(URL.class, key, defaultValue);
    1116     }
    1117
    1118     /***
    1119      * Get a list of URLs associated with the given configuration key.
    1120      * If the key doesn't map to an existing object an empty list is returned.
    1121      *
    1122      * @param key The configuration key.
    1123      * @return The associated URL list if the key is found.
    1124      *
    1125      * @throws ConversionException is thrown if the key maps to an
    1126      *         object that is not a list of URLs.
    1127      */
    1128     public List getURLList(String key)
    1129     {
    1130         return getURLList(key, new ArrayList());
    1131     }
    1132
    1133     /***
    1134      * Get a list of URLs associated with the given configuration key.
    1135      * If the key doesn't map to an existing object, the default value is
    1136      * returned.
    1137      *
    1138      * @param key The configuration key.
    1139      * @param defaultValue The default value.
    1140      * @return The associated List of URLs.
    1141      *
    1142      * @throws ConversionException is thrown if the key maps to an
    1143      *         object that is not a list of URLs.
    1144      */
    1145     public List getURLList(String key, List defaultValue)
    1146     {
    1147         return getList(URL.class, key, defaultValue);
    1148     }
    1149
    1150     /***
    1151      * Get an array of URLs associated with the given configuration key.
    1152      * If the key doesn't map to an existing object an empty array is returned.
    1153      *
    1154      * @param key The configuration key.
    1155      * @return The associated URL array if the key is found.
    1156      *
    1157      * @throws ConversionException is thrown if the key maps to an
    1158      *         object that is not a list of URLs.
    1159      */
    1160     public URL[] getURLArray(String key)
    1161     {
    1162         return getURLArray(key, new URL[0]);
    1163     }
    1164
    1165     /***
    1166      * Get an array of URLs associated with the given configuration key.
    1167      * If the key doesn't map to an existing object an empty array is returned.
    1168      *
    1169      * @param key The configuration key.
    1170      * @param defaultValue the default value, which will be returned if the property is not found
    1171      * @return The associated URL array if the key is found.
    1172      *
    1173      * @throws ConversionException is thrown if the key maps to an
    1174      *         object that is not a list of URLs.
    1175      */
    1176     public URL[] getURLArray(String key, URL[] defaultValue)
    1177     {
    1178         return (URL[]) getArray(URL.class, key, defaultValue);
    1179     }
    1180
    1181     /***
    1182      * Get a Date associated with the given configuration key. If the property
    1183      * is a String, it will be parsed with the format defined by the user in
    1184      * the {@link #DATE_FORMAT_KEY} property, or if it's not defined with the
    1185      * {@link #DEFAULT_DATE_FORMAT} pattern.
    1186      *
    1187      * @param key The configuration key.
    1188      * @return The associated Date.
    1189      *
    1190      * @throws ConversionException is thrown if the key maps to an
    1191      *         object that is not a Date.
    1192      */
    1193     public Date getDate(String key)
    1194     {
    1195         return (Date) get(Date.class, key);
    1196     }
    1197
    1198     /***
    1199      * Get a Date associated with the given configuration key. If the property
    1200      * is a String, it will be parsed with the specified format pattern.
    1201      *
    1202      * @param key    The configuration key.
    1203      * @param format The non-localized {@link java.text.DateFormat} pattern.
    1204      * @return The associated Date
    1205      *
    1206      * @throws ConversionException is thrown if the key maps to an
    1207      *         object that is not a Date.
    1208      */
    1209     public Date getDate(String key, String format)
    1210     {
    1211         Date value = getDate(key, null, format);
    1212         if (value != null)
    1213         {
    1214             return value;
    1215         }
    1216         else if (isThrowExceptionOnMissing())
    1217         {
    1218             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
    1219         }
    1220         else
    1221         {
    1222             return null;
    1223         }
    1224     }
    1225
    1226     /***
    1227      * Get a Date associated with the given configuration key. If the property
    1228      * is a String, it will be parsed with the format defined by the user in
    1229      * the {@link #DATE_FORMAT_KEY} property, or if it's not defined with the
    1230      * {@link #DEFAULT_DATE_FORMAT} pattern. If the key doesn't map to an
    1231      * existing object, the default value is returned.
    1232      *
    1233      * @param key          The configuration key.
    1234      * @param defaultValue The default value.
    1235      * @return The associated Date.
    1236      *
    1237      * @throws ConversionException is thrown if the key maps to an
    1238      *         object that is not a Date.
    1239      */
    1240     public Date getDate(String key, Date defaultValue)
    1241     {
    1242         return getDate(key, defaultValue, getDefaultDateFormat());
    1243     }
    1244
    1245     /***
    1246      * Get a Date associated with the given configuration key. If the property
    1247      * is a String, it will be parsed with the specified format pattern.
    1248      * If the key doesn't map to an existing object, the default value
    1249      * is returned.
    1250      *
    1251      * @param key          The configuration key.
    1252      * @param defaultValue The default value.
    1253      * @param format       The non-localized {@link java.text.DateFormat} pattern.
    1254      * @return The associated Date.
    1255      *
    1256      * @throws ConversionException is thrown if the key maps to an
    1257      *         object that is not a Date.
    1258      */
    1259     public Date getDate(String key, Date defaultValue, String format)
    1260     {
    1261         Object value = resolveContainerStore(key);
    1262
    1263         if (value == null)
    1264         {
    1265             return defaultValue;
    1266         }
    1267         else
    1268         {
    1269             try
    1270             {
    1271                 return PropertyConverter.toDate(interpolate(value), format);
    1272             }
    1273             catch (ConversionException e)
    1274             {
    1275                 throw new ConversionException('\'' + key + "' doesn't map to a Date", e);
    1276             }
    1277         }
    1278     }
    1279
    1280     /***
    1281      * Get a list of Dates associated with the given configuration key.
    1282      * If the property is a list of Strings, they will be parsed with the
    1283      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
    1284      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1285      * If the key doesn't map to an existing object an empty list is returned.
    1286      *
    1287      * @param key The configuration key.
    1288      * @return The associated Date list if the key is found.
    1289      *
    1290      * @throws ConversionException is thrown if the key maps to an
    1291      *         object that is not a list of Dates.
    1292      */
    1293     public List getDateList(String key)
    1294     {
    1295         return getDateList(key, new ArrayList());
    1296     }
    1297
    1298     /***
    1299      * Get a list of Dates associated with the given configuration key.
    1300      * If the property is a list of Strings, they will be parsed with the
    1301      * specified format pattern. If the key doesn't map to an existing object
    1302      * an empty list is returned.
    1303      *
    1304      * @param key    The configuration key.
    1305      * @param format The non-localized {@link java.text.DateFormat} pattern.
    1306      * @return The associated Date list if the key is found.
    1307      *
    1308      * @throws ConversionException is thrown if the key maps to an
    1309      *         object that is not a list of Dates.
    1310      */
    1311     public List getDateList(String key, String format)
    1312     {
    1313         return getDateList(key, new ArrayList(), format);
    1314     }
    1315
    1316     /***
    1317      * Get a list of Dates associated with the given configuration key.
    1318      * If the property is a list of Strings, they will be parsed with the
    1319      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
    1320      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1321      * If the key doesn't map to an existing object, the default value is
    1322      * returned.
    1323      *
    1324      * @param key          The configuration key.
    1325      * @param defaultValue The default value.
    1326      * @return The associated Date list if the key is found.
    1327      *
    1328      * @throws ConversionException is thrown if the key maps to an
    1329      *         object that is not a list of Dates.
    1330      */
    1331     public List getDateList(String key, List defaultValue)
    1332     {
    1333         return getDateList(key, defaultValue, getDefaultDateFormat());
    1334     }
    1335
    1336     /***
    1337      * Get a list of Dates associated with the given configuration key.
    1338      * If the property is a list of Strings, they will be parsed with the
    1339      * specified format pattern. If the key doesn't map to an existing object,
    1340      * the default value is returned.
    1341      *
    1342      * @param key          The configuration key.
    1343      * @param defaultValue The default value.
    1344      * @param format       The non-localized {@link java.text.DateFormat} pattern.
    1345      * @return The associated Date list if the key is found.
    1346      *
    1347      * @throws ConversionException is thrown if the key maps to an
    1348      *         object that is not a list of Dates.
    1349      */
    1350     public List getDateList(String key, List defaultValue, String format)
    1351     {
    1352         Object value = getProperty(key);
    1353
    1354         List list;
    1355
    1356         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
    1357         {
    1358             list = defaultValue;
    1359         }
    1360         else if (value.getClass().isArray())
    1361         {
    1362             list = new ArrayList();
    1363             int length = Array.getLength(value);
    1364             for (int i = 0; i < length; i++)
    1365             {
    1366                 list.add(PropertyConverter.toDate(interpolate(Array.get(value, i)), format));
    1367             }
    1368         }
    1369         else if (value instanceof Collection)
    1370         {
    1371             Collection values = (Collection) value;
    1372             list = new ArrayList();
    1373
    1374             Iterator it = values.iterator();
    1375             while (it.hasNext())
    1376             {
    1377                 list.add(PropertyConverter.toDate(interpolate(it.next()), format));
    1378             }
    1379         }
    1380         else
    1381         {
    1382             try
    1383             {
    1384                 // attempt to convert a single value
    1385                 list = new ArrayList();
    1386                 list.add(PropertyConverter.toDate(interpolate(value), format));
    1387             }
    1388             catch (ConversionException e)
    1389             {
    1390                 throw new ConversionException('\'' + key + "' doesn't map to a list of Dates", e);
    1391             }
    1392         }
    1393
    1394         return list;
    1395     }
    1396
    1397     /***
    1398      * Get an array of Dates associated with the given configuration key.
    1399      * If the property is a list of Strings, they will be parsed with the
    1400      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
    1401      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1402      * If the key doesn't map to an existing object an empty array is returned.
    1403      *
    1404      * @param key The configuration key.
    1405      * @return The associated Date array if the key is found.
    1406      *
    1407      * @throws ConversionException is thrown if the key maps to an
    1408      *         object that is not a list of Dates.
    1409      */
    1410     public Date[] getDateArray(String key)
    1411     {
    1412         return getDateArray(key, new Date[0]);
    1413     }
    1414
    1415     /***
    1416      * Get an array of Dates associated with the given configuration key.
    1417      * If the property is a list of Strings, they will be parsed with the
    1418      * specified format pattern. If the key doesn't map to an existing object
    1419      * an empty array is returned.
    1420      *
    1421      * @param key    The configuration key.
    1422      * @param format The non-localized {@link java.text.DateFormat} pattern.
    1423      * @return The associated Date array if the key is found.
    1424      *
    1425      * @throws ConversionException is thrown if the key maps to an
    1426      *         object that is not a list of Dates.
    1427      */
    1428     public Date[] getDateArray(String key, String format)
    1429     {
    1430         return getDateArray(key, new Date[0], format);
    1431     }
    1432
    1433     /***
    1434      * Get an array of Dates associated with the given configuration key.
    1435      * If the property is a list of Strings, they will be parsed with the
    1436      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
    1437      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1438      * If the key doesn't map to an existing object an empty array is returned.
    1439      *
    1440      * @param key The configuration key.
    1441      * @param defaultValue the default value, which will be returned if the property is not found
    1442      * @return The associated Date array if the key is found.
    1443      *
    1444      * @throws ConversionException is thrown if the key maps to an
    1445      *         object that is not a list of Dates.
    1446      */
    1447     public Date[] getDateArray(String key, Date[] defaultValue)
    1448     {
    1449         return getDateArray(key, defaultValue, getDefaultDateFormat());
    1450     }
    1451
    1452     /***
    1453      * Get an array of Dates associated with the given configuration key.
    1454      * If the property is a list of Strings, they will be parsed with the
    1455      * specified format pattern. If the key doesn't map to an existing object,
    1456      * the default value is returned.
    1457      *
    1458      * @param key          The configuration key.
    1459      * @param defaultValue The default value.
    1460      * @param format       The non-localized {@link java.text.DateFormat} pattern.
    1461      * @return The associated Date array if the key is found.
    1462      *
    1463      * @throws ConversionException is thrown if the key maps to an
    1464      *         object that is not a list of Dates.
    1465      */
    1466     public Date[] getDateArray(String key, Date[] defaultValue, String format)
    1467     {
    1468         List list = getDateList(key, format);
    1469         if (list.isEmpty())
    1470         {
    1471             return defaultValue;
    1472         }
    1473         else
    1474         {
    1475             return (Date[]) list.toArray(new Date[list.size()]);
    1476         }
    1477     }
    1478
    1479     /***
    1480      * Get a Calendar associated with the given configuration key. If the
    1481      * property is a String, it will be parsed with the format defined by the
    1482      * user in the {@link #DATE_FORMAT_KEY} property, or if it's not defined
    1483      * with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1484      *
    1485      * @param key The configuration key.
    1486      * @return The associated Calendar.
    1487      *
    1488      * @throws ConversionException is thrown if the key maps to an
    1489      *         object that is not a Calendar.
    1490      */
    1491     public Calendar getCalendar(String key)
    1492     {
    1493         return (Calendar) get(Calendar.class, key);
    1494     }
    1495
    1496     /***
    1497      * Get a Calendar associated with the given configuration key. If the
    1498      * property is a String, it will be parsed with the specified format
    1499      * pattern.
    1500      *
    1501      * @param key    The configuration key.
    1502      * @param format The non-localized {@link java.text.DateFormat} pattern.
    1503      * @return The associated Calendar
    1504      *
    1505      * @throws ConversionException is thrown if the key maps to an
    1506      *         object that is not a Calendar.
    1507      */
    1508     public Calendar getCalendar(String key, String format)
    1509     {
    1510         Calendar value = getCalendar(key, null, format);
    1511         if (value != null)
    1512         {
    1513             return value;
    1514         }
    1515         else if (isThrowExceptionOnMissing())
    1516         {
    1517             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
    1518         }
    1519         else
    1520         {
    1521             return null;
    1522         }
    1523     }
    1524
    1525     /***
    1526      * Get a Calendar associated with the given configuration key. If the
    1527      * property is a String, it will be parsed with the format defined by the
    1528      * user in the {@link #DATE_FORMAT_KEY} property, or if it's not defined
    1529      * with the {@link #DEFAULT_DATE_FORMAT} pattern. If the key doesn't map
    1530      * to an existing object, the default value is returned.
    1531      *
    1532      * @param key          The configuration key.
    1533      * @param defaultValue The default value.
    1534      * @return The associated Calendar.
    1535      *
    1536      * @throws ConversionException is thrown if the key maps to an
    1537      *         object that is not a Calendar.
    1538      */
    1539     public Calendar getCalendar(String key, Calendar defaultValue)
    1540     {
    1541         return getCalendar(key, defaultValue, getDefaultDateFormat());
    1542     }
    1543
    1544     /***
    1545      * Get a Calendar associated with the given configuration key. If the
    1546      * property is a String, it will be parsed with the specified format
    1547      * pattern. If the key doesn't map to an existing object, the default
    1548      * value is returned.
    1549      *
    1550      * @param key          The configuration key.
    1551      * @param defaultValue The default value.
    1552      * @param format       The non-localized {@link java.text.DateFormat} pattern.
    1553      * @return The associated Calendar.
    1554      *
    1555      * @throws ConversionException is thrown if the key maps to an
    1556      *         object that is not a Calendar.
    1557      */
    1558     public Calendar getCalendar(String key, Calendar defaultValue, String format)
    1559     {
    1560         Object value = resolveContainerStore(key);
    1561
    1562         if (value == null)
    1563         {
    1564             return defaultValue;
    1565         }
    1566         else
    1567         {
    1568             try
    1569             {
    1570                 return PropertyConverter.toCalendar(interpolate(value), format);
    1571             }
    1572             catch (ConversionException e)
    1573             {
    1574                 throw new ConversionException('\'' + key + "' doesn't map to a Calendar", e);
    1575             }
    1576         }
    1577     }
    1578
    1579     /***
    1580      * Get a list of Calendars associated with the given configuration key.
    1581      * If the property is a list of Strings, they will be parsed with the
    1582      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
    1583      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1584      * If the key doesn't map to an existing object an empty list is returned.
    1585      *
    1586      * @param key The configuration key.
    1587      * @return The associated Calendar list if the key is found.
    1588      *
    1589      * @throws ConversionException is thrown if the key maps to an
    1590      *         object that is not a list of Calendars.
    1591      */
    1592     public List getCalendarList(String key)
    1593     {
    1594         return getCalendarList(key, new ArrayList());
    1595     }
    1596
    1597     /***
    1598      * Get a list of Calendars associated with the given configuration key.
    1599      * If the property is a list of Strings, they will be parsed with the
    1600      * specified format pattern. If the key doesn't map to an existing object
    1601      * an empty list is returned.
    1602      *
    1603      * @param key    The configuration key.
    1604      * @param format The non-localized {@link java.text.DateFormat} pattern.
    1605      * @return The associated Calendar list if the key is found.
    1606      *
    1607      * @throws ConversionException is thrown if the key maps to an
    1608      *         object that is not a list of Calendars.
    1609      */
    1610     public List getCalendarList(String key, String format)
    1611     {
    1612         return getCalendarList(key, new ArrayList(), format);
    1613     }
    1614
    1615     /***
    1616      * Get a list of Calendars associated with the given configuration key.
    1617      * If the property is a list of Strings, they will be parsed with the
    1618      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
    1619      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1620      * If the key doesn't map to an existing object, the default value is
    1621      * returned.
    1622      *
    1623      * @param key The configuration key.
    1624      * @param defaultValue The default value.
    1625      * @return The associated Calendar list if the key is found.
    1626      *
    1627      * @throws ConversionException is thrown if the key maps to an
    1628      *         object that is not a list of Calendars.
    1629      */
    1630     public List getCalendarList(String key, List defaultValue)
    1631     {
    1632         return getCalendarList(key, defaultValue, getDefaultDateFormat());
    1633     }
    1634
    1635     /***
    1636      * Get a list of Calendars associated with the given configuration key.
    1637      * If the property is a list of Strings, they will be parsed with the
    1638      * specified format pattern. If the key doesn't map to an existing object,
    1639      * the default value is returned.
    1640      *
    1641      * @param key          The configuration key.
    1642      * @param defaultValue The default value.
    1643      * @param format       The non-localized {@link java.text.DateFormat} pattern.
    1644      * @return The associated Calendar list if the key is found.
    1645      *
    1646      * @throws ConversionException is thrown if the key maps to an
    1647      *         object that is not a list of Calendars.
    1648      */
    1649     public List getCalendarList(String key, List defaultValue, String format)
    1650     {
    1651         Object value = getProperty(key);
    1652
    1653         List list;
    1654
    1655         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
    1656         {
    1657             list = defaultValue;
    1658         }
    1659         else if (value.getClass().isArray())
    1660         {
    1661             list = new ArrayList();
    1662             int length = Array.getLength(value);
    1663             for (int i = 0; i < length; i++)
    1664             {
    1665                 list.add(PropertyConverter.toCalendar(interpolate(Array.get(value, i)), format));
    1666             }
    1667         }
    1668         else if (value instanceof Collection)
    1669         {
    1670             Collection values = (Collection) value;
    1671             list = new ArrayList();
    1672
    1673             Iterator it = values.iterator();
    1674             while (it.hasNext())
    1675             {
    1676                 list.add(PropertyConverter.toCalendar(interpolate(it.next()), format));
    1677             }
    1678         }
    1679         else
    1680         {
    1681             try
    1682             {
    1683                 // attempt to convert a single value
    1684                 list = new ArrayList();
    1685                 list.add(PropertyConverter.toCalendar(interpolate(value), format));
    1686             }
    1687             catch (ConversionException e)
    1688             {
    1689                 throw new ConversionException('\'' + key + "' doesn't map to a list of Calendars", e);
    1690             }
    1691         }
    1692
    1693         return list;
    1694     }
    1695
    1696     /***
    1697      * Get an array of Calendars associated with the given configuration key.
    1698      * If the property is a list of Strings, they will be parsed with the
    1699      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
    1700      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1701      * If the key doesn't map to an existing object an empty array is returned.
    1702      *
    1703      * @param key The configuration key.
    1704      * @return The associated Calendar array if the key is found.
    1705      *
    1706      * @throws ConversionException is thrown if the key maps to an
    1707      *         object that is not a list of Calendars.
    1708      */
    1709     public Calendar[] getCalendarArray(String key)
    1710     {
    1711         return getCalendarArray(key, new Calendar[0]);
    1712     }
    1713
    1714     /***
    1715      * Get an array of Calendars associated with the given configuration key.
    1716      * If the property is a list of Strings, they will be parsed with the
    1717      * specified format pattern. If the key doesn't map to an existing object
    1718      * an empty array is returned.
    1719      *
    1720      * @param key    The configuration key.
    1721      * @param format The non-localized {@link java.text.DateFormat} pattern.
    1722      * @return The associated Calendar array if the key is found.
    1723      *
    1724      * @throws ConversionException is thrown if the key maps to an
    1725      *         object that is not a list of Calendars.
    1726      */
    1727     public Calendar[] getCalendarArray(String key, String format)
    1728     {
    1729         return getCalendarArray(key, new Calendar[0], format);
    1730     }
    1731
    1732     /***
    1733      * Get an array of Calendars associated with the given configuration key.
    1734      * If the property is a list of Strings, they will be parsed with the
    1735      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
    1736      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
    1737      * If the key doesn't map to an existing object an empty array is returned.
    1738      *
    1739      * @param key The configuration key.
    1740      * @param defaultValue the default value, which will be returned if the property is not found
    1741      * @return The associated Calendar array if the key is found.
    1742      *
    1743      * @throws ConversionException is thrown if the key maps to an
    1744      *         object that is not a list of Calendars.
    1745      */
    1746     public Calendar[] getCalendarArray(String key, Calendar[] defaultValue)
    1747     {
    1748         return getCalendarArray(key, defaultValue, getDefaultDateFormat());
    1749     }
    1750
    1751     /***
    1752      * Get an array of Calendars associated with the given configuration key.
    1753      * If the property is a list of Strings, they will be parsed with the
    1754      * specified format pattern. If the key doesn't map to an existing object,
    1755      * the default value is returned.
    1756      *
    1757      * @param key          The configuration key.
    1758      * @param defaultValue The default value.
    1759      * @param format       The non-localized {@link java.text.DateFormat} pattern.
    1760      * @return The associated Calendar array if the key is found.
    1761      *
    1762      * @throws ConversionException is thrown if the key maps to an
    1763      *         object that is not a list of Calendars.
    1764      */
    1765     public Calendar[] getCalendarArray(String key, Calendar[] defaultValue, String format)
    1766     {
    1767         List list = getCalendarList(key, format);
    1768         if (list.isEmpty())
    1769         {
    1770             return defaultValue;
    1771         }
    1772         else
    1773         {
    1774             return (Calendar[]) list.toArray(new Calendar[list.size()]);
    1775         }
    1776     }
    1777
    1778     /***
    1779      * Returns the date format specified by the user in the DATE_FORMAT_KEY
    1780      * property, or the default format otherwise.
    1781      *
    1782      * @return the default date format
    1783      */
    1784     private String getDefaultDateFormat()
    1785     {
    1786         return getString(DATE_FORMAT_KEY, DEFAULT_DATE_FORMAT);
    1787     }
    1788
    1789     /***
    1790      * Get a Locale associated with the given configuration key.
    1791      *
    1792      * @param key The configuration key.
    1793      * @return The associated Locale.
    1794      *
    1795      * @throws ConversionException is thrown if the key maps to an
    1796      *         object that is not a Locale.
    1797      */
    1798     public Locale getLocale(String key)
    1799     {
    1800         return (Locale) get(Locale.class, key);
    1801     }
    1802
    1803     /***
    1804      * Get a Locale associated with the given configuration key.
    1805      * If the key doesn't map to an existing object, the default value
    1806      * is returned.
    1807      *
    1808      * @param key          The configuration key.
    1809      * @param defaultValue The default value.
    1810      * @return The associated Locale.
    1811      *
    1812      * @throws ConversionException is thrown if the key maps to an
    1813      *         object that is not a Locale.
    1814      */
    1815     public Locale getLocale(String key, Locale defaultValue)
    1816     {
    1817         return (Locale) get(Locale.class, key, defaultValue);
    1818     }
    1819
    1820     /***
    1821      * Get a list of Locales associated with the given configuration key.
    1822      * If the key doesn't map to an existing object an empty list is returned.
    1823      *
    1824      * @param key The configuration key.
    1825      * @return The associated Locale list if the key is found.
    1826      *
    1827      * @throws ConversionException is thrown if the key maps to an
    1828      *         object that is not a list of Locales.
    1829      */
    1830     public List getLocaleList(String key)
    1831     {
    1832         return getLocaleList(key, new ArrayList());
    1833     }
    1834
    1835     /***
    1836      * Get a list of Locales associated with the given configuration key.
    1837      * If the key doesn't map to an existing object, the default value is
    1838      * returned.
    1839      *
    1840      * @param key The configuration key.
    1841      * @param defaultValue The default value.
    1842      * @return The associated List of Locales.
    1843      *
    1844      * @throws ConversionException is thrown if the key maps to an
    1845      *         object that is not a list of Locales.
    1846      */
    1847     public List getLocaleList(String key, List defaultValue)
    1848     {
    1849         return getList(Locale.class, key, defaultValue);
    1850     }
    1851
    1852     /***
    1853      * Get an array of Locales associated with the given
    1854      * configuration key. If the key doesn't map to an existing object
    1855      * an empty array is returned.
    1856      *
    1857      * @param key The configuration key.
    1858      * @return The associated Locale array if the key is found.
    1859      *
    1860      * @throws ConversionException is thrown if the key maps to an
    1861      *         object that is not a list of Locales.
    1862      */
    1863     public Locale[] getLocaleArray(String key)
    1864     {
    1865         return getLocaleArray(key, new Locale[0]);
    1866     }
    1867
    1868     /***
    1869      * Get an array of Locales associated with the given
    1870      * configuration key. If the key doesn't map to an existing object
    1871      * an empty array is returned.
    1872      *
    1873      * @param key The configuration key.
    1874      * @param defaultValue the default value, which will be returned if the property is not found
    1875      * @return The associated Locale array if the key is found.
    1876      *
    1877      * @throws ConversionException is thrown if the key maps to an
    1878      *         object that is not a list of Locales.
    1879      */
    1880     public Locale[] getLocaleArray(String key, Locale[] defaultValue)
    1881     {
    1882         return (Locale[]) getArray(Locale.class, key, defaultValue);
    1883     }
    1884
    1885     /***
    1886      * Get a Color associated with the given configuration key.
    1887      *
    1888      * @param key The configuration key.
    1889      * @return The associated Color.
    1890      *
    1891      * @throws ConversionException is thrown if the key maps to an
    1892      *         object that is not a Color.
    1893      */
    1894     public Color getColor(String key)
    1895     {
    1896         return (Color) get(Color.class, key);
    1897     }
    1898
    1899     /***
    1900      * Get a Color associated with the given configuration key.
    1901      * If the key doesn't map to an existing object, the default value
    1902      * is returned.
    1903      *
    1904      * @param key          The configuration key.
    1905      * @param defaultValue The default value.
    1906      * @return The associated Color.
    1907      *
    1908      * @throws ConversionException is thrown if the key maps to an
    1909      *         object that is not a Color.
    1910      */
    1911     public Color getColor(String key, Color defaultValue)
    1912     {
    1913         return (Color) get(Color.class, key, defaultValue);
    1914     }
    1915
    1916     /***
    1917      * Get a list of Colors associated with the given configuration key.
    1918      * If the key doesn't map to an existing object an empty list is returned.
    1919      *
    1920      * @param key The configuration key.
    1921      * @return The associated Color list if the key is found.
    1922      *
    1923      * @throws ConversionException is thrown if the key maps to an
    1924      *         object that is not a list of Colors.
    1925      */
    1926     public List getColorList(String key)
    1927     {
    1928         return getColorList(key, new ArrayList());
    1929     }
    1930
    1931     /***
    1932      * Get a list of Colors associated with the given configuration key.
    1933      * If the key doesn't map to an existing object, the default value is
    1934      * returned.
    1935      *
    1936      * @param key The configuration key.
    1937      * @param defaultValue The default value.
    1938      * @return The associated List of Colors.
    1939      *
    1940      * @throws ConversionException is thrown if the key maps to an
    1941      *         object that is not a list of Colors.
    1942      */
    1943     public List getColorList(String key, List defaultValue)
    1944     {
    1945         return getList(Color.class, key, defaultValue);
    1946     }
    1947
    1948     /***
    1949      * Get an array of Colors associated with the given
    1950      * configuration key. If the key doesn't map to an existing object
    1951      * an empty array is returned.
    1952      *
    1953      * @param key The configuration key.
    1954      * @return The associated Color array if the key is found.
    1955      *
    1956      * @throws ConversionException is thrown if the key maps to an
    1957      *         object that is not a list of Colors.
    1958      */
    1959     public Color[] getColorArray(String key)
    1960     {
    1961         return getColorArray(key, new Color[0]);
    1962     }
    1963
    1964     /***
    1965      * Get an array of Colors associated with the given
    1966      * configuration key. If the key doesn't map to an existing object
    1967      * an empty array is returned.
    1968      *
    1969      * @param key The configuration key.
    1970      * @param defaultValue the default value, which will be returned if the property is not found
    1971      * @return The associated Color array if the key is found.
    1972      *
    1973      * @throws ConversionException is thrown if the key maps to an
    1974      *         object that is not a list of Colors.
    1975      */
    1976     public Color[] getColorArray(String key, Color[] defaultValue)
    1977     {
    1978         return (Color[]) getArray(Color.class, key, defaultValue);
    1979     }
    1980
    1981 }