📄 imapfolder.java
字号:
} 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 total message count is ..
synchronized(messageCacheLock) {
// tickle the folder and store connections.
try {
keepConnectionAlive(true);
return total;
} catch (ConnectionException cex) {
throw new FolderClosedException(this, cex.getMessage());
} catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex);
}
}
}
/**
* Get the new message count.
*/
public synchronized int getNewMessageCount()
throws MessagingException {
if (!opened) {
checkExists();
// If this folder is not yet open, we use STATUS to
// get the new message count
try {
Status status = getStatus();
return status.recent;
} catch (BadCommandException bex) {
// doesn't support STATUS, probably vanilla IMAP4 ..
// lets try EXAMINE
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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -