imapmessage.java
来自「此源码是在sun站点上提供的javamail基础上改进。用来解决中文邮件或很多国」· Java 代码 · 共 1,442 行 · 第 1/3 页
JAVA
1,442 行
return true; // no flags
if (needBodyStructure && m._getBodyStructure() == null)
return true; // no BODYSTRUCTURE
if (needUID && m.getUID() == -1) // no UID
return true;
if (needHeaders && !m.areHeadersLoaded()) // no headers
return true;
if (needSize && m.size == -1) // no size
return true;
// Is the desired header present ?
for (int i = 0; i < hdrs.length; i++) {
if (!m.isHeaderLoaded(hdrs[i]))
return true; // Nope, return
}
return false;
}
}
StringBuffer command = new StringBuffer();
boolean first = true;
boolean allHeaders = false;
if (fp.contains(FetchProfile.Item.ENVELOPE)) {
command.append(EnvelopeCmd);
first = false;
}
if (fp.contains(FetchProfile.Item.FLAGS)) {
command.append(first ? "FLAGS" : " FLAGS");
first = false;
}
if (fp.contains(FetchProfile.Item.CONTENT_INFO)) {
command.append(first ? "BODYSTRUCTURE" : " BODYSTRUCTURE");
first = false;
}
if (fp.contains(UIDFolder.FetchProfileItem.UID)) {
command.append(first ? "UID" : " UID");
first = false;
}
if (fp.contains(IMAPFolder.FetchProfileItem.HEADERS)) {
allHeaders = true;
if (folder.protocol.isREV1())
command.append(first ?
"BODY.PEEK[HEADER]" : " BODY.PEEK[HEADER]");
else
command.append(first ? "RFC822.HEADER" : " RFC822.HEADER");
first = false;
}
if (fp.contains(IMAPFolder.FetchProfileItem.SIZE)) {
command.append(first ? "RFC822.SIZE" : " RFC822.SIZE");
first = false;
}
// if we're not fetching all headers, fetch individual headers
String[] hdrs = null;
if (!allHeaders) {
hdrs = fp.getHeaderNames();
if (hdrs.length > 0) {
if (!first)
command.append(" ");
command.append(craftHeaderCmd(folder.protocol, hdrs));
}
}
Utility.Condition condition = new FetchProfileCondition(fp);
// Acquire the Folder's MessageCacheLock.
synchronized(folder.messageCacheLock) {
// Apply the test, and get the sequence-number set for
// the messages that need to be prefetched.
MessageSet[] msgsets = Utility.toMessageSet(msgs, condition);
if (msgsets == null)
// We already have what we need.
return;
Response[] r = null;
Vector v = new Vector(); // to collect non-FETCH responses &
// unsolicited FETCH FLAG responses
try {
r = folder.protocol.fetch(msgsets, command.toString());
} catch (ConnectionException cex) {
throw new FolderClosedException(folder, cex.getMessage());
} catch (CommandFailedException cfx) {
// Ignore these, as per RFC 2180
} catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex);
}
if (r == null)
return;
for (int i = 0; i < r.length; i++) {
if (r[i] == null)
continue;
if (!(r[i] instanceof FetchResponse)) {
v.addElement(r[i]); // Unsolicited Non-FETCH response
continue;
}
// Got a FetchResponse.
FetchResponse f = (FetchResponse)r[i];
// Get the corresponding message.
IMAPMessage msg = folder.getMessageBySeqNumber(f.getNumber());
int count = f.getItemCount();
boolean unsolicitedFlags = false;
for (int j = 0; j < count; j++) {
Item item = f.getItem(j);
// Check for the FLAGS item
if (item instanceof Flags) {
if (!fp.contains(FetchProfile.Item.FLAGS) ||
msg == null)
// Ok, Unsolicited FLAGS update.
unsolicitedFlags = true;
else
msg.flags = (Flags)item;
}
// Check for ENVELOPE items
else if (item instanceof ENVELOPE)
msg.envelope = (ENVELOPE)item;
else if (item instanceof INTERNALDATE)
msg.receivedDate = ((INTERNALDATE)item).getDate();
else if (item instanceof RFC822SIZE)
msg.size = ((RFC822SIZE)item).size;
// Check for the BODYSTRUCTURE item
else if (item instanceof BODYSTRUCTURE)
msg.bs = (BODYSTRUCTURE)item;
// Check for the UID item
else if (item instanceof UID) {
UID u = (UID)item;
msg.uid = u.uid; // set uid
// add entry into uid table
if (folder.uidTable == null)
folder.uidTable = new Hashtable();
folder.uidTable.put(new Long(u.uid), msg);
}
// Check for header items
else if (item instanceof RFC822DATA ||
item instanceof BODY) {
InputStream headerStream;
if (item instanceof RFC822DATA) // IMAP4
headerStream =
((RFC822DATA)item).getByteArrayInputStream();
else // IMAP4rev1
headerStream =
((BODY)item).getByteArrayInputStream();
// Load the obtained headers.
InternetHeaders h = new InternetHeaders();
h.load(headerStream);
if (msg.headers == null || allHeaders)
msg.headers = h;
else {
/*
* This is really painful. A second fetch
* of the same headers (which might occur because
* a new header was added to the set requested)
* will return headers we already know about.
* In this case, only load the headers we haven't
* seen before to avoid adding duplicates of
* headers we already have.
*/
Enumeration e = h.getAllHeaders();
while (e.hasMoreElements()) {
Header he = (Header)e.nextElement();
if (!msg.isHeaderLoaded(he.getName()))
msg.headers.addHeader(
he.getName(), he.getValue());
}
}
// if we asked for all headers, assume we got them
if (allHeaders)
msg.setHeadersLoaded(true);
else {
// Mark all headers we asked for as 'loaded'
for (int k = 0; k < hdrs.length; k++)
msg.setHeaderLoaded(hdrs[k]);
}
}
}
// If this response contains any unsolicited FLAGS
// add it to the unsolicited response vector
if (unsolicitedFlags)
v.addElement(f);
}
// Dispatch any unsolicited responses
int size = v.size();
if (size != 0) {
Response[] responses = new Response[size];
v.copyInto(responses);
folder.handleResponses(responses);
}
} // Release messageCacheLock
}
/*
* Load the Envelope for this message.
*/
private synchronized void loadEnvelope() throws MessagingException {
if (envelope != null) // already loaded
return;
Response[] r = null;
// Acquire MessageCacheLock, to freeze seqnum.
synchronized(getMessageCacheLock()) {
try {
IMAPProtocol p = getProtocol();
checkExpunged(); // Insure that this message is not expunged
int seqnum = getSequenceNumber();
r = p.fetch(seqnum, EnvelopeCmd);
for (int i = 0; i < r.length; i++) {
// If this response is NOT a FetchResponse or if it does
// not match our seqnum, skip.
if (r[i] == null ||
!(r[i] instanceof FetchResponse) ||
((FetchResponse)r[i]).getNumber() != seqnum)
continue;
FetchResponse f = (FetchResponse)r[i];
// Look for the Envelope items.
int count = f.getItemCount();
for (int j = 0; j < count; j++) {
Item item = f.getItem(j);
if (item instanceof ENVELOPE)
envelope = (ENVELOPE)item;
else if (item instanceof INTERNALDATE)
receivedDate = ((INTERNALDATE)item).getDate();
else if (item instanceof RFC822SIZE)
size = ((RFC822SIZE)item).size;
}
}
// ((IMAPFolder)folder).handleResponses(r);
p.notifyResponseHandlers(r);
p.handleResult(r[r.length - 1]);
} catch (ConnectionException cex) {
throw new FolderClosedException(folder, cex.getMessage());
} catch (ProtocolException pex) {
forceCheckExpunged();
throw new MessagingException(pex.getMessage(), pex);
}
} // Release MessageCacheLock
if (envelope == null)
throw new MessagingException("Failed to load IMAP envelope");
}
private static String craftHeaderCmd(IMAPProtocol p, String[] hdrs) {
StringBuffer sb;
if (p.isREV1())
sb = new StringBuffer("BODY.PEEK[HEADER.FIELDS (");
else
sb = new StringBuffer("RFC822.HEADER.LINES (");
for (int i = 0; i < hdrs.length; i++) {
if (i > 0)
sb.append(" ");
sb.append(hdrs[i]);
}
if (p.isREV1())
sb.append(")]");
else
sb.append(")");
return sb.toString();
}
/*
* Load the BODYSTRUCTURE
*/
private synchronized void loadBODYSTRUCTURE()
throws MessagingException {
if (bs != null) // already loaded
return;
// Acquire MessageCacheLock, to freeze seqnum.
synchronized(getMessageCacheLock()) {
try {
IMAPProtocol p = getProtocol();
// This message could be expunged when we were waiting
// to acquire the lock ...
checkExpunged();
bs = p.fetchBodyStructure(getSequenceNumber());
} catch (ConnectionException cex) {
throw new FolderClosedException(folder, cex.getMessage());
} catch (ProtocolException pex) {
forceCheckExpunged();
throw new MessagingException(pex.getMessage(), pex);
}
if (bs == null) {
// if the FETCH is successful, we should always get a
// BODYSTRUCTURE, but some servers fail to return it
// if the message has been expunged
forceCheckExpunged();
throw new MessagingException("Unable to load BODYSTRUCTURE");
}
}
}
/*
* Load all headers.
*/
private synchronized void loadHeaders() throws MessagingException {
if (headersLoaded)
return;
InputStream is = null;
// Acquire MessageCacheLock, to freeze seqnum.
synchronized (getMessageCacheLock()) {
try {
IMAPProtocol p = getProtocol();
// This message could be expunged when we were waiting
// to acquire the lock ...
checkExpunged();
if (p.isREV1()) {
BODY b = p.peekBody(getSequenceNumber(),
toSection("HEADER"));
if (b != null)
is = b.getByteArrayInputStream();
} else {
RFC822DATA rd = p.fetchRFC822(getSequenceNumber(),
"HEADER");
if (rd != null)
is = rd.getByteArrayInputStream();
}
} catch (ConnectionException cex) {
throw new FolderClosedException(folder, cex.getMessage());
} catch (ProtocolException pex) {
forceCheckExpunged();
throw new MessagingException(pex.getMessage(), pex);
}
} // Release MessageCacheLock
if (is == null)
throw new MessagingException("Cannot load header");
headers = new InternetHeaders(is);
headersLoaded = true;
}
/*
* Load this message's Flags
*/
private synchronized void loadFlags() throws MessagingException {
if (flags != null)
return;
// Acquire MessageCacheLock, to freeze seqnum.
synchronized(getMessageCacheLock()) {
try {
IMAPProtocol p = getProtocol();
// This message could be expunged when we were waiting
// to acquire the lock ...
checkExpunged();
flags = p.fetchFlags(getSequenceNumber());
} catch (ConnectionException cex) {
throw new FolderClosedException(folder, cex.getMessage());
} catch (ProtocolException pex) {
forceCheckExpunged();
throw new MessagingException(pex.getMessage(), pex);
}
} // Release MessageCacheLock
}
/*
* Are all headers loaded?
*/
private synchronized boolean areHeadersLoaded() {
return headersLoaded;
}
/*
* Set whether all headers are loaded.
*/
private synchronized void setHeadersLoaded(boolean loaded) {
headersLoaded = loaded;
}
/*
* Check if the given header was ever loaded from the server
*/
private synchronized boolean isHeaderLoaded(String name) {
if (headersLoaded) // All headers for this message have been loaded
return true;
return (loadedHeaders != null) ?
loadedHeaders.containsKey(name.toUpperCase(Locale.ENGLISH)) :
false;
}
/*
* Mark that the given headers have been loaded from the server.
*/
private synchronized void setHeaderLoaded(String name) {
if (loadedHeaders == null)
loadedHeaders = new Hashtable(1);
loadedHeaders.put(name.toUpperCase(Locale.ENGLISH), name);
}
/*
* Convert the given FETCH item identifier to the approriate
* section-string for this message.
*/
private String toSection(String what) {
if (sectionId == null)
return what;
else
return sectionId + "." + what;
}
/*
* Clone an array of InternetAddresses.
*/
private InternetAddress[] aaclone(InternetAddress[] aa) {
if (aa == null)
return null;
else
return (InternetAddress[])aa.clone();
}
private Flags _getFlags() {
return flags;
}
private ENVELOPE _getEnvelope() {
return envelope;
}
private BODYSTRUCTURE _getBodyStructure() {
return bs;
}
/***********************************************************
* accessor routines to make available certain private/protected
* fields to other classes in this package.
***********************************************************/
/*
* Called by IMAPFolder.
* Must not be synchronized.
*/
void _setFlags(Flags flags) {
this.flags = flags;
}
/*
* Called by IMAPNestedMessage.
*/
Session _getSession() {
return session;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?