1 16 17 package org.apache.commons.configuration; 18 19 import java.math.BigDecimal ; 20 import java.math.BigInteger ; 21 import java.util.ArrayList ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.NoSuchElementException ; 25 import java.util.Properties ; 26 27 import org.apache.commons.collections.Predicate; 28 import org.apache.commons.collections.iterators.FilterIterator; 29 import org.apache.commons.lang.BooleanUtils; 30 31 42 public abstract class AbstractConfiguration implements Configuration 43 { 44 45 protected static final String START_TOKEN = "${"; 46 47 48 protected static final String END_TOKEN = "}"; 49 50 51 private static char DELIMITER = ','; 52 53 57 private boolean throwExceptionOnMissing = false; 58 59 65 public static void setDelimiter(char delimiter) 66 { 67 AbstractConfiguration.DELIMITER = delimiter; 68 } 69 70 75 public static char getDelimiter() 76 { 77 return AbstractConfiguration.DELIMITER; 78 } 79 80 85 public void setThrowExceptionOnMissing(boolean throwExceptionOnMissing) 86 { 87 this.throwExceptionOnMissing = throwExceptionOnMissing; 88 } 89 90 95 public boolean isThrowExceptionOnMissing() 96 { 97 return throwExceptionOnMissing; 98 } 99 100 103 public void addProperty(String key, Object value) 104 { 105 Iterator it = PropertyConverter.toIterator(value, DELIMITER); 106 while (it.hasNext()) 107 { 108 addPropertyDirect(key, it.next()); 109 } 110 } 111 112 119 protected abstract void addPropertyDirect(String key, Object obj); 120 121 128 protected String interpolate(String base) 129 { 130 return interpolateHelper(base, null); 131 } 132 133 146 protected String interpolateHelper(String base, List priorVariables) 147 { 148 if (base == null) 149 { 150 return null; 151 } 152 153 if (priorVariables == null) 156 { 157 priorVariables = new ArrayList (); 158 priorVariables.add(base); 159 } 160 161 int begin = -1; 162 int end = -1; 163 int prec = 0 - END_TOKEN.length(); 164 String variable = null; 165 StringBuffer result = new StringBuffer (); 166 167 while (((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length())) > -1) 169 && ((end = base.indexOf(END_TOKEN, begin)) > -1)) 170 { 171 result.append(base.substring(prec + END_TOKEN.length(), begin)); 172 variable = base.substring(begin + START_TOKEN.length(), end); 173 174 if (priorVariables.contains(variable)) 176 { 177 String initialBase = priorVariables.remove(0).toString(); 178 priorVariables.add(variable); 179 StringBuffer priorVariableSb = new StringBuffer (); 180 181 for (Iterator it = priorVariables.iterator(); it.hasNext();) 184 { 185 priorVariableSb.append(it.next()); 186 if (it.hasNext()) 187 { 188 priorVariableSb.append("->"); 189 } 190 } 191 192 throw new IllegalStateException ("infinite loop in property interpolation of " + initialBase + ": " 193 + priorVariableSb.toString()); 194 } 195 else 197 { 198 priorVariables.add(variable); 199 } 200 201 Object value = getProperty(variable); 202 if (value != null) 203 { 204 result.append(interpolateHelper(value.toString(), priorVariables)); 205 206 priorVariables.remove(priorVariables.size() - 1); 211 } 212 else 213 { 214 result.append(START_TOKEN).append(variable).append(END_TOKEN); 216 } 217 218 prec = end; 219 } 220 result.append(base.substring(prec + END_TOKEN.length(), base.length())); 221 return result.toString(); 222 } 223 224 227 public Configuration subset(String prefix) 228 { 229 return new SubsetConfiguration(this, prefix, "."); 230 } 231 232 235 public abstract boolean isEmpty(); 236 237 240 public abstract boolean containsKey(String key); 241 242 245 public void setProperty(String key, Object value) 246 { 247 clearProperty(key); 248 addProperty(key, value); 249 } 250 251 254 public abstract void clearProperty(String key); 255 256 259 public void clear() 260 { 261 Iterator it = getKeys(); 262 while (it.hasNext()) 263 { 264 String key = (String ) it.next(); 265 it.remove(); 266 267 if (containsKey(key)) 268 { 269 clearProperty(key); 271 } 272 } 273 } 274 275 278 public abstract Iterator getKeys(); 279 280 283 public Iterator getKeys(final String prefix) 284 { 285 return new FilterIterator(getKeys(), new Predicate() 286 { 287 public boolean evaluate(Object obj) 288 { 289 String key = (String ) obj; 290 return key.startsWith(prefix + ".") || key.equals(prefix); 291 } 292 }); 293 } 294 295 298 public Properties getProperties(String key) 299 { 300 return getProperties(key, null); 301 } 302 303 318 public Properties getProperties(String key, Properties defaults) 319 { 320 323 String [] tokens = getStringArray(key); 324 325 328 Properties props = defaults == null ? new Properties () : new Properties (defaults); 329 for (int i = 0; i < tokens.length; i++) 330 { 331 String token = tokens[i]; 332 int equalSign = token.indexOf('='); 333 if (equalSign > 0) 334 { 335 String pkey = token.substring(0, equalSign).trim(); 336 String pvalue = token.substring(equalSign + 1).trim(); 337 props.put(pkey, pvalue); 338 } 339 else if (tokens.length == 1 && "".equals(token)) 340 { 341 break; 344 } 345 else 346 { 347 throw new IllegalArgumentException ('\'' + token + "' does not contain an equals sign"); 348 } 349 } 350 return props; 351 } 352 353 356 public boolean getBoolean(String key) 357 { 358 Boolean b = getBoolean(key, null); 359 if (b != null) 360 { 361 return b.booleanValue(); 362 } 363 else 364 { 365 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 366 } 367 } 368 369 372 public boolean getBoolean(String key, boolean defaultValue) 373 { 374 return getBoolean(key, BooleanUtils.toBooleanObject(defaultValue)).booleanValue(); 375 } 376 377 380 public Boolean getBoolean(String key, Boolean defaultValue) 381 { 382 Object value = resolveContainerStore(key); 383 384 if (value == null) 385 { 386 return defaultValue; 387 } 388 else 389 { 390 try 391 { 392 return PropertyConverter.toBoolean(value); 393 } 394 catch (ConversionException e) 395 { 396 throw new ConversionException('\'' + key + "' doesn't map to a Boolean object", e); 397 } 398 } 399 } 400 401 404 public byte getByte(String key) 405 { 406 Byte b = getByte(key, null); 407 if (b != null) 408 { 409 return b.byteValue(); 410 } 411 else 412 { 413 throw new NoSuchElementException ('\'' + key + " doesn't map to an existing object"); 414 } 415 } 416 417 420 public byte getByte(String key, byte defaultValue) 421 { 422 return getByte(key, new Byte (defaultValue)).byteValue(); 423 } 424 425 428 public Byte getByte(String key, Byte defaultValue) 429 { 430 Object value = resolveContainerStore(key); 431 432 if (value == null) 433 { 434 return defaultValue; 435 } 436 else 437 { 438 try 439 { 440 return PropertyConverter.toByte(value); 441 } 442 catch (ConversionException e) 443 { 444 throw new ConversionException('\'' + key + "' doesn't map to a Byte object", e); 445 } 446 } 447 } 448 449 452 public double getDouble(String key) 453 { 454 Double d = getDouble(key, null); 455 if (d != null) 456 { 457 return d.doubleValue(); 458 } 459 else 460 { 461 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 462 } 463 } 464 465 468 public double getDouble(String key, double defaultValue) 469 { 470 return getDouble(key, new Double (defaultValue)).doubleValue(); 471 } 472 473 476 public Double getDouble(String key, Double defaultValue) 477 { 478 Object value = resolveContainerStore(key); 479 480 if (value == null) 481 { 482 return defaultValue; 483 } 484 else 485 { 486 try 487 { 488 return PropertyConverter.toDouble(value); 489 } 490 catch (ConversionException e) 491 { 492 throw new ConversionException('\'' + key + "' doesn't map to a Double object", e); 493 } 494 } 495 } 496 497 500 public float getFloat(String key) 501 { 502 Float f = getFloat(key, null); 503 if (f != null) 504 { 505 return f.floatValue(); 506 } 507 else 508 { 509 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 510 } 511 } 512 513 516 public float getFloat(String key, float defaultValue) 517 { 518 return getFloat(key, new Float (defaultValue)).floatValue(); 519 } 520 521 524 public Float getFloat(String key, Float defaultValue) 525 { 526 Object value = resolveContainerStore(key); 527 528 if (value == null) 529 { 530 return defaultValue; 531 } 532 else 533 { 534 try 535 { 536 return PropertyConverter.toFloat(value); 537 } 538 catch (ConversionException e) 539 { 540 throw new ConversionException('\'' + key + "' doesn't map to a Float object", e); 541 } 542 } 543 } 544 545 548 public int getInt(String key) 549 { 550 Integer i = getInteger(key, null); 551 if (i != null) 552 { 553 return i.intValue(); 554 } 555 else 556 { 557 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 558 } 559 } 560 561 564 public int getInt(String key, int defaultValue) 565 { 566 Integer i = getInteger(key, null); 567 568 if (i == null) 569 { 570 return defaultValue; 571 } 572 573 return i.intValue(); 574 } 575 576 579 public Integer getInteger(String key, Integer defaultValue) 580 { 581 Object value = resolveContainerStore(key); 582 583 if (value == null) 584 { 585 return defaultValue; 586 } 587 else 588 { 589 try 590 { 591 return PropertyConverter.toInteger(value); 592 } 593 catch (ConversionException e) 594 { 595 throw new ConversionException('\'' + key + "' doesn't map to an Integer object", e); 596 } 597 } 598 } 599 600 603 public long getLong(String key) 604 { 605 Long l = getLong(key, null); 606 if (l != null) 607 { 608 return l.longValue(); 609 } 610 else 611 { 612 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 613 } 614 } 615 616 619 public long getLong(String key, long defaultValue) 620 { 621 return getLong(key, new Long (defaultValue)).longValue(); 622 } 623 624 627 public Long getLong(String key, Long defaultValue) 628 { 629 Object value = resolveContainerStore(key); 630 631 if (value == null) 632 { 633 return defaultValue; 634 } 635 else 636 { 637 try 638 { 639 return PropertyConverter.toLong(value); 640 } 641 catch (ConversionException e) 642 { 643 throw new ConversionException('\'' + key + "' doesn't map to a Long object", e); 644 } 645 } 646 } 647 648 651 public short getShort(String key) 652 { 653 Short s = getShort(key, null); 654 if (s != null) 655 { 656 return s.shortValue(); 657 } 658 else 659 { 660 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 661 } 662 } 663 664 667 public short getShort(String key, short defaultValue) 668 { 669 return getShort(key, new Short (defaultValue)).shortValue(); 670 } 671 672 675 public Short getShort(String key, Short defaultValue) 676 { 677 Object value = resolveContainerStore(key); 678 679 if (value == null) 680 { 681 return defaultValue; 682 } 683 else 684 { 685 try 686 { 687 return PropertyConverter.toShort(value); 688 } 689 catch (ConversionException e) 690 { 691 throw new ConversionException('\'' + key + "' doesn't map to a Short object", e); 692 } 693 } 694 } 695 696 699 public BigDecimal getBigDecimal(String key) 700 { 701 BigDecimal number = getBigDecimal(key, null); 702 if (number != null) 703 { 704 return number; 705 } 706 else if (isThrowExceptionOnMissing()) 707 { 708 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 709 } 710 else 711 { 712 return null; 713 } 714 } 715 716 719 public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) 720 { 721 Object value = resolveContainerStore(key); 722 723 if (value == null) 724 { 725 return defaultValue; 726 } 727 else 728 { 729 try 730 { 731 return PropertyConverter.toBigDecimal(value); 732 } 733 catch (ConversionException e) 734 { 735 throw new ConversionException('\'' + key + "' doesn't map to a BigDecimal object", e); 736 } 737 } 738 } 739 740 743 public BigInteger getBigInteger(String key) 744 { 745 BigInteger number = getBigInteger(key, null); 746 if (number != null) 747 { 748 return number; 749 } 750 else if (isThrowExceptionOnMissing()) 751 { 752 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 753 } 754 else 755 { 756 return null; 757 } 758 } 759 760 763 public BigInteger getBigInteger(String key, BigInteger defaultValue) 764 { 765 Object value = resolveContainerStore(key); 766 767 if (value == null) 768 { 769 return defaultValue; 770 } 771 else 772 { 773 try 774 { 775 return PropertyConverter.toBigInteger(value); 776 } 777 catch (ConversionException e) 778 { 779 throw new ConversionException('\'' + key + "' doesn't map to a BigDecimal object", e); 780 } 781 } 782 } 783 784 787 public String getString(String key) 788 { 789 String s = getString(key, null); 790 if (s != null) 791 { 792 return s; 793 } 794 else if (isThrowExceptionOnMissing()) 795 { 796 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 797 } 798 else 799 { 800 return null; 801 } 802 } 803 804 807 public String getString(String key, String defaultValue) 808 { 809 Object value = resolveContainerStore(key); 810 811 if (value instanceof String ) 812 { 813 return interpolate((String ) value); 814 } 815 else if (value == null) 816 { 817 return interpolate(defaultValue); 818 } 819 else 820 { 821 throw new ConversionException('\'' + key + "' doesn't map to a String object"); 822 } 823 } 824 825 828 public String [] getStringArray(String key) 829 { 830 Object value = getProperty(key); 831 832 String [] array; 833 834 if (value instanceof String ) 835 { 836 array = new String [1]; 837 838 array[0] = interpolate((String ) value); 839 } 840 else if (value instanceof List ) 841 { 842 List list = (List ) value; 843 array = new String [list.size()]; 844 845 for (int i = 0; i < array.length; i++) 846 { 847 array[i] = interpolate((String ) list.get(i)); 848 } 849 } 850 else if (value == null) 851 { 852 array = new String [0]; 853 } 854 else 855 { 856 throw new ConversionException('\'' + key + "' doesn't map to a String/List object"); 857 } 858 return array; 859 } 860 861 864 public List getList(String key) 865 { 866 return getList(key, new ArrayList ()); 867 } 868 869 872 public List getList(String key, List defaultValue) 873 { 874 Object value = getProperty(key); 875 List list = null; 876 877 if (value instanceof String ) 878 { 879 list = new ArrayList (1); 880 list.add(value); 881 } 882 else if (value instanceof List ) 883 { 884 list = (List ) value; 885 } 886 else if (value == null) 887 { 888 list = defaultValue; 889 } 890 else 891 { 892 throw new ConversionException('\'' + key + "' doesn't map to a List object: " + value + ", a " 893 + value.getClass().getName()); 894 } 895 return list; 896 } 897 898 906 protected Object resolveContainerStore(String key) 907 { 908 Object value = getProperty(key); 909 if (value != null) 910 { 911 if (value instanceof List ) 912 { 913 List list = (List ) value; 914 value = list.isEmpty() ? null : list.get(0); 915 } 916 else if (value instanceof Object []) 917 { 918 Object [] array = (Object []) value; 919 value = array.length == 0 ? null : array[0]; 920 } 921 else if (value instanceof boolean[]) 922 { 923 boolean[] array = (boolean[]) value; 924 value = array.length == 0 ? null : new Boolean (array[0]); 925 } 926 else if (value instanceof byte[]) 927 { 928 byte[] array = (byte[]) value; 929 value = array.length == 0 ? null : new Byte (array[0]); 930 } 931 else if (value instanceof short[]) 932 { 933 short[] array = (short[]) value; 934 value = array.length == 0 ? null : new Short (array[0]); 935 } 936 else if (value instanceof int[]) 937 { 938 int[] array = (int[]) value; 939 value = array.length == 0 ? null : new Integer (array[0]); 940 } 941 else if (value instanceof long[]) 942 { 943 long[] array = (long[]) value; 944 value = array.length == 0 ? null : new Long (array[0]); 945 } 946 else if (value instanceof float[]) 947 { 948 float[] array = (float[]) value; 949 value = array.length == 0 ? null : new Float (array[0]); 950 } 951 else if (value instanceof double[]) 952 { 953 double[] array = (double[]) value; 954 value = array.length == 0 ? null : new Double (array[0]); 955 } 956 } 957 958 return value; 959 } 960 961 } 962 | Popular Tags |