📄 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 + -