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

📄 imapfolder.java

📁 java Email you can use it to send email to others
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * 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. *//* * @(#)IMAPFolder.java	1.85 07/09/05 */package com.sun.mail.imap;import java.util.Date;import java.util.Vector;import java.util.Hashtable;import java.util.NoSuchElementException;import java.io.*;import javax.mail.*;import javax.mail.event.*;import javax.mail.internet.*;import javax.mail.search.*;import com.sun.mail.util.*;import com.sun.mail.iap.*;import com.sun.mail.imap.protocol.*;/** * This class implements an IMAP folder. <p> * * A closed IMAPFolder object shares a protocol connection with its IMAPStore * object. When the folder is opened, it gets its own protocol connection. <p> * * Applications that need to make use of IMAP-specific features may cast * a <code>Folder</code> object to an <code>IMAPFolder</code> object and * use the methods on this class. The {@link #getQuota getQuota} and * {@link #setQuota setQuota} methods support the IMAP QUOTA extension. * Refer to <A HREF="http://www.ietf.org/rfc/rfc2087.txt">RFC 2087</A> * for more information. <p> * * The {@link #getACL getACL}, {@link #addACL addACL}, * {@link #removeACL removeACL}, {@link #addRights addRights}, * {@link #removeRights removeRights}, {@link #listRights listRights}, and * {@link #myRights myRights} methods support the IMAP ACL extension. * Refer to <A HREF="http://www.ietf.org/rfc/rfc2086.txt">RFC 2086</A> * for more information. <p> * * The {@link #doCommand doCommand} method and * {@link IMAPFolder.ProtocolCommand IMAPFolder.ProtocolCommand} * interface support use of arbitrary IMAP protocol commands. <p> * * See the <a href="package-summary.html">com.sun.mail.imap</a> package * documentation for further information on the IMAP protocol provider. <p> * * <strong>WARNING:</strong> The APIs unique to this class should be * considered <strong>EXPERIMENTAL</strong>.  They may be changed in the * future in ways that are incompatible with applications using the * current APIs. * * @version 1.85, 07/09/05 * @author  John Mani * @author  Bill Shannon * @author  Jim Glennon *//* * The folder object itself serves as a lock for the folder's state * EXCEPT for the message cache (see below), typically by using * synchronized methods.  When checking that a folder is open or * closed, the folder's lock must be held.  It's important that the * folder's lock is acquired before the messageCacheLock (see below). * Thus, the locking hierarchy is that the folder lock, while optional, * must be acquired before the messageCacheLock, if it's acquired at * all.  Be especially careful of callbacks that occur while holding * the messageCacheLock into (e.g.) superclass Folder methods that are * synchronized.  Note that methods in IMAPMessage will acquire the * messageCacheLock without acquiring the folder lock. <p> * * When a folder is opened, it creates a messageCache (a Vector) of  * empty IMAPMessage objects. Each Message has a messageNumber - which * is its index into the messageCache, and a sequenceNumber - which is * its IMAP sequence-number. All operations on a Message which involve * communication with the server, use the message's sequenceNumber. <p> * * The most important thing to note here is that the server can send * unsolicited EXPUNGE notifications as part of the responses for "most" * commands. Refer RFC2060, sections 5.3 &  5.5 for gory details. Also,  * the server sends these  notifications AFTER the message has been  * expunged. And once a message is expunged, the sequence-numbers of  * those messages after the expunged one are renumbered. This essentially * means that the mapping between *any* Message and its sequence-number  * can change in the period when a IMAP command is issued and its responses * are processed. Hence we impose a strict locking model as follows: <p> * * We define one mutex per folder - this is just a Java Object (named  * messageCacheLock). Any time a command is to be issued to the IMAP * server (i.e., anytime the corresponding IMAPProtocol method is * invoked), follow the below style: *		 *	synchronized (messageCacheLock) { // ACQUIRE LOCK *	    issue command () *	     *	    // The response processing is typically done within *	    // the handleResponse() callback. A few commands (Fetch, *	    // Expunge) return *all* responses and hence their *	    // processing is done here itself. Now, as part of the *	    // processing unsolicited EXPUNGE responses, we renumber *	    // the necessary sequence-numbers. Thus the renumbering *	    // happens within this critical-region, surrounded by *	    // locks. *	    process responses () *	} // RELEASE LOCK * * This technique is used both by methods in IMAPFolder and by methods * in IMAPMessage and other classes that operate on data in the folder. * Note that holding the messageCacheLock has the side effect of * preventing the folder from being closed, and thus ensuring that the * folder's protocol object is still valid.  The protocol object should * only be accessed while holding the messageCacheLock (except for calls * to IMAPProtocol.isREV1(), which don't need to be protected because it * doesn't access the server). *	     * Note that interactions with the Store's protocol connection do * not have to be protected as above, since the Store's protocol is * never in a "meaningful" SELECT-ed state. */public class IMAPFolder extends Folder implements UIDFolder, ResponseHandler {        protected String fullName;		// full name    protected String name;		// name    protected int type;			// folder type.     protected char separator;		// separator    protected Flags availableFlags; 	// available flags    protected Flags permanentFlags; 	// permanent flags    protected boolean exists = false; 	// whether this folder really exists ?    protected boolean isNamespace = false; // folder is a namespace name    protected String[] attributes;	// name attributes from LIST response    protected IMAPProtocol protocol; 	// this folder's own protocol object    protected Vector messageCache;  	// message cache    protected Object messageCacheLock; 	// accessor lock for message cache    protected Hashtable uidTable;	// UID->Message hashtable    /* An IMAP delimiter is a 7bit US-ASCII character. (except NUL).     * We use '\uffff' (a non 7bit character) to indicate that we havent     * yet determined what the separator character is.     * We use '\u0000' (NUL) to indicate that no separator character     * exists, i.e., a flat hierarchy     */    static final protected char UNKNOWN_SEPARATOR = '\uffff';    private boolean opened = false; 	// is this folder opened ?    /* This field tracks the state of this folder. If the folder is closed     * due to external causes (i.e, not thru the close() method), then     * this field will remain false. If the folder is closed thru the     * close() method, then this field is set to true.     *     * If reallyClosed is false, then a FolderClosedException is     * generated when a method is invoked on any Messaging object     * owned by this folder. If reallyClosed is true, then the     * IllegalStateException runtime exception is thrown.     */    private boolean reallyClosed = true;    /*     * The idleState field supports the IDLE command.     * Normally when executing an IMAP command we hold the     * messageCacheLock and often the folder lock (see above).     * While executing the IDLE command we can't hold either     * of these locks or it would prevent other threads from     * entering Folder methods even far enough to check whether     * an IDLE command is in progress.  We need to check before     * issuing another command so that we can abort the IDLE     * command.     *     * The idleState field is protected by the messageCacheLock.     * The RUNNING state is the normal state and means no IDLE     * command is in progress.  The IDLE state means we've issued     * an IDLE command and are reading responses.  The ABORTING     * state means we've sent the DONE continuation command and     * are waiting for the thread running the IDLE command to     * break out of its read loop.     *     * When an IDLE command is in progress, the thread calling     * the idle method will be reading from the IMAP connection     * while holding neither the folder lock nor the messageCacheLock.     * It's obviously critical that no other thread try to send a     * command or read from the connection while in this state.     * However, other threads can send the DONE continuation     * command that will cause the server to break out of the IDLE     * loop and send the ending tag response to the IDLE command.     * The thread in the idle method that's reading the responses     * from the IDLE command will see this ending response and     * complete the idle method, setting the idleState field back     * to RUNNING, and notifying any threads waiting to use the     * connection.     *     * All uses of the IMAP connection (IMAPProtocol object) must     * be done while holding the messageCacheLock and must be     * preceeded by a check to make sure an IDLE command is not     * running, and abort the IDLE command if necessary.  While     * waiting for the IDLE command to complete, these other threads     * will give up the messageCacheLock, but might still be holding     * the folder lock.  This check is done by the getProtocol()     * method, resulting in a typical usage pattern of:     *     *	    synchronized (messageCacheLock) {     *		IMAPProtocol p = getProtocol();	// may block waiting for IDLE     *		// ... use protocol     *	    }     */    private static final int RUNNING = 0;	// not doing IDLE command    private static final int IDLE = 1;		// IDLE command in effect    private static final int ABORTING = 2;	// IDLE command aborting    private int idleState = RUNNING;    private int total = -1;		// total number of messages in the					// message cache    private int recent = -1;		// number of recent messages    private int realTotal = -1;		// total number of messages on    					// the server    private long uidvalidity = -1;	// UIDValidity    private long uidnext = -1;		// UIDNext    private boolean doExpungeNotification = true; // used in expunge handler    private Status cachedStatus = null;    private long cachedStatusTime = 0;    private boolean debug = false;    private PrintStream out;		// debug output stream    private boolean connectionPoolDebug;    /**     * A fetch profile item for fetching headers.     * This inner class extends the <code>FetchProfile.Item</code>     * class to add new FetchProfile item types, specific to IMAPFolders.     *     * @see FetchProfile     */    public static class FetchProfileItem extends FetchProfile.Item {	protected FetchProfileItem(String name) {	    super(name);	}	/**	 * HEADERS is a fetch profile item that can be included in a	 * <code>FetchProfile</code> during a fetch request to a Folder.	 * This item indicates that the headers for messages in the specified 	 * range are desired to be prefetched. <p>	 * 	 * An example of how a client uses this is below: <p>	 * <blockquote><pre>	 *	 * 	FetchProfile fp = new FetchProfile();	 *	fp.add(IMAPFolder.FetchProfileItem.HEADERS);	 *	folder.fetch(msgs, fp);	 *	 * </pre></blockquote><p>	 */ 	public static final FetchProfileItem HEADERS = 		new FetchProfileItem("HEADERS");	/**	 * SIZE is a fetch profile item that can be included in a	 * <code>FetchProfile</code> during a fetch request to a Folder.	 * This item indicates that the sizes of the messages in the specified 	 * range are desired to be prefetched. <p>	 *	 * SIZE should move to FetchProfile.Item in JavaMail 1.3.	 */	public static final FetchProfileItem SIZE = 		new FetchProfileItem("SIZE");    }    /**     * Constructor used to create a possibly non-existent folder.     *     * @param fullName	fullname of this folder     * @param separator the default separator character for this      *			folder's namespace     * @param store	the Store     */    protected IMAPFolder(String fullName, char separator, IMAPStore store) {	super(store);	if (fullName == null)	    throw new NullPointerException("Folder name is null");	this.fullName = fullName;	this.separator = separator;	messageCacheLock = new Object();        debug = store.getSession().getDebug();        connectionPoolDebug = ((IMAPStore)store).getConnectionPoolDebug();	out = store.getSession().getDebugOut();	if (out == null)	// should never happen	    out = System.out;	/*	 * Work around apparent bug in Exchange.  Exchange	 * will return a name of "Public Folders/" from	 * LIST "%".	 *	 * If name has one separator, and it's at the end,	 * assume this is a namespace name and treat it	 * accordingly.  Usually this will happen as a result	 * of the list method, but this also allows getFolder	 * to work with namespace names.	 */	this.isNamespace = false;	if (separator != UNKNOWN_SEPARATOR && separator != '\0') {	    int i = this.fullName.indexOf(separator);	    if (i > 0 && i == this.fullName.length() - 1) {		this.fullName = this.fullName.substring(0, i);		this.isNamespace = true;	    }	}    }    /**     * Constructor used to create a possibly non-existent folder.     *     * @param fullName	fullname of this folder     * @param separator the default separator character for this      *			folder's namespace     * @param store	the Store     */    protected IMAPFolder(String fullName, char separator, IMAPStore store,				boolean isNamespace) {	this(fullName, separator, store);	this.isNamespace = isNamespace;    }    /**     * Constructor used to create an existing folder.     */    protected IMAPFolder(ListInfo li, IMAPStore store) {	this(li.name, li.separator, store);	if (li.hasInferiors)	    type |= HOLDS_FOLDERS;	if (li.canOpen)	    type |= HOLDS_MESSAGES;	exists = true;	attributes = li.attrs;    }	    /*     * Ensure that this folder exists. If 'exists' has been set to true,     * we don't attempt to validate it with the server again. Note that     * this can result in a possible loss of sync with the server.     */    private void checkExists() throws MessagingException {	// If the boolean field 'exists' is false, check with the	// server by invoking exists() ..	if (!exists && !exists())	    throw new FolderNotFoundException(		this, fullName + " not found");    }    /*     * Ensure the folder is closed.     * ASSERT: Must be called with this folder's synchronization lock held.     */    private void checkClosed() {	if (opened)	    throw new IllegalStateException(		"This operation is not allowed on an open folder"		);    }    /*     * Ensure the folder is open.     * ASSERT: Must be called with this folder's synchronization lock held.     */    private void checkOpened() throws FolderClosedException {	assert Thread.holdsLock(this);	if (!opened) {	    if (reallyClosed)		throw new IllegalStateException(		    "This operation is not allowed on a closed folder"	    	);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -