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 855 public void validate() throws AddressException { 856 checkAddress(getAddress(), true, true); 857 } 858 859 private static final String specialsNoDotNoAt = "()<>,;:\\\"[]"; 860 private static final String specialsNoDot = specialsNoDotNoAt + "@"; 861 862 869 private static void checkAddress(String addr, 870 boolean routeAddr, boolean validate) 871 throws AddressException { 872 int i, start = 0; 873 if (addr.indexOf('"') >= 0) 874 return; if (routeAddr) { 876 880 for (start = 0; (i = indexOfAny(addr, ",:", start)) >= 0; 881 start = i+1) { 882 if (addr.charAt(start) != '@') 883 throw new AddressException ("Illegal route-addr", addr); 884 if (addr.charAt(i) == ':') { 885 start = i + 1; 887 break; 888 } 889 } 890 } 891 895 String local; 896 String domain; 897 if ((i = addr.indexOf('@', start)) >= 0) { 898 if (i == start) 899 throw new AddressException ("Missing local name", addr); 900 if (i == addr.length() - 1) 901 throw new AddressException ("Missing domain", addr); 902 local = addr.substring(start, i); 903 domain = addr.substring(i + 1); 904 } else { 905 914 if (validate) 915 throw new AddressException ("Missing final '@domain'", addr); 916 917 921 local = addr; 922 domain = null; 923 } 924 if (indexOfAny(addr, " \t\n\r") >= 0) 926 throw new AddressException ("Illegal whitespace in address", addr); 927 if (indexOfAny(local, specialsNoDot) >= 0) 929 throw new AddressException ("Illegal character in local name", addr); 930 if (domain != null && domain.indexOf('[') < 0) { 932 if (indexOfAny(domain, specialsNoDot) >= 0) 933 throw new AddressException ("Illegal character in domain", addr); 934 } 935 } 936 937 941 private boolean isSimple() { 942 return address == null || indexOfAny(address, specialsNoDotNoAt) < 0; 943 } 944 945 954 public boolean isGroup() { 955 return address != null && 957 address.endsWith(";") && address.indexOf(':') > 0; 958 } 959 960 971 public InternetAddress [] getGroup(boolean strict) throws AddressException { 972 Vector groups = null; 973 String addr = getAddress(); 974 if (!addr.endsWith(";")) 976 return null; 977 int ix = addr.indexOf(':'); 978 if (ix < 0) 979 return null; 980 String list = addr.substring(ix + 1, addr.length() - 1); 982 return InternetAddress.parseHeader(list, strict); 984 } 985 986 992 private static int indexOfAny(String s, String any) { 993 return indexOfAny(s, any, 0); 994 } 995 996 private static int indexOfAny(String s, String any, int start) { 997 try { 998 int len = s.length(); 999 for (int i = start; i < len; i++) { 1000 if (any.indexOf(s.charAt(i)) >= 0) 1001 return i; 1002 } 1003 return -1; 1004 } catch (StringIndexOutOfBoundsException e) { 1005 return -1; 1006 } 1007 } 1008 1009 1037} 1038 | Popular Tags |