| 1 21 22 27 28 package javax.mail.internet; 29 30 import java.io.UnsupportedEncodingException ; 31 import java.net.InetAddress ; 32 import java.net.UnknownHostException ; 33 import java.util.Vector ; 34 import java.util.StringTokenizer ; 35 import javax.mail.*; 36 37 46 47 public class InternetAddress extends Address implements Cloneable { 48 49 protected String address; 51 54 protected String personal; 55 56 64 protected String encodedPersonal; 65 66 private static final long serialVersionUID = -7507595530758302903L; 67 68 71 public InternetAddress() { } 72 73 89 public InternetAddress(String address) throws AddressException { 90 InternetAddress a[] = parse(address, true); 92 if (a.length != 1) 94 throw new AddressException ("Illegal address", address); 95 96 102 this.address = a[0].address; 103 this.personal = a[0].personal; 104 this.encodedPersonal = a[0].encodedPersonal; 105 } 106 107 117 public InternetAddress(String address, boolean strict) 118 throws AddressException { 119 this(address); 120 if (strict) 121 checkAddress(this.address, true, true); 122 } 123 124 131 public InternetAddress(String address, String personal) 132 throws UnsupportedEncodingException { 133 this(address, personal, null); 134 } 135 136 144 public InternetAddress(String address, String personal, String charset) 145 throws UnsupportedEncodingException { 146 this.address = address; 147 setPersonal(personal, charset); 148 } 149 150 154 public Object clone() { 155 InternetAddress a = null; 156 try { 157 a = (InternetAddress )super.clone(); 158 } catch (CloneNotSupportedException e) {} return a; 160 } 161 162 166 public String getType() { 167 return "rfc822"; 168 } 169 170 175 public void setAddress(String address) { 176 this.address = address; 177 } 178 179 192 public void setPersonal(String name, String charset) 193 throws UnsupportedEncodingException { 194 personal = name; 195 if (name != null) 196 encodedPersonal = MimeUtility.encodeWord(name, charset, null); 197 else 198 encodedPersonal = null; 199 } 200 201 212 public void setPersonal(String name) 213 throws UnsupportedEncodingException { 214 personal = name; 215 if (name != null) 216 encodedPersonal = MimeUtility.encodeWord(name); 217 else 218 encodedPersonal = null; 219 } 220 221 225 public String getAddress() { 226 return address; 227 } 228 229 236 public String getPersonal() { 237 if (personal != null) 238 return personal; 239 240 if (encodedPersonal != null) { 241 try { 242 personal = MimeUtility.decodeText(encodedPersonal); 243 return personal; 244 } catch (Exception ex) { 245 return encodedPersonal; 249 } 250 } 251 return null; 253 } 254 255 262 public String toString() { 263 if (encodedPersonal == null && personal != null) 264 try { 265 encodedPersonal = MimeUtility.encodeWord(personal); 266 } catch (UnsupportedEncodingException ex) { } 267 268 if (encodedPersonal != null) 269 return quotePhrase(encodedPersonal) + " <" + address + ">"; 270 else if (isGroup() || isSimple()) 271 return address; 272 else 273 return "<" + address + ">"; 274 } 275 276 283 public String toUnicodeString() { 284 String p = getPersonal(); 285 if (p != null) 286 return quotePhrase(p) + " <" + address + ">"; 287 else if (isGroup() || isSimple()) 288 return address; 289 else 290 return "<" + address + ">"; 291 } 292 293 308 309 private static final String rfc822phrase = 310 HeaderTokenizer.RFC822.replace(' ', '\0').replace('\t', '\0'); 311 312 private static String quotePhrase(String phrase) { 313 int len = phrase.length(); 314 boolean needQuoting = false; 315 316 for (int i = 0; i < len; i++) { 317 char c = phrase.charAt(i); 318 if (c == '"' || c == '\\') { 319 StringBuffer sb = new StringBuffer (len + 3); 321 sb.append('"'); 322 for (int j = 0; j < len; j++) { 323 char cc = phrase.charAt(j); 324 if (cc == '"' || cc == '\\') 325 sb.append('\\'); 327 sb.append(cc); 328 } 329 sb.append('"'); 330 return sb.toString(); 331 } else if ((c < 040 && c != '\r' && c != '\n' && c != '\t') || 332 c >= 0177 || rfc822phrase.indexOf(c) >= 0) 333 needQuoting = true; 335 } 336 337 if (needQuoting) { 338 StringBuffer sb = new StringBuffer (len + 2); 339 sb.append('"').append(phrase).append('"'); 340 return sb.toString(); 341 } else 342 return phrase; 343 } 344 345 private static String unquote(String s) { 346 if (s.startsWith("\"") && s.endsWith("\"")) { 347 s = s.substring(1, s.length() - 1); 348 if (s.indexOf('\\') >= 0) { 350 StringBuffer sb = new StringBuffer (s.length()); for (int i = 0; i < s.length(); i++) { 352 char c = s.charAt(i); 353 if (c == '\\' && i < s.length() - 1) 354 c = s.charAt(++i); 355 sb.append(c); 356 } 357 s = sb.toString(); 358 } 359 } 360 return s; 361 } 362 363 366 public boolean equals(Object a) { 367 if (!(a instanceof InternetAddress )) 368 return false; 369 370 String s = ((InternetAddress )a).getAddress(); 371 if (s == address) 372 return true; 373 if (address != null && address.equalsIgnoreCase(s)) 374 return true; 375 376 return false; 377 } 378 379 382 public int hashCode() { 383 if (address == null) 384 return 0; 385 else 386 return address.toLowerCase().hashCode(); 387 } 388 389 401 public static String toString(Address [] addresses) { 402 return toString(addresses, 0); 403 } 404 405 425 public static String toString(Address [] addresses, int used) { 426 if (addresses == null || addresses.length == 0) 427 return null; 428 429 StringBuffer sb = new StringBuffer (); 430 431 for (int i = 0; i < addresses.length; i++) { 432 if (i != 0) { sb.append(", "); 434 used += 2; 435 } 436 437 String s = addresses[i].toString(); 438 int len = lengthOfFirstSegment(s); if (used + len > 76) { sb.append("\r\n\t"); used = 8; } 443 sb.append(s); 444 used = lengthOfLastSegment(s, used); 445 } 446 447 return sb.toString(); 448 } 449 450 453 private static int lengthOfFirstSegment(String s) { 454 int pos; 455 if ((pos = s.indexOf("\r\n")) != -1) 456 return pos; 457 else 458 return s.length(); 459 } 460 461 466 private static int lengthOfLastSegment(String s, int used) { 467 int pos; 468 if ((pos = s.lastIndexOf("\r\n")) != -1) 469 return s.length() - pos - 2; 470 else 471 return s.length() + used; 472 } 473 474 487 public static InternetAddress getLocalAddress(Session session) { 488 String user=null, host=null, address=null; 489 try { 490 if (session == null) { 491 user = System.getProperty("user.name"); 492 host = InetAddress.getLocalHost().getHostName(); 493 } else { 494 address = session.getProperty("mail.from"); 495 if (address == null) { 496 user = session.getProperty("mail.user"); 497 if (user == null || user.length() == 0) 498 user = session.getProperty("user.name"); 499 if (user == null || user.length() == 0) 500 user = System.getProperty("user.name"); 501 host = session.getProperty("mail.host"); 502 if (host == null || host.length() == 0) { 503 InetAddress me = InetAddress.getLocalHost(); 504 if (me != null) 505 host = me.getHostName(); 506 } 507 } 508 } 509 510 if (address == null && user != null && user.length() != 0 && 511 host != null && host.length() != 0) 512 address = user + "@" + host; 513 514 if (address != null) 515 return new InternetAddress (address); 516 } catch (SecurityException sex) { } catch (AddressException ex) { } catch (UnknownHostException ex) { } return null; 520 } 521 522 530 public static InternetAddress [] parse(String addresslist) 531 throws AddressException { 532 return parse(addresslist, true); 533 } 534 535 553 public static InternetAddress [] parse(String addresslist, boolean strict) 554 throws AddressException { 555 return parse(addresslist, strict, false); 556 } 557 558 578 public static InternetAddress [] parseHeader(String addresslist, 579 boolean strict) throws AddressException { 580 return parse(addresslist, strict, true); 581 } 582 583 591 private static InternetAddress [] parse(String s, boolean strict, 592 boolean parseHdr) throws AddressException { 593 int start, end, index, nesting; 594 int start_personal = -1, end_personal = -1; 595 int length = s.length(); 596 boolean in_group = false; boolean route_addr = false; boolean rfc822 = false; char c; 600 Vector v = new Vector (); 601 InternetAddress ma; 602 603 for (start = end = -1, index = 0; index < length; index++) { 604 c = s.charAt(index); 605 606 switch (c) { 607 case '(': rfc822 = true; 611 if (start >= 0 && end == -1) 612 end = index; 613 if (start_personal == -1) 614 start_personal = index + 1; 615 for (index++, nesting = 1; index < length && nesting > 0; 616 index++) { 617 c = s.charAt(index); 618 switch (c) { 619 case '\\': 620 index++; break; 622 case '(': 623 nesting++; 624 break; 625 case ')': 626 nesting--; 627 break; 628 default: 629 break; 630 } 631 } 632 if (nesting > 0) 633 throw new AddressException ("Missing ')'", s, index); 634 index--; if (end_personal == -1) 636 end_personal = index; 637 break; 638 639 case ')': 640 throw new AddressException ("Missing '('", s, index); 641 642 case '<': 643 rfc822 = true; 644 if (route_addr) 645 throw new AddressException ("Extra route-addr", s, index); 646 if (!in_group) { 647 start_personal = start; 648 if (start_personal >= 0) 649 end_personal = index; 650 start = index + 1; 651 } 652 653 boolean inquote = false; 654 outf: 655 for (index++; index < length; index++) { 656 c = s.charAt(index); 657 switch (c) { 658 case '\\': index++; break; 661 case '"': 662 inquote = !inquote; 663 break; 664 case '>': 665 if (inquote) 666 continue; 667 break outf; default: 669 break; 670 } 671 } 672 if (index >= length) { 673 if (inquote) 674 throw new AddressException ("Missing '\"'", s, index); 675 else 676 throw new AddressException ("Missing '>'", s, index); 677 } 678 route_addr = true; 679 end = index; 680 break; 681 case '>': 682 throw new AddressException ("Missing '<'", s, index); 683 684 case '"': rfc822 = true; 686 if (start == -1) 687 start = index; 688 outq: 689 for (index++; index < length; index++) { 690 c = s.charAt(index); 691 switch (c) { 692 case '\\': 693 index++; break; 695 case '"': 696 break outq; default: 698 break; 699 } 700 } 701 if (index >= length) 702 throw new AddressException ("Missing '\"'", s, index); 703 break; 704 705 case '[': rfc822 = true; 707 outb: 708 for (index++; index < length; index++) { 709 c = s.charAt(index); 710 switch (c) { 711 case '\\': 712 index++; break; 714 case ']': 715 break outb; default: 717 break; 718 } 719 } 720 if (index >= length) 721 throw new AddressException ("Missing ']'", s, index); 722 break; 723 724 case ',': if (start == -1) { 726 route_addr = false; 727 rfc822 = false; 728 start = end = -1; 729 break; } 731 if (in_group) { 732 route_addr = false; 733 break; 734 } 735 if (end == -1) 737 end = index; 738 String addr = s.substring(start, end).trim(); 739 if (rfc822 || strict || parseHdr) { 740 if (strict || !parseHdr) 741 checkAddress(addr, route_addr, false); 742 ma = new InternetAddress (); 743 ma.setAddress(addr); 744 if (start_personal >= 0) { 745 ma.encodedPersonal = unquote( 746 s.substring(start_personal, end_personal).trim()); 747 start_personal = end_personal = -1; 748 } 749 v.addElement(ma); 750 } else { 751 StringTokenizer st = new StringTokenizer (addr); 753 while (st.hasMoreTokens()) { 754 String a = st.nextToken(); 755 checkAddress(a, false, false); 756 ma = new InternetAddress (); 757 ma.setAddress(a); 758 v.addElement(ma); 759 } 760 } 761 762 route_addr = false; 763 rfc822 = false; 764 start = end = -1; 765 break; 766 767 case ':': 768 rfc822 = true; 769 if (in_group) 770 throw new AddressException ("Nested group", s, index); 771 in_group = true; 772 if (start == -1) 773 start = index; 774 break; 775 776 case ';': 777 if (start == -1) 778 start = index; 779 if (!in_group) 780 throw new AddressException ( 781 "Illegal semicolon, not in group", s, index); 782 in_group = false; 783 if (start == -1) 784 start = index; 785 ma = new InternetAddress (); 786 end = index + 1; 787 ma.setAddress(s.substring(start, end).trim()); 788 v.addElement(ma); 789 790 route_addr = false; 791 start = end = -1; 792 break; 793 794 case ' ': 796 case '\t': 797 case '\r': 798 case '\n': 799 break; 800 801 default: 802 if (start == -1) 803 start = index; 804 break; 805 } 806 } 807 808 if (start >= 0) { 809 814 if (end == -1) 815 end = index; 816 String addr = s.substring(start, end).trim(); 817 if (rfc822 || strict || parseHdr) { 818 if (strict || !parseHdr) 819 checkAddress(addr, route_addr, false); 820 ma = new InternetAddress (); 821 ma.setAddress(addr); 822 if (start_personal >= 0) { 823 ma.encodedPersonal = unquote( 824 s.substring(start_personal, end_personal).trim()); 825 } 826 v.addElement(ma); 827 } else { 828 StringTokenizer st = new StringTokenizer (addr); 830 while (st.hasMoreTokens()) { 831 String a = st.nextToken(); 832 checkAddress(a, false, false); 833 ma = new InternetAddress (); 834 ma.setAddress(a); 835 v.addElement(ma); 836 } 837 } 838 } 839 840 InternetAddress [] a = new InternetAddress [v.size()]; 841 v.copyInto(a); 842 return a; 843 } 844 845 |