1 package gov.nasa.jpf; 20 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.io.PrintWriter ; 26 import java.io.StringWriter ; 27 import java.lang.reflect.Constructor ; 28 import java.lang.reflect.InvocationTargetException ; 29 import java.net.URL ; 30 import java.util.ArrayList ; 31 import java.util.Enumeration ; 32 import java.util.Iterator ; 33 import java.util.Properties ; 34 import java.util.TreeSet ; 35 import java.util.logging.Level ; 36 import java.util.logging.Logger ; 37 38 59 public class Config extends Properties { 60 61 static final String TARGET_KEY = "target"; 62 63 static final String TARGET_ARGS_KEY = "target_args"; 64 65 69 public class Exception extends java.lang.Exception { 70 public Exception(String msg) { 71 super(msg); 72 } 73 74 public Exception(String msg, Throwable cause) { 75 super(msg, cause); 76 } 77 78 public Exception(String key, Class cls, String failure) { 79 super("error instantiating class " + cls.getName() + " for entry \"" 80 + key + "\":" + failure); 81 } 82 83 public Exception(String key, Class cls, String failure, Throwable cause) { 84 this(key, cls, failure); 85 initCause(cause); 86 } 87 88 public String toString() { 89 StringBuffer sb = new StringBuffer (); 90 sb.append("JPF configuration error: "); 91 sb.append(getMessage()); 92 93 return sb.toString(); 94 } 95 } 96 97 String fileName; 98 99 Object source; 100 101 boolean gotProperties; 102 103 106 String [] freeArgs; 107 108 111 private Config(String alternatePath, Class codeBase) { 112 gotProperties = loadFile("default.properties", alternatePath, codeBase); 113 } 114 115 public Config(String [] args, String fileName, String alternatePath, 116 Class codeBase) { 117 super(new Config(alternatePath, 118 (codeBase == null) ? codeBase = getCallerClass(1) : codeBase)); 119 120 this.fileName = fileName; 121 gotProperties = loadFile(fileName, alternatePath, codeBase); 122 123 if (args != null){ 124 processArgs(args); 125 } 126 normalizeValues(); 127 } 128 129 public boolean gotDefaultProperties() { 130 if (defaults != null && defaults instanceof Config) { 131 return ((Config) defaults).gotProperties(); 132 } 133 return false; 134 } 135 136 public boolean gotProperties() { 137 return gotProperties; 138 } 139 140 public String getFileName() { 141 return fileName; 142 } 143 144 public String getSourceName() { 145 if (source == null) { 146 return null; 147 } else if (source instanceof File ) { 148 return ((File ) source).getAbsolutePath(); 149 } else if (source instanceof URL ) { 150 return source.toString(); 151 } else { 152 return source.toString(); 153 } 154 } 155 156 public String getDefaultsSourceName() { 157 if ((defaults != null) && (defaults instanceof Config)) { 158 return ((Config) defaults).getSourceName(); 159 } else { 160 return null; 161 } 162 } 163 164 public Object getSource() { 165 return source; 166 } 167 168 public String [] getArgs() { 169 return freeArgs; 170 } 171 172 public void throwException(String msg) throws Exception { 173 throw new Exception (msg); 174 } 175 176 183 public static Class getCallerClass(int up) { 184 int idx = up + 1; 186 StackTraceElement [] st = (new Throwable ()).getStackTrace(); 187 if ((up < 0) || (idx >= st.length)) { 188 return null; 189 } else { 190 try { 191 return Class.forName(st[idx].getClassName()); 192 } catch (Throwable t) { 193 return null; 194 } 195 } 196 } 197 198 boolean loadFile(String fileName, String alternatePath, Class codeBase) { 199 InputStream is = null; 200 201 try { 202 File f = new File (fileName); 204 if (!f.exists()) { 205 if (!f.isAbsolute() && (alternatePath != null)) { 207 f = new File (alternatePath, fileName); 208 } 209 } 210 211 if (f.exists()) { 212 source = f; 213 is = new FileInputStream (f); 214 } else { 215 Class clazz = (codeBase != null) ? codeBase : Config.class; 217 is = clazz.getResourceAsStream(fileName); 218 if (is != null) { 219 source = clazz.getResource(fileName); } 221 } 222 223 if (is != null) { 224 load(is); 225 return true; 226 } 227 } catch (IOException iex) { 228 return false; 229 } 230 231 return false; 232 } 233 234 241 void processArgs(String [] args) { 242 int i; 243 String arg; 244 ArrayList list = new ArrayList (); 245 246 for (i = 0; i < args.length; i++) { 247 String a = args[i]; 248 if (a != null) { 249 if (a.charAt(0) == '+') { 250 int idx = a.indexOf("="); 251 if (idx > 0) { 252 setProperty(a.substring(1, idx), a.substring(idx + 1)); 253 } else { 254 setProperty(a.substring(1), ""); 255 } 256 } else { 257 list.add(a); 258 } 259 } 260 } 261 262 int n = list.size(); 263 freeArgs = new String [n]; 264 for (i = 0; i < n; i++) { 265 freeArgs[i] = (String ) list.get(i); 266 } 267 } 268 269 273 public int getNonOptionArgIndex() { 274 if ((freeArgs == null) || (freeArgs.length == 0)) 275 return -1; 276 277 for (int i = 0; i < freeArgs.length; i++) { 278 String a = freeArgs[i]; 279 if (a != null) { 280 char c = a.charAt(0); 281 if (c != '-') { 282 return i; 283 } 284 } 285 } 286 287 return -1; 288 } 289 290 294 public String getTargetArg() { 295 int i = getNonOptionArgIndex(); 296 if (i < 0) { 297 return getString(TARGET_KEY); 298 } else { 299 return freeArgs[i]; 300 } 301 } 302 303 307 public String [] getTargetArgParameters() { 308 int i = getNonOptionArgIndex(); 309 if (i >= freeArgs.length - 1) { 310 String [] a = getStringArray(TARGET_ARGS_KEY); 311 if (a != null) { 312 return a; 313 } else { 314 return new String [0]; 315 } 316 } else { 317 int n = freeArgs.length - (i + 1); 318 String [] a = new String [n]; 319 System.arraycopy(freeArgs, i + 1, a, 0, n); 320 return a; 321 } 322 } 323 324 public String getArg(int i) { 325 if (freeArgs == null) 326 return null; 327 if (freeArgs.length - 1 < i) 328 return null; 329 if (i < 0) 330 return null; 331 332 return freeArgs[i]; 333 } 334 335 339 void normalizeValues() { 340 for (Enumeration keys = keys(); keys.hasMoreElements();) { 341 String k = (String ) keys.nextElement(); 342 String v = getProperty(k); 343 344 String v0 = v; 346 v = v.trim(); 347 if (v != v0) { 348 put(k, v); 349 } 350 351 if ("true".equalsIgnoreCase(v) || "t".equalsIgnoreCase(v) 352 || "yes".equalsIgnoreCase(v) || "y".equalsIgnoreCase(v)) { 353 put(k, "true"); 354 } else if ("false".equalsIgnoreCase(v) || "f".equalsIgnoreCase(v) 355 || "no".equalsIgnoreCase(v) || "n".equalsIgnoreCase(v)) { 356 put(k, "false"); 357 } 358 } 359 } 360 361 public boolean getBoolean(String key) { 362 String v = getProperty(key); 363 return (v != null) && ("true".equals(v)); 364 } 365 366 public boolean getBoolean(String key, boolean def) { 367 String v = getProperty(key); 368 if (v != null) { 369 return ("true".equals(v)); 370 } else { 371 return def; 372 } 373 } 374 375 public int[] getIntArray (String key) throws Exception { 376 String v = getProperty(key); 377 378 if (v != null) { 379 String [] sa = v.split("[:;, ]+"); 380 int[] a = new int[sa.length]; 381 int i = 0; 382 try { 383 for (; i<sa.length; i++) { 384 a[i] = Integer.parseInt(sa[i]); 385 } 386 return a; 387 } catch (NumberFormatException nfx) { 388 throw new Exception ("illegal int[] element in '" + key + "' = \"" + sa[i] + '"'); 389 } 390 } else { 391 return null; 392 } 393 } 394 395 public int getInt(String key) { 396 return getInt(key, 0); 397 } 398 399 public int getInt(String key, int defValue) { 400 String v = getProperty(key); 401 if (v != null) { 402 try { 403 return Integer.parseInt(v); 404 } catch (NumberFormatException nfx) { 405 return defValue; 406 } 407 } 408 409 return defValue; 410 } 411 412 public long getLong(String key) { 413 return getLong(key, 0L); 414 } 415 416 public long getLong(String key, long defValue) { 417 String v = getProperty(key); 418 if (v != null) { 419 try { 420 return Long.parseLong(v); 421 } catch (NumberFormatException nfx) { 422 return defValue; 423 } 424 } 425 426 return defValue; 427 } 428 429 public long[] getLongArray (String key) throws Exception { 430 String v = getProperty(key); 431 432 if (v != null) { 433 String [] sa = v.split("[:;, ]+"); 434 long[] a = new long[sa.length]; 435 int i = 0; 436 try { 437 for (; i<sa.length; i++) { 438 a[i] = Long.parseLong(sa[i]); 439 } 440 return a; 441 } catch (NumberFormatException nfx) { 442 throw new Exception ("illegal long[] element in " + key + " = " + sa[i]); 443 } 444 } else { 445 return null; 446 } 447 } 448 449 450 public double getDouble (String key) { 451 return getDouble(key, 0.0); 452 } 453 454 public double getDouble (String key, double defValue) { 455 String v = getProperty(key); 456 if (v != null) { 457 try { 458 return Double.parseDouble(v); 459 } catch (NumberFormatException nfx) { 460 return defValue; 461 } 462 } 463 464 return defValue; 465 } 466 467 public double[] getDoubleArray (String key) throws Exception { 468 String v = getProperty(key); 469 470 if (v != null) { 471 String [] sa = v.split("[:;, ]+"); 472 double[] a = new double[sa.length]; 473 int i = 0; 474 try { 475 for (; i<sa.length; i++) { 476 a[i] = Double.parseDouble(sa[i]); 477 } 478 return a; 479 } catch (NumberFormatException nfx) { 480 throw new Exception ("illegal double[] element in " + key + " = " + sa[i]); 481 } 482 } else { 483 return null; 484 } 485 } 486 487 488 public String getString(String key) { 489 return getProperty(key); 490 } 491 492 public String getString(String key, String defValue) { 493 String s = getProperty(key); 494 if (s != null) { 495 return s; 496 } else { 497 return defValue; 498 } 499 } 500 501 506 public String getExpandedString(String key) { 507 int i, j = 0; 508 String s = getString(key); 509 if (s == null || s.length() == 0) { 510 return s; 511 } 512 513 while ((i = s.indexOf("${", j)) >= 0) { 514 if ((j = s.indexOf('}', i)) > 0) { 515 String k = s.substring(i + 2, j); 516 String v = getString(k, ""); 517 if (v != null) { 518 s = s.substring(0, i) + v + s.substring(j + 1, s.length()); 519 j = i + v.length(); 520 } else { 521 s = s.substring(0, i) + s.substring(j + 1, s.length()); 522 j = i; 523 } 524 } 525 } 526 527 return s; 528 } 529 530 535 public long getMemorySize(String key, long defValue) { 536 String v = getProperty(key); 537 long sz = defValue; 538 539 if (v != null) { 540 int n = v.length() - 1; 541 try { 542 char c = v.charAt(n); 543 544 if ((c == 'M') || (c == 'm')) { 545 sz = Long.parseLong(v.substring(0, n)) << 20; 546 } else if ((c == 'K') || (c == 'k')) { 547 sz = Long.parseLong(v.substring(0, n)) << 10; 548 } else { 549 sz = Long.parseLong(v); 550 } 551 552 } catch (NumberFormatException nfx) { 553 return defValue; 554 } 555 } 556 557 return sz; 558 } 559 560 public String [] getStringArray(String key) { 561 String v = getProperty(key); 562 if (v != null) { 563 return v.split("[:;, ]+"); 564 } 565 566 return null; 567 } 568 569 public Class getClass(String key) throws Exception { 570 String v = getProperty(key); 571 if ((v != null) && (v.length() > 0)) { 572 try { 573 return Class.forName(v); 574 } catch (ClassNotFoundException cfx) { 575 throw new Exception ("class not found " + v); 576 } catch (ExceptionInInitializerError ix) { 577 throw new Exception ("class initialization of " + v + " failed: " + ix, 578 ix); 579 } 580 } 581 582 return null; 583 } 584 585 public Class getEssentialClass(String key) throws Exception { 586 Class cls = getClass(key); 587 if (cls == null) { 588 throw new Exception ("no classname entry for: \"" + key + "\""); 589 } 590 591 return cls; 592 } 593 594 public Class [] getClasses(String key) throws Exception { 595 String [] v = getStringArray(key); 596 if (v != null) { 597 int n = v.length; 598 Class [] a = new Class [n]; 599 for (int i = 0; i < n; i++) { 600 try { 601 a[i] = Class.forName(v[i]); 602 } catch (ClassNotFoundException cnfx) { 603 throw new Exception ("class not found " + v[i]); 604 } catch (ExceptionInInitializerError ix) { 605 throw new Exception ("class initialization of " + v[i] + " failed: " 606 + ix, ix); 607 } 608 } 609 610 return a; 611 } 612 613 return null; 614 } 615 616 public Object [] getInstances(String key, Class type) throws Exception { 617 Class [] c = getClasses(key); 618 if (c != null) { 619 Class [] argTypes = { Config.class }; 620 Object [] args = { this }; 621 Object [] a = new Object [c.length]; 622 623 for (int i = 0; i < c.length; i++) { 624 a[i] = getInstance(key, c[i], type, argTypes, args); 625 } 626 627 return a; 628 } 629 630 return null; 631 } 632 633 public Object getInstance(String key, Class type) throws Exception { 634 Class [] argTypes = { Config.class }; 635 Object [] args = { this }; 636 637 return getInstance(key, type, argTypes, args); 638 } 639 640 public Object getInstance(String key, Class type, Class [] argTypes, 641 Object [] args) throws Exception { 642 Class cls = getClass(key); 643 if (cls != null) { 644 return getInstance(key, cls, type, argTypes, args); 645 } else { 646 return null; 647 } 648 } 649 650 public Object getEssentialInstance(String key, Class type) throws Exception { 651 Class [] argTypes = { Config.class }; 652 Object [] args = { this }; 653 return getEssentialInstance(key, type, argTypes, args); 654 } 655 656 public Object getEssentialInstance(String key, Class type, Class [] argTypes, 657 Object [] args) throws Exception { 658 Class cls = getEssentialClass(key); 659 return getInstance(key, cls, type, argTypes, args); 660 } 661 662 668 Object getInstance(String key, Class cls, Class type, Class [] argTypes, 669 Object [] args) throws Exception { 670 Object o = null; 671 Constructor ctor = null; 672 673 if (cls == null) { 674 return null; 675 } 676 677 do { 678 try { 679 ctor = cls.getConstructor(argTypes); 680 o = ctor.newInstance(args); 681 } catch (NoSuchMethodException nmx) { 682 if (argTypes.length >= 1) { 683 if (argTypes[0] != Config.class) { 684 argTypes = new Class [1]; 686 argTypes[0] = Config.class; 687 args = new Object [1]; 688 args[0] = this; 689 } else { 690 argTypes = new Class [0]; 692 args = new Object [0]; 693 } 694 } else { 695 throw new Exception (key, cls, "no suitable ctor found"); 697 } 698 } catch (IllegalAccessException iacc) { 699 throw new Exception (key, cls, "\n> ctor not accessible: " 700 + getMethodSignature(ctor)); 701 } catch (IllegalArgumentException iarg) { 702 throw new Exception (key, cls, "\n> illegal constructor arguments: " 703 + getMethodSignature(ctor)); 704 } catch (InvocationTargetException ix) { 705 Throwable tx = ix.getTargetException(); 706 if (tx instanceof Config.Exception) { 707 throw new Exception (tx.getMessage() + "\n> used within \"" + key 708 + "\" instantiation of " + cls); 709 } else { 710 throw new Exception (key, cls, "\n> exception in " 711 + getMethodSignature(ctor) + ":\n>> " + tx, tx); 712 } 713 } catch (InstantiationException ivt) { 714 throw new Exception (key, cls, 715 "\n> abstract class cannot be instantiated"); 716 } catch (ExceptionInInitializerError eie) { 717 throw new Exception (key, cls, "\n> static initialization failed:\n>> " 718 + eie.getException(), eie.getException()); 719 } 720 } while (o == null); 721 722 if ((type != null) && !type.isInstance(o)) { 724 throw new Exception (key, cls, "\n> instance not of type: " 725 + type.getName()); 726 } 727 728 return o; 729 } 730 731 String getMethodSignature(Constructor ctor) { 732 StringBuffer sb = new StringBuffer (); 733 sb.append(ctor.getName()); 734 sb.append('('); 735 Class [] argTypes = ctor.getParameterTypes(); 736 for (int i = 0; i < argTypes.length; i++) { 737 if (i > 0) { 738 sb.append(','); 739 } 740 sb.append(argTypes[i].getName()); 741 } 742 sb.append(')'); 743 return sb.toString(); 744 } 745 746 753 public boolean hasArg(String regex) { 754 if (freeArgs == null) { 755 return false; 756 } 757 758 for (int i = 0; i < freeArgs.length; i++) { 759 if (freeArgs[i].matches(regex)) { 760 return true; 761 } 762 } 763 764 return false; 765 } 766 767 public boolean hasValue(String key) { 768 String v = getProperty(key); 769 return ((v != null) && (v.length() > 0)); 770 } 771 772 public boolean hasValueIgnoreCase(String key, String value) { 773 String v = getProperty(key); 774 if (v != null) { 775 return v.equalsIgnoreCase(value); 776 } 777 778 return false; 779 } 780 781 public int getChoiceIndexIgnoreCase(String key, String [] choices) { 782 String v = getProperty(key); 783 784 if ((v != null) && (choices != null)) { 785 for (int i = 0; i < choices.length; i++) { 786 if (v.equalsIgnoreCase(choices[i])) { 787 return i; 788 } 789 } 790 } 791 792 return -1; 793 } 794 795 public void print (PrintWriter pw) { 796 pw.println("----------- dictionary contents"); 797 798 TreeSet kset = new TreeSet (); 800 for (Enumeration e = propertyNames(); e.hasMoreElements();) { 801 kset.add(e.nextElement()); 802 } 803 for (Iterator it = kset.iterator(); it.hasNext();) { 804 String key = (String ) it.next(); 805 String val = getExpandedString(key); 806 pw.print(key); 807 pw.print(" = "); 808 pw.println(val); 809 } 810 811 if ((freeArgs != null) && (freeArgs.length > 0)) { 812 pw.println("----------- free arguments"); 813 for (int i = 0; i < freeArgs.length; i++) { 814 pw.println(freeArgs[i]); 815 } 816 } 817 818 pw.flush(); 819 } 820 821 public void printStatus(Logger log) { 822 log.config("configuration initialized from: " + getSourceName()); 823 824 Config def = (Config) defaults; 825 if (def.source == null) { 826 log.warning("no defaults.properties found"); 827 } else { 828 log.config("default configuration initialized from: " 829 + def.getSourceName()); 830 } 831 } 832 } 833 | Popular Tags |