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.

This commit is contained in:
bitblaster 2011-04-05 02:31:17 -07:00 committed by Jesse Vincent
parent c46372b58c
commit 0a5d7ba953
1 changed files with 195 additions and 124 deletions

View File

@ -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.*;
/**
* <pre>
@ -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<String, WebDavFolder> mFolderList = new HashMap<String, WebDavFolder>();
/**
@ -231,63 +217,120 @@ public class WebDavStore extends Store {
@Override
public List <? extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException {
LinkedList<Folder> folderList = new LinkedList<Folder>();
HashMap<String, String> headers = new HashMap<String, String>();
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<String, String> headers = new HashMap<String, String>();
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<String, String> 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<String, String>();
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<Folder> 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("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>");
buffer.append("<propfind xmlns=\"DAV:\">");
buffer.append("<prop>");
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("<sendmsg xmlns=\"urn:schemas:httpmail:\"/>");
//TODO: What is the id of the spam folder???
//buffer.append("<").append(DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
buffer.append("</prop>");
buffer.append("</propfind>");
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<String, String> getSpecialFolderToUrl() {
// We return the first (and only) map
for (HashMap<String, String> folderMap : mData.values()) {
return folderMap;
}
return new HashMap<String, String>();
}
/**
* Returns a hashmap of Message UID => Message Url
*/
public HashMap<String, String> getUidToUrl() {