1 7 8 package java.util; 9 10 import java.io.IOException ; 11 import java.io.PrintStream ; 12 import java.io.PrintWriter ; 13 import java.io.InputStream ; 14 import java.io.OutputStream ; 15 import java.io.OutputStreamWriter ; 16 import java.io.BufferedWriter ; 17 18 83 public 84 class Properties extends Hashtable <Object ,Object > { 85 88 private static final long serialVersionUID = 4112578634029874840L; 89 90 96 protected Properties defaults; 97 98 101 public Properties() { 102 this(null); 103 } 104 105 110 public Properties(Properties defaults) { 111 this.defaults = defaults; 112 } 113 114 127 public synchronized Object setProperty(String key, String value) { 128 return put(key, value); 129 } 130 131 282 public synchronized void load(InputStream inStream) throws IOException { 283 char[] convtBuf = new char[1024]; 284 LineReader lr = new LineReader(inStream); 285 286 int limit; 287 int keyLen; 288 int valueStart; 289 char c; 290 boolean hasSep; 291 boolean precedingBackslash; 292 293 while ((limit = lr.readLine()) >= 0) { 294 c = 0; 295 keyLen = 0; 296 valueStart = limit; 297 hasSep = false; 298 299 precedingBackslash = false; 301 while (keyLen < limit) { 302 c = lr.lineBuf[keyLen]; 303 if ((c == '=' || c == ':') && !precedingBackslash) { 305 valueStart = keyLen + 1; 306 hasSep = true; 307 break; 308 } else if ((c == ' ' || c == '\t' || c == '\f') && !precedingBackslash) { 309 valueStart = keyLen + 1; 310 break; 311 } 312 if (c == '\\') { 313 precedingBackslash = !precedingBackslash; 314 } else { 315 precedingBackslash = false; 316 } 317 keyLen++; 318 } 319 while (valueStart < limit) { 320 c = lr.lineBuf[valueStart]; 321 if (c != ' ' && c != '\t' && c != '\f') { 322 if (!hasSep && (c == '=' || c == ':')) { 323 hasSep = true; 324 } else { 325 break; 326 } 327 } 328 valueStart++; 329 } 330 String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf); 331 String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf); 332 put(key, value); 333 } 334 } 335 336 342 class LineReader { 343 public LineReader(InputStream inStream) { 344 this.inStream = inStream; 345 } 346 byte[] inBuf = new byte[8192]; 347 char[] lineBuf = new char[1024]; 348 int inLimit = 0; 349 int inOff = 0; 350 InputStream inStream; 351 352 int readLine() throws IOException { 353 int len = 0; 354 char c = 0; 355 356 boolean skipWhiteSpace = true; 357 boolean isCommentLine = false; 358 boolean isNewLine = true; 359 boolean appendedLineBegin = false; 360 boolean precedingBackslash = false; 361 boolean skipLF = false; 362 363 while (true) { 364 if (inOff >= inLimit) { 365 inLimit = inStream.read(inBuf); 366 inOff = 0; 367 if (inLimit <= 0) { 368 if (len == 0 || isCommentLine) { 369 return -1; 370 } 371 return len; 372 } 373 } 374 c = (char) (0xff & inBuf[inOff++]); 377 if (skipLF) { 378 skipLF = false; 379 if (c == '\n') { 380 continue; 381 } 382 } 383 if (skipWhiteSpace) { 384 if (c == ' ' || c == '\t' || c == '\f') { 385 continue; 386 } 387 if (!appendedLineBegin && (c == '\r' || c == '\n')) { 388 continue; 389 } 390 skipWhiteSpace = false; 391 appendedLineBegin = false; 392 } 393 if (isNewLine) { 394 isNewLine = false; 395 if (c == '#' || c == '!') { 396 isCommentLine = true; 397 continue; 398 } 399 } 400 401 if (c != '\n' && c != '\r') { 402 lineBuf[len++] = c; 403 if (len == lineBuf.length) { 404 int newLength = lineBuf.length * 2; 405 if (newLength < 0) { 406 newLength = Integer.MAX_VALUE; 407 } 408 char[] buf = new char[newLength]; 409 System.arraycopy(lineBuf, 0, buf, 0, lineBuf.length); 410 lineBuf = buf; 411 } 412 if (c == '\\') { 414 precedingBackslash = !precedingBackslash; 415 } else { 416 precedingBackslash = false; 417 } 418 } 419 else { 420 if (isCommentLine || len == 0) { 422 isCommentLine = false; 423 isNewLine = true; 424 skipWhiteSpace = true; 425 len = 0; 426 continue; 427 } 428 if (inOff >= inLimit) { 429 inLimit = inStream.read(inBuf); 430 inOff = 0; 431 if (inLimit <= 0) { 432 return len; 433 } 434 } 435 if (precedingBackslash) { 436 len -= 1; 437 skipWhiteSpace = true; 439 appendedLineBegin = true; 440 precedingBackslash = false; 441 if (c == '\r') { 442 skipLF = true; 443 } 444 } else { 445 return len; 446 } 447 } 448 } 449 } 450 } 451 452 456 private String loadConvert (char[] in, int off, int len, char[] convtBuf) { 457 if (convtBuf.length < len) { 458 int newLen = len * 2; 459 if (newLen < 0) { 460 newLen = Integer.MAX_VALUE; 461 } 462 convtBuf = new char[newLen]; 463 } 464 char aChar; 465 char[] out = convtBuf; 466 int outLen = 0; 467 int end = off + len; 468 469 while (off < end) { 470 aChar = in[off++]; 471 if (aChar == '\\') { 472 aChar = in[off++]; 473 if(aChar == 'u') { 474 int value=0; 476 for (int i=0; i<4; i++) { 477 aChar = in[off++]; 478 switch (aChar) { 479 case '0': case '1': case '2': case '3': case '4': 480 case '5': case '6': case '7': case '8': case '9': 481 value = (value << 4) + aChar - '0'; 482 break; 483 case 'a': case 'b': case 'c': 484 case 'd': case 'e': case 'f': 485 value = (value << 4) + 10 + aChar - 'a'; 486 break; 487 case 'A': case 'B': case 'C': 488 case 'D': case 'E': case 'F': 489 value = (value << 4) + 10 + aChar - 'A'; 490 break; 491 default: 492 throw new IllegalArgumentException ( 493 "Malformed \\uxxxx encoding."); 494 } 495 } 496 out[outLen++] = (char)value; 497 } else { 498 if (aChar == 't') aChar = '\t'; 499 else if (aChar == 'r') aChar = '\r'; 500 else if (aChar == 'n') aChar = '\n'; 501 else if (aChar == 'f') aChar = '\f'; 502 out[outLen++] = aChar; 503 } 504 } else { 505 out[outLen++] = (char)aChar; 506 } 507 } 508 return new String (out, 0, outLen); 509 } 510 511 515 private String saveConvert(String theString, boolean escapeSpace) { 516 int len = theString.length(); 517 int bufLen = len * 2; 518 if (bufLen < 0) { 519 bufLen = Integer.MAX_VALUE; 520 } 521 StringBuffer outBuffer = new StringBuffer (bufLen); 522 523 for(int x=0; x<len; x++) { 524 char aChar = theString.charAt(x); 525 if ((aChar > 61) && (aChar < 127)) { 528 if (aChar == '\\') { 529 outBuffer.append('\\'); outBuffer.append('\\'); 530 continue; 531 } 532 outBuffer.append(aChar); 533 continue; 534 } 535 switch(aChar) { 536 case ' ': 537 if (x == 0 || escapeSpace) 538 outBuffer.append('\\'); 539 outBuffer.append(' '); 540 break; 541 case '\t':outBuffer.append('\\'); outBuffer.append('t'); 542 break; 543 case '\n':outBuffer.append('\\'); outBuffer.append('n'); 544 break; 545 case '\r':outBuffer.append('\\'); outBuffer.append('r'); 546 break; 547 case '\f':outBuffer.append('\\'); outBuffer.append('f'); 548 break; 549 case '=': case ':': case '#': case '!': 553 outBuffer.append('\\'); outBuffer.append(aChar); 554 break; 555 default: 556 if ((aChar < 0x0020) || (aChar > 0x007e)) { 557 outBuffer.append('\\'); 558 outBuffer.append('u'); 559 outBuffer.append(toHex((aChar >> 12) & 0xF)); 560 outBuffer.append(toHex((aChar >> 8) & 0xF)); 561 outBuffer.append(toHex((aChar >> 4) & 0xF)); 562 outBuffer.append(toHex( aChar & 0xF)); 563 } else { 564 outBuffer.append(aChar); 565 } 566 } 567 } 568 return outBuffer.toString(); 569 } 570 571 587 @Deprecated 588 public synchronized void save(OutputStream out, String comments) { 589 try { 590 store(out, comments); 591 } catch (IOException e) { 592 } 593 } 594 595 647 public synchronized void store(OutputStream out, String comments) 648 throws IOException 649 { 650 BufferedWriter awriter; 651 awriter = new BufferedWriter (new OutputStreamWriter (out, "8859_1")); 652 if (comments != null) 653 writeln(awriter, "#" + comments); 654 writeln(awriter, "#" + new Date ().toString()); 655 for (Enumeration e = keys(); e.hasMoreElements();) { 656 String key = (String )e.nextElement(); 657 String val = (String )get(key); 658 key = saveConvert(key, true); 659 660 663 val = saveConvert(val, false); 664 writeln(awriter, key + "=" + val); 665 } 666 awriter.flush(); 667 } 668 669 private static void writeln(BufferedWriter bw, String s) throws IOException { 670 bw.write(s); 671 bw.newLine(); 672 } 673 674 696 public synchronized void loadFromXML(InputStream in) 697 throws IOException , InvalidPropertiesFormatException 698 { 699 if (in == null) 700 throw new NullPointerException (); 701 XMLUtils.load(this, in); 702 } 703 704 721 public synchronized void storeToXML(OutputStream os, String comment) 722 throws IOException 723 { 724 if (os == null) 725 throw new NullPointerException (); 726 storeToXML(os, comment, "UTF-8"); 727 } 728 729 753 public synchronized void storeToXML(OutputStream os, String comment, 754 String encoding) 755 throws IOException 756 { 757 if (os == null) 758 throw new NullPointerException (); 759 XMLUtils.save(this, os, comment, encoding); 760 } 761 762 773 public String getProperty(String key) { 774 Object oval = super.get(key); 775 String sval = (oval instanceof String ) ? (String )oval : null; 776 return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval; 777 } 778 779 792 public String getProperty(String key, String defaultValue) { 793 String val = getProperty(key); 794 return (val == null) ? defaultValue : val; 795 } 796 797 808 public Enumeration <?> propertyNames() { 809 Hashtable h = new Hashtable (); 810 enumerate(h); 811 return h.keys(); 812 } 813 814 820 public void list(PrintStream out) { 821 out.println("-- listing properties --"); 822 Hashtable h = new Hashtable (); 823 enumerate(h); 824 for (Enumeration e = h.keys() ; e.hasMoreElements() ;) { 825 String key = (String )e.nextElement(); 826 String val = (String )h.get(key); 827 if (val.length() > 40) { 828 val = val.substring(0, 37) + "..."; 829 } 830 out.println(key + "=" + val); 831 } 832 } 833 834 841 846 public void list(PrintWriter out) { 847 out.println("-- listing properties --"); 848 Hashtable h = new Hashtable (); 849 enumerate(h); 850 for (Enumeration e = h.keys() ; e.hasMoreElements() ;) { 851 String key = (String )e.nextElement(); 852 String val = (String )h.get(key); 853 if (val.length() > 40) { 854 val = val.substring(0, 37) + "..."; 855 } 856 out.println(key + "=" + val); 857 } 858 } 859 860 864 private synchronized void enumerate(Hashtable h) { 865 if (defaults != null) { 866 defaults.enumerate(h); 867 } 868 for (Enumeration e = keys() ; e.hasMoreElements() ;) { 869 String key = (String )e.nextElement(); 870 h.put(key, get(key)); 871 } 872 } 873 874 878 private static char toHex(int nibble) { 879 return hexDigit[(nibble & 0xF)]; 880 } 881 882 883 private static final char[] hexDigit = { 884 '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' 885 }; 886 } 887 | Popular Tags |