📄 imapmessage.java
字号:
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* @(#)IMAPMessage.java 1.47 07/05/04
*/
package com.sun.mail.imap;
import java.util.Date;
import java.io.*;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Locale;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import com.sun.mail.util.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.protocol.*;
/**
* This class implements an IMAPMessage object. <p>
*
* An IMAPMessage object starts out as a light-weight object. It gets
* filled-in incrementally when a request is made for some item. Or
* when a prefetch is done using the FetchProfile. <p>
*
* An IMAPMessage has a messageNumber and a sequenceNumber. The
* messageNumber is its index into its containing folder's messageCache.
* The sequenceNumber is its IMAP sequence-number.
*
* @version 1.47, 07/05/04
* @author John Mani
* @author Bill Shannon
*/
/*
* The lock hierarchy is that the lock on the IMAPMessage object, if
* it's acquired at all, must be acquired before the message cache lock.
* The IMAPMessage lock protects the message flags, sort of.
*
* XXX - I'm not convinced that all fields of IMAPMessage are properly
* protected by locks.
*/
public class IMAPMessage extends MimeMessage {
protected BODYSTRUCTURE bs; // BODYSTRUCTURE
protected ENVELOPE envelope; // ENVELOPE
private Date receivedDate; // INTERNALDATE
private int size = -1; // RFC822.SIZE
private boolean peek; // use BODY.PEEK when fetching content?
// this message's IMAP sequence number
private int seqnum;
// this message's IMAP UID
private long uid = -1;
// this message's IMAP sectionId (null for toplevel message,
// non-null for a nested message)
protected String sectionId;
// processed values
private String type; // Content-Type (with params)
private String subject; // decoded (Unicode) subject
private String description; // decoded (Unicode) desc
// Indicates that we've loaded *all* headers for this message
private boolean headersLoaded = false;
/* Hashtable of names of headers we've loaded from the server.
* Used in isHeaderLoaded() and setHeaderLoaded() to keep track
* of those headers we've attempted to load from the server. We
* need this table of names to avoid multiple attempts at loading
* headers that don't exist for a particular message.
*
* Could this somehow be included in the InternetHeaders object ??
*/
private Hashtable loadedHeaders;
// This is our Envelope
private static String EnvelopeCmd = "ENVELOPE INTERNALDATE RFC822.SIZE";
/**
* Constructor.
*/
protected IMAPMessage(IMAPFolder folder, int msgnum, int seqnum) {
super(folder, msgnum);
this.seqnum = seqnum;
flags = null;
}
/**
* Constructor, for use by IMAPNestedMessage.
*/
protected IMAPMessage(Session session) {
super(session);
}
/**
* Get this message's folder's protocol connection.
* Throws FolderClosedException, if the protocol connection
* is not available.
*
* ASSERT: Must hold the messageCacheLock.
*/
protected IMAPProtocol getProtocol()
throws ProtocolException, FolderClosedException {
((IMAPFolder)folder).waitIfIdle();
IMAPProtocol p = ((IMAPFolder)folder).protocol;
if (p == null)
throw new FolderClosedException(folder);
else
return p;
}
/*
* Is this an IMAP4 REV1 server?
*/
protected boolean isREV1() throws FolderClosedException {
// access the folder's protocol object without waiting
// for IDLE to complete
IMAPProtocol p = ((IMAPFolder)folder).protocol;
if (p == null)
throw new FolderClosedException(folder);
else
return p.isREV1();
}
/**
* Get the messageCacheLock, associated with this Message's
* Folder.
*/
protected Object getMessageCacheLock() {
return ((IMAPFolder)folder).messageCacheLock;
}
/**
* Get this message's IMAP sequence number.
*
* ASSERT: This method must be called only when holding the
* messageCacheLock.
*/
protected int getSequenceNumber() {
return seqnum;
}
/**
* Set this message's IMAP sequence number.
*
* ASSERT: This method must be called only when holding the
* messageCacheLock.
*/
protected void setSequenceNumber(int seqnum) {
this.seqnum = seqnum;
}
/**
* Wrapper around the protected method Message.setMessageNumber() to
* make that method accessible to IMAPFolder.
*/
protected void setMessageNumber(int msgnum) {
super.setMessageNumber(msgnum);
}
protected long getUID() {
return uid;
}
protected void setUID(long uid) {
this.uid = uid;
}
// overrides super.setExpunged()
protected void setExpunged(boolean set) {
super.setExpunged(set);
seqnum = -1;
}
// Convenience routine
protected void checkExpunged() throws MessageRemovedException {
if (expunged)
throw new MessageRemovedException();
}
/**
* Do a NOOP to force any untagged EXPUNGE responses
* and then check if this message is expunged.
*/
protected void forceCheckExpunged()
throws MessageRemovedException, FolderClosedException {
synchronized (getMessageCacheLock()) {
try {
getProtocol().noop();
} catch (ConnectionException cex) {
throw new FolderClosedException(folder, cex.getMessage());
} catch (ProtocolException pex) {
// ignore it
}
}
if (expunged)
throw new MessageRemovedException();
}
// Return the block size for FETCH requests
protected int getFetchBlockSize() {
return ((IMAPStore)folder.getStore()).getFetchBlockSize();
}
/**
* Get the "From" attribute.
*/
public Address[] getFrom() throws MessagingException {
checkExpunged();
loadEnvelope();
return aaclone(envelope.from);
}
public void setFrom(Address address) throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
public void addFrom(Address[] addresses) throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
/**
* Get the "Sender" attribute.
*/
public Address getSender() throws MessagingException {
checkExpunged();
loadEnvelope();
if (envelope.sender != null)
return (envelope.sender)[0]; // there can be only one sender
else
return null;
}
public void setSender(Address address) throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
/**
* Get the desired Recipient type.
*/
public Address[] getRecipients(Message.RecipientType type)
throws MessagingException {
checkExpunged();
loadEnvelope();
if (type == Message.RecipientType.TO)
return aaclone(envelope.to);
else if (type == Message.RecipientType.CC)
return aaclone(envelope.cc);
else if (type == Message.RecipientType.BCC)
return aaclone(envelope.bcc);
else
return super.getRecipients(type);
}
public void setRecipients(Message.RecipientType type, Address[] addresses)
throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
public void addRecipients(Message.RecipientType type, Address[] addresses)
throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
/**
* Get the ReplyTo addresses.
*/
public Address[] getReplyTo() throws MessagingException {
checkExpunged();
loadEnvelope();
return aaclone(envelope.replyTo);
}
public void setReplyTo(Address[] addresses) throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
/**
* Get the decoded subject.
*/
public String getSubject() throws MessagingException {
checkExpunged();
if (subject != null) // already cached ?
return subject;
loadEnvelope();
if (envelope.subject == null) // no subject
return null;
// Cache and return the decoded value.
try {
subject = MimeUtility.decodeText(envelope.subject);
} catch (UnsupportedEncodingException ex) {
subject = envelope.subject;
}
return subject;
}
public void setSubject(String subject, String charset)
throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
/**
* Get the SentDate.
*/
public Date getSentDate() throws MessagingException {
checkExpunged();
loadEnvelope();
if (envelope.date == null)
return null;
else
return new Date(envelope.date.getTime());
}
public void setSentDate(Date d) throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
/**
* Get the recieved date (INTERNALDATE)
*/
public Date getReceivedDate() throws MessagingException {
checkExpunged();
loadEnvelope();
if (receivedDate == null)
return null;
else
return new Date(receivedDate.getTime());
}
/**
* Get the message size. <p>
*
* Note that this returns RFC822.SIZE. That is, it's the
* size of the whole message, header and body included.
*/
public int getSize() throws MessagingException {
checkExpunged();
if (size == -1)
loadEnvelope(); // XXX - could just fetch the size
return size;
}
/**
* Get the total number of lines. <p>
*
* Returns the "body_fld_lines" field from the
* BODYSTRUCTURE. Note that this field is available
* only for text/plain and message/rfc822 types
*/
public int getLineCount() throws MessagingException {
checkExpunged();
loadBODYSTRUCTURE();
return bs.lines;
}
/**
* Get the content language.
*/
public String[] getContentLanguage() throws MessagingException {
checkExpunged();
loadBODYSTRUCTURE();
if (bs.language != null)
return (String[])(bs.language).clone();
else
return null;
}
public void setContentLanguage(String[] languages)
throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
/**
* Get the In-Reply-To header.
*
* @since JavaMail 1.3.3
*/
public String getInReplyTo() throws MessagingException {
checkExpunged();
loadEnvelope();
return envelope.inReplyTo;
}
/**
* Get the Content-Type.
*
* Generate this header from the BODYSTRUCTURE. Append parameters
* as well.
*/
public String getContentType() throws MessagingException {
checkExpunged();
// If we haven't cached the type yet ..
if (type == null) {
loadBODYSTRUCTURE();
// generate content-type from BODYSTRUCTURE
ContentType ct = new ContentType(bs.type, bs.subtype, bs.cParams);
type = ct.toString();
}
return type;
}
/**
* Get the Content-Disposition.
*/
public String getDisposition() throws MessagingException {
checkExpunged();
loadBODYSTRUCTURE();
return bs.disposition;
}
public void setDisposition(String disposition) throws MessagingException {
throw new IllegalWriteException("IMAPMessage is read-only");
}
/**
* Get the Content-Transfer-Encoding.
*/
public String getEncoding() throws MessagingException {
checkExpunged();
loadBODYSTRUCTURE();
return bs.encoding;
}
/**
* Get the Content-ID.
*/
public String getContentID() throws MessagingException {
checkExpunged();
loadBODYSTRUCTURE();
return bs.id;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -