001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.configuration; 019 020 import java.awt.Color; 021 import java.io.Serializable; 022 import java.lang.reflect.Array; 023 import java.math.BigDecimal; 024 import java.math.BigInteger; 025 import java.net.URL; 026 import java.util.ArrayList; 027 import java.util.Calendar; 028 import java.util.Collection; 029 import java.util.Date; 030 import java.util.Iterator; 031 import java.util.List; 032 import java.util.Locale; 033 import java.util.NoSuchElementException; 034 035 import org.apache.commons.lang.ClassUtils; 036 import org.apache.commons.lang.StringUtils; 037 038 /** 039 * Decorator providing additional getters for any Configuration. This extended 040 * Configuration supports more types: 041 * <ul> 042 * <li>{@link java.net.URL}</li> 043 * <li>{@link java.util.Locale}</li> 044 * <li>{@link java.util.Date}</li> 045 * <li>{@link java.util.Calendar}</li> 046 * <li>{@link java.awt.Color}</li> 047 * <li>{@link java.net.InetAddress}</li> 048 * <li>{@link javax.mail.internet.InternetAddress} (requires Javamail in the classpath)</li> 049 * <li>{@link java.lang.Enum} (Java 5 enumeration types)</li> 050 * </ul> 051 * 052 * Lists and arrays are available for all types. 053 * 054 * <h4>Example</h4> 055 * 056 * Configuration file <tt>config.properties</tt>: 057 * <pre> 058 * title.color = #0000FF 059 * remote.host = 192.168.0.53 060 * default.locales = fr,en,de 061 * email.contact = ebourg@apache.org, oheger@apache.org 062 * </pre> 063 * 064 * Usage: 065 * 066 * <pre> 067 * DataConfiguration config = new DataConfiguration(new PropertiesConfiguration("config.properties")); 068 * 069 * // retrieve a property using a specialized getter 070 * Color color = config.getColor("title.color"); 071 * 072 * // retrieve a property using a generic getter 073 * InetAddress host = (InetAddress) config.get(InetAddress.class, "remote.host"); 074 * Locale[] locales = (Locale[]) config.getArray(Locale.class, "default.locales"); 075 * List contacts = config.getList(InternetAddress.class, "email.contact"); 076 * </pre> 077 * 078 * <h4>Dates</h4> 079 * 080 * Date objects are expected to be formatted with the pattern <tt>yyyy-MM-dd HH:mm:ss</tt>. 081 * This default format can be changed by specifying another format in the 082 * getters, or by putting a date format in the configuration under the key 083 * <tt>org.apache.commons.configuration.format.date</tt>. 084 * 085 * @author <a href="ebourg@apache.org">Emmanuel Bourg</a> 086 * @version $Id: DataConfiguration.java 1234985 2012-01-23 21:09:09Z oheger $ 087 * @since 1.1 088 */ 089 public class DataConfiguration extends AbstractConfiguration implements Serializable 090 { 091 /** The key of the property storing the user defined date format. */ 092 public static final String DATE_FORMAT_KEY = "org.apache.commons.configuration.format.date"; 093 094 /** The default format for dates. */ 095 public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; 096 097 /** 098 * The serial version UID. 099 */ 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} 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 @Override 132 protected void addPropertyDirect(String key, Object obj) 133 { 134 if (configuration instanceof AbstractConfiguration) 135 { 136 ((AbstractConfiguration) configuration).addPropertyDirect(key, obj); 137 } 138 else 139 { 140 configuration.addProperty(key, obj); 141 } 142 } 143 144 @Override 145 public void addProperty(String key, Object value) 146 { 147 getConfiguration().addProperty(key, value); 148 } 149 150 public boolean isEmpty() 151 { 152 return configuration.isEmpty(); 153 } 154 155 public boolean containsKey(String key) 156 { 157 return configuration.containsKey(key); 158 } 159 160 @Override 161 public void clearProperty(String key) 162 { 163 configuration.clearProperty(key); 164 } 165 166 @Override 167 public void setProperty(String key, Object value) 168 { 169 configuration.setProperty(key, value); 170 } 171 172 public Iterator<String> getKeys() 173 { 174 return configuration.getKeys(); 175 } 176 177 /** 178 * Get an object of the specified type associated with the given 179 * configuration key. If the key doesn't map to an existing object, the 180 * method returns null unless {@link #isThrowExceptionOnMissing()} is set 181 * to <tt>true</tt>. 182 * 183 * @param <T> the target type of the value 184 * @param cls the target class of the value 185 * @param key the key of the value 186 * 187 * @return the value of the requested type for the key 188 * 189 * @throws NoSuchElementException if the key doesn't map to an existing 190 * object and <tt>throwExceptionOnMissing=true</tt> 191 * @throws ConversionException if the value is not compatible with the requested type 192 * 193 * @since 1.5 194 */ 195 public <T> T get(Class<T> cls, String key) 196 { 197 T value = get(cls, key, null); 198 if (value != null) 199 { 200 return value; 201 } 202 else if (isThrowExceptionOnMissing()) 203 { 204 throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); 205 } 206 else 207 { 208 return null; 209 } 210 } 211 212 /** 213 * Get an object of the specified type associated with the given 214 * configuration key. If the key doesn't map to an existing object, the 215 * default value is returned. 216 * 217 * @param <T> the target type of the value 218 * @param cls the target class of the value 219 * @param key the key of the value 220 * @param defaultValue the default value 221 * 222 * @return the value of the requested type for the key 223 * 224 * @throws ConversionException if the value is not compatible with the requested type 225 * 226 * @since 1.5 227 */ 228 public <T> T get(Class<T> cls, String key, T defaultValue) 229 { 230 Object value = resolveContainerStore(key); 231 232 if (value == null) 233 { 234 return defaultValue; 235 } 236 237 if (Date.class.equals(cls) || Calendar.class.equals(cls)) 238 { 239 return convert(cls, key, interpolate(value), new String[] {getDefaultDateFormat()}); 240 } 241 else 242 { 243 return convert(cls, key, interpolate(value), null); 244 } 245 } 246 247 /** 248 * Get a list of typed objects associated with the given configuration key. 249 * If the key doesn't map to an existing object, an empty list is returned. 250 * 251 * @param <T> the type expected for the elements of the list 252 * @param cls the class expected for the elements of the list 253 * @param key The configuration key. 254 * @return The associated list if the key is found. 255 * 256 * @throws ConversionException is thrown if the key maps to an object that 257 * is not compatible with a list of the specified class. 258 * 259 * @since 1.5 260 */ 261 public <T> List<T> getList(Class<T> cls, String key) 262 { 263 return getList(cls, key, new ArrayList<T>()); 264 } 265 266 /** 267 * Get a list of typed objects associated with the given configuration key. 268 * If the key doesn't map to an existing object, the default value is 269 * returned. 270 * 271 * @param <T> the type expected for the elements of the list 272 * @param cls the class expected for the elements of the list 273 * @param key the configuration key. 274 * @param defaultValue the default value. 275 * @return The associated List. 276 * 277 * @throws ConversionException is thrown if the key maps to an object that 278 * is not compatible with a list of the specified class. 279 * 280 * @since 1.5 281 */ 282 public <T> List<T> getList(Class<T> cls, String key, List<T> defaultValue) 283 { 284 Object value = getProperty(key); 285 Class<?> valueClass = value != null ? value.getClass() : null; 286 287 List<T> list; 288 289 if (value == null || (value instanceof String && StringUtils.isEmpty((String) value))) 290 { 291 // the value is null or is an empty string 292 list = defaultValue; 293 } 294 else 295 { 296 list = new ArrayList<T>(); 297 298 Object[] params = null; 299 if (cls.equals(Date.class) || cls.equals(Calendar.class)) 300 { 301 params = new Object[] {getDefaultDateFormat()}; 302 } 303 304 if (valueClass.isArray()) 305 { 306 // get the class of the objects contained in the array 307 Class<?> arrayType = valueClass.getComponentType(); 308 int length = Array.getLength(value); 309 310 if (arrayType.equals(cls) 311 || (arrayType.isPrimitive() && cls.equals(ClassUtils.primitiveToWrapper(arrayType)))) 312 { 313 // the value is an array of the specified type, or an array 314 // of the primitive type derived from the specified type 315 for (int i = 0; i < length; i++) 316 { 317 list.add(cls.cast(Array.get(value, i))); 318 } 319 } 320 else 321 { 322 // attempt to convert the elements of the array 323 for (int i = 0; i < length; i++) 324 { 325 list.add(convert(cls, key, interpolate(Array.get(value, i)), params)); 326 } 327 } 328 } 329 else if (value instanceof Collection) 330 { 331 Collection<?> values = (Collection<?>) value; 332 333 for (Object o : values) 334 { 335 list.add(convert(cls, key, interpolate(o), params)); 336 } 337 } 338 else 339 { 340 // attempt to convert a single value 341 list.add(convert(cls, key, interpolate(value), params)); 342 } 343 } 344 345 return list; 346 } 347 348 /** 349 * Get an array of typed objects associated with the given configuration key. 350 * If the key doesn't map to an existing object, an empty list is returned. 351 * 352 * @param cls the type expected for the elements of the array 353 * @param key The configuration key. 354 * @return The associated array if the key is found, and the value compatible with the type specified. 355 * 356 * @throws ConversionException is thrown if the key maps to an object that 357 * is not compatible with a list of the specified class. 358 * 359 * @since 1.5 360 */ 361 public Object getArray(Class<?> cls, String key) 362 { 363 return getArray(cls, key, Array.newInstance(cls, 0)); 364 } 365 366 /** 367 * Get an array of typed objects associated with the given configuration key. 368 * If the key doesn't map to an existing object, the default value is returned. 369 * 370 * @param cls the type expected for the elements of the array 371 * @param key the configuration key. 372 * @param defaultValue the default value 373 * @return The associated array if the key is found, and the value compatible with the type specified. 374 * 375 * @throws ConversionException is thrown if the key maps to an object that 376 * is not compatible with an array of the specified class. 377 * @throws IllegalArgumentException if the default value is not an array of the specified type 378 * 379 * @since 1.5 380 */ 381 public Object getArray(Class<?> cls, String key, Object defaultValue) 382 { 383 // check the type of the default value 384 if (defaultValue != null 385 && (!defaultValue.getClass().isArray() || !cls 386 .isAssignableFrom(defaultValue.getClass() 387 .getComponentType()))) 388 { 389 throw new IllegalArgumentException( 390 "The type of the default value (" + defaultValue.getClass() 391 + ")" + " is not an array of the specified class (" 392 + cls + ")"); 393 } 394 395 if (cls.isPrimitive()) 396 { 397 return getPrimitiveArray(cls, key, defaultValue); 398 } 399 400 List<?> list = getList(cls, key); 401 if (list.isEmpty()) 402 { 403 return defaultValue; 404 } 405 else 406 { 407 return list.toArray((Object[]) Array.newInstance(cls, list.size())); 408 } 409 } 410 411 /** 412 * Get an array of primitive values associated with the given configuration key. 413 * If the key doesn't map to an existing object, the default value is returned. 414 * 415 * @param cls the primitive type expected for the elements of the array 416 * @param key the configuration key. 417 * @param defaultValue the default value 418 * @return The associated array if the key is found, and the value compatible with the type specified. 419 * 420 * @throws ConversionException is thrown if the key maps to an object that 421 * is not compatible with an array of the specified class. 422 * 423 * @since 1.5 424 */ 425 private Object getPrimitiveArray(Class<?> cls, String key, Object defaultValue) 426 { 427 Object value = getProperty(key); 428 Class<?> valueClass = value != null ? value.getClass() : null; 429 430 Object array; 431 432 if (value == null || (value instanceof String && StringUtils.isEmpty((String) value))) 433 { 434 // the value is null or is an empty string 435 array = defaultValue; 436 } 437 else 438 { 439 if (valueClass.isArray()) 440 { 441 // get the class of the objects contained in the array 442 Class<?> arrayType = valueClass.getComponentType(); 443 int length = Array.getLength(value); 444 445 if (arrayType.equals(cls)) 446 { 447 // the value is an array of the same primitive type 448 array = value; 449 } 450 else if (arrayType.equals(ClassUtils.primitiveToWrapper(cls))) 451 { 452 // the value is an array of the wrapper type derived from the specified primitive type 453 array = Array.newInstance(cls, length); 454 455 for (int i = 0; i < length; i++) 456 { 457 Array.set(array, i, Array.get(value, i)); 458 } 459 } 460 else 461 { 462 throw new ConversionException('\'' + key + "' (" + arrayType + ")" 463 + " doesn't map to a compatible array of " + cls); 464 } 465 } 466 else if (value instanceof Collection) 467 { 468 Collection<?> values = (Collection<?>) value; 469 470 array = Array.newInstance(cls, values.size()); 471 472 int i = 0; 473 for (Object o : values) 474 { 475 // This is safe because PropertyConverter can handle 476 // conversion to wrapper classes correctly. 477 @SuppressWarnings("unchecked") 478 Object convertedValue = convert(ClassUtils.primitiveToWrapper(cls), key, interpolate(o), null); 479 Array.set(array, i++, convertedValue); 480 } 481 } 482 else 483 { 484 // attempt to convert a single value 485 // This is safe because PropertyConverter can handle 486 // conversion to wrapper classes correctly. 487 @SuppressWarnings("unchecked") 488 Object convertedValue = convert(ClassUtils.primitiveToWrapper(cls), key, interpolate(value), null); 489 490 // create an array of one element 491 array = Array.newInstance(cls, 1); 492 Array.set(array, 0, convertedValue); 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<Boolean> getBooleanList(String key) 511 { 512 return getBooleanList(key, new ArrayList<Boolean>()); 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<Boolean> getBooleanList(String key, List<Boolean> 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<Byte> getByteList(String key) 576 { 577 return getByteList(key, new ArrayList<Byte>()); 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<Byte> getByteList(String key, List<Byte> 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<Short> getShortList(String key) 641 { 642 return getShortList(key, new ArrayList<Short>()); 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<Short> getShortList(String key, List<Short> 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<Integer> getIntegerList(String key) 707 { 708 return getIntegerList(key, new ArrayList<Integer>()); 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<Integer> getIntegerList(String key, List<Integer> 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<Long> getLongList(String key) 772 { 773 return getLongList(key, new ArrayList<Long>()); 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<Long> getLongList(String key, List<Long> 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<Float> getFloatList(String key) 837 { 838 return getFloatList(key, new ArrayList<Float>()); 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<Float> getFloatList(String key, List<Float> 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<Double> getDoubleList(String key) 903 { 904 return getDoubleList(key, new ArrayList<Double>()); 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<Double> getDoubleList(String key, List<Double> 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<BigInteger> getBigIntegerList(String key) 968 { 969 return getBigIntegerList(key, new ArrayList<BigInteger>()); 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<BigInteger> getBigIntegerList(String key, List<BigInteger> 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<BigDecimal> getBigDecimalList(String key) 1033 { 1034 return getBigDecimalList(key, new ArrayList<BigDecimal>()); 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<BigDecimal> getBigDecimalList(String key, List<BigDecimal> 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 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 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<URL> getURLList(String key) 1129 { 1130 return getURLList(key, new ArrayList<URL>()); 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<URL> getURLList(String key, List<URL> 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 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 public List<Date> getDateList(String key) 1280 { 1281 return getDateList(key, new ArrayList<Date>()); 1282 } 1283 1284 /** 1285 * Get a list of Dates associated with the given configuration key. 1286 * If the property is a list of Strings, they will be parsed with the 1287 * specified format pattern. If the key doesn't map to an existing object 1288 * an empty list is returned. 1289 * 1290 * @param key The configuration key. 1291 * @param format The non-localized {@link java.text.DateFormat} pattern. 1292 * @return The associated Date list if the key is found. 1293 * 1294 * @throws ConversionException is thrown if the key maps to an 1295 * object that is not a list of Dates. 1296 */ 1297 public List<Date> getDateList(String key, String format) 1298 { 1299 return getDateList(key, new ArrayList<Date>(), format); 1300 } 1301 1302 /** 1303 * Get a list of Dates associated with the given configuration key. 1304 * If the property is a list of Strings, they will be parsed with the 1305 * format defined by the user in the {@link #DATE_FORMAT_KEY} property, 1306 * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern. 1307 * If the key doesn't map to an existing object, the default value is 1308 * returned. 1309 * 1310 * @param key The configuration key. 1311 * @param defaultValue The default value. 1312 * @return The associated Date list if the key is found. 1313 * 1314 * @throws ConversionException is thrown if the key maps to an 1315 * object that is not a list of Dates. 1316 */ 1317 public List<Date> getDateList(String key, List<Date> defaultValue) 1318 { 1319 return getDateList(key, defaultValue, getDefaultDateFormat()); 1320 } 1321 1322 /** 1323 * Get a list of Dates associated with the given configuration key. 1324 * If the property is a list of Strings, they will be parsed with the 1325 * specified format pattern. If the key doesn't map to an existing object, 1326 * the default value is returned. 1327 * 1328 * @param key The configuration key. 1329 * @param defaultValue The default value. 1330 * @param format The non-localized {@link java.text.DateFormat} pattern. 1331 * @return The associated Date list if the key is found. 1332 * 1333 * @throws ConversionException is thrown if the key maps to an 1334 * object that is not a list of Dates. 1335 */ 1336 public List<Date> getDateList(String key, List<Date> defaultValue, String format) 1337 { 1338 Object value = getProperty(key); 1339 1340 List<Date> list; 1341 1342 if (value == null || (value instanceof String && StringUtils.isEmpty((String) value))) 1343 { 1344 list = defaultValue; 1345 } 1346 else if (value.getClass().isArray()) 1347 { 1348 list = new ArrayList<Date>(); 1349 int length = Array.getLength(value); 1350 for (int i = 0; i < length; i++) 1351 { 1352 list.add(convert(Date.class, key, interpolate(Array.get(value, i)), new String[] {format})); 1353 } 1354 } 1355 else if (value instanceof Collection) 1356 { 1357 Collection<?> values = (Collection<?>) value; 1358 list = new ArrayList<Date>(); 1359 1360 for (Object o : values) 1361 { 1362 list.add(convert(Date.class, key, interpolate(o), new String[] {format})); 1363 } 1364 } 1365 else 1366 { 1367 // attempt to convert a single value 1368 list = new ArrayList<Date>(); 1369 list.add(convert(Date.class, key, interpolate(value), new String[] {format})); 1370 } 1371 1372 return list; 1373 } 1374 1375 /** 1376 * Get an array of Dates associated with the given configuration key. 1377 * If the property is a list of Strings, they will be parsed with the 1378 * format defined by the user in the {@link #DATE_FORMAT_KEY} property, 1379 * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern. 1380 * If the key doesn't map to an existing object an empty array is returned. 1381 * 1382 * @param key The configuration key. 1383 * @return The associated Date array if the key is found. 1384 * 1385 * @throws ConversionException is thrown if the key maps to an 1386 * object that is not a list of Dates. 1387 */ 1388 public Date[] getDateArray(String key) 1389 { 1390 return getDateArray(key, new Date[0]); 1391 } 1392 1393 /** 1394 * Get an array of Dates associated with the given configuration key. 1395 * If the property is a list of Strings, they will be parsed with the 1396 * specified format pattern. If the key doesn't map to an existing object 1397 * an empty array is returned. 1398 * 1399 * @param key The configuration key. 1400 * @param format The non-localized {@link java.text.DateFormat} pattern. 1401 * @return The associated Date array if the key is found. 1402 * 1403 * @throws ConversionException is thrown if the key maps to an 1404 * object that is not a list of Dates. 1405 */ 1406 public Date[] getDateArray(String key, String format) 1407 { 1408 return getDateArray(key, new Date[0], format); 1409 } 1410 1411 /** 1412 * Get an array of Dates associated with the given configuration key. 1413 * If the property is a list of Strings, they will be parsed with the 1414 * format defined by the user in the {@link #DATE_FORMAT_KEY} property, 1415 * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern. 1416 * If the key doesn't map to an existing object an empty array is returned. 1417 * 1418 * @param key The configuration key. 1419 * @param defaultValue the default value, which will be returned if the property is not found 1420 * @return The associated Date array 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 Dates. 1424 */ 1425 public Date[] getDateArray(String key, Date[] defaultValue) 1426 { 1427 return getDateArray(key, defaultValue, getDefaultDateFormat()); 1428 } 1429 1430 /** 1431 * Get an array of Dates associated with the given configuration key. 1432 * If the property is a list of Strings, they will be parsed with the 1433 * specified format pattern. If the key doesn't map to an existing object, 1434 * the default value is returned. 1435 * 1436 * @param key The configuration key. 1437 * @param defaultValue The default value. 1438 * @param format The non-localized {@link java.text.DateFormat} pattern. 1439 * @return The associated Date array if the key is found. 1440 * 1441 * @throws ConversionException is thrown if the key maps to an 1442 * object that is not a list of Dates. 1443 */ 1444 public Date[] getDateArray(String key, Date[] defaultValue, String format) 1445 { 1446 List<Date> list = getDateList(key, format); 1447 if (list.isEmpty()) 1448 { 1449 return defaultValue; 1450 } 1451 else 1452 { 1453 return list.toArray(new Date[list.size()]); 1454 } 1455 } 1456 1457 /** 1458 * Get a Calendar associated with the given configuration key. If the 1459 * property is a String, it will be parsed with the format defined by the 1460 * user in the {@link #DATE_FORMAT_KEY} property, or if it's not defined 1461 * with the {@link #DEFAULT_DATE_FORMAT} pattern. 1462 * 1463 * @param key The configuration key. 1464 * @return The associated Calendar. 1465 * 1466 * @throws ConversionException is thrown if the key maps to an 1467 * object that is not a Calendar. 1468 */ 1469 public Calendar getCalendar(String key) 1470 { 1471 return get(Calendar.class, key); 1472 } 1473 1474 /** 1475 * Get a Calendar associated with the given configuration key. If the 1476 * property is a String, it will be parsed with the specified format 1477 * pattern. 1478 * 1479 * @param key The configuration key. 1480 * @param format The non-localized {@link java.text.DateFormat} pattern. 1481 * @return The associated Calendar 1482 * 1483 * @throws ConversionException is thrown if the key maps to an 1484 * object that is not a Calendar. 1485 */ 1486 public Calendar getCalendar(String key, String format) 1487 { 1488 Calendar value = getCalendar(key, null, format); 1489 if (value != null) 1490 { 1491 return value; 1492 } 1493 else if (isThrowExceptionOnMissing()) 1494 { 1495 throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object"); 1496 } 1497 else 1498 { 1499 return null; 1500 } 1501 } 1502 1503 /** 1504 * Get a Calendar associated with the given configuration key. If the 1505 * property is a String, it will be parsed with the format defined by the 1506 * user in the {@link #DATE_FORMAT_KEY} property, or if it's not defined 1507 * with the {@link #DEFAULT_DATE_FORMAT} pattern. If the key doesn't map 1508 * to an existing object, the default value is returned. 1509 * 1510 * @param key The configuration key. 1511 * @param defaultValue The default value. 1512 * @return The associated Calendar. 1513 * 1514 * @throws ConversionException is thrown if the key maps to an 1515 * object that is not a Calendar. 1516 */ 1517 public Calendar getCalendar(String key, Calendar defaultValue) 1518 { 1519 return getCalendar(key, defaultValue, getDefaultDateFormat()); 1520 } 1521 1522 /** 1523 * Get a Calendar associated with the given configuration key. If the 1524 * property is a String, it will be parsed with the specified format 1525 * pattern. If the key doesn't map to an existing object, the default 1526 * value is returned. 1527 * 1528 * @param key The configuration key. 1529 * @param defaultValue The default value. 1530 * @param format The non-localized {@link java.text.DateFormat} pattern. 1531 * @return The associated Calendar. 1532 * 1533 * @throws ConversionException is thrown if the key maps to an 1534 * object that is not a Calendar. 1535 */ 1536 public Calendar getCalendar(String key, Calendar defaultValue, String format) 1537 { 1538 Object value = resolveContainerStore(key); 1539 1540 if (value == null) 1541 { 1542 return defaultValue; 1543 } 1544 else 1545 { 1546 try 1547 { 1548 return PropertyConverter.toCalendar(interpolate(value), format); 1549 } 1550 catch (ConversionException e) 1551 { 1552 throw new ConversionException('\'' + key + "' doesn't map to a Calendar", e); 1553 } 1554 } 1555 } 1556 1557 /** 1558 * Get a list of Calendars associated with the given configuration key. 1559 * If the property is a list of Strings, they will be parsed with the 1560 * format defined by the user in the {@link #DATE_FORMAT_KEY} property, 1561 * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern. 1562 * If the key doesn't map to an existing object an empty list is returned. 1563 * 1564 * @param key The configuration key. 1565 * @return The associated Calendar list if the key is found. 1566 * 1567 * @throws ConversionException is thrown if the key maps to an 1568 * object that is not a list of Calendars. 1569 */ 1570 public List<Calendar> getCalendarList(String key) 1571 { 1572 return getCalendarList(key, new ArrayList<Calendar>()); 1573 } 1574 1575 /** 1576 * Get a list of Calendars associated with the given configuration key. 1577 * If the property is a list of Strings, they will be parsed with the 1578 * specified format pattern. If the key doesn't map to an existing object 1579 * an empty list is returned. 1580 * 1581 * @param key The configuration key. 1582 * @param format The non-localized {@link java.text.DateFormat} pattern. 1583 * @return The associated Calendar list if the key is found. 1584 * 1585 * @throws ConversionException is thrown if the key maps to an 1586 * object that is not a list of Calendars. 1587 */ 1588 public List<Calendar> getCalendarList(String key, String format) 1589 { 1590 return getCalendarList(key, new ArrayList<Calendar>(), format); 1591 } 1592 1593 /** 1594 * Get a list of Calendars associated with the given configuration key. 1595 * If the property is a list of Strings, they will be parsed with the 1596 * format defined by the user in the {@link #DATE_FORMAT_KEY} property, 1597 * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern. 1598 * If the key doesn't map to an existing object, the default value is 1599 * returned. 1600 * 1601 * @param key The configuration key. 1602 * @param defaultValue The default value. 1603 * @return The associated Calendar list if the key is found. 1604 * 1605 * @throws ConversionException is thrown if the key maps to an 1606 * object that is not a list of Calendars. 1607 */ 1608 public List<Calendar> getCalendarList(String key, List<Calendar> defaultValue) 1609 { 1610 return getCalendarList(key, defaultValue, getDefaultDateFormat()); 1611 } 1612 1613 /** 1614 * Get a list of Calendars associated with the given configuration key. 1615 * If the property is a list of Strings, they will be parsed with the 1616 * specified format pattern. If the key doesn't map to an existing object, 1617 * the default value is returned. 1618 * 1619 * @param key The configuration key. 1620 * @param defaultValue The default value. 1621 * @param format The non-localized {@link java.text.DateFormat} pattern. 1622 * @return The associated Calendar list if the key is found. 1623 * 1624 * @throws ConversionException is thrown if the key maps to an 1625 * object that is not a list of Calendars. 1626 */ 1627 public List<Calendar> getCalendarList(String key, List<Calendar> defaultValue, String format) 1628 { 1629 Object value = getProperty(key); 1630 1631 List<Calendar> list; 1632 1633 if (value == null || (value instanceof String && StringUtils.isEmpty((String) value))) 1634 { 1635 list = defaultValue; 1636 } 1637 else if (value.getClass().isArray()) 1638 { 1639 list = new ArrayList<Calendar>(); 1640 int length = Array.getLength(value); 1641 for (int i = 0; i < length; i++) 1642 { 1643 list.add(convert(Calendar.class, key, interpolate(Array.get(value, i)), new String[] {format})); 1644 } 1645 } 1646 else if (value instanceof Collection) 1647 { 1648 Collection<?> values = (Collection<?>) value; 1649 list = new ArrayList<Calendar>(); 1650 1651 for (Object o : values) 1652 { 1653 list.add(convert(Calendar.class, key, interpolate(o), new String[] {format})); 1654 } 1655 } 1656 else 1657 { 1658 // attempt to convert a single value 1659 list = new ArrayList<Calendar>(); 1660 list.add(convert(Calendar.class, key, interpolate(value), new String[] {format})); 1661 } 1662 1663 return list; 1664 } 1665 1666 /** 1667 * Get an array of Calendars associated with the given configuration key. 1668 * If the property is a list of Strings, they will be parsed with the 1669 * format defined by the user in the {@link #DATE_FORMAT_KEY} property, 1670 * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern. 1671 * If the key doesn't map to an existing object an empty array is returned. 1672 * 1673 * @param key The configuration key. 1674 * @return The associated Calendar array if the key is found. 1675 * 1676 * @throws ConversionException is thrown if the key maps to an 1677 * object that is not a list of Calendars. 1678 */ 1679 public Calendar[] getCalendarArray(String key) 1680 { 1681 return getCalendarArray(key, new Calendar[0]); 1682 } 1683 1684 /** 1685 * Get an array of Calendars associated with the given configuration key. 1686 * If the property is a list of Strings, they will be parsed with the 1687 * specified format pattern. If the key doesn't map to an existing object 1688 * an empty array is returned. 1689 * 1690 * @param key The configuration key. 1691 * @param format The non-localized {@link java.text.DateFormat} pattern. 1692 * @return The associated Calendar array if the key is found. 1693 * 1694 * @throws ConversionException is thrown if the key maps to an 1695 * object that is not a list of Calendars. 1696 */ 1697 public Calendar[] getCalendarArray(String key, String format) 1698 { 1699 return getCalendarArray(key, new Calendar[0], format); 1700 } 1701 1702 /** 1703 * Get an array of Calendars associated with the given configuration key. 1704 * If the property is a list of Strings, they will be parsed with the 1705 * format defined by the user in the {@link #DATE_FORMAT_KEY} property, 1706 * or if it's not defined with the {@link #DEFAULT_DATE_FORMAT} pattern. 1707 * If the key doesn't map to an existing object an empty array is returned. 1708 * 1709 * @param key The configuration key. 1710 * @param defaultValue the default value, which will be returned if the property is not found 1711 * @return The associated Calendar array if the key is found. 1712 * 1713 * @throws ConversionException is thrown if the key maps to an 1714 * object that is not a list of Calendars. 1715 */ 1716 public Calendar[] getCalendarArray(String key, Calendar[] defaultValue) 1717 { 1718 return getCalendarArray(key, defaultValue, getDefaultDateFormat()); 1719 } 1720 1721 /** 1722 * Get an array of Calendars associated with the given configuration key. 1723 * If the property is a list of Strings, they will be parsed with the 1724 * specified format pattern. If the key doesn't map to an existing object, 1725 * the default value is returned. 1726 * 1727 * @param key The configuration key. 1728 * @param defaultValue The default value. 1729 * @param format The non-localized {@link java.text.DateFormat} pattern. 1730 * @return The associated Calendar array if the key is found. 1731 * 1732 * @throws ConversionException is thrown if the key maps to an 1733 * object that is not a list of Calendars. 1734 */ 1735 public Calendar[] getCalendarArray(String key, Calendar[] defaultValue, String format) 1736 { 1737 List<Calendar> list = getCalendarList(key, format); 1738 if (list.isEmpty()) 1739 { 1740 return defaultValue; 1741 } 1742 else 1743 { 1744 return list.toArray(new Calendar[list.size()]); 1745 } 1746 } 1747 1748 /** 1749 * Returns the date format specified by the user in the DATE_FORMAT_KEY 1750 * property, or the default format otherwise. 1751 * 1752 * @return the default date format 1753 */ 1754 private String getDefaultDateFormat() 1755 { 1756 return getString(DATE_FORMAT_KEY, DEFAULT_DATE_FORMAT); 1757 } 1758 1759 /** 1760 * Get a Locale associated with the given configuration key. 1761 * 1762 * @param key The configuration key. 1763 * @return The associated Locale. 1764 * 1765 * @throws ConversionException is thrown if the key maps to an 1766 * object that is not a Locale. 1767 */ 1768 public Locale getLocale(String key) 1769 { 1770 return get(Locale.class, key); 1771 } 1772 1773 /** 1774 * Get a Locale associated with the given configuration key. 1775 * If the key doesn't map to an existing object, the default value 1776 * is returned. 1777 * 1778 * @param key The configuration key. 1779 * @param defaultValue The default value. 1780 * @return The associated Locale. 1781 * 1782 * @throws ConversionException is thrown if the key maps to an 1783 * object that is not a Locale. 1784 */ 1785 public Locale getLocale(String key, Locale defaultValue) 1786 { 1787 return get(Locale.class, key, defaultValue); 1788 } 1789 1790 /** 1791 * Get a list of Locales associated with the given configuration key. 1792 * If the key doesn't map to an existing object an empty list is returned. 1793 * 1794 * @param key The configuration key. 1795 * @return The associated Locale list if the key is found. 1796 * 1797 * @throws ConversionException is thrown if the key maps to an 1798 * object that is not a list of Locales. 1799 */ 1800 public List<Locale> getLocaleList(String key) 1801 { 1802 return getLocaleList(key, new ArrayList<Locale>()); 1803 } 1804 1805 /** 1806 * Get a list of Locales associated with the given configuration key. 1807 * If the key doesn't map to an existing object, the default value is 1808 * returned. 1809 * 1810 * @param key The configuration key. 1811 * @param defaultValue The default value. 1812 * @return The associated List of Locales. 1813 * 1814 * @throws ConversionException is thrown if the key maps to an 1815 * object that is not a list of Locales. 1816 */ 1817 public List<Locale> getLocaleList(String key, List<Locale> defaultValue) 1818 { 1819 return getList(Locale.class, key, defaultValue); 1820 } 1821 1822 /** 1823 * Get an array of Locales associated with the given 1824 * configuration key. If the key doesn't map to an existing object 1825 * an empty array is returned. 1826 * 1827 * @param key The configuration key. 1828 * @return The associated Locale array if the key is found. 1829 * 1830 * @throws ConversionException is thrown if the key maps to an 1831 * object that is not a list of Locales. 1832 */ 1833 public Locale[] getLocaleArray(String key) 1834 { 1835 return getLocaleArray(key, new Locale[0]); 1836 } 1837 1838 /** 1839 * Get an array of Locales associated with the given 1840 * configuration key. If the key doesn't map to an existing object 1841 * an empty array is returned. 1842 * 1843 * @param key The configuration key. 1844 * @param defaultValue the default value, which will be returned if the property is not found 1845 * @return The associated Locale array if the key is found. 1846 * 1847 * @throws ConversionException is thrown if the key maps to an 1848 * object that is not a list of Locales. 1849 */ 1850 public Locale[] getLocaleArray(String key, Locale[] defaultValue) 1851 { 1852 return (Locale[]) getArray(Locale.class, key, defaultValue); 1853 } 1854 1855 /** 1856 * Get a Color associated with the given configuration key. 1857 * 1858 * @param key The configuration key. 1859 * @return The associated Color. 1860 * 1861 * @throws ConversionException is thrown if the key maps to an 1862 * object that is not a Color. 1863 */ 1864 public Color getColor(String key) 1865 { 1866 return get(Color.class, key); 1867 } 1868 1869 /** 1870 * Get a Color associated with the given configuration key. 1871 * If the key doesn't map to an existing object, the default value 1872 * is returned. 1873 * 1874 * @param key The configuration key. 1875 * @param defaultValue The default value. 1876 * @return The associated Color. 1877 * 1878 * @throws ConversionException is thrown if the key maps to an 1879 * object that is not a Color. 1880 */ 1881 public Color getColor(String key, Color defaultValue) 1882 { 1883 return get(Color.class, key, defaultValue); 1884 } 1885 1886 /** 1887 * Get a list of Colors associated with the given configuration key. 1888 * If the key doesn't map to an existing object an empty list is returned. 1889 * 1890 * @param key The configuration key. 1891 * @return The associated Color list if the key is found. 1892 * 1893 * @throws ConversionException is thrown if the key maps to an 1894 * object that is not a list of Colors. 1895 */ 1896 public List<Color> getColorList(String key) 1897 { 1898 return getColorList(key, new ArrayList<Color>()); 1899 } 1900 1901 /** 1902 * Get a list of Colors associated with the given configuration key. 1903 * If the key doesn't map to an existing object, the default value is 1904 * returned. 1905 * 1906 * @param key The configuration key. 1907 * @param defaultValue The default value. 1908 * @return The associated List of Colors. 1909 * 1910 * @throws ConversionException is thrown if the key maps to an 1911 * object that is not a list of Colors. 1912 */ 1913 public List<Color> getColorList(String key, List<Color> defaultValue) 1914 { 1915 return getList(Color.class, key, defaultValue); 1916 } 1917 1918 /** 1919 * Get an array of Colors associated with the given 1920 * configuration key. If the key doesn't map to an existing object 1921 * an empty array is returned. 1922 * 1923 * @param key The configuration key. 1924 * @return The associated Color array if the key is found. 1925 * 1926 * @throws ConversionException is thrown if the key maps to an 1927 * object that is not a list of Colors. 1928 */ 1929 public Color[] getColorArray(String key) 1930 { 1931 return getColorArray(key, new Color[0]); 1932 } 1933 1934 /** 1935 * Get an array of Colors associated with the given 1936 * configuration key. If the key doesn't map to an existing object 1937 * an empty array is returned. 1938 * 1939 * @param key The configuration key. 1940 * @param defaultValue the default value, which will be returned if the property is not found 1941 * @return The associated Color array if the key is found. 1942 * 1943 * @throws ConversionException is thrown if the key maps to an 1944 * object that is not a list of Colors. 1945 */ 1946 public Color[] getColorArray(String key, Color[] defaultValue) 1947 { 1948 return (Color[]) getArray(Color.class, key, defaultValue); 1949 } 1950 1951 /** 1952 * Helper method for performing a type conversion using the 1953 * {@code PropertyConverter} class. 1954 * 1955 * @param <T> the target type of the conversion 1956 * @param cls the target class of the conversion 1957 * @param key the configuration key 1958 * @param value the value to be converted 1959 * @param params additional parameters 1960 * @throws ConversionException if the value is not compatible with the 1961 * requested type 1962 */ 1963 private static <T> T convert(Class<T> cls, String key, Object value, 1964 Object[] params) 1965 { 1966 try 1967 { 1968 Object result = PropertyConverter.to(cls, value, params); 1969 // Will not throw a ClassCastException because PropertyConverter 1970 // would have thrown a ConversionException if conversion had failed. 1971 return cls.cast(result); 1972 } 1973 catch (ConversionException e) 1974 { 1975 throw new ConversionException('\'' + key + "' doesn't map to a " 1976 + cls, e); 1977 } 1978 } 1979 }