1 16 package org.apache.commons.collections; 17 18 import java.io.File ; 19 import java.io.FileInputStream ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.io.InputStreamReader ; 23 import java.io.LineNumberReader ; 24 import java.io.OutputStream ; 25 import java.io.PrintWriter ; 26 import java.io.Reader ; 27 import java.io.UnsupportedEncodingException ; 28 import java.util.ArrayList ; 29 import java.util.Enumeration ; 30 import java.util.Hashtable ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.NoSuchElementException ; 34 import java.util.Properties ; 35 import java.util.StringTokenizer ; 36 import java.util.Vector ; 37 38 141 public class ExtendedProperties extends Hashtable { 142 143 146 private ExtendedProperties defaults; 147 148 154 protected String file; 155 156 160 protected String basePath; 161 162 165 protected String fileSeparator = System.getProperty("file.separator"); 166 167 170 protected boolean isInitialized = false; 171 172 176 protected static String include = "include"; 177 178 184 protected ArrayList keysAsListed = new ArrayList (); 185 186 protected final static String START_TOKEN="${"; 187 protected final static String END_TOKEN="}"; 188 189 190 196 protected String interpolate(String base) { 197 return (interpolateHelper(base, null)); 199 } 200 201 215 protected String interpolateHelper(String base, List priorVariables) { 216 if (base == null) { 218 return null; 219 } 220 221 if (priorVariables == null) { 224 priorVariables = new ArrayList (); 225 priorVariables.add(base); 226 } 227 228 int begin = -1; 229 int end = -1; 230 int prec = 0 - END_TOKEN.length(); 231 String variable = null; 232 StringBuffer result = new StringBuffer (); 233 234 while (((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length())) > -1) 236 && ((end = base.indexOf(END_TOKEN, begin)) > -1)) { 237 result.append(base.substring(prec + END_TOKEN.length(), begin)); 238 variable = base.substring(begin + START_TOKEN.length(), end); 239 240 if (priorVariables.contains(variable)) { 242 String initialBase = priorVariables.remove(0).toString(); 243 priorVariables.add(variable); 244 StringBuffer priorVariableSb = new StringBuffer (); 245 246 for (Iterator it = priorVariables.iterator(); it.hasNext();) { 249 priorVariableSb.append(it.next()); 250 if (it.hasNext()) { 251 priorVariableSb.append("->"); 252 } 253 } 254 255 throw new IllegalStateException ( 256 "infinite loop in property interpolation of " + initialBase + ": " + priorVariableSb.toString()); 257 } 258 else { 260 priorVariables.add(variable); 261 } 262 263 Object value = getProperty(variable); 265 if (value != null) { 266 result.append(interpolateHelper(value.toString(), priorVariables)); 267 268 priorVariables.remove(priorVariables.size() - 1); 273 } else if (defaults != null && defaults.getString(variable, null) != null) { 274 result.append(defaults.getString(variable)); 275 } else { 276 result.append(START_TOKEN).append(variable).append(END_TOKEN); 278 } 279 prec = end; 280 } 281 result.append(base.substring(prec + END_TOKEN.length(), base.length())); 282 283 return result.toString(); 284 } 285 286 289 private static String escape(String s) { 290 StringBuffer buf = new StringBuffer (s); 291 for (int i = 0; i < buf.length(); i++) { 292 char c = buf.charAt(i); 293 if (c == ',' || c == '\\') { 294 buf.insert(i, '\\'); 295 i++; 296 } 297 } 298 return buf.toString(); 299 } 300 301 304 private static String unescape(String s) { 305 StringBuffer buf = new StringBuffer (s); 306 for (int i = 0; i < buf.length() - 1; i++) { 307 char c1 = buf.charAt(i); 308 char c2 = buf.charAt(i + 1); 309 if (c1 == '\\' && c2 == '\\') { 310 buf.deleteCharAt(i); 311 } 312 } 313 return buf.toString(); 314 } 315 316 320 private static int countPreceding(String line, int index, char ch) { 321 int i; 322 for (i = index - 1; i >= 0; i--) { 323 if (line.charAt(i) != ch) { 324 break; 325 } 326 } 327 return index - 1 - i; 328 } 329 330 333 private static boolean endsWithSlash(String line) { 334 if (!line.endsWith("\\")) { 335 return false; 336 } 337 return (countPreceding(line, line.length() - 1, '\\') % 2 == 0); 338 } 339 340 346 static class PropertiesReader extends LineNumberReader { 347 352 public PropertiesReader(Reader reader) { 353 super(reader); 354 } 355 356 362 public String readProperty() throws IOException { 363 StringBuffer buffer = new StringBuffer (); 364 365 try { 366 while (true) { 367 String line = readLine().trim(); 368 if ((line.length() != 0) && (line.charAt(0) != '#')) { 369 if (endsWithSlash(line)) { 370 line = line.substring(0, line.length() - 1); 371 buffer.append(line); 372 } else { 373 buffer.append(line); 374 break; 375 } 376 } 377 } 378 } catch (NullPointerException ex) { 379 return null; 380 } 381 382 return buffer.toString(); 383 } 384 } 385 386 391 static class PropertiesTokenizer extends StringTokenizer { 392 395 static final String DELIMITER = ","; 396 397 402 public PropertiesTokenizer(String string) { 403 super(string, DELIMITER); 404 } 405 406 411 public boolean hasMoreTokens() { 412 return super.hasMoreTokens(); 413 } 414 415 420 public String nextToken() { 421 StringBuffer buffer = new StringBuffer (); 422 423 while (hasMoreTokens()) { 424 String token = super.nextToken(); 425 if (endsWithSlash(token)) { 426 buffer.append(token.substring(0, token.length() - 1)); 427 buffer.append(DELIMITER); 428 } else { 429 buffer.append(token); 430 break; 431 } 432 } 433 434 return buffer.toString().trim(); 435 } 436 } 437 438 441 public ExtendedProperties() { 442 super(); 443 } 444 445 451 public ExtendedProperties(String file) throws IOException { 452 this(file, null); 453 } 454 455 462 public ExtendedProperties(String file, String defaultFile) throws IOException { 463 this.file = file; 464 465 basePath = new File (file).getAbsolutePath(); 466 basePath = basePath.substring(0, basePath.lastIndexOf(fileSeparator) + 1); 467 468 FileInputStream in = null; 469 try { 470 in = new FileInputStream (file); 471 this.load(in); 472 } finally { 473 try { 474 if (in != null) { 475 in.close(); 476 } 477 } catch (IOException ex) {} 478 } 479 480 if (defaultFile != null) { 481 defaults = new ExtendedProperties(defaultFile); 482 } 483 } 484 485 489 public boolean isInitialized() { 490 return isInitialized; 491 } 492 493 499 public String getInclude() { 500 return include; 501 } 502 503 509 public void setInclude(String inc) { 510 include = inc; 511 } 512 513 519 public void load(InputStream input) throws IOException { 520 load(input, null); 521 } 522 523 531 public synchronized void load(InputStream input, String enc) throws IOException { 532 PropertiesReader reader = null; 533 if (enc != null) { 534 try { 535 reader = new PropertiesReader(new InputStreamReader (input, enc)); 536 537 } catch (UnsupportedEncodingException ex) { 538 } 540 } 541 542 if (reader == null) { 543 try { 544 reader = new PropertiesReader(new InputStreamReader (input, "8859_1")); 545 546 } catch (UnsupportedEncodingException ex) { 547 reader = new PropertiesReader(new InputStreamReader (input)); 550 } 551 } 552 553 try { 554 while (true) { 555 String line = reader.readProperty(); 556 int equalSign = line.indexOf('='); 557 558 if (equalSign > 0) { 559 String key = line.substring(0, equalSign).trim(); 560 String value = line.substring(equalSign + 1).trim(); 561 562 if ("".equals(value)) { 564 continue; 565 } 566 567 if (getInclude() != null && key.equalsIgnoreCase(getInclude())) { 568 File file = null; 570 571 if (value.startsWith(fileSeparator)) { 572 file = new File (value); 574 575 } else { 576 if (value.startsWith("." + fileSeparator)) { 580 value = value.substring(2); 581 } 582 583 file = new File (basePath + value); 584 } 585 586 if (file != null && file.exists() && file.canRead()) { 587 load(new FileInputStream (file)); 588 } 589 } else { 590 addProperty(key, value); 591 } 592 } 593 } 594 } catch (NullPointerException ex) { 595 return; 597 } finally { 598 isInitialized = true; 600 } 601 } 602 603 610 public Object getProperty(String key) { 611 Object obj = this.get(key); 613 614 if (obj == null) { 615 if (defaults != null) { 618 obj = defaults.get(key); 619 } 620 } 621 622 return obj; 623 } 624 625 644 public void addProperty(String key, Object value) { 645 if (value instanceof String ) { 646 String str = (String ) value; 647 if (str.indexOf(PropertiesTokenizer.DELIMITER) > 0) { 648 PropertiesTokenizer tokenizer = new PropertiesTokenizer(str); 650 while (tokenizer.hasMoreTokens()) { 651 String token = tokenizer.nextToken(); 652 addPropertyInternal(key, unescape(token)); 653 } 654 } else { 655 addPropertyInternal(key, unescape(str)); 657 } 658 } else { 659 addPropertyInternal(key, value); 660 } 661 662 isInitialized = true; 664 } 665 666 673 private void addPropertyDirect(String key, Object value) { 674 if (!containsKey(key)) { 676 keysAsListed.add(key); 677 } 678 put(key, value); 679 } 680 681 692 private void addPropertyInternal(String key, Object value) { 693 Object current = this.get(key); 694 695 if (current instanceof String ) { 696 Vector v = new Vector (2); 698 v.addElement(current); 699 v.addElement(value); 700 put(key, v); 701 702 } else if (current instanceof Vector ) { 703 ((Vector ) current).addElement(value); 705 706 } else { 707 if (!containsKey(key)) { 709 keysAsListed.add(key); 710 } 711 put(key, value); 712 } 713 } 714 715 723 public void setProperty(String key, Object value) { 724 clearProperty(key); 725 addProperty(key, value); 726 } 727 728 737 public synchronized void save(OutputStream output, String header) throws IOException { 738 if (output == null) { 739 return; 740 } 741 PrintWriter theWrtr = new PrintWriter (output); 742 if (header != null) { 743 theWrtr.println(header); 744 } 745 746 Enumeration theKeys = keys(); 747 while (theKeys.hasMoreElements()) { 748 String key = (String ) theKeys.nextElement(); 749 Object value = get(key); 750 if (value != null) { 751 if (value instanceof String ) { 752 StringBuffer currentOutput = new StringBuffer (); 753 currentOutput.append(key); 754 currentOutput.append("="); 755 currentOutput.append(escape((String ) value)); 756 theWrtr.println(currentOutput.toString()); 757 758 } else if (value instanceof Vector ) { 759 Vector values = (Vector ) value; 760 Enumeration valuesEnum = values.elements(); 761 while (valuesEnum.hasMoreElements()) { 762 String currentElement = (String ) valuesEnum.nextElement(); 763 StringBuffer currentOutput = new StringBuffer (); 764 currentOutput.append(key); 765 currentOutput.append("="); 766 currentOutput.append(escape(currentElement)); 767 theWrtr.println(currentOutput.toString()); 768 } 769 } 770 } 771 theWrtr.println(); 772 theWrtr.flush(); 773 } 774 } 775 776 783 public void combine(ExtendedProperties props) { 784 for (Iterator it = props.getKeys(); it.hasNext();) { 785 String key = (String ) it.next(); 786 setProperty(key, props.get(key)); 787 } 788 } 789 790 795 public void clearProperty(String key) { 796 if (containsKey(key)) { 797 for (int i = 0; i < keysAsListed.size(); i++) { 800 if (( keysAsListed.get(i)).equals(key)) { 801 keysAsListed.remove(i); 802 break; 803 } 804 } 805 remove(key); 806 } 807 } 808 809 815 public Iterator getKeys() { 816 return keysAsListed.iterator(); 817 } 818 819 826 public Iterator getKeys(String prefix) { 827 Iterator keys = getKeys(); 828 ArrayList matchingKeys = new ArrayList (); 829 830 while (keys.hasNext()) { 831 Object key = keys.next(); 832 833 if (key instanceof String && ((String ) key).startsWith(prefix)) { 834 matchingKeys.add(key); 835 } 836 } 837 return matchingKeys.iterator(); 838 } 839 840 848 public ExtendedProperties subset(String prefix) { 849 ExtendedProperties c = new ExtendedProperties(); 850 Iterator keys = getKeys(); 851 boolean validSubset = false; 852 853 while (keys.hasNext()) { 854 Object key = keys.next(); 855 856 if (key instanceof String && ((String ) key).startsWith(prefix)) { 857 if (!validSubset) { 858 validSubset = true; 859 } 860 861 867 String newKey = null; 868 if (((String ) key).length() == prefix.length()) { 869 newKey = prefix; 870 } else { 871 newKey = ((String ) key).substring(prefix.length() + 1); 872 } 873 874 879 c.addPropertyDirect(newKey, get(key)); 880 } 881 } 882 883 if (validSubset) { 884 return c; 885 } else { 886 return null; 887 } 888 } 889 890 893 public void display() { 894 Iterator i = getKeys(); 895 896 while (i.hasNext()) { 897 String key = (String ) i.next(); 898 Object value = get(key); 899 System.out.println(key + " => " + value); 900 } 901 } 902 903 911 public String getString(String key) { 912 return getString(key, null); 913 } 914 915 925 public String getString(String key, String defaultValue) { 926 Object value = get(key); 927 928 if (value instanceof String ) { 929 return interpolate((String ) value); 930 931 } else if (value == null) { 932 if (defaults != null) { 933 return interpolate(defaults.getString(key, defaultValue)); 934 } else { 935 return interpolate(defaultValue); 936 } 937 } else if (value instanceof Vector ) { 938 return interpolate((String ) ((Vector ) value).get(0)); 939 } else { 940 throw new ClassCastException ('\'' + key + "' doesn't map to a String object"); 941 } 942 } 943 944 955 public Properties getProperties(String key) { 956 return getProperties(key, new Properties ()); 957 } 958 959 970 public Properties getProperties(String key, Properties defaults) { 971 974 String [] tokens = getStringArray(key); 975 976 Properties props = new Properties (defaults); 978 for (int i = 0; i < tokens.length; i++) { 979 String token = tokens[i]; 980 int equalSign = token.indexOf('='); 981 if (equalSign > 0) { 982 String pkey = token.substring(0, equalSign).trim(); 983 String pvalue = token.substring(equalSign + 1).trim(); 984 props.put(pkey, pvalue); 985 } else { 986 throw new IllegalArgumentException ('\'' + token + "' does not contain " + "an equals sign"); 987 } 988 } 989 return props; 990 } 991 992 1001 public String [] getStringArray(String key) { 1002 Object value = get(key); 1003 1004 Vector vector; 1006 if (value instanceof String ) { 1007 vector = new Vector (1); 1008 vector.addElement(value); 1009 1010 } else if (value instanceof Vector ) { 1011 vector = (Vector ) value; 1012 1013 } else if (value == null) { 1014 if (defaults != null) { 1015 return defaults.getStringArray(key); 1016 } else { 1017 return new String [0]; 1018 } 1019 } else { 1020 throw new ClassCastException ('\'' + key + "' doesn't map to a String/Vector object"); 1021 } 1022 1023 String [] tokens = new String [vector.size()]; 1024 for (int i = 0; i < tokens.length; i++) { 1025 tokens[i] = (String ) vector.elementAt(i); 1026 } 1027 1028 return tokens; 1029 } 1030 1031 1040 public Vector getVector(String key) { 1041 return getVector(key, null); 1042 } 1043 1044 1054 public Vector getVector(String key, Vector defaultValue) { 1055 Object value = get(key); 1056 1057 if (value instanceof Vector ) { 1058 return (Vector ) value; 1059 1060 } else if (value instanceof String ) { 1061 Vector v = new Vector (1); 1062 v.addElement(value); 1063 put(key, v); 1064 return v; 1065 1066 } else if (value == null) { 1067 if (defaults != null) { 1068 return defaults.getVector(key, defaultValue); 1069 } else { 1070 return ((defaultValue == null) ? new Vector () : defaultValue); 1071 } 1072 } else { 1073 throw new ClassCastException ('\'' + key + "' doesn't map to a Vector object"); 1074 } 1075 } 1076 1077 1087 public boolean getBoolean(String key) { 1088 Boolean b = getBoolean(key, null); 1089 if (b != null) { 1090 return b.booleanValue(); 1091 } else { 1092 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 1093 } 1094 } 1095 1096 1105 public boolean getBoolean(String key, boolean defaultValue) { 1106 return getBoolean(key, new Boolean (defaultValue)).booleanValue(); 1107 } 1108 1109 1119 public Boolean getBoolean(String key, Boolean defaultValue) { 1120 1121 Object value = get(key); 1122 1123 if (value instanceof Boolean ) { 1124 return (Boolean ) value; 1125 1126 } else if (value instanceof String ) { 1127 String s = testBoolean((String ) value); 1128 Boolean b = new Boolean (s); 1129 put(key, b); 1130 return b; 1131 1132 } else if (value == null) { 1133 if (defaults != null) { 1134 return defaults.getBoolean(key, defaultValue); 1135 } else { 1136 return defaultValue; 1137 } 1138 } else { 1139 throw new ClassCastException ('\'' + key + "' doesn't map to a Boolean object"); 1140 } 1141 } 1142 1143 1155 public String testBoolean(String value) { 1156 String s = value.toLowerCase(); 1157 1158 if (s.equals("true") || s.equals("on") || s.equals("yes")) { 1159 return "true"; 1160 } else if (s.equals("false") || s.equals("off") || s.equals("no")) { 1161 return "false"; 1162 } else { 1163 return null; 1164 } 1165 } 1166 1167 1179 public byte getByte(String key) { 1180 Byte b = getByte(key, null); 1181 if (b != null) { 1182 return b.byteValue(); 1183 } else { 1184 throw new NoSuchElementException ('\'' + key + " doesn't map to an existing object"); 1185 } 1186 } 1187 1188 1199 public byte getByte(String key, byte defaultValue) { 1200 return getByte(key, new Byte (defaultValue)).byteValue(); 1201 } 1202 1203 1215 public Byte getByte(String key, Byte defaultValue) { 1216 Object value = get(key); 1217 1218 if (value instanceof Byte ) { 1219 return (Byte ) value; 1220 1221 } else if (value instanceof String ) { 1222 Byte b = new Byte ((String ) value); 1223 put(key, b); 1224 return b; 1225 1226 } else if (value == null) { 1227 if (defaults != null) { 1228 return defaults.getByte(key, defaultValue); 1229 } else { 1230 return defaultValue; 1231 } 1232 } else { 1233 throw new ClassCastException ('\'' + key + "' doesn't map to a Byte object"); 1234 } 1235 } 1236 1237 1249 public short getShort(String key) { 1250 Short s = getShort(key, null); 1251 if (s != null) { 1252 return s.shortValue(); 1253 } else { 1254 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 1255 } 1256 } 1257 1258 1269 public short getShort(String key, short defaultValue) { 1270 return getShort(key, new Short (defaultValue)).shortValue(); 1271 } 1272 1273 1285 public Short getShort(String key, Short defaultValue) { 1286 Object value = get(key); 1287 1288 if (value instanceof Short ) { 1289 return (Short ) value; 1290 1291 } else if (value instanceof String ) { 1292 Short s = new Short ((String ) value); 1293 put(key, s); 1294 return s; 1295 1296 } else if (value == null) { 1297 if (defaults != null) { 1298 return defaults.getShort(key, defaultValue); 1299 } else { 1300 return defaultValue; 1301 } 1302 } else { 1303 throw new ClassCastException ('\'' + key + "' doesn't map to a Short object"); 1304 } 1305 } 1306 1307 1314 public int getInt(String name) { 1315 return getInteger(name); 1316 } 1317 1318 1326 public int getInt(String name, int def) { 1327 return getInteger(name, def); 1328 } 1329 1330 1342 public int getInteger(String key) { 1343 Integer i = getInteger(key, null); 1344 if (i != null) { 1345 return i.intValue(); 1346 } else { 1347 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 1348 } 1349 } 1350 1351 1362 public int getInteger(String key, int defaultValue) { 1363 Integer i = getInteger(key, null); 1364 1365 if (i == null) { 1366 return defaultValue; 1367 } 1368 return i.intValue(); 1369 } 1370 1371 1383 public Integer getInteger(String key, Integer defaultValue) { 1384 Object value = get(key); 1385 1386 if (value instanceof Integer ) { 1387 return (Integer ) value; 1388 1389 } else if (value instanceof String ) { 1390 Integer i = new Integer ((String ) value); 1391 put(key, i); 1392 return i; 1393 1394 } else if (value == null) { 1395 if (defaults != null) { 1396 return defaults.getInteger(key, defaultValue); 1397 } else { 1398 return defaultValue; 1399 } 1400 } else { 1401 throw new ClassCastException ('\'' + key + "' doesn't map to a Integer object"); 1402 } 1403 } 1404 1405 1417 public long getLong(String key) { 1418 Long l = getLong(key, null); 1419 if (l != null) { 1420 return l.longValue(); 1421 } else { 1422 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 1423 } 1424 } 1425 1426 1437 public long getLong(String key, long defaultValue) { 1438 return getLong(key, new Long (defaultValue)).longValue(); 1439 } 1440 1441 1453 public Long getLong(String key, Long defaultValue) { 1454 Object value = get(key); 1455 1456 if (value instanceof Long ) { 1457 return (Long ) value; 1458 1459 } else if (value instanceof String ) { 1460 Long l = new Long ((String ) value); 1461 put(key, l); 1462 return l; 1463 1464 } else if (value == null) { 1465 if (defaults != null) { 1466 return defaults.getLong(key, defaultValue); 1467 } else { 1468 return defaultValue; 1469 } 1470 } else { 1471 throw new ClassCastException ('\'' + key + "' doesn't map to a Long object"); 1472 } 1473 } 1474 1475 1487 public float getFloat(String key) { 1488 Float f = getFloat(key, null); 1489 if (f != null) { 1490 return f.floatValue(); 1491 } else { 1492 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 1493 } 1494 } 1495 1496 1507 public float getFloat(String key, float defaultValue) { 1508 return getFloat(key, new Float (defaultValue)).floatValue(); 1509 } 1510 1511 1523 public Float getFloat(String key, Float defaultValue) { 1524 Object value = get(key); 1525 1526 if (value instanceof Float ) { 1527 return (Float ) value; 1528 1529 } else if (value instanceof String ) { 1530 Float f = new Float ((String ) value); 1531 put(key, f); 1532 return f; 1533 1534 } else if (value == null) { 1535 if (defaults != null) { 1536 return defaults.getFloat(key, defaultValue); 1537 } else { 1538 return defaultValue; 1539 } 1540 } else { 1541 throw new ClassCastException ('\'' + key + "' doesn't map to a Float object"); 1542 } 1543 } 1544 1545 1557 public double getDouble(String key) { 1558 Double d = getDouble(key, null); 1559 if (d != null) { 1560 return d.doubleValue(); 1561 } else { 1562 throw new NoSuchElementException ('\'' + key + "' doesn't map to an existing object"); 1563 } 1564 } 1565 1566 1577 public double getDouble(String key, double defaultValue) { 1578 return getDouble(key, new Double (defaultValue)).doubleValue(); 1579 } 1580 1581 1593 public Double getDouble(String key, Double defaultValue) { 1594 Object value = get(key); 1595 1596 if (value instanceof Double ) { 1597 return (Double ) value; 1598 1599 } else if (value instanceof String ) { 1600 Double d = new Double ((String ) value); 1601 put(key, d); 1602 return d; 1603 1604 } else if (value == null) { 1605 if (defaults != null) { 1606 return defaults.getDouble(key, defaultValue); 1607 } else { 1608 return defaultValue; 1609 } 1610 } else { 1611 throw new ClassCastException ('\'' + key + "' doesn't map to a Double object"); 1612 } 1613 } 1614 1615 1621 public static ExtendedProperties convertProperties(Properties props) { 1622 ExtendedProperties c = new ExtendedProperties(); 1623 1624 for (Enumeration e = props.keys(); e.hasMoreElements();) { 1625 String s = (String ) e.nextElement(); 1626 c.setProperty(s, props.getProperty(s)); 1627 } 1628 1629 return c; 1630 } 1631 1632} 1633 | Popular Tags |