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

📄 folderproxy.java

📁 一个接收基于WebDav邮件的开源项目
💻 JAVA
字号:
/*
 *  This file is part of the JDAVMail package
 *  Copyright (C) 2002-2003 Luc Claes. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
 *  SHALL THE JDAVMail AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 *  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *  SUCH DAMAGE. See the GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA 02111-1307, USA
 *
 *  For questions, suggestions, bug-reports, enhancement-requests etc.
 *  I may be contacted at:
 *
 *  luc@posisoft.com
 *
 *  The JDAVMail's home page is located at:
 *
 *  http://jdavmail.sourceforge.net
 *
 */
package com.posisoft.jdavmail;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.URLName;

import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

/**
 * Surrogate for a remote JDAVMail Folder
 * 
 * @author Luc Claes
 */
public class FolderProxy {
    static private final Log m_log			= LogFactory.getLog("com.posisoft.JDAVMail.FolderProxy");
	private	String		m_strName			= null;
	private URI			m_uri				= null;
	private List		m_children			= null;
	private FolderProxy	m_parent			= null;
	private int			m_nType				= 0;
	private boolean		m_bSpecial			= false;
	
	// dynamic data
	private int			m_nUnreadCount		= -1;
	private int			m_nVisibleCount		= -1;
	
	private int			m_nOpen				= 0;
	private List		m_messages			= null;
	private JDAVMailService m_service		= null;
	
												 
	/**
	 * private: force the FolderProxy creation through the 'createInstance' and 'createRootInstance' methods.
	 */
	private FolderProxy(JDAVMailService service){
		m_service = service;
	}
	
	/**
	 */
	protected static FolderProxy getInstance(JDAVMailService service, Element elemResponse) throws URIException {
		Element elemProp = elemResponse.getChild("propstat", JDAVMail.NS_DAV).getChild("prop", JDAVMail.NS_DAV);
		
		// Is this really a folder?
		if (!Util.getBooleanValue(elemProp.getChild("isfolder", JDAVMail.NS_DAV), false)) {
			// TODO: log
			return null;
		}
		
		FolderProxy fp = new FolderProxy(service);

		// Get this folder's name
		String strName = Util.getStringValue(elemProp.getChild("displayname", JDAVMail.NS_DAV), null);
		if ((strName == null) || (strName.length() == 0)) {
			// Could be a 'special' folder (inbox, sent items, ...)
			strName = Util.getStringValue(elemProp.getChild("special", JDAVMail.NS_HTTPMAIL), null);
			if ((strName == null) || (strName.length() == 0)) {
				return null;
			}
			fp.m_bSpecial = true;
		}
		fp.m_strName = strName;

		// fp.setURI(elemResponse.getChild("href", JDAVMail.NS_DAV).getText());
		// The URI, while XML-encoded, is escaped (...)
		// so, we have to use an URI 'escaped' constructor
		fp.m_uri = new URI(elemResponse.getChild("href", JDAVMail.NS_DAV).getText().toCharArray());
		
		//TODO: if nosubs == 0...
		fp.m_nType = Folder.READ_WRITE | Folder.HOLDS_MESSAGES;
		
		fp.m_nVisibleCount = Util.getIntValue(elemProp.getChild("visiblecount", JDAVMail.NS_DAV), -1);
		fp.m_nUnreadCount = Util.getIntValue(elemProp.getChild("unreadcount", JDAVMail.NS_HTTPMAIL), -1);
		
		return fp;
	}
	
	/**
	 */
	protected static FolderProxy createInstance(JDAVMailFolder folder) throws Exception {
		JDAVMailService service = ((JDAVMailStore)(folder.getStore()))._getService();
		FolderProxy fpRoot = service.getRootFolderProxy();
		String strFolderName = folder.getName();

		CreateFolderMethod meth = new CreateFolderMethod(fpRoot, strFolderName);
		try {
			service.executeMethod(meth);
		} finally {
			meth.releaseConnection();
		}
		
		service.updateFoldersInfo();
		
		return service.getFolderProxy(strFolderName);
	}
	
	/**
	 */
	protected static FolderProxy createRootInstance(JDAVMailService service, Element elemResponse) throws URIException {
		Element elemRoot = elemResponse.getChild("propstat", JDAVMail.NS_DAV)
										.getChild("prop", JDAVMail.NS_DAV)
										.getChild("msgfolderroot", JDAVMail.NS_HTTPMAIL);
		
		FolderProxy fp = new FolderProxy(service);
		fp.m_strName = "";
		fp.m_bSpecial = true;
		fp.setURI(elemRoot.getText());
		fp.m_nType = Folder.READ_WRITE | Folder.HOLDS_FOLDERS;
		
		return fp;
	}
	
	/**
	 */
	protected static FolderProxy createSendMsgInstance(JDAVMailService service, Element elemResponse) throws URIException {
		Element elemSendMsg = elemResponse.getChild("propstat", JDAVMail.NS_DAV)
										.getChild("prop", JDAVMail.NS_DAV)
										.getChild("sendmsg", JDAVMail.NS_HTTPMAIL);
		
		FolderProxy fp = new FolderProxy(service);
		fp.m_strName = "";
		fp.m_bSpecial = true;
		fp.setURI(elemSendMsg.getText());
		fp.m_nType = Folder.READ_WRITE;
		
		return fp;
	}
	
	/**
	 */
	protected final String getName(){
		return m_strName;
	}
	
	/**
	 */
	protected final URI getURI(){
		return m_uri;
	}
	
	/**
	 */
	protected void setURI(URI uri){
		m_uri = uri;
	}
	
	/**
	 */
	protected void setURI(String strURI) throws URIException {
		m_uri = new URI(strURI);
	}
	
	/**
	 * Is this a 'special' folder (Inbox, sent items, ...) ?
	 */
	protected boolean isSpecial(){
		return m_bSpecial;
	}
	
	/**
	 */
	protected FolderProxy getParent(){
		return m_parent;
	}
	
	/**
	 */
	protected FolderProxy getChild(String strName){		if (m_children != null) {			for (Iterator iterFP = m_children.iterator(); iterFP.hasNext(); ) {
				FolderProxy fp = (FolderProxy) iterFP.next();
				if (fp.getName().equalsIgnoreCase(strName)) {
					return fp;
				}			}
		}		return null;
	}
	
	/**
	 */
	protected FolderProxy getChild(URLName url) throws URIException {
		URI uri = new URI(url.toString());		if (m_children != null) {			for (Iterator iterFP = m_children.iterator(); iterFP.hasNext(); ) {
				FolderProxy fp = (FolderProxy) iterFP.next();
				if (fp.getURI().equals(url)) {
					return fp;
				}			}
		}		return null;
	}
	
	/**
	 */
	protected void addChild(FolderProxy fp){
		if (m_children == null) {			m_children = new Vector();
		}		m_children.add(fp);		fp.m_parent = this;
	}
	
	/**
	 * Same spec as Folder.getType(), but does not throw exception
	 */
	protected int getType(){		return m_nType;
	}
		/**
	 */	protected void setType(int nType){		m_nType = nType;
	}	
	/**
	 */
	protected boolean hasNewMessages(){		return (m_nUnreadCount > 0);
	}
		/**
	 */	protected int getNewMessagesCount() throws MessagingException {		return getUnreadMessagesCount();
	}	
	/**
	 */
	protected int getUnreadMessagesCount() throws MessagingException {
		try {
			m_service.updateFoldersInfo();
		} catch (Exception e) {
			throw new MessagingException("Could not update Folders info", e);
		}
		return m_nUnreadCount;
	}
	
	/**
	 */
	protected int getMessagesCount(){
		return (m_messages != null) ? m_messages.size() : m_nVisibleCount;
	}
	
	/**
	 */	protected Message getMessage(int nIndex){
		if ((m_messages == null) || (nIndex < 1) || (nIndex > m_messages.size())) {			throw new IndexOutOfBoundsException();
		}
		return (Message) m_messages.get(nIndex - 1);	}	
	/**
	 */
	protected boolean isOpen(){		return m_nOpen > 0;
	}
	
	/**
	 * Open this FolderProxy, if not already done.
	 * A 'reference count' is maintained in order to handle multiple JDAVMailFolder connections.
	 * 
	 */
	protected synchronized void open(JDAVMailFolder folder, int nMode) throws Exception {		if (m_nOpen == 0) {
			Document docFolderContent = null; 
			GetFolderContentMethod m = new GetFolderContentMethod(this);
			try {
				m_service.executeMethod(m);
				docFolderContent = new SAXBuilder().build(m.getResponseBodyAsStream());
			} finally {
				m.releaseConnection();
			}
			// Build the JDOM Document
		
			if (m_log.isTraceEnabled()) {
				m_log.trace(new XMLOutputter(Format.getPrettyFormat()).outputString(docFolderContent));
			}
		
			// Create the JDAVMailMessage instances (without actually reading the messages content).
			m_messages = new Vector();
			List listMessages = docFolderContent.getRootElement().getChildren("response", JDAVMail.NS_DAV);
			int nSequenceNumber = 1;
			for (Iterator iterMessages = listMessages.iterator(); iterMessages.hasNext(); ) {
				JDAVMailMessage msg = JDAVMailMessage.createInstance(folder, m_messages.size() + 1, (Element) iterMessages.next());
				if (msg != null) {
					m_messages.add(msg);
					msg.setMessageNumber(nSequenceNumber++);
				}
			}
		}
		m_nOpen++;	}
	
	/**
	 */
	protected synchronized void close(boolean bExpunge) throws MessagingException {
		if (--m_nOpen <= 0) {
			if (bExpunge) {				expunge();
			}			m_messages = null;		}
	}
	
    /**
     * 'Delete' the marked messages by moving them to the 'deleteditems' folder.
     *      */    protected Message[] expunge() throws MessagingException {		Vector vectExpunged = new Vector();		if (m_messages != null) {			FolderProxy trashcan = m_service.getTrashCan();			int nSequenceNumber = 1;
			for (Iterator iterMsg = m_messages.iterator(); iterMsg.hasNext(); ) {				JDAVMailMessage msg = (JDAVMailMessage) iterMsg.next();				if (msg.getFlags().contains(Flags.Flag.DELETED)) {					// This could be optimized by calling a single 'MoveMessagesMethod' instead					// of multiple 'MoveMessageMethod'
					MoveMethod meth = new MoveMethod(msg, trashcan);					try {
						m_service.executeMethod(meth);						vectExpunged.add(msg);
						msg.setExpunged(true);
						iterMsg.remove();		// remove from this folder					} catch (Exception e) {
						m_log.error("FolderProxy expunge exception: ", e);
						// re-throw?					} finally {
						meth.releaseConnection();
					}
				}				if (!msg.isExpunged()) {
					msg.setMessageNumber(nSequenceNumber++);				}
			}		}
		return (Message[]) (vectExpunged.toArray(new Message[vectExpunged.size()]));    }
	
	/**
	 * Delete this folder
	 */
	protected synchronized boolean delete(boolean bRecurse) throws MessagingException, URIException {		if (isSpecial()) {
			throw new MessagingException("It is not allowed to delete a special folder");		}				if (m_nOpen > 0) {			throw new IllegalStateException("The folder (proxy) is still open...");
		}		
		//TODO: delete the contained messages first...
				DeleteFolderMethod meth = new DeleteFolderMethod(this);
		try {			m_service.executeMethod(meth);
		} catch (Exception e) {
			throw new MessagingException("Could not delete folder : "  + m_strName, e);		} finally {			meth.releaseConnection();
		}

		try {			m_service.updateFoldersInfo();		} catch (Exception e) {			//TODO
		}				return true;
	}
	
    /**     */    protected List list(String strPattern) {
		//TODO: handle the pattern matching...		return m_children;    }
	/**
	 */
	protected FolderProxy[] getChildren(){		return (m_children != null) ? ((FolderProxy[])(m_children.toArray(new FolderProxy[m_children.size()])))									  : new FolderProxy[0];
	}
	
	/**
	 */
	protected void removeChild(FolderProxy fp){		if (m_children != null) {
			m_children.remove(fp);		}
	}
	
	/**
	 * Refresh this FolderProxy instance with the data from a 'youngest' image of the
	 * proxied folder.
	 */
	protected void refreshWith(FolderProxy myYoungClone){		m_uri = myYoungClone.m_uri;
		m_nVisibleCount = myYoungClone.m_nVisibleCount;
		m_nUnreadCount = myYoungClone.m_nUnreadCount;
		// other data to refresh?
	}
	
    /**     */    protected void appendMessages(Message[] msgs) throws MessagingException {
		for (int i = 0; i < msgs.length; i++) {
			if (!(msgs[i] instanceof JDAVMailMessage)) {
				throw new MessagingException("Messages upload is not (yet?) supported");			}			JDAVMailMessage msg = (JDAVMailMessage) msgs[i];
			CopyMessageMethod meth = new CopyMessageMethod(msg, this);			try {
				m_service.executeMethod(meth);
			} catch (Exception e) {				throw new MessagingException("COPY method exception", e);
			} finally {				meth.releaseConnection();
			}
			m_messages.add(msg);
			msg.setMessageNumber(m_messages.size());		}
    }
	
	/**
	 * Rename this folder.
	 * @exception MessagingException - If this folder is a 'special' folder.
	 */
	protected boolean renameTo(String strNewName) throws URIException, MessagingException {		if (isSpecial()) {
			throw new MessagingException("It is not allowed to rename a special folder");		}
		MoveMethod meth = new MoveMethod(this, strNewName);		try {
			m_service.executeMethod(meth);
			m_service.updateFoldersInfo();
		} catch (Exception e) {			throw new MessagingException("Folder rename exception ", e);
		} finally {
			meth.releaseConnection();
		}
		return true;
	}}

⌨️ 快捷键说明

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