1 21 22 27 28 package com.sun.mail.imap; 29 30 import java.util.Date ; 31 import java.io.*; 32 import java.util.Enumeration ; 33 import java.util.Vector ; 34 import java.util.Hashtable ; 35 36 import javax.mail.*; 37 import javax.mail.internet.*; 38 import javax.activation.*; 39 40 import com.sun.mail.util.*; 41 import com.sun.mail.iap.*; 42 import com.sun.mail.imap.protocol.*; 43 44 59 67 68 public class IMAPMessage extends MimeMessage { 69 protected BODYSTRUCTURE bs; protected ENVELOPE envelope; 72 private Date receivedDate; private int size = -1; 75 private boolean peek; 77 private int seqnum; 79 private long uid = -1; 81 82 protected String sectionId; 85 86 private String type; private String subject; private String description; 91 private boolean headersLoaded = false; 93 94 102 private Hashtable loadedHeaders; 103 104 private static String EnvelopeCmd = "ENVELOPE INTERNALDATE RFC822.SIZE"; 106 107 110 protected IMAPMessage(IMAPFolder folder, int msgnum, int seqnum) { 111 super(folder, msgnum); 112 this.seqnum = seqnum; 113 flags = null; 114 } 115 116 119 protected IMAPMessage(Session session) { 120 super(session); 121 } 122 123 130 protected IMAPProtocol getProtocol() throws FolderClosedException { 131 IMAPProtocol p = ((IMAPFolder)folder).protocol; 132 if (p == null) 133 throw new FolderClosedException(folder); 134 else 135 return p; 136 } 137 138 142 protected Object getMessageCacheLock() { 143 return ((IMAPFolder)folder).messageCacheLock; 144 } 145 146 152 protected int getSequenceNumber() { 153 return seqnum; 154 } 155 156 162 protected void setSequenceNumber(int seqnum) { 163 this.seqnum = seqnum; 164 } 165 166 170 protected void setMessageNumber(int msgnum) { 171 super.setMessageNumber(msgnum); 172 } 173 174 protected long getUID() { 175 return uid; 176 } 177 178 protected void setUID(long uid) { 179 this.uid = uid; 180 } 181 182 protected void setExpunged(boolean set) { 184 super.setExpunged(set); 185 seqnum = -1; 186 } 187 188 protected void checkExpunged() throws MessageRemovedException { 190 if (expunged) 191 throw new MessageRemovedException(); 192 } 193 194 198 protected void forceCheckExpunged() 199 throws MessageRemovedException, FolderClosedException { 200 synchronized (getMessageCacheLock()) { 201 try { 202 getProtocol().noop(); 203 } catch (ConnectionException cex) { 204 throw new FolderClosedException(folder, cex.getMessage()); 205 } catch (ProtocolException pex) { 206 } 208 } 209 if (expunged) 210 throw new MessageRemovedException(); 211 } 212 213 protected int getFetchBlockSize() { 215 return ((IMAPStore)folder.getStore()).getFetchBlockSize(); 216 } 217 218 221 public Address[] getFrom() throws MessagingException { 222 checkExpunged(); 223 loadEnvelope(); 224 return aaclone(envelope.from); 225 } 226 227 public void setFrom(Address address) throws MessagingException { 228 throw new IllegalWriteException("IMAPMessage is read-only"); 229 } 230 231 public void addFrom(Address[] addresses) throws MessagingException { 232 throw new IllegalWriteException("IMAPMessage is read-only"); 233 } 234 235 238 public Address getSender() throws MessagingException { 239 checkExpunged(); 240 loadEnvelope(); 241 if (envelope.sender != null) 242 return (envelope.sender)[0]; else 244 return null; 245 } 246 247 248 public void setSender(Address address) throws MessagingException { 249 throw new IllegalWriteException("IMAPMessage is read-only"); 250 } 251 252 255 public Address[] getRecipients(Message.RecipientType type) 256 throws MessagingException { 257 checkExpunged(); 258 loadEnvelope(); 259 260 if (type == Message.RecipientType.TO) 261 return aaclone(envelope.to); 262 else if (type == Message.RecipientType.CC) 263 return aaclone(envelope.cc); 264 else if (type == Message.RecipientType.BCC) 265 return aaclone(envelope.bcc); 266 else 267 return super.getRecipients(type); 268 } 269 270 public void setRecipients(Message.RecipientType type, Address[] addresses) 271 throws MessagingException { 272 throw new IllegalWriteException("IMAPMessage is read-only"); 273 } 274 275 public void addRecipients(Message.RecipientType type, Address[] addresses) 276 throws MessagingException { 277 throw new IllegalWriteException("IMAPMessage is read-only"); 278 } 279 280 283 public Address[] getReplyTo() throws MessagingException { 284 checkExpunged(); 285 loadEnvelope(); 286 return aaclone(envelope.replyTo); 287 } 288 289 public void setReplyTo(Address[] addresses) throws MessagingException { 290 throw new IllegalWriteException("IMAPMessage is read-only"); 291 } 292 293 296 public String getSubject() throws MessagingException { 297 checkExpunged(); 298 299 if (subject != null) return subject; 301 302 loadEnvelope(); 303 if (envelope.subject == null) return null; 305 306 try { 308 subject = MimeUtility.decodeText(envelope.subject); 309 } catch (UnsupportedEncodingException ex) { 310 subject = envelope.subject; 311 } 312 313 return subject; 314 } 315 316 public void setSubject(String subject, String charset) 317 throws MessagingException { 318 throw new IllegalWriteException("IMAPMessage is read-only"); 319 } 320 321 324 public Date getSentDate() throws MessagingException { 325 checkExpunged(); 326 loadEnvelope(); 327 if (envelope.date == null) 328 return null; 329 else 330 return new Date (envelope.date.getTime()); 331 } 332 333 public void setSentDate(Date d) throws MessagingException { 334 throw new IllegalWriteException("IMAPMessage is read-only"); 335 } 336 337 340 public Date getReceivedDate() throws MessagingException { 341 checkExpunged(); 342 loadEnvelope(); 343 if (receivedDate == null) 344 return null; 345 else 346 return new Date (receivedDate.getTime()); 347 } 348 349 355 public int getSize() throws MessagingException { 356 checkExpunged(); 357 if (size == -1) 358 loadEnvelope(); return size; 360 } 361 362 369 public int getLineCount() throws MessagingException { 370 checkExpunged(); 371 loadBODYSTRUCTURE(); 372 return bs.lines; 373 } 374 375 378 public String [] getContentLangauge() throws MessagingException { 379 checkExpunged(); 380 loadBODYSTRUCTURE(); 381 if (bs.language != null) 382 return (String [])(bs.language).clone(); 383 else 384 return null; 385 } 386 387 public void setContentLanguage(String [] languages) 388 throws MessagingException { 389 throw new IllegalWriteException("IMAPMessage is read-only"); 390 } 391 392 397 public String getInReplyTo() throws MessagingException { 398 checkExpunged(); 399 loadEnvelope(); 400 return envelope.inReplyTo; 401 } 402 403 409 public String getContentType() throws MessagingException { 410 checkExpunged(); 411 412 if (type == null) { 414 loadBODYSTRUCTURE(); 415 ContentType ct = new ContentType(bs.type, bs.subtype, bs.cParams); 417 type = ct.toString(); 418 } 419 return type; 420 } 421 422 425 public String getDisposition() throws MessagingException { 426 checkExpunged(); 427 loadBODYSTRUCTURE(); 428 return bs.disposition; 429 } 430 431 public void setDisposition(String disposition) throws MessagingException { 432 throw new IllegalWriteException("IMAPMessage is read-only"); 433 } 434 435 438 public String getEncoding() throws MessagingException { 439 checkExpunged(); 440 loadBODYSTRUCTURE(); 441 return bs.encoding; 442 } 443 444 447 public String getContentID() throws MessagingException { 448 checkExpunged(); 449 loadBODYSTRUCTURE(); 450 return bs.id; 451 } 452 453 public void setContentID(String cid) throws MessagingException { 454 throw new IllegalWriteException("IMAPMessage is read-only"); 455 } 456 457 460 public String getContentMD5() throws MessagingException { 461 checkExpunged(); 462 loadBODYSTRUCTURE(); 463 return bs.md5; 464 } 465 466 public void setContentMD5(String md5) throws MessagingException { 467 throw new IllegalWriteException("IMAPMessage is read-only"); 468 } 469 470 473 public String getDescription() throws MessagingException { 474 checkExpunged(); 475 476 if (description != null) return description; 478 479 loadBODYSTRUCTURE(); 480 if (bs.description == null) 481 return null; 482 483 try { 484 description = MimeUtility.decodeText(bs.description); 485 } catch (UnsupportedEncodingException ex) { 486 description = bs.description; 487 } 488 489 return description; 490 } 491 492 public void setDescription(String description, String charset) 493 throws MessagingException { 494 throw new IllegalWriteException("IMAPMessage is read-only"); 495 } 496 497 500 public String getMessageID() throws MessagingException { 501 checkExpunged(); 502 loadEnvelope(); 503 return envelope.messageId; 504 } 505 506 511 public String getFileName() throws MessagingException { 512 checkExpunged(); 513 514 String filename = null; 515 loadBODYSTRUCTURE(); 516 517 if (bs.dParams != null) 518 filename = bs.dParams.get("filename"); 519 if (filename == null && bs.cParams != null) 520 filename = bs.cParams.get("name"); 521 return filename; 522 } 523 524 public void setFileName(String filename) throws MessagingException { 525 throw new IllegalWriteException("IMAPMessage is read-only"); 526 } 527 528 535 protected InputStream getContentStream() throws MessagingException { 536 InputStream is = null; 537 boolean pk = getPeek(); 539 synchronized(getMessageCacheLock()) { 541 542 IMAPProtocol p = getProtocol(); 543 if (p.isREV1() && (getFetchBlockSize() != -1)) return new IMAPInputStream(this, toSection("TEXT"), 545 bs != null ? bs.size : -1, pk); 546 547 checkExpunged(); 550 551 try { 552 if (p.isREV1()) { 553 BODY b; 554 if (pk) 555 b = p.peekBody(getSequenceNumber(), toSection("TEXT")); 556 else 557 b = p.fetchBody(getSequenceNumber(), toSection("TEXT")); 558 if (b != null) 559 is = b.getByteArrayInputStream(); 560 } else { 561 RFC822DATA rd = p.fetchRFC822(getSequenceNumber(), "TEXT"); 562 if (rd != null) 563 is = rd.getByteArrayInputStream(); 564 } 565 } catch (ConnectionException cex) { 566 throw new FolderClosedException(folder, cex.getMessage()); 567 } catch (ProtocolException pex) { 568 forceCheckExpunged(); 569 throw new MessagingException(pex.getMessage(), pex); 570 } 571 } 572 573 if (is == null) 574 throw new MessagingException("No content"); 575 else 576 return is; 577 } 578 579 582 public synchronized DataHandler getDataHandler() 583 throws MessagingException { 584 checkExpunged(); 585 586 if (dh == null) { 587 loadBODYSTRUCTURE(); 588 if (type == null) { ContentType ct = new ContentType(bs.type, bs.subtype, 591 bs.cParams); 592 type = ct.toString(); 593 } 594 595 598 if (bs.isMulti()) 599 dh = new DataHandler( 600 new IMAPMultipartDataSource(this, bs.bodies, 601 sectionId, this) 602 ); 603 else if (bs.isNested() && getProtocol().isREV1()) 604 608 dh = new DataHandler( 609 new IMAPNestedMessage(this, 610 bs.bodies[0], 611 bs.envelope, 612 sectionId == null ? "1" : sectionId + ".1"), 613 type 614 ); 615 } 616 617 return super.getDataHandler(); 618 } 619 620 public void setDataHandler(DataHandler content) 621 throws MessagingException { 622 throw new IllegalWriteException("IMAPMessage is read-only"); 623 } 624 625 628 public void writeTo(OutputStream os) 629 throws IOException, MessagingException { 630 InputStream is = null; 631 boolean pk = getPeek(); 633 synchronized(getMessageCacheLock()) { 635 checkExpunged(); 637 IMAPProtocol p = getProtocol(); 638 try { 639 if (p.isREV1()) { 640 BODY b; 641 if (pk) 642 b = p.peekBody(getSequenceNumber(), sectionId); 643 else 644 b = p.fetchBody(getSequenceNumber(), sectionId); 645 if (b != null) 646 is = b.getByteArrayInputStream(); 647 } else { 648 RFC822DATA rd = p.fetchRFC822(getSequenceNumber(), null); 649 if (rd != null) 650 is = rd.getByteArrayInputStream(); 651 } 652 } catch (ConnectionException cex) { 653 throw new FolderClosedException(folder, cex.getMessage()); 654 } catch (ProtocolException pex) { 655 forceCheckExpunged(); 656 throw new MessagingException(pex.getMessage(), pex); 657 } 658 } 659 660 if (is == null) 661 throw new MessagingException("No content"); 662 663 byte[] bytes = new byte[1024]; 665 int count; 666 while ((count = is.read(bytes)) != -1) 667 os.write(bytes, 0, count); 668 } 669 670 673 public String [] getHeader(String name) throws MessagingException { 674 checkExpunged(); 675 676 if (isHeaderLoaded(name)) return headers.getHeader(name); 678 679 InputStream is = null; 681 682 synchronized(getMessageCacheLock()) { 684 685 checkExpunged(); 688 689 IMAPProtocol p = getProtocol(); 690 try { 691 if (p.isREV1()) { 692 BODY b = p.peekBody(getSequenceNumber(), 693 toSection("HEADER.FIELDS (" + name + ")") 694 ); 695 if (b != null) 696 is = b.getByteArrayInputStream(); 697 } else { 698 RFC822DATA rd = p.fetchRFC822(getSequenceNumber(), 699 "HEADER.LINES (" + name + ")"); 700 if (rd != null) 701 is = rd.getByteArrayInputStream(); 702 } 703 } catch (ConnectionException cex) { 704 throw new FolderClosedException(folder, cex.getMessage()); 705 } catch (ProtocolException pex) { 706 forceCheckExpunged(); 707 throw new MessagingException(pex.getMessage(), pex); 708 } 709 } 710 711 if (is == null) 714 return null; 715 716 if (headers == null) 717 headers = new InternetHeaders(); 718 headers.load(is); setHeaderLoaded(name); 721 return headers.getHeader(name); 722 } 723 724 727 public String getHeader(String name, String delimiter) 728 throws MessagingException { 729 checkExpunged(); 730 731 if (getHeader(name) == null) 733 return null; 734 return headers.getHeader(name, delimiter); 735 } 736 737 public void setHeader(String name, String value) 738 throws MessagingException { 739 throw new IllegalWriteException("IMAPMessage is read-only"); 740 } 741 742 public void addHeader(String name, String value) 743 throws MessagingException { 744 throw new IllegalWriteException("IMAPMessage is read-only"); 745 } 746 747 public void removeHeader(String name) 748 throws MessagingException { 749 throw new IllegalWriteException("IMAPMessage is read-only"); 750 } 751 752 755 public Enumeration getAllHeaders() throws MessagingException { 756 checkExpunged(); 757 loadHeaders(); 758 return super.getAllHeaders(); 759 } 760 761 764 public Enumeration getMatchingHeaders(String [] names) 765 throws MessagingException { 766 checkExpunged(); 767 loadHeaders(); 768 return super.getMatchingHeaders(names); 769 } 770 771 774 public Enumeration getNonMatchingHeaders(String [] names) 775 throws MessagingException { 776 checkExpunged(); 777 loadHeaders(); 778 return super.getNonMatchingHeaders(names); 779 } 780 781 public void addHeaderLine(String line) throws MessagingException { 782 throw new IllegalWriteException("IMAPMessage is read-only"); 783 } 784 785 788 public Enumeration getAllHeaderLines() throws MessagingException { 789 checkExpunged(); 790 loadHeaders(); 791 return super.getAllHeaderLines(); 792 } 793 794 797 public Enumeration getMatchingHeaderLines(String [] names) 798 throws MessagingException { 799 checkExpunged(); 800 loadHeaders(); 801 return super.getMatchingHeaderLines(names); 802 } 803 804 807 public Enumeration getNonMatchingHeaderLines(String [] names) 808 throws MessagingException { 809 checkExpunged(); 810 loadHeaders(); 811 return super.getNonMatchingHeaderLines(names); 812 } 813 814 817 public synchronized Flags getFlags() throws MessagingException { 818 checkExpunged(); 819 loadFlags(); 820 return super.getFlags(); 821 } 822 823 826 public synchronized boolean isSet(Flags.Flag flag) 827 throws MessagingException { 828 checkExpunged(); 829 loadFlags(); 830 return super.isSet(flag); 831 } 832 833 836 public synchronized void setFlags(Flags flag, boolean set) 837 throws MessagingException { 838 synchronized(getMessageCacheLock()) { 840 checkExpunged(); 842 try { 843 getProtocol().storeFlags(getSequenceNumber(), flag, set); 844 } catch (ConnectionException cex) { 845 throw new FolderClosedException(folder, cex.getMessage()); 846 } catch (ProtocolException pex) { 847 throw new MessagingException(pex.getMessage(), pex); 848 } 849 } 850 } 851 852 858 public synchronized void setPeek(boolean peek) { 859 this.peek = peek; 860 } 861 862 868 public synchronized boolean getPeek() { 869 return peek; 870 } 871 872 879 public synchronized void invalidateHeaders() { 880 headersLoaded = false; 881 loadedHeaders = null; 882 envelope = null; 883 bs = null; 884 receivedDate = null; 885 size = -1; 886 type = null; 887 subject = null; 888 description = null; 889 } 890 891 894 static void fetch(IMAPFolder folder, Message[] msgs, 895 FetchProfile fp) throws MessagingException { 896 897 903 class FetchProfileCondition implements Utility.Condition { 904 private boolean needEnvelope = false; 905 private boolean needFlags = false; 906 private boolean needBodyStructure = false; 907 private boolean needUID = false; 908 private boolean needHeaders = false; 909 private boolean needSize = false; 910 private String [] hdrs = null; 911 912 public FetchProfileCondition(FetchProfile fp) { 913 if (fp.contains(FetchProfile.Item.ENVELOPE)) 914 needEnvelope = true; 915 if (fp.contains(FetchProfile.Item.FLAGS)) 916 needFlags = true; 917 if (fp.contains(FetchProfile.Item.CONTENT_INFO)) 918 needBodyStructure = true; 919 if (fp.contains(UIDFolder.FetchProfileItem.UID)) 920 needUID = true; 921 if (fp.contains(IMAPFolder.FetchProfileItem.HEADERS)) 922 needHeaders = true; 923 if (fp.contains(IMAPFolder.FetchProfileItem.SIZE)) 924 needSize = true; 925 hdrs = fp.getHeaderNames(); 926 } 927 928 public boolean test(IMAPMessage m) { 930 if (needEnvelope && m._getEnvelope() == null) 931 return true; if (needFlags && m._getFlags() == null) 933 return true; if (needBodyStructure && m._getBodyStructure() == null) 935 return true; if (needUID && m.getUID() == -1) return true; 938 if (needHeaders && !m.headersLoaded) return true; 940 if (needSize && m.size == -1) return true; 942 943 for (int i = 0; i < hdrs.length; i++) { 945 if (!m.isHeaderLoaded(hdrs[i])) 946 return true; } 948 949 return false; 950 } 951 } 952 953 StringBuffer command = new StringBuffer (); 954 boolean first = true; 955 boolean allHeaders = false; 956 957 if (fp.contains(FetchProfile.Item.ENVELOPE)) { 958 command.append(EnvelopeCmd); 959 first = false; 960 } 961 if (fp.contains(FetchProfile.Item.FLAGS)) { 962 command.append(first ? "FLAGS" : " FLAGS"); 963 first = false; 964 } 965 if (fp.contains(FetchProfile.Item.CONTENT_INFO)) { 966 command.append(first ? "BODYSTRUCTURE" : " BODYSTRUCTURE"); 967 first = false; 968 } 969 if (fp.contains(UIDFolder.FetchProfileItem.UID)) { 970 command.append(first ? "UID" : " UID"); 971 first = false; 972 } 973 if (fp.contains(IMAPFolder.FetchProfileItem.HEADERS)) { 974 allHeaders = true; 975 if (folder.protocol.isREV1()) 976 command.append(first ? 977 "BODY.PEEK[HEADER]" : " BODY.PEEK[HEADER]"); 978 else 979 command.append(first ? "RFC822.HEADER" : " RFC822.HEADER"); 980 first = false; 981 } 982 if (fp.contains(IMAPFolder.FetchProfileItem.SIZE)) { 983 command.append(first ? "RFC822.SIZE" : " RFC822.SIZE"); 984 first = false; 985 } 986 987 String [] hdrs = null; 989 if (!allHeaders) { 990 hdrs = fp.getHeaderNames(); 991 if (hdrs.length > 0) { 992 if (!first) 993 command.append(" "); 994 command.append(craftHeaderCmd(folder.protocol, hdrs)); 995 } 996 } 997 998 Utility.Condition condition = new FetchProfileCondition(fp); 999 1000 synchronized(folder.messageCacheLock) { 1002 1003 MessageSet[] msgsets = Utility.toMessageSet(msgs, condition); 1006 1007 if (msgsets == null) 1008 return; 1010 1011 Response[] r = null; 1012 Vector v = new Vector (); try { 1015 r = folder.protocol.fetch(msgsets, command.toString()); 1016 } catch (ConnectionException cex) { 1017 throw new FolderClosedException(folder, cex.getMessage()); 1018 } catch (CommandFailedException cfx) { 1019 } catch (ProtocolException pex) { 1021 throw new MessagingException(pex.getMessage(), pex); 1022 } 1023 1024 if (r == null) 1025 return; 1026 1027 for (int i = 0; i < r.length; i++) { 1028 if (r[i] == null) 1029 continue; 1030 if (!(r[i] instanceof FetchResponse)) { 1031 v.addElement(r[i]); continue; 1033 } 1034 1035 FetchResponse f = (FetchResponse)r[i]; 1037 IMAPMessage msg = folder.getMessageBySeqNumber(f.getNumber()); 1039 1040 int count = f.getItemCount(); 1041 boolean unsolicitedFlags = false; 1042 1043 for (int j = 0; j < count; j++) { 1044 Item item = f.getItem(j); 1045 1046 if (item instanceof Flags) { 1048 if (!fp.contains(FetchProfile.Item.FLAGS) || 1049 msg == null) 1050 unsolicitedFlags = true; 1052 else 1053 msg.flags = (Flags)item; 1054 } 1055 1056 else if (item instanceof ENVELOPE) 1058 msg.envelope = (ENVELOPE)item; 1059 else if (item instanceof INTERNALDATE) 1060 msg.receivedDate = ((INTERNALDATE)item).getDate(); 1061 else if (item instanceof RFC822SIZE) 1062 msg.size = ((RFC822SIZE)item).size; 1063 1064 else if (item instanceof BODYSTRUCTURE) 1066 msg.bs = (BODYSTRUCTURE)item; 1067 else if (item instanceof UID) { 1069 UID u = (UID)item; 1070 msg.uid = u.uid; if (folder.uidTable == null) 1073 folder.uidTable = new Hashtable (); 1074 folder.uidTable.put(new Long (u.uid), msg); 1075 } 1076 1077 else if (item instanceof RFC822DATA || 1079 item instanceof BODY) { 1080 InputStream headerStream; 1081 if (item instanceof RFC822DATA) headerStream = 1083 ((RFC822DATA)item).getByteArrayInputStream(); 1084 else headerStream = 1086 ((BODY)item).getByteArrayInputStream(); 1087 1088 InternetHeaders h = new InternetHeaders(); 1090 h.load(headerStream); 1091 if (msg.headers == null || allHeaders) 1092 msg.headers = h; 1093 else { 1094 1103 Enumeration e = h.getAllHeaders(); 1104 while (e.hasMoreElements()) { 1105 Header he = (Header)e.nextElement(); 1106 if (!msg.isHeaderLoaded(he.getName())) 1107 msg.headers.addHeader( 1108 he.getName(), he.getValue()); 1109 } 1110 } 1111 1112 if (allHeaders) 1114 msg.headersLoaded = true; 1115 else { 1116 for (int k = 0; k < hdrs.length; k++) 1118 msg.setHeaderLoaded(hdrs[k]); 1119 } 1120 } 1121 } 1122 1123 if (unsolicitedFlags) 1126 v.addElement(f); 1127 } 1128 1129 int size = v.size(); 1131 if (size != 0) { 1132 Response[] responses = new Response[size]; 1133 v.copyInto(responses); 1134 folder.handleResponses(responses); 1135 } 1136 1137 } } 1139 1140 1143 private synchronized void loadEnvelope() throws MessagingException { 1144 if (envelope != null) return; 1146 1147 IMAPProtocol p = getProtocol(); 1148 Response[] r = null; 1149 1150 synchronized(getMessageCacheLock()) { 1152 1153 checkExpunged(); 1155 int seqnum = getSequenceNumber(); 1156 try { 1157 r = p.fetch(seqnum, EnvelopeCmd); 1158 1159 for (int i = 0; i < r.length; i++) { 1160 if (r[i] == null || 1163 !(r[i] instanceof FetchResponse) || 1164 ((FetchResponse)r[i]).getNumber() != seqnum) 1165 continue; 1166 1167 FetchResponse f = (FetchResponse)r[i]; 1168 1169 int count = f.getItemCount(); 1171 for (int j = 0; j < count; j++) { 1172 Item item = f.getItem(j); 1173 1174 if (item instanceof ENVELOPE) 1175 envelope = (ENVELOPE)item; 1176 else if (item instanceof INTERNALDATE) 1177 receivedDate = ((INTERNALDATE)item).getDate(); 1178 else if (item instanceof RFC822SIZE) 1179 size = ((RFC822SIZE)item).size; 1180 } 1181 } 1182 1183 p.notifyResponseHandlers(r); 1185 p.handleResult(r[r.length - 1]); 1186 } catch (ConnectionException cex) { 1187 throw new FolderClosedException(folder, cex.getMessage()); 1188 } catch (ProtocolException pex) { 1189 forceCheckExpunged(); 1190 throw new MessagingException(pex.getMessage(), pex); 1191 } 1192 1193 } 1195 if (envelope == null) 1196 throw new MessagingException("Failed to load IMAP envelope"); 1197 } 1198 1199 private static String craftHeaderCmd(IMAPProtocol p, String [] hdrs) { 1200 StringBuffer sb; 1201 1202 if (p.isREV1()) 1203 sb = new StringBuffer ("BODY.PEEK[HEADER.FIELDS ("); 1204 else 1205 sb = new StringBuffer ("RFC822.HEADER.LINES ("); 1206 1207 for (int i = 0; i < hdrs.length; i++) { 1208 if (i > 0) 1209 sb.append(" "); 1210 sb.append(hdrs[i]); 1211 } 1212 1213 if (p.isREV1()) 1214 sb.append(")]"); 1215 else 1216 sb.append(")"); 1217 1218 return sb.toString(); 1219 } 1220 1221 1224 private synchronized void loadBODYSTRUCTURE() 1225 throws MessagingException { 1226 if (bs != null) return; 1228 1229 synchronized(getMessageCacheLock()) { 1231 checkExpunged(); 1234 1235 try { 1236 bs = getProtocol().fetchBodyStructure(getSequenceNumber()); 1237 } catch (ConnectionException cex) { 1238 throw new FolderClosedException(folder, cex.getMessage()); 1239 } catch (ProtocolException pex) { 1240 forceCheckExpunged(); 1241 throw new MessagingException(pex.getMessage(), pex); 1242 } 1243 if (bs == null) 1244 throw new MessagingException("Unable to load BODYSTRUCTURE"); 1245 } 1246 } 1247 1248 1251 private synchronized void loadHeaders() throws MessagingException { 1252 if (headersLoaded) 1253 return; 1254 1255 InputStream is = null; 1256 1257 synchronized (getMessageCacheLock()) { 1259 1260 checkExpunged(); 1263 1264 IMAPProtocol p = getProtocol(); 1265 try { 1266 if (p.isREV1()) { 1267 BODY b = p.peekBody(getSequenceNumber(), 1268 toSection("HEADER")); 1269 if (b != null) 1270 is = b.getByteArrayInputStream(); 1271 } else { 1272 RFC822DATA rd = p.fetchRFC822(getSequenceNumber(), 1273 "HEADER"); 1274 if (rd != null) 1275 is = rd.getByteArrayInputStream(); 1276 } 1277 } catch (ConnectionException cex) { 1278 throw new FolderClosedException(folder, cex.getMessage()); 1279 } catch (ProtocolException pex) { 1280 forceCheckExpunged(); 1281 throw new MessagingException(pex.getMessage(), pex); 1282 } 1283 } 1285 if (is == null) 1286 throw new MessagingException("Cannot load header"); 1287 headers = new InternetHeaders(is); 1288 headersLoaded = true; 1289 } 1290 1291 1294 private synchronized void loadFlags() throws MessagingException { 1295 if (flags != null) 1296 return; 1297 1298 synchronized(getMessageCacheLock()) { 1300 1301 checkExpunged(); 1304 1305 try { 1306 flags = getProtocol().fetchFlags(getSequenceNumber()); 1307 } catch (ConnectionException cex) { 1308 throw new FolderClosedException(folder, cex.getMessage()); 1309 } catch (ProtocolException pex) { 1310 forceCheckExpunged(); 1311 throw new MessagingException(pex.getMessage(), pex); 1312 } 1313 } } 1315 1316 1319 private boolean isHeaderLoaded(String name) { 1320 if (headersLoaded) return true; 1322 1323 return (loadedHeaders != null) ? 1324 loadedHeaders.containsKey(name.toUpperCase()) : false; 1325 } 1326 1327 1330 private void setHeaderLoaded(String name) { 1331 if (loadedHeaders == null) 1332 loadedHeaders = new Hashtable (1); 1333 loadedHeaders.put(name.toUpperCase(), name); 1334 } 1335 1336 1340 private String toSection(String what) { 1341 if (sectionId == null) 1342 return what; 1343 else 1344 return sectionId + "." + what; 1345 } 1346 1347 1350 private InternetAddress[] aaclone(InternetAddress[] aa) { 1351 if (aa == null) 1352 return null; 1353 else 1354 return (InternetAddress[])aa.clone(); 1355 } 1356 1357 private Flags _getFlags() { 1358 return flags; 1359 } 1360 1361 private ENVELOPE _getEnvelope() { 1362 return envelope; 1363 } 1364 1365 private BODYSTRUCTURE _getBodyStructure() { 1366 return bs; 1367 } 1368 1369 1373 1374 1378 void _setFlags(Flags flags) { 1379 this.flags = flags; 1380 } 1381 1382 1385 Session _getSession() { 1386 return session; 1387 } 1388} 1389 | Popular Tags |