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 HashMapmFolderList = new HashMap (); /** @@ -231,63 +217,120 @@ public class WebDavStore extends Store { @Override public List extends Folder > 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(" "); + 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"); + 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(" "); + 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(" 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() {