📄 imapfolder.java
字号:
IMAPProtocol p = null; try { p = getStoreProtocol(); // XXX MailboxInfo minfo = p.examine(fullName); p.close(); return minfo.recent; } catch (ProtocolException pex) { // Give up. throw new MessagingException(pex.getMessage(), pex); } finally { releaseStoreProtocol(p); } } catch (ConnectionException cex) { throw new StoreClosedException(store, cex.getMessage()); } catch (ProtocolException pex) { throw new MessagingException(pex.getMessage(), pex); } } // Folder is open, we know what the new message count is .. synchronized(messageCacheLock) { // tickle the folder and store connections. try { keepConnectionAlive(true); return recent; } catch (ConnectionException cex) { throw new FolderClosedException(this, cex.getMessage()); } catch (ProtocolException pex) { throw new MessagingException(pex.getMessage(), pex); } } } /** * Get the unread message count. */ public synchronized int getUnreadMessageCount() throws MessagingException { if (!opened) { checkExists(); // If this folder is not yet open, we use STATUS to // get the unseen message count try { Status status = getStatus(); return status.unseen; } catch (BadCommandException bex) { // doesn't support STATUS, probably vanilla IMAP4 .. // Could EXAMINE, SEARCH for UNREAD messages and // return the count .. bah, not worth it. return -1; } catch (ConnectionException cex) { throw new StoreClosedException(store, cex.getMessage()); } catch (ProtocolException pex) { throw new MessagingException(pex.getMessage(), pex); } } // if opened, issue server-side search for messages that do // *not* have the SEEN flag. Flags f = new Flags(); f.add(Flags.Flag.SEEN); try { synchronized(messageCacheLock) { int[] matches = getProtocol().search(new FlagTerm(f, false)); return matches.length; // NOTE: 'matches' is never null } } catch (ConnectionException cex) { throw new FolderClosedException(this, cex.getMessage()); } catch (ProtocolException pex) { // Shouldn't happen throw new MessagingException(pex.getMessage(), pex); } } /** * Get the deleted message count. */ public synchronized int getDeletedMessageCount() throws MessagingException { if (!opened) { checkExists(); // no way to do this on closed folders return -1; } // if opened, issue server-side search for messages that do // have the DELETED flag. Flags f = new Flags(); f.add(Flags.Flag.DELETED); try { synchronized(messageCacheLock) { int[] matches = getProtocol().search(new FlagTerm(f, true)); return matches.length; // NOTE: 'matches' is never null } } catch (ConnectionException cex) { throw new FolderClosedException(this, cex.getMessage()); } catch (ProtocolException pex) { // Shouldn't happen throw new MessagingException(pex.getMessage(), pex); } } /* * Get results of STATUS command for this folder, checking cache first. * ASSERT: Must be called with this folder's synchronization lock held. * ASSERT: The folder must be closed. */ private Status getStatus() throws ProtocolException { int statusCacheTimeout = ((IMAPStore)store).getStatusCacheTimeout(); // if allowed to cache and our cache is still valid, return it if (statusCacheTimeout > 0 && cachedStatus != null && System.currentTimeMillis() - cachedStatusTime < statusCacheTimeout) return cachedStatus; IMAPProtocol p = null; try { p = getStoreProtocol(); // XXX Status s = p.status(fullName, null); // if allowed to cache, do so if (statusCacheTimeout > 0) { cachedStatus = s; cachedStatusTime = System.currentTimeMillis(); } return s; } finally { releaseStoreProtocol(p); } } /** * Get the specified message. */ public synchronized Message getMessage(int msgnum) throws MessagingException { checkOpened(); checkRange(msgnum); return (Message)messageCache.elementAt(msgnum-1); } /** * Append the given messages into this folder. */ public synchronized void appendMessages(Message[] msgs) throws MessagingException { checkExists(); // verify that self exists // XXX - have to verify that messages are in a different // store (if any) than target folder, otherwise could // deadlock trying to fetch messages on the same connection // we're using for the append. int maxsize = ((IMAPStore)store).getAppendBufferSize(); for (int i = 0; i < msgs.length; i++) { final Message m = msgs[i]; final MessageLiteral mos; try { // if we know the message is too big, don't buffer any of it mos = new MessageLiteral(m, m.getSize() > maxsize ? 0 : maxsize); } catch (IOException ex) { throw new MessagingException( "IOException while appending messages", ex); } catch (MessageRemovedException mrex) { continue; // just skip this expunged message } Date d = m.getReceivedDate(); // retain dates if (d == null) d = m.getSentDate(); final Date dd = d; final Flags f = m.getFlags(); doCommand(new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { p.append(fullName, f, dd, mos); return null; } }); } } /** * Append the given messages into this folder. * Return array of AppendUID objects containing * UIDs of these messages in the destination folder. * Each element of the returned array corresponds to * an element of the <code>msgs</code> array. A null * element means the server didn't return UID information * for the appended message. <p> * * Depends on the APPENDUID response code defined by the * UIDPLUS extension - * <A HREF="http://www.ietf.org/rfc/rfc2359.txt">RFC 2359</A>. * * @since JavaMail 1.4 */ public synchronized AppendUID[] appendUIDMessages(Message[] msgs) throws MessagingException { checkExists(); // verify that self exists // XXX - have to verify that messages are in a different // store (if any) than target folder, otherwise could // deadlock trying to fetch messages on the same connection // we're using for the append. int maxsize = ((IMAPStore)store).getAppendBufferSize(); AppendUID[] uids = new AppendUID[msgs.length]; for (int i = 0; i < msgs.length; i++) { final Message m = msgs[i]; final MessageLiteral mos; try { // if we know the message is too big, don't buffer any of it mos = new MessageLiteral(m, m.getSize() > maxsize ? 0 : maxsize); } catch (IOException ex) { throw new MessagingException( "IOException while appending messages", ex); } catch (MessageRemovedException mrex) { continue; // just skip this expunged message } Date d = m.getReceivedDate(); // retain dates if (d == null) d = m.getSentDate(); final Date dd = d; final Flags f = m.getFlags(); AppendUID auid = (AppendUID)doCommand(new ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { return p.appenduid(fullName, f, dd, mos); } }); uids[i] = auid; } return uids; } /** * Append the given messages into this folder. * Return array of Message objects representing * the messages in the destination folder. Note * that the folder must be open. * Each element of the returned array corresponds to * an element of the <code>msgs</code> array. A null * element means the server didn't return UID information * for the appended message. <p> * * Depends on the APPENDUID response code defined by the * UIDPLUS extension - * <A HREF="http://www.ietf.org/rfc/rfc2359.txt">RFC 2359</A>. * * @since JavaMail 1.4 */ public synchronized Message[] addMessages(Message[] msgs) throws MessagingException { checkOpened(); Message[] rmsgs = new MimeMessage[msgs.length]; AppendUID[] uids = appendUIDMessages(msgs); for (int i = 0; i < uids.length; i++) { AppendUID auid = uids[i]; if (auid != null) { if (auid.uidvalidity == uidvalidity) { try { rmsgs[i] = getMessageByUID(auid.uid); } catch (MessagingException mex) { // ignore errors at this stage } } } } return rmsgs; } /** * Copy the specified messages from this folder, to the * specified destination. */ public synchronized void copyMessages(Message[] msgs, Folder folder) throws MessagingException { checkOpened(); if (msgs.length == 0) // boundary condition return; // If the destination belongs to our same store, optimize if (folder.getStore() == store) { synchronized(messageCacheLock) { try { IMAPProtocol p = getProtocol(); MessageSet[] ms = Utility.toMessageSet(msgs, null); if (ms == null) throw new MessageRemovedException( "Messages have been removed"); p.copy(ms, folder.getFullName()); } catch (CommandFailedException cfx) { if (cfx.getMessage().indexOf("TRYCREATE") != -1) throw new FolderNotFoundException( folder, folder.getFullName() + " does not exist" ); else throw new MessagingException(cfx.getMessage(), cfx); } catch (ConnectionException cex) { throw new FolderClosedException(this, cex.getMessage()); } catch (ProtocolException pex) { throw new MessagingException(pex.getMessage(), pex); } } } else // destination is a different store. super.copyMessages(msgs, folder); } /** * Expunge all messages marked as DELETED. */ public synchronized Message[] expunge() throws MessagingException { return expunge(null); } /** * Expunge the indicated messages, which must have been marked as DELETED. */ public synchronized Message[] expunge(Message[] msgs) throws MessagingException { checkOpened(); Vector v = new Vector(); // to collect expunged messages if (msgs != null) { // call fetch to make sure we have all the UIDs FetchProfile fp = new FetchProfile(); fp.add(UIDFolder.FetchProfileItem.UID); fetch(msgs, fp); } synchronized(messageCacheLock) { doExpungeNotification = false; // We do this ourselves later try { IMAPProtocol p = getProtocol(); if (msgs != null) p.uidexpunge(Utility.toUIDSet(msgs)); else p.expunge(); } catch (CommandFailedException cfx) { // expunge not allowed, perhaps due to a permission problem? if (mode != READ_WRITE) throw new IllegalStateException( "Cannot expunge READ_ONLY folder: " + fullName); else throw new MessagingException(cfx.getMessage(), cfx); } catch (ConnectionException cex) { throw new FolderClosedException(this, cex.getMessage()); } catch (ProtocolException pex) { // Bad bad server .. throw new MessagingException(pex.getMessage(), pex); } finally { doExpungeNotification = true; } // Cleanup expunged messages and sync messageCache with // reality. for (int i = 0; i < messageCache.size(); ) { IMAPMessage m = (IMAPMessage)messageCache.elementAt(i); if (m.isExpunged()) { v.addElement(m); // add into vector of expunged messages /* remove this message from the messageCache. * * Note that this also causes all succeeding messages * in the cache to shifted downward in the vector, * therby decrementing the vector's size. (and hence * we need to do messageCache.size() at the top of * this loop. */ messageCache.removeElementAt(i); /* remove this message from the UIDTable */ if (uidTable != null) { long uid = m.getUID(); if (uid != -1) uidTable.remove(new Long(uid)); } } else { /* Valid message, sync its message number with * its sequence number. */ m.setMessageNumber(m.getSequenceNumber()); i++; // done; increment index, go check next message } } } // Update 'total' total = messageCache.size(); // Notify listeners. This time its for real, guys. Message[] rmsgs = new Message[v.size()]; v.copyInto(rmsgs); if (rmsgs.length > 0) notifyMessageRemovedListeners(true, rmsgs); return rmsgs; } /** * Search whole folder for messages matching the given term.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -