View Javadoc

1   /*
2    * Copyright 2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License")
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.configuration;
18  
19  import java.awt.Color;
20  import java.math.BigDecimal;
21  import java.math.BigInteger;
22  import java.net.URL;
23  import java.util.ArrayList;
24  import java.util.Calendar;
25  import java.util.Collection;
26  import java.util.Date;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.Locale;
30  
31  import org.apache.commons.collections.CollectionUtils;
32  import org.apache.commons.lang.ArrayUtils;
33  import org.apache.commons.lang.StringUtils;
34  
35  /***
36   * Decorator providing additional getters for any Configuration. This extended
37   * Configuration supports more types: URL, Locale, Date, Calendar, Color, as
38   * well as lists and arrays for all types.
39   *
40   * <p>Let us know if you find this useful, the most frequently used getters
41   * are likely to be integrated in the Configuration interface in a future
42   * version.</p>
43   *
44   * @author <a href="ebourg@apache.org">Emmanuel Bourg</a>
45   * @version $Revision: 155408 $, $Date: 2005-02-26 13:56:39 +0100 (Sa, 26 Feb 2005) $
46   * @since 1.1
47   */
48  public class DataConfiguration extends AbstractConfiguration
49  {
50      /*** The key of the property storing the user defined date format. */
51      public static final String DATE_FORMAT_KEY = "org.apache.commons.configuration.format.date";
52  
53      /*** The default format for dates. */
54      public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
55  
56      protected Configuration configuration;
57  
58      public DataConfiguration(Configuration configuration)
59      {
60          this.configuration = configuration;
61      }
62  
63      /***
64       * Return the configuration decorated by this DataConfiguration.
65       */
66      public Configuration getConfiguration()
67      {
68          return configuration;
69      }
70  
71      public Object getProperty(String key)
72      {
73          return configuration.getProperty(key);
74      }
75  
76      protected void addPropertyDirect(String key, Object obj)
77      {
78          configuration.addProperty(key, obj);
79      }
80  
81      public boolean isEmpty()
82      {
83          return configuration.isEmpty();
84      }
85  
86      public boolean containsKey(String key)
87      {
88          return configuration.containsKey(key);
89      }
90  
91      public void clearProperty(String key)
92      {
93          configuration.clearProperty(key);
94      }
95  
96      public Iterator getKeys()
97      {
98          return configuration.getKeys();
99      }
100 
101     /***
102      * Get a list of Boolean objects associated with the given
103      * configuration key. If the key doesn't map to an existing object
104      * an empty list is returned.
105      *
106      * @param key The configuration key.
107      * @return The associated Boolean list if the key is found.
108      *
109      * @throws ConversionException is thrown if the key maps to an
110      *         object that is not a list of booleans.
111      */
112     public List getBooleanList(String key)
113     {
114         return getBooleanList(key, new ArrayList());
115     }
116 
117     /***
118      * Get a list of Boolean objects associated with the given
119      * configuration key. If the key doesn't map to an existing object,
120      * the default value is returned.
121      *
122      * @param key The configuration key.
123      * @param defaultValue The default value.
124      * @return The associated List of strings.
125      *
126      * @throws ConversionException is thrown if the key maps to an
127      *         object that is not a list of booleans.
128      */
129     public List getBooleanList(String key, List defaultValue)
130     {
131         Object value = getProperty(key);
132 
133         List list = null;
134 
135         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
136         {
137             list = defaultValue;
138         }
139         else if (value instanceof boolean[])
140         {
141             list = new ArrayList();
142             CollectionUtils.addAll(list, ArrayUtils.toObject((boolean[]) value));
143         }
144         else if (value instanceof Boolean[])
145         {
146             list = new ArrayList();
147             CollectionUtils.addAll(list, (Boolean[]) value);
148         }
149         else if (value instanceof Collection)
150         {
151             Collection values = (Collection) value;
152             list = new ArrayList();
153 
154             Iterator it = values.iterator();
155             while (it.hasNext())
156             {
157                 list.add(PropertyConverter.toBoolean(it.next()));
158             }
159         }
160         else
161         {
162             try
163             {
164                 // attempt to convert a single value
165                 list = new ArrayList();
166                 list.add(PropertyConverter.toBoolean(value));
167             }
168             catch (ConversionException e)
169             {
170                 throw new ConversionException('\'' + key + "' doesn't map to a list of booleans", e);
171             }
172         }
173 
174         return list;
175     }
176 
177     /***
178      * Get an array of boolean primitives associated with the given
179      * configuration key. If the key doesn't map to an existing object
180      * an empty array is returned.
181      *
182      * @param key The configuration key.
183      * @return The associated boolean array if the key is found.
184      *
185      * @throws ConversionException is thrown if the key maps to an
186      *         object that is not a list of booleans.
187      */
188     public boolean[] getBooleanArray(String key)
189     {
190         return getBooleanArray(key, new boolean[0]);
191     }
192 
193     /***
194      * Get an array of boolean primitives associated with the given
195      * configuration key. If the key doesn't map to an existing object,
196      * the default value is returned.
197      *
198      * @param key          The configuration key.
199      * @param defaultValue The default value.
200      * @return The associated boolean array if the key is found.
201      *
202      * @throws ConversionException is thrown if the key maps to an
203      *         object that is not a list of booleans.
204      */
205     public boolean[] getBooleanArray(String key, boolean[] defaultValue)
206     {
207         Object value = getProperty(key);
208 
209         boolean[] array;
210 
211         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
212         {
213             array = defaultValue;
214         }
215         else if (value instanceof boolean[])
216         {
217             array = (boolean[]) value;
218         }
219         else if (value instanceof Boolean[])
220         {
221             array = ArrayUtils.toPrimitive((Boolean[]) value);
222         }
223         else if (value instanceof Collection)
224         {
225             Collection values = (Collection) value;
226             array = new boolean[values.size()];
227 
228             int i = 0;
229             Iterator it = values.iterator();
230             while (it.hasNext())
231             {
232                 array[i++] = PropertyConverter.toBoolean(it.next()).booleanValue();
233             }
234         }
235         else
236         {
237             try
238             {
239                 // attempt to convert a single value
240                 array = new boolean[1];
241                 array[0] = PropertyConverter.toBoolean(value).booleanValue();
242             }
243             catch (ConversionException e)
244             {
245                 throw new ConversionException('\'' + key + "' doesn't map to a list of booleans", e);
246             }
247         }
248 
249         return array;
250     }
251 
252     /***
253      * Get a list of Byte objects associated with the given configuration key.
254      * If the key doesn't map to an existing object an empty list is returned.
255      *
256      * @param key The configuration key.
257      * @return The associated Byte list if the key is found.
258      *
259      * @throws ConversionException is thrown if the key maps to an
260      *         object that is not a list of bytes.
261      */
262     public List getByteList(String key)
263     {
264         return getByteList(key, new ArrayList());
265     }
266 
267     /***
268      * Get a list of Byte objects associated with the given configuration key.
269      * If the key doesn't map to an existing object, the default value is
270      * returned.
271      *
272      * @param key The configuration key.
273      * @param defaultValue The default value.
274      * @return The associated List of Bytes.
275      *
276      * @throws ConversionException is thrown if the key maps to an
277      *         object that is not a list of bytes.
278      */
279     public List getByteList(String key, List defaultValue)
280     {
281         Object value = getProperty(key);
282 
283         List list = null;
284 
285         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
286         {
287             list = defaultValue;
288         }
289         else if (value instanceof byte[])
290         {
291             list = new ArrayList();
292             CollectionUtils.addAll(list, ArrayUtils.toObject((byte[]) value));
293         }
294         else if (value instanceof Byte[])
295         {
296             list = new ArrayList();
297             CollectionUtils.addAll(list, (Byte[]) value);
298         }
299         else if (value instanceof Collection)
300         {
301             Collection values = (Collection) value;
302             list = new ArrayList();
303 
304             Iterator it = values.iterator();
305             while (it.hasNext())
306             {
307                 list.add(PropertyConverter.toByte(it.next()));
308             }
309         }
310         else
311         {
312             try
313             {
314                 // attempt to convert a single value
315                 list = new ArrayList();
316                 list.add(PropertyConverter.toByte(value));
317             }
318             catch (ConversionException e)
319             {
320                 throw new ConversionException('\'' + key + "' doesn't map to a list of bytes", e);
321             }
322         }
323 
324         return list;
325     }
326 
327     /***
328      * Get an array of byte primitives associated with the given
329      * configuration key. If the key doesn't map to an existing object
330      * an empty array is returned.
331      *
332      * @param key The configuration key.
333      * @return The associated byte array if the key is found.
334      *
335      * @throws ConversionException is thrown if the key maps to an
336      *         object that is not a list of bytes.
337      */
338     public byte[] getByteArray(String key)
339     {
340         return getByteArray(key, new byte[0]);
341     }
342 
343     /***
344      * Get an array of byte primitives associated with the given
345      * configuration key. If the key doesn't map to an existing object
346      * an empty array is returned.
347      *
348      * @param key The configuration key.
349      * @return The associated byte array if the key is found.
350      *
351      * @throws ConversionException is thrown if the key maps to an
352      *         object that is not a list of bytes.
353      */
354     public byte[] getByteArray(String key, byte[] defaultValue)
355     {
356         Object value = getProperty(key);
357 
358         byte[] array;
359 
360         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
361         {
362             array = defaultValue;
363         }
364         else if (value instanceof byte[])
365         {
366             array = (byte[]) value;
367         }
368         else if (value instanceof Byte[])
369         {
370             array = ArrayUtils.toPrimitive((Byte[]) value);
371         }
372         else if (value instanceof Collection)
373         {
374             Collection values = (Collection) value;
375             array = new byte[values.size()];
376 
377             int i = 0;
378             Iterator it = values.iterator();
379             while (it.hasNext())
380             {
381                 array[i++] = PropertyConverter.toByte(it.next()).byteValue();
382             }
383         }
384         else
385         {
386             try
387             {
388                 // attempt to convert a single value
389                 array = new byte[1];
390                 array[0] = PropertyConverter.toByte(value).byteValue();
391             }
392             catch (ConversionException e)
393             {
394                 throw new ConversionException('\'' + key + "' doesn't map to a list of bytes", e);
395             }
396         }
397 
398         return array;
399     }
400 
401     /***
402      * Get a list of Short objects associated with the given configuration key.
403      * If the key doesn't map to an existing object an empty list is returned.
404      *
405      * @param key The configuration key.
406      * @return The associated Short list if the key is found.
407      *
408      * @throws ConversionException is thrown if the key maps to an
409      *         object that is not a list of shorts.
410      */
411     public List getShortList(String key)
412     {
413         return getShortList(key, new ArrayList());
414     }
415 
416     /***
417      * Get a list of Short objects associated with the given configuration key.
418      * If the key doesn't map to an existing object, the default value is
419      * returned.
420      *
421      * @param key The configuration key.
422      * @param defaultValue The default value.
423      * @return The associated List of Shorts.
424      *
425      * @throws ConversionException is thrown if the key maps to an
426      *         object that is not a list of shorts.
427      */
428     public List getShortList(String key, List defaultValue)
429     {
430         Object value = getProperty(key);
431 
432         List list = null;
433 
434         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
435         {
436             list = defaultValue;
437         }
438         else if (value instanceof short[])
439         {
440             list = new ArrayList();
441             CollectionUtils.addAll(list, ArrayUtils.toObject((short[]) value));
442         }
443         else if (value instanceof Short[])
444         {
445             list = new ArrayList();
446             CollectionUtils.addAll(list, (Short[]) value);
447         }
448         else if (value instanceof Collection)
449         {
450             Collection values = (Collection) value;
451             list = new ArrayList();
452 
453             Iterator it = values.iterator();
454             while (it.hasNext())
455             {
456                 list.add(PropertyConverter.toShort(it.next()));
457             }
458         }
459         else
460         {
461             try
462             {
463                 // attempt to convert a single value
464                 list = new ArrayList();
465                 list.add(PropertyConverter.toShort(value));
466             }
467             catch (ConversionException e)
468             {
469                 throw new ConversionException('\'' + key + "' doesn't map to a list of shorts", e);
470             }
471         }
472 
473         return list;
474     }
475 
476     /***
477      * Get an array of short primitives associated with the given
478      * configuration key. If the key doesn't map to an existing object
479      * an empty array is returned.
480      *
481      * @param key The configuration key.
482      * @return The associated short array if the key is found.
483      *
484      * @throws ConversionException is thrown if the key maps to an
485      *         object that is not a list of shorts.
486      */
487     public short[] getShortArray(String key)
488     {
489         return getShortArray(key, new short[0]);
490     }
491 
492     /***
493      * Get an array of short primitives associated with the given
494      * configuration key. If the key doesn't map to an existing object
495      * an empty array is returned.
496      *
497      * @param key The configuration key.
498      * @return The associated short array if the key is found.
499      *
500      * @throws ConversionException is thrown if the key maps to an
501      *         object that is not a list of shorts.
502      */
503     public short[] getShortArray(String key, short[] defaultValue)
504     {
505         Object value = getProperty(key);
506 
507         short[] array;
508 
509         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
510         {
511             array = defaultValue;
512         }
513         else if (value instanceof short[])
514         {
515             array = (short[]) value;
516         }
517         else if (value instanceof Short[])
518         {
519             array = ArrayUtils.toPrimitive((Short[]) value);
520         }
521         else if (value instanceof Collection)
522         {
523             Collection values = (Collection) value;
524             array = new short[values.size()];
525 
526             int i = 0;
527             Iterator it = values.iterator();
528             while (it.hasNext())
529             {
530                 array[i++] = PropertyConverter.toShort(it.next()).shortValue();
531             }
532         }
533         else
534         {
535             try
536             {
537                 // attempt to convert a single value
538                 array = new short[1];
539                 array[0] = PropertyConverter.toShort(value).shortValue();
540             }
541             catch (ConversionException e)
542             {
543                 throw new ConversionException('\'' + key + "' doesn't map to a list of shorts", e);
544             }
545         }
546 
547         return array;
548     }
549 
550     /***
551      * Get a list of Integer objects associated with the given
552      * configuration key. If the key doesn't map to an existing object
553      * an empty list is returned.
554      *
555      * @param key The configuration key.
556      * @return The associated Integer list if the key is found.
557      *
558      * @throws ConversionException is thrown if the key maps to an
559      *         object that is not a list of integers.
560      */
561     public List getIntegerList(String key)
562     {
563         return getIntegerList(key, new ArrayList());
564     }
565 
566     /***
567      * Get a list of Integer objects associated with the given
568      * configuration key. If the key doesn't map to an existing object,
569      * the default value is returned.
570      *
571      * @param key The configuration key.
572      * @param defaultValue The default value.
573      * @return The associated List of Integers.
574      *
575      * @throws ConversionException is thrown if the key maps to an
576      *         object that is not a list of integers.
577      */
578     public List getIntegerList(String key, List defaultValue)
579     {
580         Object value = getProperty(key);
581 
582         List list = null;
583 
584         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
585         {
586             list = defaultValue;
587         }
588         else if (value instanceof int[])
589         {
590             list = new ArrayList();
591             CollectionUtils.addAll(list, ArrayUtils.toObject((int[]) value));
592         }
593         else if (value instanceof Integer[])
594         {
595             list = new ArrayList();
596             CollectionUtils.addAll(list, (Integer[]) value);
597         }
598         else if (value instanceof Collection)
599         {
600             Collection values = (Collection) value;
601             list = new ArrayList();
602 
603             Iterator it = values.iterator();
604             while (it.hasNext())
605             {
606                 list.add(PropertyConverter.toInteger(it.next()));
607             }
608         }
609         else
610         {
611             try
612             {
613                 // attempt to convert a single value
614                 list = new ArrayList();
615                 list.add(PropertyConverter.toInteger(value));
616             }
617             catch (ConversionException e)
618             {
619                 throw new ConversionException('\'' + key + "' doesn't map to a list of integers", e);
620             }
621         }
622 
623         return list;
624     }
625 
626     /***
627      * Get an array of int primitives associated with the given
628      * configuration key. If the key doesn't map to an existing object
629      * an empty array is returned.
630      *
631      * @param key The configuration key.
632      * @return The associated int array if the key is found.
633      *
634      * @throws ConversionException is thrown if the key maps to an
635      *         object that is not a list of integers.
636      */
637     public int[] getIntArray(String key)
638     {
639         return getIntArray(key, new int[0]);
640     }
641 
642     /***
643      * Get an array of int primitives associated with the given
644      * configuration key. If the key doesn't map to an existing object
645      * an empty array is returned.
646      *
647      * @param key The configuration key.
648      * @return The associated int array if the key is found.
649      *
650      * @throws ConversionException is thrown if the key maps to an
651      *         object that is not a list of integers.
652      */
653     public int[] getIntArray(String key, int[] defaultValue)
654     {
655         Object value = getProperty(key);
656 
657         int[] array;
658 
659         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
660         {
661             array = defaultValue;
662         }
663         else if (value instanceof int[])
664         {
665             array = (int[]) value;
666         }
667         else if (value instanceof Integer[])
668         {
669             array = ArrayUtils.toPrimitive((Integer[]) value);
670         }
671         else if (value instanceof Collection)
672         {
673             Collection values = (Collection) value;
674             array = new int[values.size()];
675 
676             int i = 0;
677             Iterator it = values.iterator();
678             while (it.hasNext())
679             {
680                 array[i++] = PropertyConverter.toInteger(it.next()).intValue();
681             }
682         }
683         else
684         {
685             try
686             {
687                 // attempt to convert a single value
688                 array = new int[1];
689                 array[0] = PropertyConverter.toInteger(value).intValue();
690             }
691             catch (ConversionException e)
692             {
693                 throw new ConversionException('\'' + key + "' doesn't map to a list of integers", e);
694             }
695         }
696 
697         return array;
698     }
699 
700     /***
701      * Get a list of Long objects associated with the given configuration key.
702      * If the key doesn't map to an existing object an empty list is returned.
703      *
704      * @param key The configuration key.
705      * @return The associated Long list if the key is found.
706      *
707      * @throws ConversionException is thrown if the key maps to an
708      *         object that is not a list of longs.
709      */
710     public List getLongList(String key)
711     {
712         return getLongList(key, new ArrayList());
713     }
714 
715     /***
716      * Get a list of Long objects associated with the given configuration key.
717      * If the key doesn't map to an existing object, the default value is
718      * returned.
719      *
720      * @param key The configuration key.
721      * @param defaultValue The default value.
722      * @return The associated List of Longs.
723      *
724      * @throws ConversionException is thrown if the key maps to an
725      *         object that is not a list of longs.
726      */
727     public List getLongList(String key, List defaultValue)
728     {
729         Object value = getProperty(key);
730 
731         List list = null;
732 
733         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
734         {
735             list = defaultValue;
736         }
737         else if (value instanceof long[])
738         {
739             list = new ArrayList();
740             CollectionUtils.addAll(list, ArrayUtils.toObject((long[]) value));
741         }
742         else if (value instanceof Long[])
743         {
744             list = new ArrayList();
745             CollectionUtils.addAll(list, (Long[]) value);
746         }
747         else if (value instanceof Collection)
748         {
749             Collection values = (Collection) value;
750             list = new ArrayList();
751 
752             Iterator it = values.iterator();
753             while (it.hasNext())
754             {
755                 list.add(PropertyConverter.toLong(it.next()));
756             }
757         }
758         else
759         {
760             try
761             {
762                 // attempt to convert a single value
763                 list = new ArrayList();
764                 list.add(PropertyConverter.toLong(value));
765             }
766             catch (ConversionException e)
767             {
768                 throw new ConversionException('\'' + key + "' doesn't map to a list of longs", e);
769             }
770         }
771 
772         return list;
773     }
774 
775     /***
776      * Get an array of long primitives associated with the given
777      * configuration key. If the key doesn't map to an existing object
778      * an empty array is returned.
779      *
780      * @param key The configuration key.
781      * @return The associated long array if the key is found.
782      *
783      * @throws ConversionException is thrown if the key maps to an
784      *         object that is not a list of longs.
785      */
786     public long[] getLongArray(String key)
787     {
788         return getLongArray(key, new long[0]);
789     }
790 
791     /***
792      * Get an array of long primitives associated with the given
793      * configuration key. If the key doesn't map to an existing object
794      * an empty array is returned.
795      *
796      * @param key The configuration key.
797      * @return The associated long array if the key is found.
798      *
799      * @throws ConversionException is thrown if the key maps to an
800      *         object that is not a list of longs.
801      */
802     public long[] getLongArray(String key, long[] defaultValue)
803     {
804         Object value = getProperty(key);
805 
806         long[] array;
807 
808         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
809         {
810             array = defaultValue;
811         }
812         else if (value instanceof long[])
813         {
814             array = (long[]) value;
815         }
816         else if (value instanceof Long[])
817         {
818             array = ArrayUtils.toPrimitive((Long[]) value);
819         }
820         else if (value instanceof Collection)
821         {
822             Collection values = (Collection) value;
823             array = new long[values.size()];
824 
825             int i = 0;
826             Iterator it = values.iterator();
827             while (it.hasNext())
828             {
829                 array[i++] = PropertyConverter.toLong(it.next()).longValue();
830             }
831         }
832         else
833         {
834             try
835             {
836                 // attempt to convert a single value
837                 array = new long[1];
838                 array[0] = PropertyConverter.toLong(value).longValue();
839             }
840             catch (ConversionException e)
841             {
842                 throw new ConversionException('\'' + key + "' doesn't map to a list of longs", e);
843             }
844         }
845 
846         return array;
847     }
848 
849     /***
850      * Get a list of Float objects associated with the given configuration key.
851      * If the key doesn't map to an existing object an empty list is returned.
852      *
853      * @param key The configuration key.
854      * @return The associated Float list if the key is found.
855      *
856      * @throws ConversionException is thrown if the key maps to an
857      *         object that is not a list of floats.
858      */
859     public List getFloatList(String key)
860     {
861         return getFloatList(key, new ArrayList());
862     }
863 
864     /***
865      * Get a list of Float objects associated with the given
866      * configuration key. If the key doesn't map to an existing object,
867      * the default value is returned.
868      *
869      * @param key The configuration key.
870      * @param defaultValue The default value.
871      * @return The associated List of Floats.
872      *
873      * @throws ConversionException is thrown if the key maps to an
874      *         object that is not a list of floats.
875      */
876     public List getFloatList(String key, List defaultValue)
877     {
878         Object value = getProperty(key);
879 
880         List list = null;
881 
882         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
883         {
884             list = defaultValue;
885         }
886         else if (value instanceof float[])
887         {
888             list = new ArrayList();
889             CollectionUtils.addAll(list, ArrayUtils.toObject((float[]) value));
890         }
891         else if (value instanceof Float[])
892         {
893             list = new ArrayList();
894             CollectionUtils.addAll(list, (Float[]) value);
895         }
896         else if (value instanceof Collection)
897         {
898             Collection values = (Collection) value;
899             list = new ArrayList();
900 
901             Iterator it = values.iterator();
902             while (it.hasNext())
903             {
904                 list.add(PropertyConverter.toFloat(it.next()));
905             }
906         }
907         else
908         {
909             try
910             {
911                 // attempt to convert a single value
912                 list = new ArrayList();
913                 list.add(PropertyConverter.toFloat(value));
914             }
915             catch (ConversionException e)
916             {
917                 throw new ConversionException('\'' + key + "' doesn't map to a list of floats", e);
918             }
919         }
920 
921         return list;
922     }
923 
924     /***
925      * Get an array of float 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 float 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 floats.
934      */
935     public float[] getFloatArray(String key)
936     {
937         return getFloatArray(key, new float[0]);
938     }
939 
940     /***
941      * Get an array of float 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      * @return The associated float array if the key is found.
947      *
948      * @throws ConversionException is thrown if the key maps to an
949      *         object that is not a list of floats.
950      */
951     public float[] getFloatArray(String key, float[] defaultValue)
952     {
953         Object value = getProperty(key);
954 
955         float[] array;
956 
957         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
958         {
959             array = defaultValue;
960         }
961         else if (value instanceof float[])
962         {
963             array = (float[]) value;
964         }
965         else if (value instanceof Float[])
966         {
967             array = ArrayUtils.toPrimitive((Float[]) value);
968         }
969         else if (value instanceof Collection)
970         {
971             Collection values = (Collection) value;
972             array = new float[values.size()];
973 
974             int i = 0;
975             Iterator it = values.iterator();
976             while (it.hasNext())
977             {
978                 array[i++] = PropertyConverter.toFloat(it.next()).floatValue();
979             }
980         }
981         else
982         {
983             try
984             {
985                 // attempt to convert a single value
986                 array = new float[1];
987                 array[0] = PropertyConverter.toFloat(value).floatValue();
988             }
989             catch (ConversionException e)
990             {
991                 throw new ConversionException('\'' + key + "' doesn't map to a list of floats", e);
992             }
993         }
994 
995         return array;
996     }
997 
998     /***
999      * Get a list of Double objects associated with the given
1000      * configuration key. If the key doesn't map to an existing object
1001      * an empty list is returned.
1002      *
1003      * @param key The configuration key.
1004      * @return The associated Double list if the key is found.
1005      *
1006      * @throws ConversionException is thrown if the key maps to an
1007      *         object that is not a list of doubles.
1008      */
1009     public List getDoubleList(String key)
1010     {
1011         return getDoubleList(key, new ArrayList());
1012     }
1013 
1014     /***
1015      * Get a list of Double objects associated with the given
1016      * configuration key. If the key doesn't map to an existing object,
1017      * the default value is returned.
1018      *
1019      * @param key The configuration key.
1020      * @param defaultValue The default value.
1021      * @return The associated List of Doubles.
1022      *
1023      * @throws ConversionException is thrown if the key maps to an
1024      *         object that is not a list of doubles.
1025      */
1026     public List getDoubleList(String key, List defaultValue)
1027     {
1028         Object value = getProperty(key);
1029 
1030         List list = null;
1031 
1032         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
1033         {
1034             list = defaultValue;
1035         }
1036         else if (value instanceof double[])
1037         {
1038             list = new ArrayList();
1039             CollectionUtils.addAll(list, ArrayUtils.toObject((double[]) value));
1040         }
1041         else if (value instanceof Double[])
1042         {
1043             list = new ArrayList();
1044             CollectionUtils.addAll(list, (Double[]) value);
1045         }
1046         else if (value instanceof Collection)
1047         {
1048             Collection values = (Collection) value;
1049             list = new ArrayList();
1050 
1051             Iterator it = values.iterator();
1052             while (it.hasNext())
1053             {
1054                 list.add(PropertyConverter.toDouble(it.next()));
1055             }
1056         }
1057         else
1058         {
1059             try
1060             {
1061                 // attempt to convert a single value
1062                 list = new ArrayList();
1063                 list.add(PropertyConverter.toDouble(value));
1064             }
1065             catch (ConversionException e)
1066             {
1067                 throw new ConversionException('\'' + key + "' doesn't map to a list of doubles", e);
1068             }
1069         }
1070 
1071         return list;
1072     }
1073 
1074     /***
1075      * Get an array of double primitives associated with the given
1076      * configuration key. If the key doesn't map to an existing object
1077      * an empty array is returned.
1078      *
1079      * @param key The configuration key.
1080      * @return The associated double array if the key is found.
1081      *
1082      * @throws ConversionException is thrown if the key maps to an
1083      *         object that is not a list of doubles.
1084      */
1085     public double[] getDoubleArray(String key)
1086     {
1087         return getDoubleArray(key, new double[0]);
1088     }
1089 
1090     /***
1091      * Get an array of double primitives associated with the given
1092      * configuration key. If the key doesn't map to an existing object
1093      * an empty array is returned.
1094      *
1095      * @param key The configuration key.
1096      * @return The associated double array if the key is found.
1097      *
1098      * @throws ConversionException is thrown if the key maps to an
1099      *         object that is not a list of doubles.
1100      */
1101     public double[] getDoubleArray(String key, double[] defaultValue)
1102     {
1103         Object value = getProperty(key);
1104 
1105         double[] array;
1106 
1107         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
1108         {
1109             array = defaultValue;
1110         }
1111         else if (value instanceof double[])
1112         {
1113             array = (double[]) value;
1114         }
1115         else if (value instanceof Double[])
1116         {
1117             array = ArrayUtils.toPrimitive((Double[]) value);
1118         }
1119         else if (value instanceof Collection)
1120         {
1121             Collection values = (Collection) value;
1122             array = new double[values.size()];
1123 
1124             int i = 0;
1125             Iterator it = values.iterator();
1126             while (it.hasNext())
1127             {
1128                 array[i++] = PropertyConverter.toDouble(it.next()).doubleValue();
1129             }
1130         }
1131         else
1132         {
1133             try
1134             {
1135                 // attempt to convert a single value
1136                 array = new double[1];
1137                 array[0] = PropertyConverter.toDouble(value).doubleValue();
1138             }
1139             catch (ConversionException e)
1140             {
1141                 throw new ConversionException('\'' + key + "' doesn't map to a list of doubles", e);
1142             }
1143         }
1144 
1145         return array;
1146     }
1147 
1148     /***
1149      * Get a list of BigIntegers associated with the given configuration key.
1150      * If the key doesn't map to an existing object an empty list is returned.
1151      *
1152      * @param key The configuration key.
1153      * @return The associated BigInteger list if the key is found.
1154      *
1155      * @throws ConversionException is thrown if the key maps to an
1156      *         object that is not a list of BigIntegers.
1157      */
1158     public List getBigIntegerList(String key)
1159     {
1160         return getBigIntegerList(key, new ArrayList());
1161     }
1162 
1163     /***
1164      * Get a list of BigIntegers associated with the given configuration key.
1165      * If the key doesn't map to an existing object, the default value is
1166      * returned.
1167      *
1168      * @param key The configuration key.
1169      * @param defaultValue The default value.
1170      * @return The associated List of BigIntegers.
1171      *
1172      * @throws ConversionException is thrown if the key maps to an
1173      *         object that is not a list of BigIntegers.
1174      */
1175     public List getBigIntegerList(String key, List defaultValue)
1176     {
1177         Object value = getProperty(key);
1178 
1179         List list = null;
1180 
1181         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
1182         {
1183             list = defaultValue;
1184         }
1185         else if (value instanceof BigInteger[])
1186         {
1187             list = new ArrayList();
1188             CollectionUtils.addAll(list, (BigInteger[]) value);
1189         }
1190         else if (value instanceof Collection)
1191         {
1192             Collection values = (Collection) value;
1193             list = new ArrayList();
1194 
1195             Iterator it = values.iterator();
1196             while (it.hasNext())
1197             {
1198                 list.add(PropertyConverter.toBigInteger(it.next()));
1199             }
1200         }
1201         else
1202         {
1203             try
1204             {
1205                 // attempt to convert a single value
1206                 list = new ArrayList();
1207                 list.add(PropertyConverter.toBigInteger(value));
1208             }
1209             catch (ConversionException e)
1210             {
1211                 throw new ConversionException('\'' + key + "' doesn't map to a list of big integers", e);
1212             }
1213         }
1214 
1215         return list;
1216     }
1217 
1218     /***
1219      * Get an array of BigIntegers associated with the given
1220      * configuration key. If the key doesn't map to an existing object
1221      * an empty array is returned.
1222      *
1223      * @param key The configuration key.
1224      * @return The associated BigInteger array if the key is found.
1225      *
1226      * @throws ConversionException is thrown if the key maps to an
1227      *         object that is not a list of BigIntegers.
1228      */
1229     public BigInteger[] getBigIntegerArray(String key)
1230     {
1231         return getBigIntegerArray(key, new BigInteger[0]);
1232     }
1233 
1234     /***
1235      * Get an array of BigIntegers associated with the given
1236      * configuration key. If the key doesn't map to an existing object
1237      * an empty array is returned.
1238      *
1239      * @param key The configuration key.
1240      * @return The associated BigInteger array if the key is found.
1241      *
1242      * @throws ConversionException is thrown if the key maps to an
1243      *         object that is not a list of BigIntegers.
1244      */
1245     public BigInteger[] getBigIntegerArray(String key, BigInteger[] defaultValue)
1246     {
1247         List list = getBigIntegerList(key);
1248         if (list.isEmpty())
1249         {
1250             return defaultValue;
1251         }
1252         else
1253         {
1254             return (BigInteger[]) list.toArray(new BigInteger[list.size()]);
1255         }
1256     }
1257 
1258     /***
1259      * Get a list of BigDecimals associated with the given configuration key.
1260      * If the key doesn't map to an existing object an empty list is returned.
1261      *
1262      * @param key The configuration key.
1263      * @return The associated BigDecimal list if the key is found.
1264      *
1265      * @throws ConversionException is thrown if the key maps to an
1266      *         object that is not a list of BigDecimals.
1267      */
1268     public List getBigDecimalList(String key)
1269     {
1270         return getBigDecimalList(key, new ArrayList());
1271     }
1272 
1273     /***
1274      * Get a list of BigDecimals associated with the given configuration key.
1275      * If the key doesn't map to an existing object, the default value is
1276      * returned.
1277      *
1278      * @param key The configuration key.
1279      * @param defaultValue The default value.
1280      * @return The associated List of BigDecimals.
1281      *
1282      * @throws ConversionException is thrown if the key maps to an
1283      *         object that is not a list of BigDecimals.
1284      */
1285     public List getBigDecimalList(String key, List defaultValue)
1286     {
1287         Object value = getProperty(key);
1288 
1289         List list = null;
1290 
1291         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
1292         {
1293             list = defaultValue;
1294         }
1295         else if (value instanceof BigDecimal[])
1296         {
1297             list = new ArrayList();
1298             CollectionUtils.addAll(list, (BigDecimal[]) value);
1299         }
1300         else if (value instanceof Collection)
1301         {
1302             Collection values = (Collection) value;
1303             list = new ArrayList();
1304 
1305             Iterator it = values.iterator();
1306             while (it.hasNext())
1307             {
1308                 list.add(PropertyConverter.toBigDecimal(it.next()));
1309             }
1310         }
1311         else
1312         {
1313             try
1314             {
1315                 // attempt to convert a single value
1316                 list = new ArrayList();
1317                 list.add(PropertyConverter.toBigDecimal(value));
1318             }
1319             catch (ConversionException e)
1320             {
1321                 throw new ConversionException('\'' + key + "' doesn't map to a list of big decimals", e);
1322             }
1323         }
1324 
1325         return list;
1326     }
1327 
1328     /***
1329      * Get an array of BigDecimals associated with the given
1330      * configuration key. If the key doesn't map to an existing object
1331      * an empty array is returned.
1332      *
1333      * @param key The configuration key.
1334      * @return The associated BigDecimal array if the key is found.
1335      *
1336      * @throws ConversionException is thrown if the key maps to an
1337      *         object that is not a list of BigDecimals.
1338      */
1339     public BigDecimal[] getBigDecimalArray(String key)
1340     {
1341         return getBigDecimalArray(key, new BigDecimal[0]);
1342     }
1343 
1344     /***
1345      * Get an array of BigDecimals associated with the given
1346      * configuration key. If the key doesn't map to an existing object
1347      * an empty array is returned.
1348      *
1349      * @param key The configuration key.
1350      * @return The associated BigDecimal array if the key is found.
1351      *
1352      * @throws ConversionException is thrown if the key maps to an
1353      *         object that is not a list of BigDecimals.
1354      */
1355     public BigDecimal[] getBigDecimalArray(String key, BigDecimal[] defaultValue)
1356     {
1357         List list = getBigDecimalList(key);
1358         if (list.isEmpty())
1359         {
1360             return defaultValue;
1361         }
1362         else
1363         {
1364             return (BigDecimal[]) list.toArray(new BigDecimal[list.size()]);
1365         }
1366     }
1367 
1368     /***
1369      * Get an URL associated with the given configuration key.
1370      *
1371      * @param key The configuration key.
1372      * @return The associated URL.
1373      *
1374      * @throws ConversionException is thrown if the key maps to an
1375      *         object that is not an URL.
1376      */
1377     public URL getURL(String key)
1378     {
1379         return getURL(key, null);
1380     }
1381 
1382     /***
1383      * Get an URL associated with the given configuration key.
1384      * If the key doesn't map to an existing object, the default value
1385      * is returned.
1386      *
1387      * @param key          The configuration key.
1388      * @param defaultValue The default value.
1389      * @return The associated URL.
1390      *
1391      * @throws ConversionException is thrown if the key maps to an
1392      *         object that is not an URL.
1393      */
1394     public URL getURL(String key, URL defaultValue)
1395     {
1396         Object value = resolveContainerStore(key);
1397 
1398         if (value == null)
1399         {
1400             return defaultValue;
1401         }
1402         else
1403         {
1404             try
1405             {
1406                 return PropertyConverter.toURL(value);
1407             }
1408             catch (ConversionException e)
1409             {
1410                 throw new ConversionException('\'' + key + "' doesn't map to an URL", e);
1411             }
1412         }
1413     }
1414 
1415     /***
1416      * Get a list of URLs associated with the given configuration key.
1417      * If the key doesn't map to an existing object an empty list is returned.
1418      *
1419      * @param key The configuration key.
1420      * @return The associated URL list if the key is found.
1421      *
1422      * @throws ConversionException is thrown if the key maps to an
1423      *         object that is not a list of URLs.
1424      */
1425     public List getURLList(String key)
1426     {
1427         return getURLList(key, new ArrayList());
1428     }
1429 
1430     /***
1431      * Get a list of URLs associated with the given configuration key.
1432      * If the key doesn't map to an existing object, the default value is
1433      * returned.
1434      *
1435      * @param key The configuration key.
1436      * @param defaultValue The default value.
1437      * @return The associated List of URLs.
1438      *
1439      * @throws ConversionException is thrown if the key maps to an
1440      *         object that is not a list of URLs.
1441      */
1442     public List getURLList(String key, List defaultValue)
1443     {
1444         Object value = getProperty(key);
1445 
1446         List list = null;
1447 
1448         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
1449         {
1450             list = defaultValue;
1451         }
1452         else if (value instanceof URL[])
1453         {
1454             list = new ArrayList();
1455             CollectionUtils.addAll(list, (URL[]) value);
1456         }
1457         else if (value instanceof Collection)
1458         {
1459             Collection values = (Collection) value;
1460             list = new ArrayList();
1461 
1462             Iterator it = values.iterator();
1463             while (it.hasNext())
1464             {
1465                 list.add(PropertyConverter.toURL(it.next()));
1466             }
1467         }
1468         else
1469         {
1470             try
1471             {
1472                 // attempt to convert a single value
1473                 list = new ArrayList();
1474                 list.add(PropertyConverter.toURL(value));
1475             }
1476             catch (ConversionException e)
1477             {
1478                 throw new ConversionException('\'' + key + "' doesn't map to a list of URLs", e);
1479             }
1480         }
1481 
1482         return list;
1483     }
1484 
1485     /***
1486      * Get an array of URLs associated with the given configuration key.
1487      * If the key doesn't map to an existing object an empty array is returned.
1488      *
1489      * @param key The configuration key.
1490      * @return The associated URL array if the key is found.
1491      *
1492      * @throws ConversionException is thrown if the key maps to an
1493      *         object that is not a list of URLs.
1494      */
1495     public URL[] getURLArray(String key)
1496     {
1497         return getURLArray(key, new URL[0]);
1498     }
1499 
1500     /***
1501      * Get an array of URLs associated with the given configuration key.
1502      * If the key doesn't map to an existing object an empty array is returned.
1503      *
1504      * @param key The configuration key.
1505      * @return The associated URL array if the key is found.
1506      *
1507      * @throws ConversionException is thrown if the key maps to an
1508      *         object that is not a list of URLs.
1509      */
1510     public URL[] getURLArray(String key, URL[] defaultValue)
1511     {
1512         List list = getURLList(key);
1513         if (list.isEmpty())
1514         {
1515             return defaultValue;
1516         }
1517         else
1518         {
1519             return (URL[]) list.toArray(new URL[list.size()]);
1520         }
1521     }
1522 
1523     /***
1524      * Get a Date associated with the given configuration key. If the property
1525      * is a String, it will be parsed with the format defined by the user in
1526      * the {@link #DATE_FORMAT_KEY} property, or if it's not defined with the
1527      * {@link #DEFAULT_DATE_FORMAT} pattern.
1528      *
1529      * @param key The configuration key.
1530      * @return The associated Date.
1531      *
1532      * @throws ConversionException is thrown if the key maps to an
1533      *         object that is not a Date.
1534      */
1535     public Date getDate(String key)
1536     {
1537         return getDate(key, getDefaultDateFormat());
1538     }
1539 
1540     /***
1541      * Get a Date associated with the given configuration key. If the property
1542      * is a String, it will be parsed with the specified format pattern.
1543      *
1544      * @param key    The configuration key.
1545      * @param format The non-localized {@link java.text.DateFormat} pattern.
1546      * @return The associated Date
1547      *
1548      * @throws ConversionException is thrown if the key maps to an
1549      *         object that is not a Date.
1550      */
1551     public Date getDate(String key, String format)
1552     {
1553         return getDate(key, null, format);
1554     }
1555 
1556     /***
1557      * Get a Date associated with the given configuration key. If the property
1558      * is a String, it will be parsed with the format defined by the user in
1559      * the {@link #DATE_FORMAT_KEY} property, or if it's not defined with the
1560      * {@link #DEFAULT_DATE_FORMAT} pattern. If the key doesn't map to an
1561      * existing object, the default value is returned.
1562      *
1563      * @param key          The configuration key.
1564      * @param defaultValue The default value.
1565      * @return The associated Date.
1566      *
1567      * @throws ConversionException is thrown if the key maps to an
1568      *         object that is not a Date.
1569      */
1570     public Date getDate(String key, Date defaultValue)
1571     {
1572         return getDate(key, defaultValue, getDefaultDateFormat());
1573     }
1574 
1575     /***
1576      * Get a Date associated with the given configuration key. If the property
1577      * is a String, it will be parsed with the specified format pattern.
1578      * If the key doesn't map to an existing object, the default value
1579      * is returned.
1580      *
1581      * @param key          The configuration key.
1582      * @param defaultValue The default value.
1583      * @param format       The non-localized {@link java.text.DateFormat} pattern.
1584      * @return The associated Date.
1585      *
1586      * @throws ConversionException is thrown if the key maps to an
1587      *         object that is not a Date.
1588      */
1589     public Date getDate(String key, Date defaultValue, String format)
1590     {
1591         Object value = resolveContainerStore(key);
1592 
1593         if (value == null)
1594         {
1595             return defaultValue;
1596         }
1597         else
1598         {
1599             try
1600             {
1601                 return PropertyConverter.toDate(value, format);
1602             }
1603             catch (ConversionException e)
1604             {
1605                 throw new ConversionException('\'' + key + "' doesn't map to a Date", e);
1606             }
1607         }
1608     }
1609 
1610     /***
1611      * Get a list of Dates associated with the given configuration key.
1612      * If the property is a list of Strings, they will be parsed with the
1613      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
1614      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
1615      * If the key doesn't map to an existing object an empty list is returned.
1616      *
1617      * @param key The configuration key.
1618      * @return The associated Date list if the key is found.
1619      *
1620      * @throws ConversionException is thrown if the key maps to an
1621      *         object that is not a list of Dates.
1622      */
1623     public List getDateList(String key)
1624     {
1625         return getDateList(key, new ArrayList());
1626     }
1627 
1628     /***
1629      * Get a list of Dates associated with the given configuration key.
1630      * If the property is a list of Strings, they will be parsed with the
1631      * specified format pattern. If the key doesn't map to an existing object
1632      * an empty list is returned.
1633      *
1634      * @param key    The configuration key.
1635      * @param format The non-localized {@link java.text.DateFormat} pattern.
1636      * @return The associated Date list if the key is found.
1637      *
1638      * @throws ConversionException is thrown if the key maps to an
1639      *         object that is not a list of Dates.
1640      */
1641     public List getDateList(String key, String format)
1642     {
1643         return getDateList(key, new ArrayList(), format);
1644     }
1645 
1646     /***
1647      * Get a list of Dates associated with the given configuration key.
1648      * If the property is a list of Strings, they will be parsed with the
1649      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
1650      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
1651      * If the key doesn't map to an existing object, the default value is
1652      * returned.
1653      *
1654      * @param key          The configuration key.
1655      * @param defaultValue The default value.
1656      * @return The associated Date list if the key is found.
1657      *
1658      * @throws ConversionException is thrown if the key maps to an
1659      *         object that is not a list of Dates.
1660      */
1661     public List getDateList(String key, List defaultValue)
1662     {
1663         return getDateList(key, defaultValue, getDefaultDateFormat());
1664     }
1665 
1666     /***
1667      * Get a list of Dates associated with the given configuration key.
1668      * If the property is a list of Strings, they will be parsed with the
1669      * specified format pattern. If the key doesn't map to an existing object,
1670      * the default value is returned.
1671      *
1672      * @param key          The configuration key.
1673      * @param defaultValue The default value.
1674      * @param format       The non-localized {@link java.text.DateFormat} pattern.
1675      * @return The associated Date list if the key is found.
1676      *
1677      * @throws ConversionException is thrown if the key maps to an
1678      *         object that is not a list of Dates.
1679      */
1680     public List getDateList(String key, List defaultValue, String format)
1681     {
1682         Object value = getProperty(key);
1683 
1684         List list = null;
1685 
1686         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
1687         {
1688             list = defaultValue;
1689         }
1690         else if (value instanceof Date[])
1691         {
1692             list = new ArrayList();
1693             CollectionUtils.addAll(list, (Date[]) value);
1694         }
1695         else if (value instanceof Calendar[])
1696         {
1697             list = new ArrayList();
1698             Calendar[] values = (Calendar[]) value;
1699 
1700             for (int i = 0; i < values.length; i++)
1701             {
1702                 list.add(values[i].getTime());
1703             }
1704         }
1705         else if (value instanceof Collection)
1706         {
1707             Collection values = (Collection) value;
1708             list = new ArrayList();
1709 
1710             Iterator it = values.iterator();
1711             while (it.hasNext())
1712             {
1713                 list.add(PropertyConverter.toDate(it.next(), format));
1714             }
1715         }
1716         else
1717         {
1718             try
1719             {
1720                 // attempt to convert a single value
1721                 list = new ArrayList();
1722                 list.add(PropertyConverter.toDate(value, format));
1723             }
1724             catch (ConversionException e)
1725             {
1726                 throw new ConversionException('\'' + key + "' doesn't map to a list of Dates", e);
1727             }
1728         }
1729 
1730         return list;
1731     }
1732 
1733     /***
1734      * Get an array of Dates associated with the given configuration key.
1735      * If the property is a list of Strings, they will be parsed with the
1736      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
1737      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
1738      * If the key doesn't map to an existing object an empty array is returned.
1739      *
1740      * @param key The configuration key.
1741      * @return The associated Date 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 Dates.
1745      */
1746     public Date[] getDateArray(String key)
1747     {
1748         return getDateArray(key, new Date[0]);
1749     }
1750 
1751     /***
1752      * Get an array of Dates 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      * an empty array is returned.
1756      *
1757      * @param key    The configuration key.
1758      * @param format The non-localized {@link java.text.DateFormat} pattern.
1759      * @return The associated Date array if the key is found.
1760      *
1761      * @throws ConversionException is thrown if the key maps to an
1762      *         object that is not a list of Dates.
1763      */
1764     public Date[] getDateArray(String key, String format)
1765     {
1766         return getDateArray(key, new Date[0], format);
1767     }
1768 
1769     /***
1770      * Get an array of Dates associated with the given configuration key.
1771      * If the property is a list of Strings, they will be parsed with the
1772      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
1773      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
1774      * If the key doesn't map to an existing object an empty array is returned.
1775      *
1776      * @param key The configuration key.
1777      * @return The associated Date array if the key is found.
1778      *
1779      * @throws ConversionException is thrown if the key maps to an
1780      *         object that is not a list of Dates.
1781      */
1782     public Date[] getDateArray(String key, Date[] defaultValue)
1783     {
1784         return getDateArray(key, defaultValue, getDefaultDateFormat());
1785     }
1786 
1787     /***
1788      * Get an array of Dates associated with the given configuration key.
1789      * If the property is a list of Strings, they will be parsed with the
1790      * specified format pattern. If the key doesn't map to an existing object,
1791      * the default value is returned.
1792      *
1793      * @param key          The configuration key.
1794      * @param defaultValue The default value.
1795      * @param format       The non-localized {@link java.text.DateFormat} pattern.
1796      * @return The associated Date array if the key is found.
1797      *
1798      * @throws ConversionException is thrown if the key maps to an
1799      *         object that is not a list of Dates.
1800      */
1801     public Date[] getDateArray(String key, Date[] defaultValue, String format)
1802     {
1803         List list = getDateList(key);
1804         if (list.isEmpty())
1805         {
1806             return defaultValue;
1807         }
1808         else
1809         {
1810             return (Date[]) list.toArray(new Date[list.size()]);
1811         }
1812     }
1813 
1814     /***
1815      * Get a Calendar associated with the given configuration key. If the
1816      * property is a String, it will be parsed with the format defined by the
1817      * user in the {@link #DATE_FORMAT_KEY} property, or if it's not defined
1818      * with the {@link #DEFAULT_DATE_FORMAT} pattern.
1819      *
1820      * @param key The configuration key.
1821      * @return The associated Calendar.
1822      *
1823      * @throws ConversionException is thrown if the key maps to an
1824      *         object that is not a Calendar.
1825      */
1826     public Calendar getCalendar(String key)
1827     {
1828         return getCalendar(key, getDefaultDateFormat());
1829     }
1830 
1831     /***
1832      * Get a Calendar associated with the given configuration key. If the
1833      * property is a String, it will be parsed with the specified format
1834      * pattern.
1835      *
1836      * @param key    The configuration key.
1837      * @param format The non-localized {@link java.text.DateFormat} pattern.
1838      * @return The associated Calendar
1839      *
1840      * @throws ConversionException is thrown if the key maps to an
1841      *         object that is not a Calendar.
1842      */
1843     public Calendar getCalendar(String key, String format)
1844     {
1845         return getCalendar(key, null, format);
1846     }
1847 
1848     /***
1849      * Get a Calendar associated with the given configuration key. If the
1850      * property is a String, it will be parsed with the format defined by the
1851      * user in the {@link #DATE_FORMAT_KEY} property, or if it's not defined
1852      * with the {@link #DEFAULT_DATE_FORMAT} pattern. If the key doesn't map
1853      * to an existing object, the default value is returned.
1854      *
1855      * @param key          The configuration key.
1856      * @param defaultValue The default value.
1857      * @return The associated Calendar.
1858      *
1859      * @throws ConversionException is thrown if the key maps to an
1860      *         object that is not a Calendar.
1861      */
1862     public Calendar getCalendar(String key, Calendar defaultValue)
1863     {
1864         return getCalendar(key, defaultValue, getDefaultDateFormat());
1865     }
1866 
1867     /***
1868      * Get a Calendar associated with the given configuration key. If the
1869      * property is a String, it will be parsed with the specified format
1870      * pattern. If the key doesn't map to an existing object, the default
1871      * value is returned.
1872      *
1873      * @param key          The configuration key.
1874      * @param defaultValue The default value.
1875      * @param format       The non-localized {@link java.text.DateFormat} pattern.
1876      * @return The associated Calendar.
1877      *
1878      * @throws ConversionException is thrown if the key maps to an
1879      *         object that is not a Calendar.
1880      */
1881     public Calendar getCalendar(String key, Calendar defaultValue, String format)
1882     {
1883         Object value = resolveContainerStore(key);
1884 
1885         if (value == null)
1886         {
1887             return defaultValue;
1888         }
1889         else
1890         {
1891             try
1892             {
1893                 return PropertyConverter.toCalendar(value, format);
1894             }
1895             catch (ConversionException e)
1896             {
1897                 throw new ConversionException('\'' + key + "' doesn't map to a Calendar", e);
1898             }
1899         }
1900     }
1901 
1902     /***
1903      * Get a list of Calendars associated with the given configuration key.
1904      * If the property is a list of Strings, they will be parsed with the
1905      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
1906      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
1907      * If the key doesn't map to an existing object an empty list is returned.
1908      *
1909      * @param key The configuration key.
1910      * @return The associated Calendar list if the key is found.
1911      *
1912      * @throws ConversionException is thrown if the key maps to an
1913      *         object that is not a list of Calendars.
1914      */
1915     public List getCalendarList(String key)
1916     {
1917         return getCalendarList(key, new ArrayList());
1918     }
1919 
1920     /***
1921      * Get a list of Calendars associated with the given configuration key.
1922      * If the property is a list of Strings, they will be parsed with the
1923      * specified format pattern. If the key doesn't map to an existing object
1924      * an empty list is returned.
1925      *
1926      * @param key    The configuration key.
1927      * @param format The non-localized {@link java.text.DateFormat} pattern.
1928      * @return The associated Calendar list if the key is found.
1929      *
1930      * @throws ConversionException is thrown if the key maps to an
1931      *         object that is not a list of Calendars.
1932      */
1933     public List getCalendarList(String key, String format)
1934     {
1935         return getCalendarList(key, new ArrayList(), format);
1936     }
1937 
1938     /***
1939      * Get a list of Calendars associated with the given configuration key.
1940      * If the property is a list of Strings, they will be parsed with the
1941      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
1942      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
1943      * If the key doesn't map to an existing object, the default value is
1944      * returned.
1945      *
1946      * @param key The configuration key.
1947      * @param defaultValue The default value.
1948      * @return The associated Calendar list if the key is found.
1949      *
1950      * @throws ConversionException is thrown if the key maps to an
1951      *         object that is not a list of Calendars.
1952      */
1953     public List getCalendarList(String key, List defaultValue)
1954     {
1955         return getCalendarList(key, defaultValue, getDefaultDateFormat());
1956     }
1957 
1958     /***
1959      * Get a list of Calendars associated with the given configuration key.
1960      * If the property is a list of Strings, they will be parsed with the
1961      * specified format pattern. If the key doesn't map to an existing object,
1962      * the default value is returned.
1963      *
1964      * @param key          The configuration key.
1965      * @param defaultValue The default value.
1966      * @param format       The non-localized {@link java.text.DateFormat} pattern.
1967      * @return The associated Calendar list if the key is found.
1968      *
1969      * @throws ConversionException is thrown if the key maps to an
1970      *         object that is not a list of Calendars.
1971      */
1972     public List getCalendarList(String key, List defaultValue, String format)
1973     {
1974         Object value = getProperty(key);
1975 
1976         List list = null;
1977 
1978         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
1979         {
1980             list = defaultValue;
1981         }
1982         else if (value instanceof Calendar[])
1983         {
1984             list = new ArrayList();
1985             CollectionUtils.addAll(list, (Calendar[]) value);
1986         }
1987         else if (value instanceof Date[])
1988         {
1989             list = new ArrayList();
1990             Date[] values = (Date[]) value;
1991 
1992             for (int i = 0; i < values.length; i++)
1993             {
1994                 Calendar calendar = Calendar.getInstance();
1995                 calendar.setTime(values[i]);
1996                 list.add(calendar);
1997             }
1998         }
1999         else if (value instanceof Collection)
2000         {
2001             Collection values = (Collection) value;
2002             list = new ArrayList();
2003 
2004             Iterator it = values.iterator();
2005             while (it.hasNext())
2006             {
2007                 list.add(PropertyConverter.toCalendar(it.next(), format));
2008             }
2009         }
2010         else
2011         {
2012             try
2013             {
2014                 // attempt to convert a single value
2015                 list = new ArrayList();
2016                 list.add(PropertyConverter.toCalendar(value, format));
2017             }
2018             catch (ConversionException e)
2019             {
2020                 throw new ConversionException('\'' + key + "' doesn't map to a list of Calendars", e);
2021             }
2022         }
2023 
2024         return list;
2025     }
2026 
2027     /***
2028      * Get an array of Calendars associated with the given configuration key.
2029      * If the property is a list of Strings, they will be parsed with the
2030      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
2031      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
2032      * If the key doesn't map to an existing object an empty array is returned.
2033      *
2034      * @param key The configuration key.
2035      * @return The associated Calendar array if the key is found.
2036      *
2037      * @throws ConversionException is thrown if the key maps to an
2038      *         object that is not a list of Calendars.
2039      */
2040     public Calendar[] getCalendarArray(String key)
2041     {
2042         return getCalendarArray(key, new Calendar[0]);
2043     }
2044 
2045     /***
2046      * Get an array of Calendars associated with the given configuration key.
2047      * If the property is a list of Strings, they will be parsed with the
2048      * specified format pattern. If the key doesn't map to an existing object
2049      * an empty array is returned.
2050      *
2051      * @param key    The configuration key.
2052      * @param format The non-localized {@link java.text.DateFormat} pattern.
2053      * @return The associated Calendar array if the key is found.
2054      *
2055      * @throws ConversionException is thrown if the key maps to an
2056      *         object that is not a list of Calendars.
2057      */
2058     public Calendar[] getCalendarArray(String key, String format)
2059     {
2060         return getCalendarArray(key, new Calendar[0], format);
2061     }
2062 
2063     /***
2064      * Get an array of Calendars associated with the given configuration key.
2065      * If the property is a list of Strings, they will be parsed with the
2066      * format defined by the user in the {@link #DATE_FORMAT_KEY} property,
2067      * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern.
2068      * If the key doesn't map to an existing object an empty array is returned.
2069      *
2070      * @param key The configuration key.
2071      * @return The associated Calendar array if the key is found.
2072      *
2073      * @throws ConversionException is thrown if the key maps to an
2074      *         object that is not a list of Calendars.
2075      */
2076     public Calendar[] getCalendarArray(String key, Calendar[] defaultValue)
2077     {
2078         return getCalendarArray(key, defaultValue, getDefaultDateFormat());
2079     }
2080 
2081     /***
2082      * Get an array of Calendars associated with the given configuration key.
2083      * If the property is a list of Strings, they will be parsed with the
2084      * specified format pattern. If the key doesn't map to an existing object,
2085      * the default value is returned.
2086      *
2087      * @param key          The configuration key.
2088      * @param defaultValue The default value.
2089      * @param format       The non-localized {@link java.text.DateFormat} pattern.
2090      * @return The associated Calendar array if the key is found.
2091      *
2092      * @throws ConversionException is thrown if the key maps to an
2093      *         object that is not a list of Calendars.
2094      */
2095     public Calendar[] getCalendarArray(String key, Calendar[] defaultValue, String format)
2096     {
2097         List list = getCalendarList(key, format);
2098         if (list.isEmpty())
2099         {
2100             return defaultValue;
2101         }
2102         else
2103         {
2104             return (Calendar[]) list.toArray(new Calendar[list.size()]);
2105         }
2106     }
2107 
2108     /***
2109      * Returns the date format specified by the user in the DATE_FORMAT_KEY
2110      * property, or the default format otherwise.
2111      */
2112     private String getDefaultDateFormat()
2113     {
2114         return getString(DATE_FORMAT_KEY, DEFAULT_DATE_FORMAT);
2115     }
2116 
2117     /***
2118      * Get a Locale associated with the given configuration key.
2119      *
2120      * @param key The configuration key.
2121      * @return The associated Locale.
2122      *
2123      * @throws ConversionException is thrown if the key maps to an
2124      *         object that is not a Locale.
2125      */
2126     public Locale getLocale(String key)
2127     {
2128         return getLocale(key, null);
2129     }
2130 
2131     /***
2132      * Get a Locale associated with the given configuration key.
2133      * If the key doesn't map to an existing object, the default value
2134      * is returned.
2135      *
2136      * @param key          The configuration key.
2137      * @param defaultValue The default value.
2138      * @return The associated Locale.
2139      *
2140      * @throws ConversionException is thrown if the key maps to an
2141      *         object that is not a Locale.
2142      */
2143     public Locale getLocale(String key, Locale defaultValue)
2144     {
2145         Object value = resolveContainerStore(key);
2146 
2147         if (value == null)
2148         {
2149             return defaultValue;
2150         }
2151         else
2152         {
2153             try
2154             {
2155                 return PropertyConverter.toLocale(value);
2156             }
2157             catch (ConversionException e)
2158             {
2159                 throw new ConversionException('\'' + key + "' doesn't map to a Locale", e);
2160             }
2161         }
2162     }
2163 
2164     /***
2165      * Get a list of Locales associated with the given configuration key.
2166      * If the key doesn't map to an existing object an empty list is returned.
2167      *
2168      * @param key The configuration key.
2169      * @return The associated Locale list if the key is found.
2170      *
2171      * @throws ConversionException is thrown if the key maps to an
2172      *         object that is not a list of Locales.
2173      */
2174     public List getLocaleList(String key)
2175     {
2176         return getLocaleList(key, new ArrayList());
2177     }
2178 
2179     /***
2180      * Get a list of Locales associated with the given configuration key.
2181      * If the key doesn't map to an existing object, the default value is
2182      * returned.
2183      *
2184      * @param key The configuration key.
2185      * @param defaultValue The default value.
2186      * @return The associated List of Locales.
2187      *
2188      * @throws ConversionException is thrown if the key maps to an
2189      *         object that is not a list of Locales.
2190      */
2191     public List getLocaleList(String key, List defaultValue)
2192     {
2193         Object value = getProperty(key);
2194 
2195         List list = null;
2196 
2197         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
2198         {
2199             list = defaultValue;
2200         }
2201         else if (value instanceof Locale[])
2202         {
2203             list = new ArrayList();
2204             CollectionUtils.addAll(list, (Locale[]) value);
2205         }
2206         else if (value instanceof Collection)
2207         {
2208             Collection values = (Collection) value;
2209             list = new ArrayList();
2210 
2211             Iterator it = values.iterator();
2212             while (it.hasNext())
2213             {
2214                 list.add(PropertyConverter.toLocale(it.next()));
2215             }
2216         }
2217         else
2218         {
2219             try
2220             {
2221                 // attempt to convert a single value
2222                 list = new ArrayList();
2223                 list.add(PropertyConverter.toLocale(value));
2224             }
2225             catch (ConversionException e)
2226             {
2227                 throw new ConversionException('\'' + key + "' doesn't map to a list of Locales", e);
2228             }
2229         }
2230 
2231         return list;
2232     }
2233 
2234     /***
2235      * Get an array of Locales associated with the given
2236      * configuration key. If the key doesn't map to an existing object
2237      * an empty array is returned.
2238      *
2239      * @param key The configuration key.
2240      * @return The associated Locale array if the key is found.
2241      *
2242      * @throws ConversionException is thrown if the key maps to an
2243      *         object that is not a list of Locales.
2244      */
2245     public Locale[] getLocaleArray(String key)
2246     {
2247         return getLocaleArray(key, new Locale[0]);
2248     }
2249 
2250     /***
2251      * Get an array of Locales associated with the given
2252      * configuration key. If the key doesn't map to an existing object
2253      * an empty array is returned.
2254      *
2255      * @param key The configuration key.
2256      * @return The associated Locale array if the key is found.
2257      *
2258      * @throws ConversionException is thrown if the key maps to an
2259      *         object that is not a list of Locales.
2260      */
2261     public Locale[] getLocaleArray(String key, Locale[] defaultValue)
2262     {
2263         List list = getLocaleList(key);
2264         if (list.isEmpty())
2265         {
2266             return defaultValue;
2267         }
2268         else
2269         {
2270             return (Locale[]) list.toArray(new Locale[list.size()]);
2271         }
2272     }
2273 
2274     /***
2275      * Get a Color associated with the given configuration key.
2276      *
2277      * @param key The configuration key.
2278      * @return The associated Color.
2279      *
2280      * @throws ConversionException is thrown if the key maps to an
2281      *         object that is not a Color.
2282      */
2283     public Color getColor(String key)
2284     {
2285         return getColor(key, null);
2286     }
2287 
2288     /***
2289      * Get a Color associated with the given configuration key.
2290      * If the key doesn't map to an existing object, the default value
2291      * is returned.
2292      *
2293      * @param key          The configuration key.
2294      * @param defaultValue The default value.
2295      * @return The associated Color.
2296      *
2297      * @throws ConversionException is thrown if the key maps to an
2298      *         object that is not a Color.
2299      */
2300     public Color getColor(String key, Color defaultValue)
2301     {
2302         Object value = resolveContainerStore(key);
2303 
2304         if (value == null)
2305         {
2306             return defaultValue;
2307         }
2308         else
2309         {
2310             try
2311             {
2312                 return PropertyConverter.toColor(value);
2313             }
2314             catch (ConversionException e)
2315             {
2316                 throw new ConversionException('\'' + key + "' doesn't map to a Color", e);
2317             }
2318         }
2319     }
2320 
2321     /***
2322      * Get a list of Colors associated with the given configuration key.
2323      * If the key doesn't map to an existing object an empty list is returned.
2324      *
2325      * @param key The configuration key.
2326      * @return The associated Color list if the key is found.
2327      *
2328      * @throws ConversionException is thrown if the key maps to an
2329      *         object that is not a list of Colors.
2330      */
2331     public List getColorList(String key)
2332     {
2333         return getColorList(key, new ArrayList());
2334     }
2335 
2336     /***
2337      * Get a list of Colors associated with the given configuration key.
2338      * If the key doesn't map to an existing object, the default value is
2339      * returned.
2340      *
2341      * @param key The configuration key.
2342      * @param defaultValue The default value.
2343      * @return The associated List of Colors.
2344      *
2345      * @throws ConversionException is thrown if the key maps to an
2346      *         object that is not a list of Colors.
2347      */
2348     public List getColorList(String key, List defaultValue)
2349     {
2350         Object value = getProperty(key);
2351 
2352         List list = null;
2353 
2354         if (value == null || (value instanceof String && StringUtils.isEmpty((String) value)))
2355         {
2356             list = defaultValue;
2357         }
2358         else if (value instanceof Color[])
2359         {
2360             list = new ArrayList();
2361             CollectionUtils.addAll(list, (Color[]) value);
2362         }
2363         else if (value instanceof Collection)
2364         {
2365             Collection values = (Collection) value;
2366             list = new ArrayList();
2367 
2368             Iterator it = values.iterator();
2369             while (it.hasNext())
2370             {
2371                 list.add(PropertyConverter.toColor(it.next()));
2372             }
2373         }
2374         else
2375         {
2376             try
2377             {
2378                 // attempt to convert a single value
2379                 list = new ArrayList();
2380                 list.add(PropertyConverter.toColor(value));
2381             }
2382             catch (ConversionException e)
2383             {
2384                 throw new ConversionException('\'' + key + "' doesn't map to a list of Colors", e);
2385             }
2386         }
2387 
2388         return list;
2389     }
2390 
2391     /***
2392      * Get an array of Colors associated with the given
2393      * configuration key. If the key doesn't map to an existing object
2394      * an empty array is returned.
2395      *
2396      * @param key The configuration key.
2397      * @return The associated Color array if the key is found.
2398      *
2399      * @throws ConversionException is thrown if the key maps to an
2400      *         object that is not a list of Colors.
2401      */
2402     public Color[] getColorArray(String key)
2403     {
2404         return getColorArray(key, new Color[0]);
2405     }
2406 
2407     /***
2408      * Get an array of Colors associated with the given
2409      * configuration key. If the key doesn't map to an existing object
2410      * an empty array is returned.
2411      *
2412      * @param key The configuration key.
2413      * @return The associated Color array if the key is found.
2414      *
2415      * @throws ConversionException is thrown if the key maps to an
2416      *         object that is not a list of Colors.
2417      */
2418     public Color[] getColorArray(String key, Color[] defaultValue)
2419     {
2420         List list = getColorList(key);
2421         if (list.isEmpty())
2422         {
2423             return defaultValue;
2424         }
2425         else
2426         {
2427             return (Color[]) list.toArray(new Color[list.size()]);
2428         }
2429     }
2430 
2431 }