From 0a5d7ba953980c7dc989bcf1a1fb62345254dff7 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:31:17 -0700 Subject: [PATCH] In getPersonalNameSpaces now we ask the server for the real folder names corresponding to the special folders ids (for which we have constants), so we can map the account folders using the real names. --- src/com/fsck/k9/mail/store/WebDavStore.java | 319 ++++++++++++-------- 1 file changed, 195 insertions(+), 124 deletions(-) diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java index efedebf7b..297811357 100644 --- a/src/com/fsck/k9/mail/store/WebDavStore.java +++ b/src/com/fsck/k9/mail/store/WebDavStore.java @@ -1,58 +1,38 @@ package com.fsck.k9.mail.store; -import android.util.Log; +import java.io.*; +import java.net.*; +import java.security.*; +import java.text.*; +import java.util.*; +import java.util.zip.*; -import com.fsck.k9.Account; -import com.fsck.k9.K9; -import com.fsck.k9.R; -import com.fsck.k9.controller.MessageRetrievalListener; -import com.fsck.k9.helper.Utility; +import javax.net.ssl.*; +import javax.xml.parsers.*; + +import org.apache.http.*; +import org.apache.http.client.*; +import org.apache.http.client.entity.*; +import org.apache.http.client.methods.*; +import org.apache.http.client.protocol.*; +import org.apache.http.conn.scheme.*; +import org.apache.http.entity.*; +import org.apache.http.impl.client.*; +import org.apache.http.message.*; +import org.apache.http.protocol.*; +import org.xml.sax.*; +import org.xml.sax.helpers.*; + +import android.util.*; + +import com.fsck.k9.*; +import com.fsck.k9.controller.*; +import com.fsck.k9.helper.*; import com.fsck.k9.mail.*; import com.fsck.k9.mail.Folder.OpenMode; -import com.fsck.k9.mail.filter.EOLConvertingOutputStream; -import com.fsck.k9.mail.internet.MimeMessage; -import com.fsck.k9.mail.transport.TrustedSocketFactory; -import org.apache.http.*; -import org.apache.http.client.CookieStore; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.protocol.ClientContext; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.HttpContext; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; - -import javax.net.ssl.SSLException; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import java.io.*; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Stack; -import java.util.zip.GZIPInputStream; +import com.fsck.k9.mail.filter.*; +import com.fsck.k9.mail.internet.*; +import com.fsck.k9.mail.transport.*; /** *
@@ -79,8 +59,13 @@ public class WebDavStore extends Store {
 
     private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0];
 
+    private static final Object DAV_MAIL_INBOX_FOLDER = "inbox";
+    private static final Object DAV_MAIL_DRAFTS_FOLDER = "drafts";
+    private static final String DAV_MAIL_SPAM_FOLDER = "spam";
     private static final String DAV_MAIL_SEND_FOLDER = "##DavMailSubmissionURI##";
-    private static final String DAV_MAIL_TMP_FOLDER = "drafts";
+	private static final Object DAV_MAIL_TRASH_FOLDER = "deleteditems";
+	private static final Object DAV_MAIL_OUTBOX_FOLDER = "outbox";
+	private static final Object DAV_MAIL_SENT_FOLDER = "sentitems";
 
     private short mConnectionSecurity;
     private String mUsername; /* Stores the username for authentications */
@@ -101,6 +86,7 @@ public class WebDavStore extends Store {
     private short mAuthentication = AUTH_TYPE_NONE;
     private String mCachedLoginUrl;
 
+    private Folder mSendFolder = null;
     private HashMap mFolderList = new HashMap();
 
     /**
@@ -231,63 +217,120 @@ public class WebDavStore extends Store {
     @Override
     public List  getPersonalNamespaces(boolean forceListAll) throws MessagingException {
         LinkedList folderList = new LinkedList();
-        HashMap headers = new HashMap();
-        DataSet dataset = new DataSet();
-        String messageBody;
-        String[] folderUrls;
-        int urlLength;
-
-        String translatedInbox = K9.app.getString(R.string.special_mailbox_name_inbox);
-
         /**
          * We have to check authentication here so we have the proper URL stored
          */
         getHttpClient();
-        messageBody = getFolderListXml();
+
+        /**
+         *  Firstly we get the "special" folders list (inbox, outbox, etc)
+         *  and setup the account accordingly
+         */
+        HashMap headers = new HashMap();
+        DataSet dataset = new DataSet();
+        headers.put("Depth", "0");
         headers.put("Brief", "t");
-        dataset = processRequest(this.mUrl, "SEARCH", messageBody, headers);
+        dataset = processRequest(this.mUrl, "PROPFIND", getSpecialFoldersList(), headers);
 
-        folderUrls = dataset.getHrefs();
-        urlLength = folderUrls.length;
+        HashMap specialFoldersMap = dataset.getSpecialFolderToUrl();
+        String folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_INBOX_FOLDER));
+        if(folderName != null) {
+		mAccount.setAutoExpandFolderName(folderName);
+		mAccount.setInboxFolderName(folderName);
+        }
 
-        for (int i = 0; i < urlLength; i++) {
-            String[] urlParts = folderUrls[i].split("/");
-            String folderName = urlParts[urlParts.length - 1];
-            String fullPathName = "";
-            WebDavFolder wdFolder;
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_DRAFTS_FOLDER));
+        if(folderName != null)
+		mAccount.setDraftsFolderName(folderName);
 
-            // Check each Exchange folder name to see if it is the user's inbox.
-            // We will check for the default English inbox ("Inbox"), and the user's
-            // translation for "Inbox", in case the user is using a non-English
-            // version of Exchange.
-            if (folderName.equalsIgnoreCase("Inbox") ||
-                    folderName.equalsIgnoreCase(translatedInbox)) {
-                folderName = K9.INBOX;
-            } else {
-                for (int j = 5, count = urlParts.length; j < count; j++) {
-                    if (j != 5) {
-                        fullPathName = fullPathName + "/" + urlParts[j];
-                    } else {
-                        fullPathName = urlParts[j];
-                    }
-                }
-                try {
-                    folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
-                } catch (UnsupportedEncodingException uee) {
-                    /** If we don't support UTF-8 there's a problem, don't decode it then */
-                    folderName = fullPathName;
-                }
-            }
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_TRASH_FOLDER));
+        if(folderName != null)
+		mAccount.setTrashFolderName(folderName);
 
-            wdFolder = new WebDavFolder(this, folderName);
-            wdFolder.setUrl(folderUrls[i]);
-            folderList.add(wdFolder);
-            this.mFolderList.put(folderName, wdFolder);
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SPAM_FOLDER));
+        if(folderName != null)
+		mAccount.setSpamFolderName(folderName);
+
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_OUTBOX_FOLDER));
+        if(folderName != null)
+		mAccount.setOutboxFolderName(folderName);
+
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SENT_FOLDER));
+        if(folderName != null)
+		mAccount.setSentFolderName(folderName);
+
+        /**
+         * Next we get all the folders (including "special" ones)
+         */
+        headers = new HashMap();
+        dataset = new DataSet();
+        headers.put("Brief", "t");
+        dataset = processRequest(this.mUrl, "SEARCH", getFolderListXml(), headers);
+        String[] folderUrls = dataset.getHrefs();
+
+        for (int i = 0; i < folderUrls.length; i++) {
+            String tempUrl = folderUrls[i];
+            createFolder(tempUrl, folderList);
         }
 
         return folderList;
     }
 
+    private WebDavFolder createFolder(String folderUrl, LinkedList folderList) {
+	if(folderUrl == null || folderList == null)
+		return null;
+
+	WebDavFolder wdFolder=null;
+	String folderName = getFolderName(folderUrl);
+	if(folderName != null) {
+			if(!this.mFolderList.containsKey(folderName)) {
+                wdFolder = new WebDavFolder(this, folderName);
+                wdFolder.setUrl(folderUrl);
+		folderList.add(wdFolder);
+		mFolderList.put(folderName, wdFolder);
+			}
+        }
+	// else: Unknown URL format => NO Folder created
+
+	return wdFolder;
+	}
+
+    private String getFolderName(String folderUrl) {
+	if(folderUrl == null)
+		return null;
+
+        int folderSlash=-1;
+        for(int j=0; j < 5; j++) {
+		folderSlash=folderUrl.indexOf('/', folderSlash+1);
+		if(folderSlash < 0)
+			break;
+        }
+
+        if(folderSlash > 0) {
+		String folderName;
+		String fullPathName;
+
+		if(folderUrl.charAt(folderUrl.length()-1) == '/')
+			fullPathName = folderUrl.substring(folderSlash+1, folderUrl.length()-1);
+		else
+			fullPathName = folderUrl.substring(folderSlash+1);
+
+			try {
+				folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
+			} catch (UnsupportedEncodingException uee) {
+				/**
+				 * If we don't support UTF-8 there's a problem, don't decode
+				 * it then
+				 */
+				folderName = fullPathName;
+			}
+
+			return folderName;
+		}
+
+        return null;
+    }
+
     @Override
     public Folder getFolder(String name) {
         WebDavFolder folder;
@@ -300,7 +343,10 @@ public class WebDavStore extends Store {
     }
 
     public Folder getSendSpoolFolder() throws MessagingException {
-        return getFolder(DAV_MAIL_SEND_FOLDER);
+		if (mSendFolder == null)
+			mSendFolder = getFolder(DAV_MAIL_SEND_FOLDER);
+
+		return mSendFolder;
     }
 
     @Override
@@ -313,6 +359,27 @@ public class WebDavStore extends Store {
         return true;
     }
 
+	private String getSpecialFoldersList() {
+		StringBuffer buffer = new StringBuffer(200);
+		buffer.append("");
+		buffer.append("");
+		buffer.append("");
+		buffer.append("<").append(DAV_MAIL_INBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_DRAFTS_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_OUTBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_SENT_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_TRASH_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		// This should always be ##DavMailSubmissionURI## for which we already have a constant
+		// buffer.append("");
+
+		//TODO: What is the id of the spam folder???
+		//buffer.append("<").append(DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+
+		buffer.append("");
+		buffer.append("");
+		return buffer.toString();
+	}
+
     /***************************************************************
      * WebDAV XML Request body retrieval functions
      */
@@ -980,7 +1047,7 @@ public class WebDavStore extends Store {
 
     @Override
     public void sendMessages(Message[] messages) throws MessagingException {
-        WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(DAV_MAIL_TMP_FOLDER);
+		WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(mAccount.getDraftsFolderName());
         try {
             tmpFolder.open(OpenMode.READ_WRITE);
             Message[] retMessages = tmpFolder.appendWebDavMessages(messages);
@@ -1017,37 +1084,30 @@ public class WebDavStore extends Store {
             store = nStore;
             this.mName = name;
 
-            if (DAV_MAIL_SEND_FOLDER.equals(name)) {
-                this.mFolderUrl = getUrl() + "/" + name + "/";
-            } else {
-                String encodedName = "";
-                try {
-                    String[] urlParts = name.split("/");
-                    String url = "";
-                    for (int i = 0, count = urlParts.length; i < count; i++) {
-                        if (i != 0) {
-                            url = url + "/" + java.net.URLEncoder.encode(urlParts[i], "UTF-8");
-                        } else {
-                            url = java.net.URLEncoder.encode(urlParts[i], "UTF-8");
-                        }
+            String encodedName = "";
+            try {
+                String[] urlParts = name.split("/");
+                String url = "";
+                for (int i = 0, count = urlParts.length; i < count; i++) {
+                    if (i != 0) {
+                        url = url + "/" + java.net.URLEncoder.encode(urlParts[i], "UTF-8");
+                    } else {
+                        url = java.net.URLEncoder.encode(urlParts[i], "UTF-8");
                     }
-                    encodedName = url;
-                } catch (UnsupportedEncodingException uee) {
-                    Log.e(K9.LOG_TAG, "UnsupportedEncodingException URLEncoding folder name, skipping encoded");
-                    encodedName = name;
                 }
-
-                encodedName = encodedName.replaceAll("\\+", "%20");
-
-                if (encodedName.equals(K9.INBOX)) {
-                    encodedName = "Inbox";
-                }
-                this.mFolderUrl = WebDavStore.this.mUrl;
-                if (!WebDavStore.this.mUrl.endsWith("/")) {
-                    this.mFolderUrl += "/";
-                }
-                this.mFolderUrl += encodedName;
+                encodedName = url;
+            } catch (UnsupportedEncodingException uee) {
+                Log.e(K9.LOG_TAG, "UnsupportedEncodingException URLEncoding folder name, skipping encoded");
+                encodedName = name;
             }
+
+            encodedName = encodedName.replaceAll("\\+", "%20");
+
+            this.mFolderUrl = WebDavStore.this.mUrl;
+            if (!WebDavStore.this.mUrl.endsWith("/")) {
+                this.mFolderUrl += "/";
+            }
+            this.mFolderUrl += encodedName;
         }
 
         public void setUrl(String url) {
@@ -1978,6 +2038,17 @@ public class WebDavStore extends Store {
         }
 
         /**
+		 * Returns a hashmap of special folder name => special folder url
+		 */
+		public HashMap getSpecialFolderToUrl() {
+			// We return the first (and only) map
+			for (HashMap folderMap : mData.values()) {
+				return folderMap;
+			}
+			return new HashMap();
+		}
+
+		/**
          * Returns a hashmap of Message UID => Message Url
          */
         public HashMap getUidToUrl() {