⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imapmessage.java

📁 此源码是在sun站点上提供的javamail基础上改进。用来解决中文邮件或很多国际间邮件乱码问题。版权属于sun公司。不过当你开发webmail程序时做邮件展示时
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -