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

📄 imapfolder.java

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

    /*
     * 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"
	    	);
	    else // Folder was closed "implicitly"
		throw new FolderClosedException(this, 
		    "Lost folder connection to server"
		);
	}
    }

    /*
     * Check that the given message number is within the range
     * of messages present in this folder. If the message
     * number is out of range, we ping the server to obtain any
     * pending new message notifications from the server.
     */
    private void checkRange(int msgno) throws MessagingException {
	if (msgno < 1) // message-numbers start at 1
	    throw new IndexOutOfBoundsException();

	if (msgno <= total)
	    return;

	// Out of range, let's ping the server and see if
	// the server has more messages for us.

	synchronized(messageCacheLock) { // Acquire lock
	    try {
		keepConnectionAlive(false);
	    } catch (ConnectionException cex) {
		// Oops, lost connection
		throw new FolderClosedException(this, cex.getMessage());
	    } catch (ProtocolException pex) { 
		throw new MessagingException(pex.getMessage(), pex);
	    }
	} // Release lock

	if (msgno > total) // Still out of range ? Throw up ...
	    throw new IndexOutOfBoundsException();
    }

    /*
     * Check whether the given flags are supported by this server,
     * and also verify that the folder allows setting flags.
     */
    private void checkFlags(Flags flags) throws MessagingException {
	assert Thread.holdsLock(this);
	if (mode != READ_WRITE)
	    throw new IllegalStateException(
		"Cannot change flags on READ_ONLY folder: " + fullName
		);
	/*
	if (!availableFlags.contains(flags))
	    throw new MessagingException(
		"These flags are not supported by this implementation"
		);
	*/
    }

    /**
     * Get the name of this folder.
     */
    public synchronized String getName() {
	/* Return the last component of this Folder's full name.
	 * Folder components are delimited by the separator character.
	 */
	if (name == null) {
	    try {
		name = 	fullName.substring(
			    fullName.lastIndexOf(getSeparator()) + 1
			);
	    } catch (MessagingException mex) { }
	}
	return name;
    }

    /**
     * Get the fullname of this folder.
     */
    public synchronized String getFullName() {
	return fullName;	
    }

    /**
     * Get this folder's parent.
     */
    public synchronized Folder getParent() throws MessagingException {
	char c = getSeparator();
	int index;
	if ((index = fullName.lastIndexOf(c)) != -1)
	    return new IMAPFolder(fullName.substring(0, index), 
				  c, (IMAPStore)store);
	else
	    return new DefaultFolder((IMAPStore)store);
    }

    /**
     * Check whether this folder really exists on the server.
     */
    public synchronized boolean exists() throws MessagingException {
	// Check whether this folder exists ..
	ListInfo[] li = null;
	final String lname;
	if (isNamespace && separator != '\0')
	    lname = fullName + separator;
	else
	    lname = fullName;

	li = (ListInfo[])doCommand(new ProtocolCommand() {
	    public Object doCommand(IMAPProtocol p) throws ProtocolException {
		return p.list("", lname);
	    }
	});

	if (li != null) {
	    int i = findName(li, lname);
	    fullName = li[i].name;
	    separator = li[i].separator;
	    int len = fullName.length();
	    if (separator != '\0' && len > 0 &&
		    fullName.charAt(len - 1) == separator) {
		fullName = fullName.substring(0, len - 1);
	    }
	    type = 0;
	    if (li[i].hasInferiors)
		type |= HOLDS_FOLDERS;
	    if (li[i].canOpen)
		type |= HOLDS_MESSAGES;
	    exists = true;
	    attributes = li[i].attrs;
	} else {
	    exists = opened;
	    attributes = null;
	}

	return exists;
    }

    /**
     * Which entry in <code>li</code> matches <code>lname</code>?
     * If the name contains wildcards, more than one entry may be
     * returned.
     */
    private int findName(ListInfo[] li, String lname) {
	int i;
	// if the name contains a wildcard, there might be more than one
	for (i = 0; i < li.length; i++) {
	    if (li[i].name.equals(lname))
		break;
	}
	if (i >= li.length) {	// nothing matched exactly
	    // XXX - possibly should fail?  But what if server
	    // is case insensitive and returns the preferred
	    // case of the name here?
	    i = 0;		// use first one
	}
	return i;
    }

    /**
     * List all subfolders matching the specified pattern.
     */
    public Folder[] list(String pattern) throws MessagingException {
	return doList(pattern, false);
    }

    /**
     * List all subscribed subfolders matching the specified pattern.
     */
    public Folder[] listSubscribed(String pattern) throws MessagingException {
	return doList(pattern, true);
    }

    private synchronized Folder[] doList(final String pattern,
		final boolean subscribed) throws MessagingException {
	checkExists(); // insure that this folder does exist.
	
	if (!isDirectory()) // Why waste a roundtrip to the server ?
	    return new Folder[0];

	final char c = getSeparator();

	ListInfo[] li = (ListInfo[])doCommandIgnoreFailure(
	    new ProtocolCommand() {
		public Object doCommand(IMAPProtocol p)
			throws ProtocolException {
		    if (subscribed)
			return p.lsub("", fullName + c + pattern);
		    else 
			return p.list("", fullName + c + pattern);
		}
	    });

	if (li == null)
	    return new Folder[0];

	/*
	 * The UW based IMAP4 servers (e.g. SIMS2.0) include
	 * current folder (terminated with the separator), when
	 * the LIST pattern is '%' or '*'. i.e, <LIST "" mail/%> 
	 * returns "mail/" as the first LIST response.
	 *
	 * Doesn't make sense to include the current folder in this
	 * case, so we filter it out. Note that I'm assuming that
	 * the offending response is the *first* one, my experiments
	 * with the UW & SIMS2.0 servers indicate that .. 
	 */
	int start = 0;
	// Check the first LIST response.
	if (li.length > 0 && li[0].name.equals(fullName + c)) 
	    start = 1; // start from index = 1

	IMAPFolder[] folders = new IMAPFolder[li.length - start];
	for (int i = start; i < li.length; i++)
	    folders[i-start] = new IMAPFolder(li[i], (IMAPStore)store);
	return folders;
    }

    /**
     * Get the separator character.
     */
    public synchronized char getSeparator() throws MessagingException {
	if (separator == UNKNOWN_SEPARATOR) {
	    ListInfo[] li = null;

	    li = (ListInfo[])doCommand(new ProtocolCommand() {
		public Object doCommand(IMAPProtocol p)
			throws ProtocolException {
		    // REV1 allows the following LIST format to obtain
		    // the hierarchy delimiter of non-existent folders
		    if (p.isREV1()) // IMAP4rev1
		        return p.list(fullName, "");
		    else // IMAP4, note that this folder must exist for this
		        // to work :(
		        return p.list("", fullName);
		}
	    });

	    if (li != null) 
		separator = li[0].separator;
	    else
		separator = '/'; // punt !
	}
	return separator;
    }

    /**
     * Get the type of this folder.
     */
    public synchronized int getType() throws MessagingException {
	if (opened) {
	    // never throw FolderNotFoundException if folder is open
	    if (attributes == null)
		exists();	// try to fetch attributes
	} else {
	    checkExists();
	}
	return type;
    }
    
    /**
     * Check whether this folder is subscribed. <p>
     */
    public synchronized boolean isSubscribed() {
	ListInfo[] li = null;
	final String lname;
	if (isNamespace && separator != '\0')
	    lname = fullName + separator;
	else
	    lname = fullName;

	try {
	    li = (ListInfo[])doProtocolCommand(new ProtocolCommand() {
		public Object doCommand(IMAPProtocol p)
			throws ProtocolException {
		    return p.lsub("", lname);
		}
	    });
	} catch (ProtocolException pex) {
        }

	if (li != null) {
	    int i = findName(li, lname);
	    return li[i].canOpen;
	} else
	    return false;
    }

    /**
     * Subscribe/Unsubscribe this folder.
     */
    public synchronized void setSubscribed(final boolean subscribe) 
			throws MessagingException {
	doCommandIgnoreFailure(new ProtocolCommand() {
	    public Object doCommand(IMAPProtocol p) throws ProtocolException {
		if (subscribe)
		    p.subscribe(fullName);
		else
		    p.unsubscribe(fullName);
		return null;
	    }
	});
    }
	
    /**
     * Create this folder, with the specified type.
     */
    public synchronized boolean create(final int type)
				throws MessagingException {

	char c = 0;
	if ((type & HOLDS_MESSAGES) == 0)	// only holds folders
	    c = getSeparator();
	final char sep = c;
	Object ret = doCommandIgnoreFailure(new ProtocolCommand() {
		public Object doCommand(IMAPProtocol p)
			throws ProtocolException {
		    if ((type & HOLDS_MESSAGES) == 0)	// only holds folders
			p.create(fullName + sep);
		    else {
			p.create(fullName);

			// Certain IMAP servers do not allow creation of folders
			// that can contain messages *and* subfolders. So, if we
			// were asked to create such a folder, we should verify
			// that we could indeed do so.
			if ((type & HOLDS_FOLDERS) != 0) {
			    // we want to hold subfolders and messages. Check
			    // whether we could create such a folder.
			    ListInfo[] li = p.list("", fullName);
			    if (li != null && !li[0].hasInferiors) {
				// Hmm ..the new folder 
				// doesn't support Inferiors ? Fail
				p.delete(fullName);
				throw new ProtocolException("Unsupported type");
			    }
			}
		    }
		    return Boolean.TRUE;
		}
	    });

	if (ret == null)
	    return false; // CREATE failure, maybe this 
			  // folder already exists ?

	// exists = true;
	// this.type = type;
	boolean retb = exists();	// set exists, type, and attributes
	if (retb)		// Notify listeners on self and our Store
	    notifyFolderListeners(FolderEvent.CREATED);
	return retb;
    }

    /**
     * Check whether this folder has new messages.
     */
    public synchronized boolean hasNewMessages() throws MessagingException {
	if (opened) {	// If we are open, we already have this information
	    // Folder is open, make sure information is up to date
	    synchronized(messageCacheLock) {
		// tickle the folder and store connections.
		try {
		    keepConnectionAlive(true);
		} catch (ConnectionException cex) {
		    throw new FolderClosedException(this, cex.getMessage());
		} catch (ProtocolException pex) {
		    throw new MessagingException(pex.getMessage(), pex);
		}
		return recent > 0 ? true : false;
	    }
	}

	// First, the cheap way - use LIST and look for the \Marked
	// or \Unmarked tag

	ListInfo[] li = null;
	final String lname;
	if (isNamespace && separator != '\0')
	    lname = fullName + separator;
	else
	    lname = fullName;
	li = (ListInfo[])doCommandIgnoreFailure(new ProtocolCommand() {
	    public Object doCommand(IMAPProtocol p) throws ProtocolException {
		return p.list("", lname);
	    }
	});

	// if folder doesn't exist, throw exception
	if (li == null)

⌨️ 快捷键说明

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