From 9fd722d7cd98b0af2fe5898f09080b317c26fd8e Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 03:23:32 +0000
Subject: [PATCH 01/29] Split message code into Local/Remote
The remote network code does not need to be aware of concepts like
Accounts etc.
---
src/com/fsck/k9/Account.java | 8 +-
src/com/fsck/k9/Preferences.java | 3 +-
src/com/fsck/k9/activity/Accounts.java | 10 +-
src/com/fsck/k9/activity/MessageCompose.java | 30 ++-
.../fsck/k9/activity/MessageInfoHolder.java | 5 +-
src/com/fsck/k9/activity/MessageList.java | 12 +-
.../fsck/k9/activity/MessageReference.java | 8 +-
.../k9/activity/setup/AccountSetupBasics.java | 4 +-
.../activity/setup/AccountSetupIncoming.java | 5 +-
src/com/fsck/k9/cache/EmailProviderCache.java | 10 +-
.../controller/MessageRetrievalListener.java | 4 +-
.../k9/controller/MessagingController.java | 86 ++++---
.../fsck/k9/controller/MessagingListener.java | 25 +--
.../fsck/k9/fragment/MessageListFragment.java | 163 +++++++-------
.../fsck/k9/fragment/MessageViewFragment.java | 11 +-
src/com/fsck/k9/helper/MessageHelper.java | 16 +-
src/com/fsck/k9/mail/Folder.java | 30 +--
src/com/fsck/k9/mail/Message.java | 13 +-
src/com/fsck/k9/mail/Store.java | 209 +-----------------
.../k9/mail/store/ImapResponseParser.java | 2 +-
src/com/fsck/k9/mail/store/ImapStore.java | 74 +++----
src/com/fsck/k9/mail/store/Pop3Store.java | 40 ++--
src/com/fsck/k9/mail/store/RemoteStore.java | 122 ++++++++++
src/com/fsck/k9/mail/store/StoreConfig.java | 32 +++
src/com/fsck/k9/mail/store/WebDavStore.java | 41 ++--
.../fsck/k9/mail/store/local/LocalFolder.java | 67 ++++--
.../k9/mail/store/local/LocalMessage.java | 43 +++-
.../fsck/k9/mail/store/local/LocalStore.java | 82 ++++++-
.../fsck/k9/mail/transport/SmtpTransport.java | 3 +-
.../k9/mail/transport/WebDavTransport.java | 10 +-
.../fsck/k9/preferences/SettingsExporter.java | 4 +-
.../fsck/k9/preferences/SettingsImporter.java | 4 +-
.../fsck/k9/provider/AttachmentProvider.java | 4 +-
src/com/fsck/k9/provider/MessageProvider.java | 21 +-
.../k9/service/NotificationActionService.java | 8 +-
.../fsck/k9/mail/store/ImapStoreUriTest.java | 21 +-
36 files changed, 641 insertions(+), 589 deletions(-)
create mode 100644 src/com/fsck/k9/mail/store/RemoteStore.java
create mode 100644 src/com/fsck/k9/mail/store/StoreConfig.java
diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index 54a04197a..d7413b6d1 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -29,6 +29,8 @@ import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.Folder.FolderClass;
+import com.fsck.k9.mail.store.RemoteStore;
+import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.StorageManager;
import com.fsck.k9.mail.store.StorageManager.StorageProvider;
import com.fsck.k9.mail.store.local.LocalStore;
@@ -48,7 +50,7 @@ import com.larswerkman.colorpicker.ColorPicker;
* Account stores all of the settings for a single account defined by the user. It is able to save
* and delete itself given a Preferences to work with. Each account is defined by a UUID.
*/
-public class Account implements BaseAccount {
+public class Account implements BaseAccount, StoreConfig {
/**
* Default value for the inbox folder (never changes for POP3 and IMAP)
*/
@@ -1289,11 +1291,11 @@ public class Account implements BaseAccount {
}
public LocalStore getLocalStore() throws MessagingException {
- return Store.getLocalInstance(this, K9.app);
+ return LocalStore.getInstance(this, K9.app);
}
public Store getRemoteStore() throws MessagingException {
- return Store.getRemoteInstance(this);
+ return RemoteStore.getInstance(this);
}
// It'd be great if this actually went into the store implementation
diff --git a/src/com/fsck/k9/Preferences.java b/src/com/fsck/k9/Preferences.java
index 5fd4929a3..6504626a2 100644
--- a/src/com/fsck/k9/Preferences.java
+++ b/src/com/fsck/k9/Preferences.java
@@ -14,6 +14,7 @@ import android.content.SharedPreferences;
import android.util.Log;
import com.fsck.k9.mail.Store;
+import com.fsck.k9.mail.store.local.LocalStore;
import com.fsck.k9.preferences.Editor;
import com.fsck.k9.preferences.Storage;
@@ -121,7 +122,7 @@ public class Preferences {
accountsInOrder.remove(account);
}
- Store.removeAccount(account);
+ LocalStore.removeAccount(account);
account.deleteCertificates();
account.delete(this);
diff --git a/src/com/fsck/k9/activity/Accounts.java b/src/com/fsck/k9/activity/Accounts.java
index 738ee32a3..5b7a757ae 100644
--- a/src/com/fsck/k9/activity/Accounts.java
+++ b/src/com/fsck/k9/activity/Accounts.java
@@ -5,7 +5,6 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Calendar;
import java.util.EnumSet;
import java.util.HashSet;
@@ -76,12 +75,11 @@ import com.fsck.k9.activity.setup.Prefs;
import com.fsck.k9.activity.setup.WelcomeMessage;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.helper.SizeFormatter;
-import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ServerSettings;
-import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.internet.MimeUtility;
+import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mail.store.StorageManager;
import com.fsck.k9.mail.store.WebDavStore;
import com.fsck.k9.preferences.SettingsExporter;
@@ -771,7 +769,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
}
private void show(final Accounts activity, boolean restore) {
- ServerSettings incoming = Store.decodeStoreUri(mAccount.getStoreUri());
+ ServerSettings incoming = RemoteStore.decodeStoreUri(mAccount.getStoreUri());
ServerSettings outgoing = Transport.decodeTransportUri(mAccount.getTransportUri());
/*
@@ -992,9 +990,9 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
if (mIncomingPassword != null) {
// Set incoming server password
String storeUri = mAccount.getStoreUri();
- ServerSettings incoming = Store.decodeStoreUri(storeUri);
+ ServerSettings incoming = RemoteStore.decodeStoreUri(storeUri);
ServerSettings newIncoming = incoming.newPassword(mIncomingPassword);
- String newStoreUri = Store.createStoreUri(newIncoming);
+ String newStoreUri = RemoteStore.createStoreUri(newIncoming);
mAccount.setStoreUri(newStoreUri);
}
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 141399bcc..2e6bacf99 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -108,6 +108,7 @@ import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
import com.fsck.k9.mail.internet.TextBodyBuilder;
import com.fsck.k9.mail.store.local.LocalAttachmentBody;
+import com.fsck.k9.mail.store.local.LocalMessage;
import com.fsck.k9.mail.store.local.TempFileBody;
import com.fsck.k9.mail.store.local.TempFileMessageBody;
import com.fsck.k9.view.MessageWebView;
@@ -435,17 +436,15 @@ public class MessageCompose extends K9Activity implements OnClickListener,
* Get intent for composing a new message as a reply to the given message. If replyAll is true
* the function is reply all instead of simply reply.
* @param context
- * @param account
* @param message
* @param replyAll
* @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message
*/
public static Intent getActionReplyIntent(
- Context context,
- Account account,
- Message message,
- boolean replyAll,
- String messageBody) {
+ Context context,
+ Message message,
+ boolean replyAll,
+ String messageBody) {
Intent i = new Intent(context, MessageCompose.class);
i.putExtra(EXTRA_MESSAGE_BODY, messageBody);
i.putExtra(EXTRA_MESSAGE_REFERENCE, message.makeMessageReference());
@@ -468,25 +467,22 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/
public static void actionReply(
Context context,
- Account account,
Message message,
boolean replyAll,
String messageBody) {
- context.startActivity(getActionReplyIntent(context, account, message, replyAll, messageBody));
+ context.startActivity(getActionReplyIntent(context, message, replyAll, messageBody));
}
/**
* Compose a new message as a forward of the given message.
* @param context
- * @param account
* @param message
* @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message
*/
public static void actionForward(
- Context context,
- Account account,
- Message message,
- String messageBody) {
+ Context context,
+ Message message,
+ String messageBody) {
Intent i = new Intent(context, MessageCompose.class);
i.putExtra(EXTRA_MESSAGE_BODY, messageBody);
i.putExtra(EXTRA_MESSAGE_REFERENCE, message.makeMessageReference());
@@ -2646,7 +2642,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
* @param message
* The source message used to populate the various text fields.
*/
- private void processSourceMessage(Message message) {
+ private void processSourceMessage(LocalMessage message) {
try {
switch (mAction) {
case REPLY:
@@ -2800,7 +2796,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
}
}
- private void processDraftMessage(Message message) throws MessagingException {
+ private void processDraftMessage(LocalMessage message) throws MessagingException {
String showQuotedTextMode = "NONE";
mDraftId = MessagingController.getInstance(getApplication()).getId(message);
@@ -2852,7 +2848,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
newIdentity.setSignature(k9identity.get(IdentityField.SIGNATURE));
mSignatureChanged = true;
} else {
- newIdentity.setSignatureUse(message.getFolder().getAccount().getSignatureUse());
+ newIdentity.setSignatureUse(message.getFolder().getSignatureUse());
newIdentity.setSignature(mIdentity.getSignature());
}
@@ -3437,7 +3433,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
}
updateMessageFormat();
} else {
- processSourceMessage(message);
+ processSourceMessage((LocalMessage) message);
mSourceProcessed = true;
}
}
diff --git a/src/com/fsck/k9/activity/MessageInfoHolder.java b/src/com/fsck/k9/activity/MessageInfoHolder.java
index eecf4f80d..e217a0f78 100644
--- a/src/com/fsck/k9/activity/MessageInfoHolder.java
+++ b/src/com/fsck/k9/activity/MessageInfoHolder.java
@@ -2,6 +2,7 @@ package com.fsck.k9.activity;
import java.util.Date;
import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.store.local.LocalMessage;
public class MessageInfoHolder {
public String date;
@@ -18,7 +19,7 @@ public class MessageInfoHolder {
public boolean forwarded;
public boolean flagged;
public boolean dirty;
- public Message message;
+ public LocalMessage message;
public FolderInfoHolder folder;
public boolean selected;
public String account;
@@ -31,7 +32,7 @@ public class MessageInfoHolder {
@Override
public boolean equals(Object o) {
- if (o instanceof MessageInfoHolder == false) {
+ if (!(o instanceof MessageInfoHolder)) {
return false;
}
MessageInfoHolder other = (MessageInfoHolder)o;
diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index 25306140f..765d03673 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -1199,17 +1199,17 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
@Override
public void onForward(Message message) {
- MessageCompose.actionForward(this, message.getFolder().getAccount(), message, null);
+ MessageCompose.actionForward(this, message, null);
}
@Override
public void onReply(Message message) {
- MessageCompose.actionReply(this, message.getFolder().getAccount(), message, false, null);
+ MessageCompose.actionReply(this, message, false, null);
}
@Override
public void onReplyAll(Message message) {
- MessageCompose.actionReply(this, message.getFolder().getAccount(), message, true, null);
+ MessageCompose.actionReply(this, message, true, null);
}
@Override
@@ -1400,17 +1400,17 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
@Override
public void onReply(Message message, PgpData pgpData) {
- MessageCompose.actionReply(this, mAccount, message, false, pgpData.getDecryptedData());
+ MessageCompose.actionReply(this, message, false, pgpData.getDecryptedData());
}
@Override
public void onReplyAll(Message message, PgpData pgpData) {
- MessageCompose.actionReply(this, mAccount, message, true, pgpData.getDecryptedData());
+ MessageCompose.actionReply(this, message, true, pgpData.getDecryptedData());
}
@Override
public void onForward(Message mMessage, PgpData mPgpData) {
- MessageCompose.actionForward(this, mAccount, mMessage, mPgpData.getDecryptedData());
+ MessageCompose.actionForward(this, mMessage, mPgpData.getDecryptedData());
}
@Override
diff --git a/src/com/fsck/k9/activity/MessageReference.java b/src/com/fsck/k9/activity/MessageReference.java
index 990d99774..bb2d6264d 100644
--- a/src/com/fsck/k9/activity/MessageReference.java
+++ b/src/com/fsck/k9/activity/MessageReference.java
@@ -13,6 +13,8 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.store.local.LocalFolder;
+import com.fsck.k9.mail.store.local.LocalMessage;
import java.util.StringTokenizer;
@@ -128,13 +130,13 @@ public class MessageReference implements Parcelable {
'}';
}
- public Message restoreToLocalMessage(Context context) {
+ public LocalMessage restoreToLocalMessage(Context context) {
try {
Account account = Preferences.getPreferences(context).getAccount(accountUuid);
if (account != null) {
- Folder folder = account.getLocalStore().getFolder(folderName);
+ LocalFolder folder = account.getLocalStore().getFolder(folderName);
if (folder != null) {
- Message message = folder.getMessage(uid);
+ LocalMessage message = folder.getMessage(uid);
if (message != null) {
return message;
} else {
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupBasics.java b/src/com/fsck/k9/activity/setup/AccountSetupBasics.java
index 56d409743..eab3db5fd 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupBasics.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupBasics.java
@@ -38,9 +38,9 @@ import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.ServerSettings;
-import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.store.ImapStore;
+import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mail.transport.SmtpTransport;
import com.fsck.k9.view.ClientCertificateSpinner;
import com.fsck.k9.view.ClientCertificateSpinner.OnClientCertificateChangedListener;
@@ -421,7 +421,7 @@ public class AccountSetupBasics extends K9Activity
ConnectionSecurity.SSL_TLS_REQUIRED, authenticationType, user, password, clientCertificateAlias);
ServerSettings transportServer = new ServerSettings(SmtpTransport.TRANSPORT_TYPE, "mail." + domain, -1,
ConnectionSecurity.SSL_TLS_REQUIRED, authenticationType, user, password, clientCertificateAlias);
- String storeUri = Store.createStoreUri(storeServer);
+ String storeUri = RemoteStore.createStoreUri(storeServer);
String transportUri = Transport.createTransportUri(transportServer);
mAccount.setStoreUri(storeUri);
mAccount.setTransportUri(transportUri);
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
index ff4cd531b..5d417309f 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
@@ -27,6 +27,7 @@ import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.store.ImapStore;
import com.fsck.k9.mail.store.Pop3Store;
+import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mail.store.WebDavStore;
import com.fsck.k9.mail.store.ImapStore.ImapStoreSettings;
import com.fsck.k9.mail.store.WebDavStore.WebDavStoreSettings;
@@ -163,7 +164,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
}
try {
- ServerSettings settings = Store.decodeStoreUri(mAccount.getStoreUri());
+ ServerSettings settings = RemoteStore.decodeStoreUri(mAccount.getStoreUri());
if (savedInstanceState == null) {
// The first item is selected if settings.authenticationType is null or is not in mAuthTypeAdapter
@@ -610,7 +611,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
ServerSettings settings = new ServerSettings(mStoreType, host, port,
connectionSecurity, authType, username, password, clientCertificateAlias, extra);
- mAccount.setStoreUri(Store.createStoreUri(settings));
+ mAccount.setStoreUri(RemoteStore.createStoreUri(settings));
mAccount.setCompression(Account.TYPE_MOBILE, mCompressionMobile.isChecked());
mAccount.setCompression(Account.TYPE_WIFI, mCompressionWifi.isChecked());
diff --git a/src/com/fsck/k9/cache/EmailProviderCache.java b/src/com/fsck/k9/cache/EmailProviderCache.java
index 9b3e7d5e0..ccd712d12 100644
--- a/src/com/fsck/k9/cache/EmailProviderCache.java
+++ b/src/com/fsck/k9/cache/EmailProviderCache.java
@@ -123,13 +123,11 @@ public class EmailProviderCache {
}
}
- public void hideMessages(List messages) {
+ public void hideMessages(List messages) {
synchronized (mHiddenMessageCache) {
- for (Message message : messages) {
- LocalMessage localMessage = (LocalMessage) message;
- long messageId = localMessage.getId();
- long folderId = ((LocalFolder) localMessage.getFolder()).getId();
- mHiddenMessageCache.put(messageId, folderId);
+ for (LocalMessage message : messages) {
+ long messageId = message.getId();
+ mHiddenMessageCache.put(messageId, message.getFolder().getId());
}
}
diff --git a/src/com/fsck/k9/controller/MessageRetrievalListener.java b/src/com/fsck/k9/controller/MessageRetrievalListener.java
index 24ecb52e2..6af8714af 100644
--- a/src/com/fsck/k9/controller/MessageRetrievalListener.java
+++ b/src/com/fsck/k9/controller/MessageRetrievalListener.java
@@ -3,10 +3,10 @@ package com.fsck.k9.controller;
import com.fsck.k9.mail.Message;
-public interface MessageRetrievalListener {
+public interface MessageRetrievalListener {
public void messageStarted(String uid, int number, int ofTotal);
- public void messageFinished(Message message, int number, int ofTotal);
+ public void messageFinished(T message, int number, int ofTotal);
/**
* FIXME this method is almost never invoked by various Stores! Don't rely on it unless fixed!!
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 7f889650b..d776c5fb3 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -312,7 +312,7 @@ public class MessagingController implements Runnable {
private static final Set SYNC_FLAGS = EnumSet.of(Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED, Flag.FORWARDED);
- private void suppressMessages(Account account, List messages) {
+ private void suppressMessages(Account account, List messages) {
EmailProviderCache cache = EmailProviderCache.getCache(account.getUuid(),
mApplication.getApplicationContext());
cache.hideMessages(messages);
@@ -324,13 +324,11 @@ public class MessagingController implements Runnable {
cache.unhideMessages(messages);
}
- private boolean isMessageSuppressed(Account account, Message message) {
- LocalMessage localMessage = (LocalMessage) message;
- String accountUuid = account.getUuid();
- long messageId = localMessage.getId();
- long folderId = ((LocalFolder) localMessage.getFolder()).getId();
+ private boolean isMessageSuppressed(LocalMessage message) {
+ long messageId = message.getId();
+ long folderId = message.getFolder().getId();
- EmailProviderCache cache = EmailProviderCache.getCache(accountUuid,
+ EmailProviderCache cache = EmailProviderCache.getCache(message.getFolder().getUuid(),
mApplication.getApplicationContext());
return cache.isMessageHidden(messageId, folderId);
}
@@ -690,15 +688,15 @@ public class MessagingController implements Runnable {
}
// Collecting statistics of the search result
- MessageRetrievalListener retrievalListener = new MessageRetrievalListener() {
+ MessageRetrievalListener retrievalListener = new MessageRetrievalListener() {
@Override
public void messageStarted(String message, int number, int ofTotal) {}
@Override
public void messagesFinished(int number) {}
@Override
- public void messageFinished(Message message, int number, int ofTotal) {
- if (!isMessageSuppressed(message.getFolder().getAccount(), message)) {
- List messages = new ArrayList();
+ public void messageFinished(LocalMessage message, int number, int ofTotal) {
+ if (!isMessageSuppressed(message)) {
+ List messages = new ArrayList();
messages.add(message);
stats.unreadMessageCount += (!message.isSet(Flag.SEEN)) ? 1 : 0;
@@ -762,7 +760,7 @@ public class MessagingController implements Runnable {
final Account acct = Preferences.getPreferences(mApplication.getApplicationContext()).getAccount(acctUuid);
if (listener != null) {
- listener.remoteSearchStarted(acct, folderName);
+ listener.remoteSearchStarted(folderName);
}
List extraResults = new ArrayList();
@@ -791,7 +789,7 @@ public class MessagingController implements Runnable {
messages.clear();
if (listener != null) {
- listener.remoteSearchServerQueryComplete(acct, folderName, remoteMessages.size());
+ listener.remoteSearchServerQueryComplete(folderName, remoteMessages.size(), acct.getRemoteSearchNumResults());
}
Collections.sort(remoteMessages, new UidReverseComparator());
@@ -811,13 +809,13 @@ public class MessagingController implements Runnable {
} else {
Log.e(K9.LOG_TAG, "Could not complete remote search", e);
if (listener != null) {
- listener.remoteSearchFailed(acct, null, e.getMessage());
+ listener.remoteSearchFailed(null, e.getMessage());
}
addErrorMessage(acct, null, e);
}
} finally {
if (listener != null) {
- listener.remoteSearchFinished(acct, folderName, 0, extraResults);
+ listener.remoteSearchFinished(folderName, 0, acct.getRemoteSearchNumResults(), extraResults);
}
}
@@ -878,7 +876,7 @@ public class MessagingController implements Runnable {
}
if (listener != null) {
- listener.remoteSearchAddMessage(remoteFolder.getAccount(), remoteFolder.getName(), localMsg, i, messages.size());
+ listener.remoteSearchAddMessage(remoteFolder.getName(), localMsg, i, messages.size());
}
}
}
@@ -1455,7 +1453,7 @@ public class MessagingController implements Runnable {
}
}
- private void fetchUnsyncedMessages(final Account account, final Folder remoteFolder,
+ private void fetchUnsyncedMessages(final Account account, final Folder remoteFolder,
final LocalFolder localFolder,
List unsyncedMessages,
final List smallMessages,
@@ -1473,9 +1471,9 @@ public class MessagingController implements Runnable {
final List chunk = new ArrayList(UNSYNC_CHUNK_SIZE);
remoteFolder.fetch(unsyncedMessages, fp,
- new MessageRetrievalListener() {
+ new MessageRetrievalListener() {
@Override
- public void messageFinished(Message message, int number, int ofTotal) {
+ public void messageFinished(T message, int number, int ofTotal) {
try {
String newPushState = remoteFolder.getNewPushState(localFolder.getPushState(), message);
if (newPushState != null) {
@@ -1564,7 +1562,7 @@ public class MessagingController implements Runnable {
localFolder.appendMessages(messages);
for (final Message message : messages) {
- final Message localMessage = localFolder.getMessage(message.getUid());
+ final LocalMessage localMessage = localFolder.getMessage(message.getUid());
syncFlags(localMessage, message);
if (K9.DEBUG)
Log.v(K9.LOG_TAG, "About to notify listeners that we got a new unsynced message "
@@ -1592,9 +1590,9 @@ public class MessagingController implements Runnable {
return true;
}
- private void downloadSmallMessages(final Account account, final Folder remoteFolder,
+ private void downloadSmallMessages(final Account account, final Folder remoteFolder,
final LocalFolder localFolder,
- List smallMessages,
+ List smallMessages,
final AtomicInteger progress,
final int unreadBeforeStart,
final AtomicInteger newMessages,
@@ -1608,9 +1606,9 @@ public class MessagingController implements Runnable {
Log.d(K9.LOG_TAG, "SYNC: Fetching small messages for folder " + folder);
remoteFolder.fetch(smallMessages,
- fp, new MessageRetrievalListener() {
+ fp, new MessageRetrievalListener() {
@Override
- public void messageFinished(final Message message, int number, int ofTotal) {
+ public void messageFinished(final T message, int number, int ofTotal) {
try {
if (!shouldImportMessage(account, folder, message, progress, earliestDate)) {
@@ -1671,9 +1669,9 @@ public class MessagingController implements Runnable {
- private void downloadLargeMessages(final Account account, final Folder remoteFolder,
+ private void downloadLargeMessages(final Account account, final Folder remoteFolder,
final LocalFolder localFolder,
- List largeMessages,
+ List largeMessages,
final AtomicInteger progress,
final int unreadBeforeStart,
final AtomicInteger newMessages,
@@ -1821,11 +1819,11 @@ public class MessagingController implements Runnable {
remoteFolder.fetch(undeletedMessages, fp, null);
for (Message remoteMessage : syncFlagMessages) {
- Message localMessage = localFolder.getMessage(remoteMessage.getUid());
+ LocalMessage localMessage = localFolder.getMessage(remoteMessage.getUid());
boolean messageChanged = syncFlags(localMessage, remoteMessage);
if (messageChanged) {
boolean shouldBeNotifiedOf = false;
- if (localMessage.isSet(Flag.DELETED) || isMessageSuppressed(account, localMessage)) {
+ if (localMessage.isSet(Flag.DELETED) || isMessageSuppressed(localMessage)) {
for (MessagingListener l : getListeners()) {
l.synchronizeMailboxRemovedMessage(account, folder, localMessage);
}
@@ -1859,13 +1857,13 @@ public class MessagingController implements Runnable {
}
}
- private boolean syncFlags(Message localMessage, Message remoteMessage) throws MessagingException {
+ private boolean syncFlags(LocalMessage localMessage, Message remoteMessage) throws MessagingException {
boolean messageChanged = false;
if (localMessage == null || localMessage.isSet(Flag.DELETED)) {
return false;
}
if (remoteMessage.isSet(Flag.DELETED)) {
- if (localMessage.getFolder().getAccount().syncRemoteDeletions()) {
+ if (localMessage.getFolder().syncRemoteDeletions()) {
localMessage.setFlag(Flag.DELETED, true);
messageChanged = true;
}
@@ -2857,7 +2855,7 @@ public class MessagingController implements Runnable {
* @param newState
* {@code true}, if the flag should be set. {@code false} if it should be removed.
*/
- public void setFlag(Account account, String folderName, List messages, Flag flag,
+ public void setFlag(Account account, String folderName, List extends Message> messages, Flag flag,
boolean newState) {
// TODO: Put this into the background, but right now some callers depend on the message
// objects being modified right after this method returns.
@@ -3775,7 +3773,7 @@ public class MessagingController implements Runnable {
}
}
public void moveMessages(final Account account, final String srcFolder,
- final List messages, final String destFolder,
+ final List messages, final String destFolder,
final MessagingListener listener) {
suppressMessages(account, messages);
@@ -3790,7 +3788,7 @@ public class MessagingController implements Runnable {
}
public void moveMessagesInThread(final Account account, final String srcFolder,
- final List messages, final String destFolder) {
+ final List messages, final String destFolder) {
suppressMessages(account, messages);
@@ -3808,14 +3806,14 @@ public class MessagingController implements Runnable {
});
}
- public void moveMessage(final Account account, final String srcFolder, final Message message,
+ public void moveMessage(final Account account, final String srcFolder, final LocalMessage message,
final String destFolder, final MessagingListener listener) {
moveMessages(account, srcFolder, Collections.singletonList(message), destFolder, listener);
}
public void copyMessages(final Account account, final String srcFolder,
- final List messages, final String destFolder,
+ final List extends Message> messages, final String destFolder,
final MessagingListener listener) {
putBackground("copyMessages", null, new Runnable() {
@@ -3828,7 +3826,7 @@ public class MessagingController implements Runnable {
}
public void copyMessagesInThread(final Account account, final String srcFolder,
- final List messages, final String destFolder) {
+ final List extends Message> messages, final String destFolder) {
putBackground("copyMessagesInThread", null, new Runnable() {
@Override
@@ -3851,7 +3849,7 @@ public class MessagingController implements Runnable {
}
private void moveOrCopyMessageSynchronous(final Account account, final String srcFolder,
- final List inMessages, final String destFolder, final boolean isCopy,
+ final List extends Message> inMessages, final String destFolder, final boolean isCopy,
MessagingListener listener) {
try {
@@ -3962,7 +3960,7 @@ public class MessagingController implements Runnable {
localFolder.open(Folder.OPEN_MODE_RW);
String uid = localFolder.getMessageUidById(id);
if (uid != null) {
- Message message = localFolder.getMessage(uid);
+ LocalMessage message = localFolder.getMessage(uid);
if (message != null) {
deleteMessages(Collections.singletonList(message), null);
}
@@ -3974,7 +3972,7 @@ public class MessagingController implements Runnable {
}
}
- public void deleteThreads(final List messages) {
+ public void deleteThreads(final List messages) {
actOnMessages(messages, new MessageActor() {
@Override
@@ -4006,7 +4004,7 @@ public class MessagingController implements Runnable {
}
}
- public List collectMessagesInThreads(Account account, List messages)
+ public List collectMessagesInThreads(Account account, List extends Message> messages)
throws MessagingException {
LocalStore localStore = account.getLocalStore();
@@ -4025,7 +4023,7 @@ public class MessagingController implements Runnable {
return messagesInThreads;
}
- public void deleteMessages(final List messages, final MessagingListener listener) {
+ public void deleteMessages(final List messages, final MessagingListener listener) {
actOnMessages(messages, new MessageActor() {
@Override
@@ -5685,15 +5683,15 @@ public class MessagingController implements Runnable {
}
- private void actOnMessages(List messages, MessageActor actor) {
+ private void actOnMessages(List messages, MessageActor actor) {
Map>> accountMap = new HashMap>>();
- for (Message message : messages) {
+ for (LocalMessage message : messages) {
if ( message == null) {
continue;
}
Folder folder = message.getFolder();
- Account account = folder.getAccount();
+ Account account = message.getAccount();
Map> folderMap = accountMap.get(account);
if (folderMap == null) {
diff --git a/src/com/fsck/k9/controller/MessagingListener.java b/src/com/fsck/k9/controller/MessagingListener.java
index 5c5a66f50..470cc6387 100644
--- a/src/com/fsck/k9/controller/MessagingListener.java
+++ b/src/com/fsck/k9/controller/MessagingListener.java
@@ -11,6 +11,7 @@ import com.fsck.k9.BaseAccount;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Part;
+import com.fsck.k9.mail.store.local.LocalMessage;
/**
* Defines the interface that {@link MessagingController} will use to callback to requesters.
@@ -42,10 +43,8 @@ public class MessagingListener {
public void listLocalMessagesStarted(Account account, String folder) {}
- public void listLocalMessages(Account account, String folder, Message[] messages) {}
-
public void listLocalMessagesAddMessages(Account account, String folder,
- List messages) {}
+ List messages) {}
public void listLocalMessagesUpdateMessage(Account account, String folder, Message message) {}
@@ -156,10 +155,9 @@ public class MessagingListener {
/**
* Called when a remote search is started
*
- * @param acct
* @param folder
*/
- public void remoteSearchStarted(Account acct, String folder) {}
+ public void remoteSearchStarted(String folder) {}
/**
@@ -167,35 +165,30 @@ public class MessagingListener {
*
* @param numResults
*/
- public void remoteSearchServerQueryComplete(Account account, String folderName, int numResults) { }
+ public void remoteSearchServerQueryComplete(String folderName, int numResults, int maxResults) { }
/**
* Called when a new result message is available for a remote search
* Can assume headers have been downloaded, but potentially not body.
- * @param account
* @param folder
* @param message
*/
- public void remoteSearchAddMessage(Account account, String folder, Message message, int numDone, int numTotal) { }
+ public void remoteSearchAddMessage(String folder, Message message, int numDone, int numTotal) { }
/**
* Called when Remote Search is fully complete
- *
- * @param acct
- * @param folder
+ * @param folder
* @param numResults
*/
- public void remoteSearchFinished(Account acct, String folder, int numResults, List extraResults) {}
+ public void remoteSearchFinished(String folder, int numResults, int maxResults, List extraResults) {}
/**
* Called when there was a problem with a remote search operation.
- *
- * @param acct
- * @param folder
+ * @param folder
* @param err
*/
- public void remoteSearchFailed(Account acct, String folder, String err) { }
+ public void remoteSearchFailed(String folder, String err) { }
/**
* General notification messages subclasses can override to be notified that the controller
diff --git a/src/com/fsck/k9/fragment/MessageListFragment.java b/src/com/fsck/k9/fragment/MessageListFragment.java
index 80b19b33a..48e5b6190 100644
--- a/src/com/fsck/k9/fragment/MessageListFragment.java
+++ b/src/com/fsck/k9/fragment/MessageListFragment.java
@@ -89,6 +89,7 @@ import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.local.LocalFolder;
+import com.fsck.k9.mail.store.local.LocalMessage;
import com.fsck.k9.mail.store.local.LocalStore;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.MessageColumns;
@@ -427,7 +428,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
* Relevant messages for the current context when we have to remember the chosen messages
* between user interactions (e.g. selecting a folder for move operation).
*/
- private List mActiveMessages;
+ private List mActiveMessages;
/* package visibility for faster inner class access */
MessageHelper mMessageHelper;
@@ -1035,7 +1036,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
return null;
}
- private Folder getFolderById(Account account, long folderId) {
+ private LocalFolder getFolderById(Account account, long folderId) {
try {
LocalStore localStore = account.getLocalStore();
LocalFolder localFolder = localStore.getFolderById(folderId);
@@ -1309,11 +1310,11 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
changeSort(sorts[curIndex]);
}
- private void onDelete(Message message) {
+ private void onDelete(LocalMessage message) {
onDelete(Collections.singletonList(message));
}
- private void onDelete(List messages) {
+ private void onDelete(List messages) {
if (K9.confirmDelete()) {
// remember the message selection for #onCreateDialog(int)
mActiveMessages = messages;
@@ -1323,7 +1324,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
}
- private void onDeleteConfirmed(List messages) {
+ private void onDeleteConfirmed(List messages) {
if (mThreadedList) {
mController.deleteThreads(messages);
} else {
@@ -1345,15 +1346,14 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
final String destFolderName = data.getStringExtra(ChooseFolder.EXTRA_NEW_FOLDER);
- final List messages = mActiveMessages;
+ final List messages = mActiveMessages;
if (destFolderName != null) {
mActiveMessages = null; // don't need it any more
if (messages.size() > 0) {
- Account account = messages.get(0).getFolder().getAccount();
- account.setLastSelectedFolderName(destFolderName);
+ messages.get(0).getFolder().setLastSelectedFolderName(destFolderName);
}
switch (requestCode) {
@@ -1539,7 +1539,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
break;
}
case R.id.delete: {
- Message message = getMessageAtPosition(adapterPosition);
+ LocalMessage message = getMessageAtPosition(adapterPosition);
onDelete(message);
break;
}
@@ -1562,23 +1562,19 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
// only if the account supports this
case R.id.archive: {
- Message message = getMessageAtPosition(adapterPosition);
- onArchive(message);
+ onArchive(getMessageAtPosition(adapterPosition));
break;
}
case R.id.spam: {
- Message message = getMessageAtPosition(adapterPosition);
- onSpam(message);
+ onSpam(getMessageAtPosition(adapterPosition));
break;
}
case R.id.move: {
- Message message = getMessageAtPosition(adapterPosition);
- onMove(message);
+ onMove(getMessageAtPosition(adapterPosition));
break;
}
case R.id.copy: {
- Message message = getMessageAtPosition(adapterPosition);
- onCopy(message);
+ onCopy(getMessageAtPosition(adapterPosition));
break;
}
}
@@ -1711,7 +1707,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
class MessageListActivityListener extends ActivityListener {
@Override
- public void remoteSearchFailed(Account acct, String folder, final String err) {
+ public void remoteSearchFailed(String folder, final String err) {
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -1725,7 +1721,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
@Override
- public void remoteSearchStarted(Account acct, String folder) {
+ public void remoteSearchStarted(String folder) {
mHandler.progress(true);
mHandler.updateFooter(mContext.getString(R.string.remote_search_sending_query));
}
@@ -1736,12 +1732,12 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
@Override
- public void remoteSearchFinished(Account acct, String folder, int numResults, List extraResults) {
+ public void remoteSearchFinished(String folder, int numResults, int maxResults, List extraResults) {
mHandler.progress(false);
mHandler.remoteSearchFinished();
mExtraSearchResults = extraResults;
if (extraResults != null && extraResults.size() > 0) {
- mHandler.updateFooter(String.format(mContext.getString(R.string.load_more_messages_fmt), acct.getRemoteSearchNumResults()));
+ mHandler.updateFooter(String.format(mContext.getString(R.string.load_more_messages_fmt), maxResults));
} else {
mHandler.updateFooter("");
}
@@ -1750,11 +1746,11 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
@Override
- public void remoteSearchServerQueryComplete(Account account, String folderName, int numResults) {
+ public void remoteSearchServerQueryComplete(String folderName, int numResults, int maxResults) {
mHandler.progress(true);
- if (account != null && account.getRemoteSearchNumResults() != 0 && numResults > account.getRemoteSearchNumResults()) {
+ if (maxResults != 0 && numResults > maxResults) {
mHandler.updateFooter(mContext.getString(R.string.remote_search_downloading_limited,
- account.getRemoteSearchNumResults(), numResults));
+ maxResults, numResults));
} else {
mHandler.updateFooter(mContext.getString(R.string.remote_search_downloading, numResults));
}
@@ -2416,7 +2412,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
computeBatchDirection();
}
- private void onMove(Message message) {
+ private void onMove(LocalMessage message) {
onMove(Collections.singletonList(message));
}
@@ -2426,7 +2422,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
* @param messages
* Never {@code null}.
*/
- private void onMove(List messages) {
+ private void onMove(List messages) {
if (!checkCopyOrMovePossible(messages, FolderOperation.MOVE)) {
return;
}
@@ -2440,12 +2436,13 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
folder = null;
}
- Account account = messages.get(0).getFolder().getAccount();
- displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_MOVE, account, folder, messages);
+ displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_MOVE, folder,
+ messages.get(0).getFolder().getUuid(), null,
+ messages);
}
- private void onCopy(Message message) {
+ private void onCopy(LocalMessage message) {
onCopy(Collections.singletonList(message));
}
@@ -2455,7 +2452,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
* @param messages
* Never {@code null}.
*/
- private void onCopy(List messages) {
+ private void onCopy(List messages) {
if (!checkCopyOrMovePossible(messages, FolderOperation.COPY)) {
return;
}
@@ -2469,7 +2466,10 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
folder = null;
}
- displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_COPY, mAccount, folder, messages);
+ displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_COPY, folder,
+ messages.get(0).getFolder().getUuid(),
+ null,
+ messages);
}
/**
@@ -2486,12 +2486,13 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
*
* @see #startActivityForResult(Intent, int)
*/
- private void displayFolderChoice(int requestCode, Account account, Folder folder,
- List messages) {
+ private void displayFolderChoice(int requestCode, Folder folder,
+ String accountId, String lastSelectedFolderName,
+ List messages) {
Intent intent = new Intent(getActivity(), ChooseFolder.class);
- intent.putExtra(ChooseFolder.EXTRA_ACCOUNT, account.getUuid());
- intent.putExtra(ChooseFolder.EXTRA_SEL_FOLDER, account.getLastSelectedFolderName());
+ intent.putExtra(ChooseFolder.EXTRA_ACCOUNT, accountId);
+ intent.putExtra(ChooseFolder.EXTRA_SEL_FOLDER, lastSelectedFolderName);
if (folder == null) {
intent.putExtra(ChooseFolder.EXTRA_SHOW_CURRENT, "yes");
@@ -2504,14 +2505,14 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
startActivityForResult(intent, requestCode);
}
- private void onArchive(final Message message) {
+ private void onArchive(final LocalMessage message) {
onArchive(Collections.singletonList(message));
}
- private void onArchive(final List messages) {
- Map> messagesByAccount = groupMessagesByAccount(messages);
+ private void onArchive(final List messages) {
+ Map> messagesByAccount = groupMessagesByAccount(messages);
- for (Entry> entry : messagesByAccount.entrySet()) {
+ for (Entry> entry : messagesByAccount.entrySet()) {
Account account = entry.getKey();
String archiveFolder = account.getArchiveFolderName();
@@ -2521,14 +2522,14 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
}
- private Map> groupMessagesByAccount(final List messages) {
- Map> messagesByAccount = new HashMap>();
- for (Message message : messages) {
- Account account = message.getFolder().getAccount();
+ private Map> groupMessagesByAccount(final List messages) {
+ Map> messagesByAccount = new HashMap>();
+ for (LocalMessage message : messages) {
+ Account account = message.getAccount();
- List msgList = messagesByAccount.get(account);
+ List msgList = messagesByAccount.get(account);
if (msgList == null) {
- msgList = new ArrayList();
+ msgList = new ArrayList();
messagesByAccount.put(account, msgList);
}
@@ -2537,7 +2538,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
return messagesByAccount;
}
- private void onSpam(Message message) {
+ private void onSpam(LocalMessage message) {
onSpam(Collections.singletonList(message));
}
@@ -2547,7 +2548,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
* @param messages
* The messages to move to the spam folder. Never {@code null}.
*/
- private void onSpam(List messages) {
+ private void onSpam(List messages) {
if (K9.confirmSpam()) {
// remember the message selection for #onCreateDialog(int)
mActiveMessages = messages;
@@ -2557,10 +2558,10 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
}
- private void onSpamConfirmed(List messages) {
- Map> messagesByAccount = groupMessagesByAccount(messages);
+ private void onSpamConfirmed(List messages) {
+ Map> messagesByAccount = groupMessagesByAccount(messages);
- for (Entry> entry : messagesByAccount.entrySet()) {
+ for (Entry> entry : messagesByAccount.entrySet()) {
Account account = entry.getKey();
String spamFolder = account.getSpamFolderName();
@@ -2584,7 +2585,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
*
* @return {@code true}, if operation is possible.
*/
- private boolean checkCopyOrMovePossible(final List messages,
+ private boolean checkCopyOrMovePossible(final List messages,
final FolderOperation operation) {
if (messages.isEmpty()) {
@@ -2592,11 +2593,11 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
boolean first = true;
- for (final Message message : messages) {
+ for (final LocalMessage message : messages) {
if (first) {
first = false;
// account check
- final Account account = message.getFolder().getAccount();
+ final Account account = message.getAccount();
if ((operation == FolderOperation.MOVE && !mController.isMoveCapable(account)) ||
(operation == FolderOperation.COPY && !mController.isCopyCapable(account))) {
return false;
@@ -2622,7 +2623,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
* @param destination
* The name of the destination folder. Never {@code null}.
*/
- private void copy(List messages, final String destination) {
+ private void copy(List messages, final String destination) {
copyOrMove(messages, destination, FolderOperation.COPY);
}
@@ -2634,7 +2635,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
* @param destination
* The name of the destination folder. Never {@code null}.
*/
- private void move(List messages, final String destination) {
+ private void move(List messages, final String destination) {
copyOrMove(messages, destination, FolderOperation.MOVE);
}
@@ -2650,12 +2651,12 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
* @param operation
* Specifies what operation to perform. Never {@code null}.
*/
- private void copyOrMove(List messages, final String destination,
+ private void copyOrMove(List messages, final String destination,
final FolderOperation operation) {
- Map> folderMap = new HashMap>();
+ Map> folderMap = new HashMap>();
- for (Message message : messages) {
+ for (LocalMessage message : messages) {
if ((operation == FolderOperation.MOVE && !mController.isMoveCapable(message)) ||
(operation == FolderOperation.COPY && !mController.isCopyCapable(message))) {
@@ -2674,19 +2675,19 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
continue;
}
- List outMessages = folderMap.get(folderName);
+ List outMessages = folderMap.get(folderName);
if (outMessages == null) {
- outMessages = new ArrayList();
+ outMessages = new ArrayList();
folderMap.put(folderName, outMessages);
}
outMessages.add(message);
}
- for (Map.Entry> entry : folderMap.entrySet()) {
+ for (Map.Entry> entry : folderMap.entrySet()) {
String folderName = entry.getKey();
- List outMessages = entry.getValue();
- Account account = outMessages.get(0).getFolder().getAccount();
+ List outMessages = entry.getValue();
+ Account account = outMessages.get(0).getAccount();
if (operation == FolderOperation.MOVE) {
if (mThreadedList) {
@@ -2859,7 +2860,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
*/
switch (item.getItemId()) {
case R.id.delete: {
- List messages = getCheckedMessages();
+ List messages = getCheckedMessages();
onDelete(messages);
mSelectedCount = 0;
break;
@@ -2887,26 +2888,22 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
// only if the account supports this
case R.id.archive: {
- List messages = getCheckedMessages();
- onArchive(messages);
+ onArchive(getCheckedMessages());
mSelectedCount = 0;
break;
}
case R.id.spam: {
- List messages = getCheckedMessages();
- onSpam(messages);
+ onSpam(getCheckedMessages());
mSelectedCount = 0;
break;
}
case R.id.move: {
- List messages = getCheckedMessages();
- onMove(messages);
+ onMove(getCheckedMessages());
mSelectedCount = 0;
break;
}
case R.id.copy: {
- List messages = getCheckedMessages();
- onCopy(messages);
+ onCopy(getCheckedMessages());
mSelectedCount = 0;
break;
}
@@ -2987,7 +2984,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
final Folder remoteFolder = mCurrentFolder.folder;
remoteFolder.close();
// Send a remoteSearchFinished() message for good measure.
- mListener.remoteSearchFinished(searchAccount, mCurrentFolder.name, 0, null);
+ mListener.remoteSearchFinished(mCurrentFolder.name, 0, searchAccount.getRemoteSearchNumResults(), null);
} catch (Exception e) {
// Since the user is going back, log and squash any exceptions.
Log.e(K9.LOG_TAG, "Could not abort remote search before going back", e);
@@ -3135,7 +3132,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
changeSort(mSortType);
}
- private Message getSelectedMessage() {
+ private LocalMessage getSelectedMessage() {
int listViewPosition = mListView.getSelectedItemPosition();
int adapterPosition = listViewToAdapterPosition(listViewPosition);
@@ -3158,7 +3155,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
return AdapterView.INVALID_POSITION;
}
- private Message getMessageAtPosition(int adapterPosition) {
+ private LocalMessage getMessageAtPosition(int adapterPosition) {
if (adapterPosition == AdapterView.INVALID_POSITION) {
return null;
}
@@ -3168,7 +3165,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
Account account = getAccountFromCursor(cursor);
long folderId = cursor.getLong(FOLDER_ID_COLUMN);
- Folder folder = getFolderById(account, folderId);
+ LocalFolder folder = getFolderById(account, folderId);
try {
return folder.getMessage(uid);
@@ -3179,14 +3176,14 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
return null;
}
- private List getCheckedMessages() {
- List messages = new ArrayList(mSelected.size());
+ private List getCheckedMessages() {
+ List messages = new ArrayList(mSelected.size());
for (int position = 0, end = mAdapter.getCount(); position < end; position++) {
Cursor cursor = (Cursor) mAdapter.getItem(position);
long uniqueId = cursor.getLong(mUniqueIdColumn);
if (mSelected.contains(uniqueId)) {
- Message message = getMessageAtPosition(position);
+ LocalMessage message = getMessageAtPosition(position);
if (message != null) {
messages.add(message);
}
@@ -3197,7 +3194,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
public void onDelete() {
- Message message = getSelectedMessage();
+ LocalMessage message = getSelectedMessage();
if (message != null) {
onDelete(Collections.singletonList(message));
}
@@ -3227,21 +3224,21 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
public void onMove() {
- Message message = getSelectedMessage();
+ LocalMessage message = getSelectedMessage();
if (message != null) {
onMove(message);
}
}
public void onArchive() {
- Message message = getSelectedMessage();
+ LocalMessage message = getSelectedMessage();
if (message != null) {
onArchive(message);
}
}
public void onCopy() {
- Message message = getSelectedMessage();
+ LocalMessage message = getSelectedMessage();
if (message != null) {
onCopy(message);
}
diff --git a/src/com/fsck/k9/fragment/MessageViewFragment.java b/src/com/fsck/k9/fragment/MessageViewFragment.java
index 3a8bb4ddd..c8cfea928 100644
--- a/src/com/fsck/k9/fragment/MessageViewFragment.java
+++ b/src/com/fsck/k9/fragment/MessageViewFragment.java
@@ -75,7 +75,7 @@ public class MessageViewFragment extends Fragment implements OnClickListener,
private PgpData mPgpData;
private Account mAccount;
private MessageReference mMessageReference;
- private Message mMessage;
+ private LocalMessage mMessage;
private MessagingController mController;
private Listener mListener = new Listener();
private MessageViewHandler mHandler = new MessageViewHandler();
@@ -311,7 +311,7 @@ public class MessageViewFragment extends Fragment implements OnClickListener,
// Disable the delete button after it's tapped (to try to prevent
// accidental clicks)
mFragmentListener.disableDeleteAction();
- Message messageToDelete = mMessage;
+ LocalMessage messageToDelete = mMessage;
mFragmentListener.showNextMessageOrReturn();
mController.deleteMessages(Collections.singletonList(messageToDelete), null);
}
@@ -341,7 +341,7 @@ public class MessageViewFragment extends Fragment implements OnClickListener,
private void refileMessage(String dstFolder) {
String srcFolder = mMessageReference.folderName;
- Message messageToMove = mMessage;
+ LocalMessage messageToMove = mMessage;
mFragmentListener.showNextMessageOrReturn();
mController.moveMessage(mAccount, srcFolder, messageToMove, dstFolder, null);
}
@@ -576,7 +576,8 @@ public class MessageViewFragment extends Fragment implements OnClickListener,
@Override
public void loadMessageForViewBodyAvailable(final Account account, String folder,
String uid, final Message message) {
- if (!mMessageReference.uid.equals(uid) ||
+ if (!(message instanceof LocalMessage) ||
+ !mMessageReference.uid.equals(uid) ||
!mMessageReference.folderName.equals(folder) ||
!mMessageReference.accountUuid.equals(account.getUuid())) {
return;
@@ -586,7 +587,7 @@ public class MessageViewFragment extends Fragment implements OnClickListener,
@Override
public void run() {
try {
- mMessage = message;
+ mMessage = (LocalMessage) message;
mMessageView.setMessage(account, (LocalMessage) message, mPgpData,
mController, mListener);
mFragmentListener.updateMenu();
diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java
index 26430b9e8..5df0161b8 100644
--- a/src/com/fsck/k9/helper/MessageHelper.java
+++ b/src/com/fsck/k9/helper/MessageHelper.java
@@ -14,6 +14,7 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Message.RecipientType;
+import com.fsck.k9.mail.store.local.LocalMessage;
public class MessageHelper {
@@ -32,8 +33,10 @@ public class MessageHelper {
mContext = context;
}
- public void populate(final MessageInfoHolder target, final Message message,
- final FolderInfoHolder folder, final Account account) {
+ public void populate(final MessageInfoHolder target,
+ final LocalMessage message,
+ final FolderInfoHolder folder,
+ Account account) {
final Contacts contactHelper = K9.showContactName() ? Contacts.getInstance(mContext) : null;
try {
target.message = message;
@@ -68,14 +71,9 @@ public class MessageHelper {
target.senderAddress = target.compareCounterparty;
}
-
-
-
target.uid = message.getUid();
-
- target.account = account.getUuid();
- target.uri = "email://messages/" + account.getAccountNumber() + "/" + message.getFolder().getName() + "/" + message.getUid();
-
+ target.account = message.getFolder().getUuid();
+ target.uri = message.getUri();
} catch (MessagingException me) {
Log.w(K9.LOG_TAG, "Unable to load message info", me);
}
diff --git a/src/com/fsck/k9/mail/Folder.java b/src/com/fsck/k9/mail/Folder.java
index 88af1a31a..5669e9794 100644
--- a/src/com/fsck/k9/mail/Folder.java
+++ b/src/com/fsck/k9/mail/Folder.java
@@ -1,21 +1,17 @@
package com.fsck.k9.mail;
-import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import android.util.Log;
-import com.fsck.k9.Account;
+
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.controller.MessageRetrievalListener;
-
-public abstract class Folder {
- protected final Account mAccount;
-
+public abstract class Folder {
private String status = null;
private long lastChecked = 0;
private long lastPush = 0;
@@ -32,10 +28,6 @@ public abstract class Folder {
HOLDS_FOLDERS, HOLDS_MESSAGES,
}
- protected Folder(Account account) {
- mAccount = account;
- }
-
/**
* Forces an open of the MailProvider. If the provider is already open this
* function returns without doing anything.
@@ -83,7 +75,7 @@ public abstract class Folder {
public abstract int getUnreadMessageCount() throws MessagingException;
public abstract int getFlaggedMessageCount() throws MessagingException;
- public abstract Message getMessage(String uid) throws MessagingException;
+ public abstract T getMessage(String uid) throws MessagingException;
/**
* Fetch the shells of messages between a range of UIDs and after a given date.
@@ -94,7 +86,7 @@ public abstract class Folder {
* @return List of messages
* @throws MessagingException
*/
- public abstract List extends Message> getMessages(int start, int end, Date earliestDate, MessageRetrievalListener listener) throws MessagingException;
+ public abstract List getMessages(int start, int end, Date earliestDate, MessageRetrievalListener listener) throws MessagingException;
/**
* Fetches the given list of messages. The specified listener is notified as
@@ -104,13 +96,13 @@ public abstract class Folder {
* @param listener Listener to notify as we download messages.
* @return List of messages
*/
- public abstract List extends Message> getMessages(MessageRetrievalListener listener) throws MessagingException;
+ public abstract List getMessages(MessageRetrievalListener listener) throws MessagingException;
- public List extends Message> getMessages(MessageRetrievalListener listener, boolean includeDeleted) throws MessagingException {
+ public List getMessages(MessageRetrievalListener listener, boolean includeDeleted) throws MessagingException {
return getMessages(listener);
}
- public abstract List extends Message> getMessages(String[] uids, MessageRetrievalListener listener)
+ public abstract List getMessages(String[] uids, MessageRetrievalListener listener)
throws MessagingException;
public abstract Map appendMessages(List extends Message> messages) throws MessagingException;
@@ -149,10 +141,10 @@ public abstract class Folder {
* @throws MessagingException
*/
public abstract void fetch(List extends Message> messages, FetchProfile fp,
- MessageRetrievalListener listener) throws MessagingException;
+ MessageRetrievalListener listener) throws MessagingException;
public void fetchPart(Message message, Part part,
- MessageRetrievalListener listener) throws MessagingException {
+ MessageRetrievalListener listener) throws MessagingException {
// This is causing trouble. Disabled for now. See issue 1733
//throw new RuntimeException("fetchPart() not implemented.");
@@ -241,10 +233,6 @@ public abstract class Folder {
this.status = status;
}
- public Account getAccount() {
- return mAccount;
- }
-
public List search(String queryString, final Set requiredFlags, final Set forbiddenFlags)
throws MessagingException {
throw new MessagingException("K-9 does not support searches on this folder type");
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index 5a4d7a34a..452d312df 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -19,8 +19,8 @@ import com.fsck.k9.mail.store.UnavailableStorageException;
public abstract class Message implements Part, CompositeBody {
+ protected MessageReference mReference;
- private MessageReference mReference = null;
public enum RecipientType {
TO, CC, BCC,
@@ -55,8 +55,7 @@ public abstract class Message implements Part, CompositeBody {
}
Message other = (Message)o;
return (mUid.equals(other.getUid())
- && mFolder.getName().equals(other.getFolder().getName())
- && mFolder.getAccount().getUuid().equals(other.getFolder().getAccount().getUuid()));
+ && mFolder.getName().equals(other.getFolder().getName()));
}
@Override
@@ -65,7 +64,6 @@ public abstract class Message implements Part, CompositeBody {
int result = 1;
result = MULTIPLIER * result + mFolder.getName().hashCode();
- result = MULTIPLIER * result + mFolder.getAccount().getUuid().hashCode();
result = MULTIPLIER * result + mUid.hashCode();
return result;
}
@@ -75,7 +73,7 @@ public abstract class Message implements Part, CompositeBody {
}
public void setUid(String uid) {
- mReference = null;
+ this.mReference = null;
this.mUid = uid;
}
@@ -249,15 +247,14 @@ public abstract class Message implements Part, CompositeBody {
public void destroy() throws MessagingException {}
@Override
- public abstract void setEncoding(String encoding) throws UnavailableStorageException, MessagingException;
+ public abstract void setEncoding(String encoding) throws MessagingException;
public abstract void setCharset(String charset) throws MessagingException;
public MessageReference makeMessageReference() {
if (mReference == null) {
mReference = new MessageReference();
- mReference.accountUuid = getFolder().getAccount().getUuid();
- mReference.folderName = getFolder().getName();
+ mReference.folderName = getFolder().getName();
mReference.uid = mUid;
}
return mReference;
diff --git a/src/com/fsck/k9/mail/Store.java b/src/com/fsck/k9/mail/Store.java
index 7dbfade7e..424b6bca1 100644
--- a/src/com/fsck/k9/mail/Store.java
+++ b/src/com/fsck/k9/mail/Store.java
@@ -1,24 +1,7 @@
package com.fsck.k9.mail;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import android.app.Application;
-import android.content.Context;
-import android.util.Log;
-
-import com.fsck.k9.Account;
-import com.fsck.k9.K9;
-import com.fsck.k9.mail.store.ImapStore;
-import com.fsck.k9.mail.store.Pop3Store;
-import com.fsck.k9.mail.store.StorageManager.StorageProvider;
-import com.fsck.k9.mail.store.local.LocalStore;
-import com.fsck.k9.mail.store.UnavailableStorageException;
-import com.fsck.k9.mail.store.WebDavStore;
/**
* Store is the access point for an email message store. It's location can be
@@ -29,191 +12,6 @@ import com.fsck.k9.mail.store.WebDavStore;
* making as few network connections as possible.
*/
public abstract class Store {
- protected static final int SOCKET_CONNECT_TIMEOUT = 30000;
- protected static final int SOCKET_READ_TIMEOUT = 60000;
-
- /**
- * Remote stores indexed by Uri.
- */
- private static Map sStores = new HashMap();
-
- /**
- * Local stores indexed by UUID because the Uri may change due to migration to/from SD-card.
- */
- private static ConcurrentMap sLocalStores = new ConcurrentHashMap();
-
- /**
- * Lock objects indexed by account UUID.
- *
- * @see #getLocalInstance(Account, Application)
- */
- private static ConcurrentMap sAccountLocks = new ConcurrentHashMap();
-
- /**
- * Get an instance of a remote mail store.
- */
- public synchronized static Store getRemoteInstance(Account account) throws MessagingException {
- String uri = account.getStoreUri();
-
- if (uri.startsWith("local")) {
- throw new RuntimeException("Asked to get non-local Store object but given LocalStore URI");
- }
-
- Store store = sStores.get(uri);
- if (store == null) {
- if (uri.startsWith("imap")) {
- store = new ImapStore(account);
- } else if (uri.startsWith("pop3")) {
- store = new Pop3Store(account);
- } else if (uri.startsWith("webdav")) {
- store = new WebDavStore(account);
- }
-
- if (store != null) {
- sStores.put(uri, store);
- }
- }
-
- if (store == null) {
- throw new MessagingException("Unable to locate an applicable Store for " + uri);
- }
-
- return store;
- }
-
- /**
- * Get an instance of a local mail store.
- *
- * @throws UnavailableStorageException
- * if not {@link StorageProvider#isReady(Context)}
- */
- public static LocalStore getLocalInstance(Account account, Application application)
- throws MessagingException {
-
- String accountUuid = account.getUuid();
-
- // Create new per-account lock object if necessary
- sAccountLocks.putIfAbsent(accountUuid, new Object());
-
- // Get the account's lock object
- Object lock = sAccountLocks.get(accountUuid);
-
- // Use per-account locks so DatabaseUpgradeService always knows which account database is
- // currently upgraded.
- synchronized (lock) {
- Store store = sLocalStores.get(accountUuid);
-
- if (store == null) {
- // Creating a LocalStore instance will create or upgrade the database if
- // necessary. This could take some time.
- store = new LocalStore(account, application);
-
- sLocalStores.put(accountUuid, store);
- }
-
- return (LocalStore) store;
- }
- }
-
- public static void removeAccount(Account account) {
- try {
- removeRemoteInstance(account);
- } catch (Exception e) {
- Log.e(K9.LOG_TAG, "Failed to reset remote store for account " + account.getUuid(), e);
- }
-
- try {
- removeLocalInstance(account);
- } catch (Exception e) {
- Log.e(K9.LOG_TAG, "Failed to reset local store for account " + account.getUuid(), e);
- }
- }
-
- /**
- * Release reference to a local mail store instance.
- *
- * @param account
- * {@link Account} instance that is used to get the local mail store instance.
- */
- private static void removeLocalInstance(Account account) {
- String accountUuid = account.getUuid();
- sLocalStores.remove(accountUuid);
- }
-
- /**
- * Release reference to a remote mail store instance.
- *
- * @param account
- * {@link Account} instance that is used to get the remote mail store instance.
- */
- private synchronized static void removeRemoteInstance(Account account) {
- String uri = account.getStoreUri();
-
- if (uri.startsWith("local")) {
- throw new RuntimeException("Asked to get non-local Store object but given " +
- "LocalStore URI");
- }
-
- sStores.remove(uri);
- }
-
- /**
- * Decodes the contents of store-specific URIs and puts them into a {@link ServerSettings}
- * object.
- *
- * @param uri
- * the store-specific URI to decode
- *
- * @return A {@link ServerSettings} object holding the settings contained in the URI.
- *
- * @see ImapStore#decodeUri(String)
- * @see Pop3Store#decodeUri(String)
- * @see WebDavStore#decodeUri(String)
- */
- public static ServerSettings decodeStoreUri(String uri) {
- if (uri.startsWith("imap")) {
- return ImapStore.decodeUri(uri);
- } else if (uri.startsWith("pop3")) {
- return Pop3Store.decodeUri(uri);
- } else if (uri.startsWith("webdav")) {
- return WebDavStore.decodeUri(uri);
- } else {
- throw new IllegalArgumentException("Not a valid store URI");
- }
- }
-
- /**
- * Creates a store URI from the information supplied in the {@link ServerSettings} object.
- *
- * @param server
- * The {@link ServerSettings} object that holds the server settings.
- *
- * @return A store URI that holds the same information as the {@code server} parameter.
- *
- * @see ImapStore#createUri(ServerSettings)
- * @see Pop3Store#createUri(ServerSettings)
- * @see WebDavStore#createUri(ServerSettings)
- */
- public static String createStoreUri(ServerSettings server) {
- if (ImapStore.STORE_TYPE.equals(server.type)) {
- return ImapStore.createUri(server);
- } else if (Pop3Store.STORE_TYPE.equals(server.type)) {
- return Pop3Store.createUri(server);
- } else if (WebDavStore.STORE_TYPE.equals(server.type)) {
- return WebDavStore.createUri(server);
- } else {
- throw new IllegalArgumentException("Not a valid store URI");
- }
- }
-
-
- protected final Account mAccount;
-
-
- protected Store(Account account) {
- mAccount = account;
- }
-
public abstract Folder getFolder(String name);
public abstract List extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException;
@@ -244,14 +42,9 @@ public abstract class Store {
return true;
}
- public void sendMessages(List extends Message> messages) throws MessagingException {
- }
+ public void sendMessages(List extends Message> messages) throws MessagingException { }
public Pusher getPusher(PushReceiver receiver) {
return null;
}
-
- public Account getAccount() {
- return mAccount;
- }
}
diff --git a/src/com/fsck/k9/mail/store/ImapResponseParser.java b/src/com/fsck/k9/mail/store/ImapResponseParser.java
index 4a8c8cc2e..541ff2376 100644
--- a/src/com/fsck/k9/mail/store/ImapResponseParser.java
+++ b/src/com/fsck/k9/mail/store/ImapResponseParser.java
@@ -11,7 +11,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
-public class ImapResponseParser {
+class ImapResponseParser {
private static final SimpleDateFormat mDateTimeFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss Z", Locale.US);
private static final SimpleDateFormat badDateTimeFormat = new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z", Locale.US);
private static final SimpleDateFormat badDateTimeFormat2 = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z", Locale.US);
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index afd4384fd..98c3a6833 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -55,7 +55,6 @@ import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
-import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.controller.MessageRetrievalListener;
@@ -78,7 +77,6 @@ import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.PushReceiver;
import com.fsck.k9.mail.Pusher;
import com.fsck.k9.mail.ServerSettings;
-import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
import com.fsck.k9.mail.filter.FixedLengthInputStream;
@@ -105,7 +103,7 @@ import org.apache.commons.io.IOUtils;
* TODO Need a default response handler for things like folder updates
*
*/
-public class ImapStore extends Store {
+public class ImapStore extends RemoteStore {
public static final String STORE_TYPE = "IMAP";
private static final int IDLE_READ_TIMEOUT_INCREMENT = 5 * 60 * 1000;
@@ -113,7 +111,7 @@ public class ImapStore extends Store {
private static int MAX_DELAY_TIME = 5 * 60 * 1000; // 5 minutes
private static int NORMAL_DELAY_TIME = 5000;
- private static int FETCH_WINDOW_SIZE = 100;
+ private static final int FETCH_WINDOW_SIZE = 100;
private Set mPermanentFlagsIndex = EnumSet.noneOf(Flag.class);
@@ -387,7 +385,7 @@ public class ImapStore extends Store {
@Override
public boolean useCompression(final int type) {
- return mAccount.useCompression(type);
+ return mStoreConfig.useCompression(type);
}
@Override
@@ -439,12 +437,12 @@ public class ImapStore extends Store {
*/
private final Map mFolderCache = new HashMap();
- public ImapStore(Account account) throws MessagingException {
- super(account);
+ public ImapStore(StoreConfig storeConfig) throws MessagingException {
+ super(storeConfig);
ImapStoreSettings settings;
try {
- settings = decodeUri(mAccount.getStoreUri());
+ settings = decodeUri(storeConfig.getStoreUri());
} catch (IllegalArgumentException e) {
throw new MessagingException("Error while decoding store URI", e);
}
@@ -502,7 +500,7 @@ public class ImapStore extends Store {
ImapConnection connection = getConnection();
try {
List extends Folder > allFolders = listFolders(connection, false);
- if (forceListAll || !mAccount.subscribedFoldersOnly()) {
+ if (forceListAll || !mStoreConfig.subscribedFoldersOnly()) {
return allFolders;
} else {
List resultFolders = new LinkedList();
@@ -570,9 +568,9 @@ public class ImapStore extends Store {
mCombinedPrefix = null;
}
- if (folder.equalsIgnoreCase(mAccount.getInboxFolderName())) {
+ if (folder.equalsIgnoreCase(mStoreConfig.getInboxFolderName())) {
continue;
- } else if (folder.equals(mAccount.getOutboxFolderName())) {
+ } else if (folder.equals(mStoreConfig.getOutboxFolderName())) {
/*
* There is a folder on the server with the same name as our local
* outbox. Until we have a good plan to deal with this situation
@@ -604,7 +602,7 @@ public class ImapStore extends Store {
}
}
}
- folders.add(getFolder(mAccount.getInboxFolderName()));
+ folders.add(getFolder(mStoreConfig.getInboxFolderName()));
return folders;
}
@@ -661,17 +659,17 @@ public class ImapStore extends Store {
for (int i = 0, count = attributes.size(); i < count; i++) {
String attribute = attributes.getString(i);
if (attribute.equals("\\Drafts")) {
- mAccount.setDraftsFolderName(decodedFolderName);
+ mStoreConfig.setDraftsFolderName(decodedFolderName);
if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration detected draft folder: " + decodedFolderName);
} else if (attribute.equals("\\Sent")) {
- mAccount.setSentFolderName(decodedFolderName);
+ mStoreConfig.setSentFolderName(decodedFolderName);
if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration detected sent folder: " + decodedFolderName);
} else if (attribute.equals("\\Spam") || attribute.equals("\\Junk")) {
//rfc6154 just mentions \Junk
- mAccount.setSpamFolderName(decodedFolderName);
+ mStoreConfig.setSpamFolderName(decodedFolderName);
if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration detected spam folder: " + decodedFolderName);
} else if (attribute.equals("\\Trash")) {
- mAccount.setTrashFolderName(decodedFolderName);
+ mStoreConfig.setTrashFolderName(decodedFolderName);
if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration detected trash folder: " + decodedFolderName);
}
}
@@ -777,7 +775,7 @@ public class ImapStore extends Store {
}
- class ImapFolder extends Folder {
+ class ImapFolder extends Folder {
private String mName;
protected volatile int mMessageCount = -1;
protected volatile long uidNext = -1L;
@@ -789,14 +787,14 @@ public class ImapStore extends Store {
private boolean mInSearch = false;
public ImapFolder(ImapStore nStore, String name) {
- super(nStore.getAccount());
+ super();
store = nStore;
this.mName = name;
}
public String getPrefixedName() throws MessagingException {
String prefixedName = "";
- if (!mAccount.getInboxFolderName().equalsIgnoreCase(mName)) {
+ if (!mStoreConfig.getInboxFolderName().equalsIgnoreCase(mName)) {
ImapConnection connection = null;
synchronized (this) {
if (mConnection == null) {
@@ -1293,7 +1291,7 @@ public class ImapStore extends Store {
}
@Override
- public Message getMessage(String uid) throws MessagingException {
+ public ImapMessage getMessage(String uid) throws MessagingException {
return new ImapMessage(uid, this);
}
@@ -1351,7 +1349,7 @@ public class ImapStore extends Store {
return search(searcher, listener);
}
- private List search(ImapSearcher searcher, MessageRetrievalListener listener) throws MessagingException {
+ private List search(ImapSearcher searcher, MessageRetrievalListener listener) throws MessagingException {
checkOpen(); //only need READ access
List messages = new ArrayList();
@@ -1432,7 +1430,7 @@ public class ImapStore extends Store {
}
@Override
- public void fetch(List extends Message> messages, FetchProfile fp, MessageRetrievalListener listener)
+ public void fetch(List extends Message> messages, FetchProfile fp, MessageRetrievalListener listener)
throws MessagingException {
if (messages == null || messages.isEmpty()) {
return;
@@ -1468,8 +1466,8 @@ public class ImapStore extends Store {
}
if (fp.contains(FetchProfile.Item.BODY_SANE)) {
// If the user wants to download unlimited-size messages, don't go only for the truncated body
- if (mAccount.getMaximumAutoDownloadMessageSize() > 0) {
- fetchFields.add(String.format(Locale.US, "BODY.PEEK[]<0.%d>", mAccount.getMaximumAutoDownloadMessageSize()));
+ if (mStoreConfig.getMaximumAutoDownloadMessageSize() > 0) {
+ fetchFields.add(String.format(Locale.US, "BODY.PEEK[]<0.%d>", mStoreConfig.getMaximumAutoDownloadMessageSize()));
} else {
fetchFields.add("BODY.PEEK[]");
}
@@ -1544,7 +1542,7 @@ public class ImapStore extends Store {
}
if (listener != null) {
- listener.messageFinished(message, messageNumber, messageMap.size());
+ listener.messageFinished(imapMessage, messageNumber, messageMap.size());
}
} else {
handleUntaggedResponse(response);
@@ -1572,7 +1570,7 @@ public class ImapStore extends Store {
String partId = parts[0];
if ("TEXT".equalsIgnoreCase(partId)) {
fetch = String.format(Locale.US, "BODY.PEEK[TEXT]<0.%d>",
- mAccount.getMaximumAutoDownloadMessageSize());
+ mStoreConfig.getMaximumAutoDownloadMessageSize());
} else {
fetch = String.format("BODY.PEEK[%s]", partId);
}
@@ -2194,7 +2192,7 @@ public class ImapStore extends Store {
}
protected String getLogId() {
- String id = getAccount().getDescription() + ":" + getName() + "/" + Thread.currentThread().getName();
+ String id = mStoreConfig.toString() + ":" + getName() + "/" + Thread.currentThread().getName();
if (mConnection != null) {
id += "/" + mConnection.getLogId();
}
@@ -2213,7 +2211,7 @@ public class ImapStore extends Store {
public List search(final String queryString, final Set requiredFlags, final Set forbiddenFlags)
throws MessagingException {
- if (!mAccount.allowRemoteSearch()) {
+ if (!mStoreConfig.allowRemoteSearch()) {
throw new MessagingException("Your settings do not allow remote searching of this account");
}
@@ -2287,7 +2285,7 @@ public class ImapStore extends Store {
}
}
final String encodedQry = encodeString(queryString);
- if (mAccount.isRemoteSearchFullText()) {
+ if (mStoreConfig.isRemoteSearchFullText()) {
imapQuery += "TEXT " + encodedQry;
} else {
imapQuery += "OR SUBJECT " + encodedQry + " FROM " + encodedQry;
@@ -2424,7 +2422,7 @@ public class ImapStore extends Store {
}
}
- setReadTimeout(Store.SOCKET_READ_TIMEOUT);
+ setReadTimeout(SOCKET_READ_TIMEOUT);
mIn = new PeekableInputStream(new BufferedInputStream(mSocket.getInputStream(),
1024));
@@ -2458,7 +2456,7 @@ public class ImapStore extends Store {
mSocket = TrustedSocketFactory.createSocket(mSocket,
mSettings.getHost(), mSettings.getPort(),
mSettings.getClientCertificateAlias());
- mSocket.setSoTimeout(Store.SOCKET_READ_TIMEOUT);
+ mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
mIn = new PeekableInputStream(new BufferedInputStream(mSocket
.getInputStream(), 1024));
mParser = new ImapResponseParser(mIn);
@@ -2953,7 +2951,7 @@ public class ImapStore extends Store {
super(store, name);
receiver = nReceiver;
TracingPowerManager pm = TracingPowerManager.getPowerManager(receiver.getContext());
- wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ImapFolderPusher " + store.getAccount().getDescription() + ":" + getName());
+ wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ImapFolderPusher " + mStoreConfig.toString() + ":" + getName());
wakeLock.setReferenceCounted(false);
}
@@ -2968,7 +2966,7 @@ public class ImapStore extends Store {
if (doneSent.compareAndSet(false, true)) {
ImapConnection conn = mConnection;
if (conn != null) {
- conn.setReadTimeout(Store.SOCKET_READ_TIMEOUT);
+ conn.setReadTimeout(SOCKET_READ_TIMEOUT);
sendContinuation("DONE");
}
@@ -3030,7 +3028,7 @@ public class ImapStore extends Store {
throw new MessagingException("IMAP server is not IDLE capable:" + conn.toString());
}
- if (!stop.get() && mAccount.isPushPollOnConnect() && (conn != oldConnection || needsPoll.getAndSet(false))) {
+ if (!stop.get() && mStoreConfig.isPushPollOnConnect() && (conn != oldConnection || needsPoll.getAndSet(false))) {
List untaggedResponses = new ArrayList(storedUntaggedResponses);
storedUntaggedResponses.clear();
processUntaggedResponses(untaggedResponses);
@@ -3061,8 +3059,8 @@ public class ImapStore extends Store {
}
}
- if (startUid < newUidNext - mAccount.getDisplayCount()) {
- startUid = newUidNext - mAccount.getDisplayCount();
+ if (startUid < newUidNext - mStoreConfig.getDisplayCount()) {
+ startUid = newUidNext - mStoreConfig.getDisplayCount();
}
if (startUid < 1) {
startUid = 1;
@@ -3099,7 +3097,7 @@ public class ImapStore extends Store {
idling.set(true);
doneSent.set(false);
- conn.setReadTimeout((getAccount().getIdleRefreshMinutes() * 60 * 1000) + IDLE_READ_TIMEOUT_INCREMENT);
+ conn.setReadTimeout((mStoreConfig.getIdleRefreshMinutes() * 60 * 1000) + IDLE_READ_TIMEOUT_INCREMENT);
untaggedResponses = executeSimpleCommand(COMMAND_IDLE, false, ImapFolderPusher.this);
idling.set(false);
delayTime.set(NORMAL_DELAY_TIME);
@@ -3495,7 +3493,7 @@ public class ImapStore extends Store {
@Override
public int getRefreshInterval() {
- return (getAccount().getIdleRefreshMinutes() * 60 * 1000);
+ return (mStoreConfig.getIdleRefreshMinutes() * 60 * 1000);
}
@Override
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index 5e2ee632a..593191a14 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -3,7 +3,6 @@ package com.fsck.k9.mail.store;
import android.util.Log;
-import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.controller.MessageRetrievalListener;
@@ -24,7 +23,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
@@ -35,7 +33,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
-public class Pop3Store extends Store {
+public class Pop3Store extends RemoteStore {
public static final String STORE_TYPE = "POP3";
private static final String STLS_COMMAND = "STLS";
@@ -209,12 +207,12 @@ public class Pop3Store extends Store {
private boolean mTopNotSupported;
- public Pop3Store(Account account) throws MessagingException {
- super(account);
+ public Pop3Store(StoreConfig storeConfig) throws MessagingException {
+ super(storeConfig);
ServerSettings settings;
try {
- settings = decodeUri(mAccount.getStoreUri());
+ settings = decodeUri(storeConfig.getStoreUri());
} catch (IllegalArgumentException e) {
throw new MessagingException("Error while decoding store URI", e);
}
@@ -243,13 +241,13 @@ public class Pop3Store extends Store {
@Override
public List extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException {
List folders = new LinkedList();
- folders.add(getFolder(mAccount.getInboxFolderName()));
+ folders.add(getFolder(mStoreConfig.getInboxFolderName()));
return folders;
}
@Override
public void checkSettings() throws MessagingException {
- Pop3Folder folder = new Pop3Folder(mAccount.getInboxFolderName());
+ Pop3Folder folder = new Pop3Folder(mStoreConfig.getInboxFolderName());
folder.open(Folder.OPEN_MODE_RW);
if (!mCapabilities.uidl) {
/*
@@ -272,7 +270,7 @@ public class Pop3Store extends Store {
return false;
}
- class Pop3Folder extends Folder {
+ class Pop3Folder extends Folder {
private Socket mSocket;
private InputStream mIn;
private OutputStream mOut;
@@ -283,11 +281,11 @@ public class Pop3Store extends Store {
private int mMessageCount;
public Pop3Folder(String name) {
- super(Pop3Store.this.mAccount);
+ super();
this.mName = name;
- if (mName.equalsIgnoreCase(mAccount.getInboxFolderName())) {
- mName = mAccount.getInboxFolderName();
+ if (mName.equalsIgnoreCase(mStoreConfig.getInboxFolderName())) {
+ mName = mStoreConfig.getInboxFolderName();
}
}
@@ -297,7 +295,7 @@ public class Pop3Store extends Store {
return;
}
- if (!mName.equalsIgnoreCase(mAccount.getInboxFolderName())) {
+ if (!mName.equalsIgnoreCase(mStoreConfig.getInboxFolderName())) {
throw new MessagingException("Folder does not exist");
}
@@ -313,7 +311,7 @@ public class Pop3Store extends Store {
mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
- mSocket.setSoTimeout(Store.SOCKET_READ_TIMEOUT);
+ mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
if (!isOpen()) {
throw new MessagingException("Unable to connect socket");
}
@@ -328,7 +326,7 @@ public class Pop3Store extends Store {
mSocket = TrustedSocketFactory.createSocket(mSocket, mHost, mPort,
mClientCertificateAlias);
- mSocket.setSoTimeout(Store.SOCKET_READ_TIMEOUT);
+ mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
if (!isOpen()) {
@@ -541,7 +539,7 @@ public class Pop3Store extends Store {
@Override
public boolean exists() throws MessagingException {
- return mName.equalsIgnoreCase(mAccount.getInboxFolderName());
+ return mName.equalsIgnoreCase(mStoreConfig.getInboxFolderName());
}
@Override
@@ -559,7 +557,7 @@ public class Pop3Store extends Store {
}
@Override
- public Message getMessage(String uid) throws MessagingException {
+ public Pop3Message getMessage(String uid) throws MessagingException {
Pop3Message message = mUidToMsgMap.get(uid);
if (message == null) {
message = new Pop3Message(uid, this);
@@ -761,7 +759,7 @@ public class Pop3Store extends Store {
* @throws MessagingException
*/
@Override
- public void fetch(List extends Message> messages, FetchProfile fp, MessageRetrievalListener listener)
+ public void fetch(List extends Message> messages, FetchProfile fp, MessageRetrievalListener listener)
throws MessagingException {
if (messages == null || messages.isEmpty()) {
return;
@@ -805,9 +803,9 @@ public class Pop3Store extends Store {
* To convert the suggested download size we take the size
* divided by the maximum line size (76).
*/
- if (mAccount.getMaximumAutoDownloadMessageSize() > 0) {
+ if (mStoreConfig.getMaximumAutoDownloadMessageSize() > 0) {
fetchBody(pop3Message,
- (mAccount.getMaximumAutoDownloadMessageSize() / 76));
+ (mStoreConfig.getMaximumAutoDownloadMessageSize() / 76));
} else {
fetchBody(pop3Message, -1);
}
@@ -819,7 +817,7 @@ public class Pop3Store extends Store {
pop3Message.setBody(null);
}
if (listener != null && !(fp.contains(FetchProfile.Item.ENVELOPE) && fp.size() == 1)) {
- listener.messageFinished(message, i, count);
+ listener.messageFinished(pop3Message, i, count);
}
} catch (IOException ioe) {
throw new MessagingException("Unable to fetch message", ioe);
diff --git a/src/com/fsck/k9/mail/store/RemoteStore.java b/src/com/fsck/k9/mail/store/RemoteStore.java
new file mode 100644
index 000000000..9cad2aac2
--- /dev/null
+++ b/src/com/fsck/k9/mail/store/RemoteStore.java
@@ -0,0 +1,122 @@
+package com.fsck.k9.mail.store;
+
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.ServerSettings;
+import com.fsck.k9.mail.Store;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class RemoteStore extends Store {
+ protected static final int SOCKET_CONNECT_TIMEOUT = 30000;
+ protected static final int SOCKET_READ_TIMEOUT = 60000;
+
+ protected StoreConfig mStoreConfig;
+
+ /**
+ * Remote stores indexed by Uri.
+ */
+ private static Map sStores = new HashMap();
+
+
+ public RemoteStore(StoreConfig storeConfig) {
+ mStoreConfig = storeConfig;
+ }
+
+ /**
+ * Get an instance of a remote mail store.
+ */
+ public synchronized static Store getInstance(StoreConfig storeConfig) throws MessagingException {
+ String uri = storeConfig.getStoreUri();
+
+ if (uri.startsWith("local")) {
+ throw new RuntimeException("Asked to get non-local Store object but given LocalStore URI");
+ }
+
+ Store store = sStores.get(uri);
+ if (store == null) {
+ if (uri.startsWith("imap")) {
+ store = new ImapStore(storeConfig);
+ } else if (uri.startsWith("pop3")) {
+ store = new Pop3Store(storeConfig);
+ } else if (uri.startsWith("webdav")) {
+ store = new WebDavStore(storeConfig);
+ }
+
+ if (store != null) {
+ sStores.put(uri, store);
+ }
+ }
+
+ if (store == null) {
+ throw new MessagingException("Unable to locate an applicable Store for " + uri);
+ }
+
+ return store;
+ }
+
+ /**
+ * Release reference to a remote mail store instance.
+ *
+ * @param storeConfig {@link com.fsck.k9.mail.store.StoreConfig} instance that is used to get the remote mail store instance.
+ */
+ public static void removeInstance(StoreConfig storeConfig) {
+ String uri = storeConfig.getStoreUri();
+
+ if (uri.startsWith("local")) {
+ throw new RuntimeException("Asked to get non-local Store object but given " +
+ "LocalStore URI");
+ }
+
+ sStores.remove(uri);
+ }
+
+ /**
+ * Decodes the contents of store-specific URIs and puts them into a {@link com.fsck.k9.mail.ServerSettings}
+ * object.
+ *
+ * @param uri
+ * the store-specific URI to decode
+ *
+ * @return A {@link com.fsck.k9.mail.ServerSettings} object holding the settings contained in the URI.
+ *
+ * @see com.fsck.k9.mail.store.ImapStore#decodeUri(String)
+ * @see com.fsck.k9.mail.store.Pop3Store#decodeUri(String)
+ * @see com.fsck.k9.mail.store.WebDavStore#decodeUri(String)
+ */
+ public static ServerSettings decodeStoreUri(String uri) {
+ if (uri.startsWith("imap")) {
+ return ImapStore.decodeUri(uri);
+ } else if (uri.startsWith("pop3")) {
+ return Pop3Store.decodeUri(uri);
+ } else if (uri.startsWith("webdav")) {
+ return WebDavStore.decodeUri(uri);
+ } else {
+ throw new IllegalArgumentException("Not a valid store URI");
+ }
+ }
+
+ /**
+ * Creates a store URI from the information supplied in the {@link com.fsck.k9.mail.ServerSettings} object.
+ *
+ * @param server
+ * The {@link com.fsck.k9.mail.ServerSettings} object that holds the server settings.
+ *
+ * @return A store URI that holds the same information as the {@code server} parameter.
+ *
+ * @see com.fsck.k9.mail.store.ImapStore#createUri(com.fsck.k9.mail.ServerSettings)
+ * @see com.fsck.k9.mail.store.Pop3Store#createUri(com.fsck.k9.mail.ServerSettings)
+ * @see com.fsck.k9.mail.store.WebDavStore#createUri(com.fsck.k9.mail.ServerSettings)
+ */
+ public static String createStoreUri(ServerSettings server) {
+ if (ImapStore.STORE_TYPE.equals(server.type)) {
+ return ImapStore.createUri(server);
+ } else if (Pop3Store.STORE_TYPE.equals(server.type)) {
+ return Pop3Store.createUri(server);
+ } else if (WebDavStore.STORE_TYPE.equals(server.type)) {
+ return WebDavStore.createUri(server);
+ } else {
+ throw new IllegalArgumentException("Not a valid store URI");
+ }
+ }
+}
diff --git a/src/com/fsck/k9/mail/store/StoreConfig.java b/src/com/fsck/k9/mail/store/StoreConfig.java
new file mode 100644
index 000000000..ba83ba201
--- /dev/null
+++ b/src/com/fsck/k9/mail/store/StoreConfig.java
@@ -0,0 +1,32 @@
+package com.fsck.k9.mail.store;
+
+public interface StoreConfig {
+ String getUuid();
+ String getStoreUri();
+ String getTransportUri();
+
+ boolean subscribedFoldersOnly();
+ boolean useCompression(int type);
+
+ String getInboxFolderName();
+ String getOutboxFolderName();
+ String getDraftsFolderName();
+
+ void setInboxFolderName(String folderName);
+ void setDraftsFolderName(String decodedFolderName);
+ void setTrashFolderName(String decodedFolderName);
+ void setSpamFolderName(String decodedFolderName);
+ void setSentFolderName(String decodedFolderName);
+ void setAutoExpandFolderName(String folderName);
+
+ int getMaximumAutoDownloadMessageSize();
+
+ boolean allowRemoteSearch();
+ boolean isRemoteSearchFullText();
+
+ boolean isPushPollOnConnect();
+
+ int getDisplayCount();
+
+ int getIdleRefreshMinutes();
+}
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index 27d0c7ccb..61dba1088 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -2,7 +2,6 @@ package com.fsck.k9.mail.store;
import android.util.Log;
-import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.controller.MessageRetrievalListener;
@@ -55,7 +54,7 @@ import java.util.zip.GZIPInputStream;
* and email information.
*
*/
-public class WebDavStore extends Store {
+public class WebDavStore extends RemoteStore {
public static final String STORE_TYPE = "WebDAV";
// Authentication types
@@ -294,12 +293,12 @@ public class WebDavStore extends Store {
private Map mFolderList = new HashMap();
- public WebDavStore(Account account) throws MessagingException {
- super(account);
+ public WebDavStore(StoreConfig storeConfig) throws MessagingException {
+ super(storeConfig);
WebDavStoreSettings settings;
try {
- settings = decodeUri(mAccount.getStoreUri());
+ settings = decodeUri(storeConfig.getStoreUri());
} catch (IllegalArgumentException e) {
throw new MessagingException("Error while decoding store URI", e);
}
@@ -380,21 +379,21 @@ public class WebDavStore extends Store {
Map specialFoldersMap = dataset.getSpecialFolderToUrl();
String folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_INBOX_FOLDER));
if (folderName != null) {
- mAccount.setAutoExpandFolderName(folderName);
- mAccount.setInboxFolderName(folderName);
+ mStoreConfig.setAutoExpandFolderName(folderName);
+ mStoreConfig.setInboxFolderName(folderName);
}
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_DRAFTS_FOLDER));
if (folderName != null)
- mAccount.setDraftsFolderName(folderName);
+ mStoreConfig.setDraftsFolderName(folderName);
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_TRASH_FOLDER));
if (folderName != null)
- mAccount.setTrashFolderName(folderName);
+ mStoreConfig.setTrashFolderName(folderName);
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SPAM_FOLDER));
if (folderName != null)
- mAccount.setSpamFolderName(folderName);
+ mStoreConfig.setSpamFolderName(folderName);
// K-9 Mail's outbox is a special local folder and different from Exchange/WebDAV's outbox.
/*
@@ -405,7 +404,7 @@ public class WebDavStore extends Store {
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SENT_FOLDER));
if (folderName != null)
- mAccount.setSentFolderName(folderName);
+ mStoreConfig.setSentFolderName(folderName);
/**
* Next we get all the folders (including "special" ones)
@@ -1196,7 +1195,7 @@ public class WebDavStore extends Store {
@Override
public void sendMessages(List extends Message> messages) throws MessagingException {
- WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(mAccount.getDraftsFolderName());
+ WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(mStoreConfig.getDraftsFolderName());
try {
tmpFolder.open(Folder.OPEN_MODE_RW);
List extends Message> retMessages = tmpFolder.appendWebDavMessages(messages);
@@ -1216,7 +1215,7 @@ public class WebDavStore extends Store {
/**
* A WebDav Folder
*/
- class WebDavFolder extends Folder {
+ class WebDavFolder extends Folder {
private String mName;
private String mFolderUrl;
private boolean mIsOpen = false;
@@ -1229,7 +1228,7 @@ public class WebDavStore extends Store {
}
public WebDavFolder(WebDavStore nStore, String name) {
- super(nStore.getAccount());
+ super();
store = nStore;
this.mName = name;
@@ -1397,7 +1396,7 @@ public class WebDavStore extends Store {
}
@Override
- public Message getMessage(String uid) throws MessagingException {
+ public WebDavMessage getMessage(String uid) throws MessagingException {
return new WebDavMessage(uid, this);
}
@@ -1498,7 +1497,7 @@ public class WebDavStore extends Store {
}
@Override
- public void fetch(List extends Message> messages, FetchProfile fp, MessageRetrievalListener listener)
+ public void fetch(List extends Message> messages, FetchProfile fp, MessageRetrievalListener listener)
throws MessagingException {
if (messages == null ||
messages.isEmpty()) {
@@ -1519,8 +1518,8 @@ public class WebDavStore extends Store {
}
if (fp.contains(FetchProfile.Item.BODY_SANE)) {
- if (mAccount.getMaximumAutoDownloadMessageSize() > 0) {
- fetchMessages(messages, listener, (mAccount.getMaximumAutoDownloadMessageSize() / 76));
+ if (mStoreConfig.getMaximumAutoDownloadMessageSize() > 0) {
+ fetchMessages(messages, listener, (mStoreConfig.getMaximumAutoDownloadMessageSize() / 76));
} else {
fetchMessages(messages, listener, -1);
}
@@ -1533,7 +1532,7 @@ public class WebDavStore extends Store {
/**
* Fetches the full messages or up to lines lines and passes them to the message parser.
*/
- private void fetchMessages(List extends Message> messages, MessageRetrievalListener listener, int lines)
+ private void fetchMessages(List extends Message> messages, MessageRetrievalListener listener, int lines)
throws MessagingException {
WebDavHttpClient httpclient;
httpclient = getHttpClient();
@@ -1594,8 +1593,8 @@ public class WebDavStore extends Store {
if (entity != null) {
InputStream istream = null;
StringBuilder buffer = new StringBuilder();
- String tempText = "";
- String resultText = "";
+ String tempText;
+ String resultText;
BufferedReader reader = null;
int currentLines = 0;
diff --git a/src/com/fsck/k9/mail/store/local/LocalFolder.java b/src/com/fsck/k9/mail/store/local/LocalFolder.java
index 56e2558e4..22c3674ee 100644
--- a/src/com/fsck/k9/mail/store/local/LocalFolder.java
+++ b/src/com/fsck/k9/mail/store/local/LocalFolder.java
@@ -28,6 +28,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
+import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Account.MessageFormat;
import com.fsck.k9.activity.Search;
@@ -58,7 +59,7 @@ import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
import com.fsck.k9.provider.AttachmentProvider;
-public class LocalFolder extends Folder implements Serializable {
+public class LocalFolder extends Folder implements Serializable {
private static final long serialVersionUID = -1973296520918624767L;
@@ -80,22 +81,19 @@ public class LocalFolder extends Folder implements Serializable {
private Integer mLastUid = null;
public LocalFolder(LocalStore localStore, String name) {
- super(localStore.getAccount());
+ super();
this.localStore = localStore;
this.mName = name;
- if (this.localStore.getAccount().getInboxFolderName().equals(getName())) {
-
+ if (getAccount().getInboxFolderName().equals(getName())) {
mSyncClass = FolderClass.FIRST_CLASS;
mPushClass = FolderClass.FIRST_CLASS;
mInTopGroup = true;
}
-
-
}
public LocalFolder(LocalStore localStore, long id) {
- super(localStore.getAccount());
+ super();
this.localStore = localStore;
this.mFolderId = id;
}
@@ -104,6 +102,25 @@ public class LocalFolder extends Folder implements Serializable {
return mFolderId;
}
+ public String getUuid()
+ {
+ return getAccount().getUuid();
+ }
+
+ public boolean getSignatureUse() {
+ return getAccount().getSignatureUse();
+ }
+
+ public void setLastSelectedFolderName(String destFolderName) {
+ getAccount().setLastSelectedFolderName(destFolderName);
+ }
+
+ public boolean syncRemoteDeletions() {
+ return getAccount().syncRemoteDeletions();
+ }
+
+
+
@Override
public void open(final int mode) throws MessagingException {
@@ -216,7 +233,7 @@ public class LocalFolder extends Folder implements Serializable {
@Override
public boolean create(FolderType type) throws MessagingException {
- return create(type, mAccount.getDisplayCount());
+ return create(type, getAccount().getDisplayCount());
}
@Override
@@ -517,25 +534,25 @@ public class LocalFolder extends Folder implements Serializable {
String id = getPrefId();
// there can be a lot of folders. For the defaults, let's not save prefs, saving space, except for INBOX
- if (mDisplayClass == FolderClass.NO_CLASS && !mAccount.getInboxFolderName().equals(getName())) {
+ if (mDisplayClass == FolderClass.NO_CLASS && !getAccount().getInboxFolderName().equals(getName())) {
editor.remove(id + ".displayMode");
} else {
editor.putString(id + ".displayMode", mDisplayClass.name());
}
- if (mSyncClass == FolderClass.INHERITED && !mAccount.getInboxFolderName().equals(getName())) {
+ if (mSyncClass == FolderClass.INHERITED && !getAccount().getInboxFolderName().equals(getName())) {
editor.remove(id + ".syncMode");
} else {
editor.putString(id + ".syncMode", mSyncClass.name());
}
- if (mNotifyClass == FolderClass.INHERITED && !mAccount.getInboxFolderName().equals(getName())) {
+ if (mNotifyClass == FolderClass.INHERITED && !getAccount().getInboxFolderName().equals(getName())) {
editor.remove(id + ".notifyMode");
} else {
editor.putString(id + ".notifyMode", mNotifyClass.name());
}
- if (mPushClass == FolderClass.SECOND_CLASS && !mAccount.getInboxFolderName().equals(getName())) {
+ if (mPushClass == FolderClass.SECOND_CLASS && !getAccount().getInboxFolderName().equals(getName())) {
editor.remove(id + ".pushMode");
} else {
editor.putString(id + ".pushMode", mPushClass.name());
@@ -597,7 +614,7 @@ public class LocalFolder extends Folder implements Serializable {
}
@Override
- public void fetch(final List extends Message> messages, final FetchProfile fp, final MessageRetrievalListener listener)
+ public void fetch(final List extends Message> messages, final FetchProfile fp, final MessageRetrievalListener listener)
throws MessagingException {
try {
this.localStore.database.execute(false, new DbCallback() {
@@ -614,7 +631,7 @@ public class LocalFolder extends Folder implements Serializable {
try {
cursor = db.rawQuery("SELECT html_content, text_content, mime_type FROM messages "
+ "WHERE id = ?",
- new String[] { Long.toString(localMessage.mId) });
+ new String[] { Long.toString(localMessage.getId()) });
cursor.moveToNext();
String htmlContent = cursor.getString(0);
String textContent = cursor.getString(1);
@@ -629,7 +646,7 @@ public class LocalFolder extends Folder implements Serializable {
mp.addBodyPart(bp);
}
- if (mAccount.getMessageFormat() != MessageFormat.TEXT) {
+ if (getAccount().getMessageFormat() != MessageFormat.TEXT) {
if (htmlContent != null) {
TextBody body = new TextBody(htmlContent);
MimeBodyPart bp = new MimeBodyPart(body, "text/html");
@@ -700,7 +717,7 @@ public class LocalFolder extends Folder implements Serializable {
"content_disposition"
},
"message_id = ?",
- new String[] { Long.toString(localMessage.mId) },
+ new String[] { Long.toString(localMessage.getId()) },
null,
null,
null);
@@ -1439,12 +1456,12 @@ public class LocalFolder extends Folder implements Serializable {
message.isSet(Flag.FLAGGED) ? 1 : 0,
message.isSet(Flag.ANSWERED) ? 1 : 0,
message.isSet(Flag.FORWARDED) ? 1 : 0,
- message.mId
+ message.getId()
});
for (int i = 0, count = attachments.size(); i < count; i++) {
Part attachment = attachments.get(i);
- saveAttachment(message.mId, attachment, false);
+ saveAttachment(message.getId(), attachment, false);
}
saveHeaders(message.getId(), message);
} catch (Exception e) {
@@ -1637,7 +1654,7 @@ public class LocalFolder extends Folder implements Serializable {
File attachmentFile = new File(attachmentDirectory, Long.toString(attachmentId));
tempAttachmentFile.renameTo(attachmentFile);
contentUri = AttachmentProvider.getAttachmentUri(
- mAccount,
+ getAccount(),
attachmentId);
if (MimeUtil.isMessage(attachment.getMimeType())) {
attachment.setBody(new LocalAttachmentMessageBody(
@@ -1712,7 +1729,7 @@ public class LocalFolder extends Folder implements Serializable {
@Override
public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
db.update("messages", cv, "id = ?", new String[]
- { Long.toString(message.mId) });
+ { Long.toString(message.getId()) });
return null;
}
});
@@ -1829,7 +1846,7 @@ public class LocalFolder extends Folder implements Serializable {
setPushState(null);
setLastPush(0);
setLastChecked(0);
- setVisibleLimit(mAccount.getDisplayCount());
+ setVisibleLimit(getAccount().getDisplayCount());
}
@Override
@@ -1878,7 +1895,7 @@ public class LocalFolder extends Folder implements Serializable {
public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
Cursor attachmentsCursor = null;
try {
- String accountUuid = mAccount.getUuid();
+ String accountUuid = getUuid();
Context context = LocalFolder.this.localStore.mApplication;
// Get attachment IDs
@@ -2039,7 +2056,7 @@ public class LocalFolder extends Folder implements Serializable {
// Append the first message ID from the "In-Reply-To" header line
String[] inReplyToArray = message.getHeader("In-Reply-To");
- String inReplyTo = null;
+ String inReplyTo;
if (inReplyToArray != null && inReplyToArray.length > 0) {
inReplyTo = Utility.extractMessageId(inReplyToArray[0]);
if (inReplyTo != null) {
@@ -2194,4 +2211,8 @@ public class LocalFolder extends Folder implements Serializable {
throw(MessagingException) e.getCause();
}
}
+
+ private Account getAccount() {
+ return localStore.getAccount();
+ }
}
diff --git a/src/com/fsck/k9/mail/store/local/LocalMessage.java b/src/com/fsck/k9/mail/store/local/LocalMessage.java
index 56e20ea8d..6dd164f14 100644
--- a/src/com/fsck/k9/mail/store/local/LocalMessage.java
+++ b/src/com/fsck/k9/mail/store/local/LocalMessage.java
@@ -12,7 +12,9 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
+import com.fsck.k9.Account;
import com.fsck.k9.K9;
+import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
@@ -28,7 +30,7 @@ public class LocalMessage extends MimeMessage {
private final LocalStore localStore;
- long mId;
+ private long mId;
private int mAttachmentCount;
private String mSubject;
@@ -557,4 +559,43 @@ public class LocalMessage extends MimeMessage {
public long getRootId() {
return mRootId;
}
+
+ public Account getAccount() {
+ return localStore.getAccount();
+ }
+
+ @Override
+ public MessageReference makeMessageReference() {
+ if (mReference == null) {
+ mReference = super.makeMessageReference();
+ mReference.accountUuid = getFolder().getUuid();
+ }
+ return mReference;
+ }
+
+ @Override
+ public LocalFolder getFolder() {
+ return (LocalFolder) super.getFolder();
+ }
+
+ public String getUri() {
+ return "email://messages/" + getAccount().getAccountNumber() + "/" + getFolder().getName() + "/" + getUid();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ if (!super.equals(o)) return false;
+
+ LocalMessage that = (LocalMessage) o;
+ return !(getUid() != null ? !getUid().equals(that.getUid()) : that.getUid() != null);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (getUid() != null ? getUid().hashCode() : 0);
+ return result;
+ }
}
\ No newline at end of file
diff --git a/src/com/fsck/k9/mail/store/local/LocalStore.java b/src/com/fsck/k9/mail/store/local/LocalStore.java
index 02002c125..f4c82743a 100644
--- a/src/com/fsck/k9/mail/store/local/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/local/LocalStore.java
@@ -10,6 +10,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import android.app.Application;
import android.content.ContentResolver;
@@ -32,6 +34,8 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Store;
+import com.fsck.k9.mail.store.RemoteStore;
+import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
import com.fsck.k9.mail.store.StorageManager;
@@ -56,6 +60,18 @@ public class LocalStore extends Store implements Serializable {
static final String[] EMPTY_STRING_ARRAY = new String[0];
static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+ /**
+ * Lock objects indexed by account UUID.
+ *
+ * @see #getInstance(Account, Application)
+ */
+ private static ConcurrentMap sAccountLocks = new ConcurrentHashMap();
+
+ /**
+ * Local stores indexed by UUID because the Uri may change due to migration to/from SD-card.
+ */
+ private static ConcurrentMap sLocalStores = new ConcurrentHashMap();
+
/*
* a String containing the columns getMessages expects to work with
* in the correct order.
@@ -138,6 +154,7 @@ public class LocalStore extends Store implements Serializable {
LockableDatabase database;
private ContentResolver mContentResolver;
+ private final Account mAccount;
/**
* local://localhost/path/to/database/uuid.db
@@ -147,7 +164,7 @@ public class LocalStore extends Store implements Serializable {
* @throws UnavailableStorageException if not {@link StorageProvider#isReady(Context)}
*/
public LocalStore(final Account account, final Application application) throws MessagingException {
- super(account);
+ mAccount = account;
database = new LockableDatabase(application, account.getUuid(), new StoreSchemaDefinition(this));
mApplication = application;
@@ -158,10 +175,73 @@ public class LocalStore extends Store implements Serializable {
database.open();
}
+ /**
+ * Get an instance of a local mail store.
+ *
+ * @throws UnavailableStorageException
+ * if not {@link StorageProvider#isReady(Context)}
+ */
+ public static LocalStore getInstance(Account account, Application application)
+ throws MessagingException {
+
+ String accountUuid = account.getUuid();
+
+ // Create new per-account lock object if necessary
+ sAccountLocks.putIfAbsent(accountUuid, new Object());
+
+ // Get the account's lock object
+ Object lock = sAccountLocks.get(accountUuid);
+
+ // Use per-account locks so DatabaseUpgradeService always knows which account database is
+ // currently upgraded.
+ synchronized (lock) {
+ Store store = sLocalStores.get(accountUuid);
+
+ if (store == null) {
+ // Creating a LocalStore instance will create or upgrade the database if
+ // necessary. This could take some time.
+ store = new LocalStore(account, application);
+
+ sLocalStores.put(accountUuid, store);
+ }
+
+ return (LocalStore) store;
+ }
+ }
+
+ public static void removeAccount(StoreConfig storeConfig) {
+ try {
+ RemoteStore.removeInstance(storeConfig);
+ } catch (Exception e) {
+ Log.e(K9.LOG_TAG, "Failed to reset remote store for account " + storeConfig.getUuid(), e);
+ }
+
+ try {
+ removeInstance(storeConfig);
+ } catch (Exception e) {
+ Log.e(K9.LOG_TAG, "Failed to reset local store for account " + storeConfig.getUuid(), e);
+ }
+ }
+
+ /**
+ * Release reference to a local mail store instance.
+ *
+ * @param account
+ * {@link Account} instance that is used to get the local mail store instance.
+ */
+ private static void removeInstance(StoreConfig account) {
+ String accountUuid = account.getUuid();
+ sLocalStores.remove(accountUuid);
+ }
+
public void switchLocalStorage(final String newStorageProviderId) throws MessagingException {
database.switchProvider(newStorageProviderId);
}
+ protected Account getAccount() {
+ return mAccount;
+ }
+
protected SharedPreferences getPreferences() {
return Preferences.getPreferences(mApplication).getPreferences();
}
diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java
index 428c0dce2..a5365a33a 100644
--- a/src/com/fsck/k9/mail/transport/SmtpTransport.java
+++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java
@@ -15,6 +15,7 @@ import com.fsck.k9.mail.filter.LineWrapOutputStream;
import com.fsck.k9.mail.filter.PeekableInputStream;
import com.fsck.k9.mail.filter.SmtpDataStuffing;
import com.fsck.k9.mail.internet.MimeUtility;
+import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.local.LocalMessage;
import com.fsck.k9.net.ssl.TrustedSocketFactory;
@@ -183,7 +184,7 @@ public class SmtpTransport extends Transport {
private boolean m8bitEncodingAllowed;
private int mLargestAcceptableMessage;
- public SmtpTransport(Account account) throws MessagingException {
+ public SmtpTransport(StoreConfig account) throws MessagingException {
ServerSettings settings;
try {
settings = decodeUri(account.getTransportUri());
diff --git a/src/com/fsck/k9/mail/transport/WebDavTransport.java b/src/com/fsck/k9/mail/transport/WebDavTransport.java
index 1c94d01d5..40b8b6884 100644
--- a/src/com/fsck/k9/mail/transport/WebDavTransport.java
+++ b/src/com/fsck/k9/mail/transport/WebDavTransport.java
@@ -3,12 +3,12 @@ package com.fsck.k9.mail.transport;
import android.util.Log;
-import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.Transport;
+import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.WebDavStore;
import java.util.Collections;
@@ -43,12 +43,8 @@ public class WebDavTransport extends Transport {
private WebDavStore store;
- public WebDavTransport(Account account) throws MessagingException {
- if (account.getRemoteStore() instanceof WebDavStore) {
- store = (WebDavStore) account.getRemoteStore();
- } else {
- store = new WebDavStore(account);
- }
+ public WebDavTransport(StoreConfig configInterface) throws MessagingException {
+ store = new WebDavStore(configInterface);
if (K9.DEBUG)
Log.d(K9.LOG_TAG, ">>> New WebDavTransport creation complete");
diff --git a/src/com/fsck/k9/preferences/SettingsExporter.java b/src/com/fsck/k9/preferences/SettingsExporter.java
index 6085f3014..f49ec7a20 100644
--- a/src/com/fsck/k9/preferences/SettingsExporter.java
+++ b/src/com/fsck/k9/preferences/SettingsExporter.java
@@ -25,9 +25,9 @@ import android.util.Xml;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
-import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.Transport;
+import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.preferences.Settings.InvalidSettingValueException;
import com.fsck.k9.preferences.Settings.SettingsDescription;
@@ -223,7 +223,7 @@ public class SettingsExporter {
// Write incoming server settings
- ServerSettings incoming = Store.decodeStoreUri(account.getStoreUri());
+ ServerSettings incoming = RemoteStore.decodeStoreUri(account.getStoreUri());
serializer.startTag(null, INCOMING_SERVER_ELEMENT);
serializer.attribute(null, TYPE_ATTRIBUTE, incoming.type);
diff --git a/src/com/fsck/k9/preferences/SettingsImporter.java b/src/com/fsck/k9/preferences/SettingsImporter.java
index b3143f724..1a7af8d26 100644
--- a/src/com/fsck/k9/preferences/SettingsImporter.java
+++ b/src/com/fsck/k9/preferences/SettingsImporter.java
@@ -26,8 +26,8 @@ import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.ServerSettings;
-import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.Transport;
+import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mail.store.WebDavStore;
import com.fsck.k9.preferences.Settings.InvalidSettingValueException;
@@ -376,7 +376,7 @@ public class SettingsImporter {
// Write incoming server settings (storeUri)
ServerSettings incoming = new ImportedServerSettings(account.incoming);
- String storeUri = Store.createStoreUri(incoming);
+ String storeUri = RemoteStore.createStoreUri(incoming);
putString(editor, accountKeyPrefix + Account.STORE_URI_KEY, Utility.base64Encode(storeUri));
// Mark account as disabled if the AuthType isn't EXTERNAL and the
diff --git a/src/com/fsck/k9/provider/AttachmentProvider.java b/src/com/fsck/k9/provider/AttachmentProvider.java
index 6f5bf32ac..bfcdaac9b 100644
--- a/src/com/fsck/k9/provider/AttachmentProvider.java
+++ b/src/com/fsck/k9/provider/AttachmentProvider.java
@@ -215,7 +215,7 @@ public class AttachmentProvider extends ContentProvider {
final AttachmentInfo attachmentInfo;
try {
final Account account = Preferences.getPreferences(getContext()).getAccount(dbName);
- attachmentInfo = LocalStore.getLocalInstance(account, K9.app).getAttachmentInfo(id);
+ attachmentInfo = LocalStore.getInstance(account, K9.app).getAttachmentInfo(id);
} catch (MessagingException e) {
Log.e(K9.LOG_TAG, "Unable to retrieve attachment info from local store for ID: " + id, e);
return null;
@@ -269,7 +269,7 @@ public class AttachmentProvider extends ContentProvider {
final Account account = Preferences.getPreferences(getContext()).getAccount(dbName);
try {
- final LocalStore localStore = LocalStore.getLocalInstance(account, K9.app);
+ final LocalStore localStore = LocalStore.getInstance(account, K9.app);
AttachmentInfo attachmentInfo = localStore.getAttachmentInfo(id);
if (FORMAT_VIEW.equals(format) && mimeType != null) {
diff --git a/src/com/fsck/k9/provider/MessageProvider.java b/src/com/fsck/k9/provider/MessageProvider.java
index 6ce34baf3..c75f017df 100644
--- a/src/com/fsck/k9/provider/MessageProvider.java
+++ b/src/com/fsck/k9/provider/MessageProvider.java
@@ -32,6 +32,7 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.store.local.LocalFolder;
import com.fsck.k9.mail.store.local.LocalMessage;
import com.fsck.k9.mail.store.local.LocalStore;
import com.fsck.k9.search.SearchAccount;
@@ -200,9 +201,9 @@ public class MessageProvider extends ContentProvider {
public static class DeleteUriExtractor implements FieldExtractor {
@Override
public String getField(final MessageInfoHolder source) {
- final Message message = source.message;
+ final LocalMessage message = source.message;
return CONTENT_URI + "/delete_message/"
- + message.getFolder().getAccount().getAccountNumber() + "/"
+ + message.getAccount().getAccountNumber() + "/"
+ message.getFolder().getName() + "/" + message.getUid();
}
}
@@ -221,21 +222,21 @@ public class MessageProvider extends ContentProvider {
public static class AccountExtractor implements FieldExtractor {
@Override
public String getField(final MessageInfoHolder source) {
- return source.message.getFolder().getAccount().getDescription();
+ return source.message.getAccount().getDescription();
}
}
public static class AccountColorExtractor implements FieldExtractor {
@Override
public Integer getField(final MessageInfoHolder source) {
- return source.message.getFolder().getAccount().getChipColor();
+ return source.message.getAccount().getChipColor();
}
}
public static class AccountNumberExtractor implements FieldExtractor {
@Override
public Integer getField(final MessageInfoHolder source) {
- return source.message.getFolder().getAccount().getAccountNumber();
+ return source.message.getAccount().getAccountNumber();
}
}
@@ -910,18 +911,18 @@ public class MessageProvider extends ContentProvider {
@Override
public void listLocalMessagesAddMessages(final Account account,
- final String folderName, final List messages) {
+ final String folderName, final List messages) {
// cache fields into local variables for faster access on JVM without JIT
final MessageHelper helper = mMessageHelper;
final List holders = mHolders;
final Context context = getContext();
- for (final Message message : messages) {
+ for (final LocalMessage message : messages) {
final MessageInfoHolder messageInfoHolder = new MessageInfoHolder();
final Folder messageFolder = message.getFolder();
- final Account messageAccount = messageFolder.getAccount();
+ final Account messageAccount = messageInfoHolder.message.getAccount();
helper.populate(messageInfoHolder, message, new FolderInfoHolder(context,
messageFolder, messageAccount), messageAccount);
@@ -1038,9 +1039,9 @@ public class MessageProvider extends ContentProvider {
}
// get localstore parameter
- Message msg = null;
+ LocalMessage msg = null;
try {
- Folder lf = LocalStore.getLocalInstance(myAccount, K9.app).getFolder(folderName);
+ LocalFolder lf = LocalStore.getInstance(myAccount, K9.app).getFolder(folderName);
int msgCount = lf.getMessageCount();
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "folder msg count = " + msgCount);
diff --git a/src/com/fsck/k9/service/NotificationActionService.java b/src/com/fsck/k9/service/NotificationActionService.java
index 107bd0f4c..2baef7560 100644
--- a/src/com/fsck/k9/service/NotificationActionService.java
+++ b/src/com/fsck/k9/service/NotificationActionService.java
@@ -10,9 +10,9 @@ import com.fsck.k9.Preferences;
import com.fsck.k9.activity.MessageCompose;
import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.controller.MessagingController;
-import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.store.local.LocalMessage;
import android.app.PendingIntent;
import android.content.Context;
@@ -89,10 +89,10 @@ public class NotificationActionService extends CoreService {
List refs =
intent.getParcelableArrayListExtra(EXTRA_MESSAGE_LIST);
- List messages = new ArrayList();
+ List messages = new ArrayList();
for (MessageReference ref : refs) {
- Message m = ref.restoreToLocalMessage(this);
+ LocalMessage m = ref.restoreToLocalMessage(this);
if (m != null) {
messages.add(m);
}
@@ -106,7 +106,7 @@ public class NotificationActionService extends CoreService {
MessageReference ref = (MessageReference) intent.getParcelableExtra(EXTRA_MESSAGE);
Message message = ref.restoreToLocalMessage(this);
if (message != null) {
- Intent i = MessageCompose.getActionReplyIntent(this, account, message, false, null);
+ Intent i = MessageCompose.getActionReplyIntent(this, message, false, null);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
} else {
diff --git a/tests/src/com/fsck/k9/mail/store/ImapStoreUriTest.java b/tests/src/com/fsck/k9/mail/store/ImapStoreUriTest.java
index 92ef27dda..7badc97e0 100644
--- a/tests/src/com/fsck/k9/mail/store/ImapStoreUriTest.java
+++ b/tests/src/com/fsck/k9/mail/store/ImapStoreUriTest.java
@@ -6,14 +6,13 @@ import java.util.Map;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.ServerSettings;
-import com.fsck.k9.mail.Store;
-import com.fsck.k9.mail.store.ImapStore;
+
import junit.framework.TestCase;
public class ImapStoreUriTest extends TestCase {
public void testDecodeStoreUriImapAllExtras() {
String uri = "imap://PLAIN:user:pass@server:143/0%7CcustomPathPrefix";
- ServerSettings settings = Store.decodeStoreUri(uri);
+ ServerSettings settings = RemoteStore.decodeStoreUri(uri);
assertEquals(AuthType.PLAIN, settings.authenticationType);
assertEquals("user", settings.username);
@@ -26,7 +25,7 @@ public class ImapStoreUriTest extends TestCase {
public void testDecodeStoreUriImapNoExtras() {
String uri = "imap://PLAIN:user:pass@server:143/";
- ServerSettings settings = Store.decodeStoreUri(uri);
+ ServerSettings settings = RemoteStore.decodeStoreUri(uri);
assertEquals(AuthType.PLAIN, settings.authenticationType);
assertEquals("user", settings.username);
@@ -38,7 +37,7 @@ public class ImapStoreUriTest extends TestCase {
public void testDecodeStoreUriImapPrefixOnly() {
String uri = "imap://PLAIN:user:pass@server:143/customPathPrefix";
- ServerSettings settings = Store.decodeStoreUri(uri);
+ ServerSettings settings = RemoteStore.decodeStoreUri(uri);
assertEquals(AuthType.PLAIN, settings.authenticationType);
assertEquals("user", settings.username);
@@ -51,7 +50,7 @@ public class ImapStoreUriTest extends TestCase {
public void testDecodeStoreUriImapEmptyPrefix() {
String uri = "imap://PLAIN:user:pass@server:143/0%7C";
- ServerSettings settings = Store.decodeStoreUri(uri);
+ ServerSettings settings = RemoteStore.decodeStoreUri(uri);
assertEquals(AuthType.PLAIN, settings.authenticationType);
assertEquals("user", settings.username);
@@ -64,7 +63,7 @@ public class ImapStoreUriTest extends TestCase {
public void testDecodeStoreUriImapAutodetectAndPrefix() {
String uri = "imap://PLAIN:user:pass@server:143/1%7CcustomPathPrefix";
- ServerSettings settings = Store.decodeStoreUri(uri);
+ ServerSettings settings = RemoteStore.decodeStoreUri(uri);
assertEquals(AuthType.PLAIN, settings.authenticationType);
assertEquals("user", settings.username);
@@ -84,7 +83,7 @@ public class ImapStoreUriTest extends TestCase {
ServerSettings settings = new ServerSettings(ImapStore.STORE_TYPE, "server", 143,
ConnectionSecurity.NONE, AuthType.PLAIN, "user", "pass", null, extra);
- String uri = Store.createStoreUri(settings);
+ String uri = RemoteStore.createStoreUri(settings);
assertEquals("imap://PLAIN:user:pass@server:143/0%7CcustomPathPrefix", uri);
}
@@ -97,7 +96,7 @@ public class ImapStoreUriTest extends TestCase {
ServerSettings settings = new ServerSettings(ImapStore.STORE_TYPE, "server", 143,
ConnectionSecurity.NONE, AuthType.PLAIN, "user", "pass", null, extra);
- String uri = Store.createStoreUri(settings);
+ String uri = RemoteStore.createStoreUri(settings);
assertEquals("imap://PLAIN:user:pass@server:143/0%7C", uri);
}
@@ -106,7 +105,7 @@ public class ImapStoreUriTest extends TestCase {
ServerSettings settings = new ServerSettings(ImapStore.STORE_TYPE, "server", 143,
ConnectionSecurity.NONE, AuthType.PLAIN, "user", "pass", null);
- String uri = Store.createStoreUri(settings);
+ String uri = RemoteStore.createStoreUri(settings);
assertEquals("imap://PLAIN:user:pass@server:143/1%7C", uri);
}
@@ -118,7 +117,7 @@ public class ImapStoreUriTest extends TestCase {
ServerSettings settings = new ServerSettings(ImapStore.STORE_TYPE, "server", 143,
ConnectionSecurity.NONE, AuthType.PLAIN, "user", "pass", null, extra);
- String uri = Store.createStoreUri(settings);
+ String uri = RemoteStore.createStoreUri(settings);
assertEquals("imap://PLAIN:user:pass@server:143/1%7C", uri);
}
From 5af649c27164df1b3347b2f218ee48909baf2a74 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 06:54:34 +0000
Subject: [PATCH 02/29] Avoid cast
---
src/com/fsck/k9/mail/store/local/LocalStore.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/com/fsck/k9/mail/store/local/LocalStore.java b/src/com/fsck/k9/mail/store/local/LocalStore.java
index f4c82743a..1aad9386a 100644
--- a/src/com/fsck/k9/mail/store/local/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/local/LocalStore.java
@@ -70,7 +70,7 @@ public class LocalStore extends Store implements Serializable {
/**
* Local stores indexed by UUID because the Uri may change due to migration to/from SD-card.
*/
- private static ConcurrentMap sLocalStores = new ConcurrentHashMap();
+ private static ConcurrentMap sLocalStores = new ConcurrentHashMap();
/*
* a String containing the columns getMessages expects to work with
@@ -195,7 +195,7 @@ public class LocalStore extends Store implements Serializable {
// Use per-account locks so DatabaseUpgradeService always knows which account database is
// currently upgraded.
synchronized (lock) {
- Store store = sLocalStores.get(accountUuid);
+ LocalStore store = sLocalStores.get(accountUuid);
if (store == null) {
// Creating a LocalStore instance will create or upgrade the database if
@@ -205,7 +205,7 @@ public class LocalStore extends Store implements Serializable {
sLocalStores.put(accountUuid, store);
}
- return (LocalStore) store;
+ return store;
}
}
From 25367197490dd6e2477b067e2f185f878a980d49 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 07:03:14 +0000
Subject: [PATCH 03/29] Naming
---
src/com/fsck/k9/Account.java | 24 ++++++++++-----------
src/com/fsck/k9/mail/store/StoreConfig.java | 11 +++++-----
2 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index d7413b6d1..ac61af945 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -1078,8 +1078,8 @@ public class Account implements BaseAccount, StoreConfig {
return mDraftsFolderName;
}
- public synchronized void setDraftsFolderName(String draftsFolderName) {
- mDraftsFolderName = draftsFolderName;
+ public synchronized void setDraftsFolderName(String name) {
+ mDraftsFolderName = name;
}
/**
@@ -1098,8 +1098,8 @@ public class Account implements BaseAccount, StoreConfig {
return K9.ERROR_FOLDER_NAME;
}
- public synchronized void setSentFolderName(String sentFolderName) {
- mSentFolderName = sentFolderName;
+ public synchronized void setSentFolderName(String name) {
+ mSentFolderName = name;
}
/**
@@ -1115,8 +1115,8 @@ public class Account implements BaseAccount, StoreConfig {
return mTrashFolderName;
}
- public synchronized void setTrashFolderName(String trashFolderName) {
- mTrashFolderName = trashFolderName;
+ public synchronized void setTrashFolderName(String name) {
+ mTrashFolderName = name;
}
/**
@@ -1147,8 +1147,8 @@ public class Account implements BaseAccount, StoreConfig {
return mSpamFolderName;
}
- public synchronized void setSpamFolderName(String spamFolderName) {
- mSpamFolderName = spamFolderName;
+ public synchronized void setSpamFolderName(String name) {
+ mSpamFolderName = name;
}
/**
@@ -1167,8 +1167,8 @@ public class Account implements BaseAccount, StoreConfig {
return mAutoExpandFolderName;
}
- public synchronized void setAutoExpandFolderName(String autoExpandFolderName) {
- mAutoExpandFolderName = autoExpandFolderName;
+ public synchronized void setAutoExpandFolderName(String name) {
+ mAutoExpandFolderName = name;
}
public synchronized int getAccountNumber() {
@@ -1659,8 +1659,8 @@ public class Account implements BaseAccount, StoreConfig {
return mInboxFolderName;
}
- public void setInboxFolderName(String mInboxFolderName) {
- this.mInboxFolderName = mInboxFolderName;
+ public void setInboxFolderName(String name) {
+ this.mInboxFolderName = name;
}
public synchronized boolean syncRemoteDeletions() {
diff --git a/src/com/fsck/k9/mail/store/StoreConfig.java b/src/com/fsck/k9/mail/store/StoreConfig.java
index ba83ba201..23d177d90 100644
--- a/src/com/fsck/k9/mail/store/StoreConfig.java
+++ b/src/com/fsck/k9/mail/store/StoreConfig.java
@@ -12,12 +12,11 @@ public interface StoreConfig {
String getOutboxFolderName();
String getDraftsFolderName();
- void setInboxFolderName(String folderName);
- void setDraftsFolderName(String decodedFolderName);
- void setTrashFolderName(String decodedFolderName);
- void setSpamFolderName(String decodedFolderName);
- void setSentFolderName(String decodedFolderName);
- void setAutoExpandFolderName(String folderName);
+ void setDraftsFolderName(String name);
+ void setTrashFolderName(String name);
+ void setSpamFolderName(String name);
+ void setSentFolderName(String name);
+ void setAutoExpandFolderName(String name);
int getMaximumAutoDownloadMessageSize();
From 9f16b9f465735520f31753f7bb0f9d5075fe0ba2 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 12:34:57 +0000
Subject: [PATCH 04/29] Move SSL code into package
---
src/com/fsck/k9/Preferences.java | 1 -
.../{net => mail}/ssl/KeyChainKeyManager.java | 4 +-
.../ssl/TrustManagerFactory.java | 2 +-
.../ssl/TrustedSocketFactory.java | 2 +-
src/com/fsck/k9/mail/store/ImapStore.java | 2 +-
src/com/fsck/k9/mail/store/Pop3Store.java | 2 +-
.../k9/mail/store/WebDavSocketFactory.java | 2 +-
.../fsck/k9/mail/store/local/LocalStore.java | 79 +++++++++----------
.../fsck/k9/mail/transport/SmtpTransport.java | 2 +-
.../ssl/TrustManagerFactoryTest.java | 3 +-
10 files changed, 49 insertions(+), 50 deletions(-)
rename src/com/fsck/k9/{net => mail}/ssl/KeyChainKeyManager.java (98%)
rename src/com/fsck/k9/{net => mail}/ssl/TrustManagerFactory.java (99%)
rename src/com/fsck/k9/{net => mail}/ssl/TrustedSocketFactory.java (99%)
rename tests/src/com/fsck/k9/{net => mail}/ssl/TrustManagerFactoryTest.java (99%)
diff --git a/src/com/fsck/k9/Preferences.java b/src/com/fsck/k9/Preferences.java
index 6504626a2..04754af97 100644
--- a/src/com/fsck/k9/Preferences.java
+++ b/src/com/fsck/k9/Preferences.java
@@ -13,7 +13,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
-import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.store.local.LocalStore;
import com.fsck.k9.preferences.Editor;
import com.fsck.k9.preferences.Storage;
diff --git a/src/com/fsck/k9/net/ssl/KeyChainKeyManager.java b/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java
similarity index 98%
rename from src/com/fsck/k9/net/ssl/KeyChainKeyManager.java
rename to src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java
index c15fc58ad..52973e28b 100644
--- a/src/com/fsck/k9/net/ssl/KeyChainKeyManager.java
+++ b/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java
@@ -1,5 +1,5 @@
-package com.fsck.k9.net.ssl;
+package com.fsck.k9.mail.ssl;
import java.net.Socket;
import java.security.Principal;
@@ -29,7 +29,7 @@ import com.fsck.k9.mail.MessagingException;
* For client certificate authentication! Provide private keys and certificates
* during the TLS handshake using the Android 4.0 KeyChain API.
*/
-public class KeyChainKeyManager extends X509ExtendedKeyManager {
+class KeyChainKeyManager extends X509ExtendedKeyManager {
private static PrivateKey sClientCertificateReferenceWorkaround;
diff --git a/src/com/fsck/k9/net/ssl/TrustManagerFactory.java b/src/com/fsck/k9/mail/ssl/TrustManagerFactory.java
similarity index 99%
rename from src/com/fsck/k9/net/ssl/TrustManagerFactory.java
rename to src/com/fsck/k9/mail/ssl/TrustManagerFactory.java
index 4e20f5c67..c1956011c 100644
--- a/src/com/fsck/k9/net/ssl/TrustManagerFactory.java
+++ b/src/com/fsck/k9/mail/ssl/TrustManagerFactory.java
@@ -1,5 +1,5 @@
-package com.fsck.k9.net.ssl;
+package com.fsck.k9.mail.ssl;
import android.util.Log;
diff --git a/src/com/fsck/k9/net/ssl/TrustedSocketFactory.java b/src/com/fsck/k9/mail/ssl/TrustedSocketFactory.java
similarity index 99%
rename from src/com/fsck/k9/net/ssl/TrustedSocketFactory.java
rename to src/com/fsck/k9/mail/ssl/TrustedSocketFactory.java
index 12188f957..9d68dd205 100644
--- a/src/com/fsck/k9/net/ssl/TrustedSocketFactory.java
+++ b/src/com/fsck/k9/mail/ssl/TrustedSocketFactory.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.net.ssl;
+package com.fsck.k9.mail.ssl;
import android.util.Log;
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index 98c3a6833..542f78b83 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -90,7 +90,7 @@ import com.fsck.k9.mail.store.ImapResponseParser.ImapList;
import com.fsck.k9.mail.store.ImapResponseParser.ImapResponse;
import com.fsck.k9.mail.store.imap.ImapUtility;
import com.fsck.k9.mail.transport.imap.ImapSettings;
-import com.fsck.k9.net.ssl.TrustedSocketFactory;
+import com.fsck.k9.mail.ssl.TrustedSocketFactory;
import com.beetstra.jutf7.CharsetProvider;
import com.jcraft.jzlib.JZlib;
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index 593191a14..e0b290c76 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -12,7 +12,7 @@ import com.fsck.k9.mail.*;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.Hex;
import com.fsck.k9.mail.internet.MimeMessage;
-import com.fsck.k9.net.ssl.TrustedSocketFactory;
+import com.fsck.k9.mail.ssl.TrustedSocketFactory;
import javax.net.ssl.SSLException;
diff --git a/src/com/fsck/k9/mail/store/WebDavSocketFactory.java b/src/com/fsck/k9/mail/store/WebDavSocketFactory.java
index 3557002a2..5345b41fd 100644
--- a/src/com/fsck/k9/mail/store/WebDavSocketFactory.java
+++ b/src/com/fsck/k9/mail/store/WebDavSocketFactory.java
@@ -4,7 +4,7 @@ import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.scheme.LayeredSocketFactory;
import org.apache.http.params.HttpParams;
-import com.fsck.k9.net.ssl.TrustManagerFactory;
+import com.fsck.k9.mail.ssl.TrustManagerFactory;
import java.io.IOException;
import java.net.InetAddress;
diff --git a/src/com/fsck/k9/mail/store/local/LocalStore.java b/src/com/fsck/k9/mail/store/local/LocalStore.java
index 1aad9386a..0dded3e3f 100644
--- a/src/com/fsck/k9/mail/store/local/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/local/LocalStore.java
@@ -1,6 +1,40 @@
package com.fsck.k9.mail.store.local;
+import android.app.Application;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+import com.fsck.k9.Account;
+import com.fsck.k9.K9;
+import com.fsck.k9.Preferences;
+import com.fsck.k9.controller.MessageRetrievalListener;
+import com.fsck.k9.helper.UrlEncodingHelper;
+import com.fsck.k9.helper.Utility;
+import com.fsck.k9.mail.Flag;
+import com.fsck.k9.mail.Folder;
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.Store;
+import com.fsck.k9.mail.store.RemoteStore;
+import com.fsck.k9.mail.store.StorageManager;
+import com.fsck.k9.mail.store.StorageManager.StorageProvider;
+import com.fsck.k9.mail.store.StoreConfig;
+import com.fsck.k9.mail.store.UnavailableStorageException;
+import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
+import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
+import com.fsck.k9.provider.EmailProvider;
+import com.fsck.k9.provider.EmailProvider.MessageColumns;
+import com.fsck.k9.search.LocalSearch;
+import com.fsck.k9.search.SearchSpecification.Attribute;
+import com.fsck.k9.search.SearchSpecification.Searchfield;
+import com.fsck.k9.search.SqlQueryBuilder;
+
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
@@ -13,41 +47,6 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import android.app.Application;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.fsck.k9.Account;
-import com.fsck.k9.K9;
-import com.fsck.k9.Preferences;
-import com.fsck.k9.controller.MessageRetrievalListener;
-import com.fsck.k9.helper.UrlEncodingHelper;
-import com.fsck.k9.helper.Utility;
-import com.fsck.k9.mail.Flag;
-import com.fsck.k9.mail.Folder;
-import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.mail.Store;
-import com.fsck.k9.mail.store.RemoteStore;
-import com.fsck.k9.mail.store.StoreConfig;
-import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
-import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
-import com.fsck.k9.mail.store.StorageManager;
-import com.fsck.k9.mail.store.StorageManager.StorageProvider;
-import com.fsck.k9.mail.store.UnavailableStorageException;
-import com.fsck.k9.provider.EmailProvider;
-import com.fsck.k9.provider.EmailProvider.MessageColumns;
-import com.fsck.k9.search.LocalSearch;
-import com.fsck.k9.search.SearchSpecification.Attribute;
-import com.fsck.k9.search.SearchSpecification.Searchfield;
-import com.fsck.k9.search.SqlQueryBuilder;
-
/**
*
* Implements a SQLite database backed local store for Messages.
@@ -209,17 +208,17 @@ public class LocalStore extends Store implements Serializable {
}
}
- public static void removeAccount(StoreConfig storeConfig) {
+ public static void removeAccount(Account account) {
try {
- RemoteStore.removeInstance(storeConfig);
+ RemoteStore.removeInstance(account);
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Failed to reset remote store for account " + storeConfig.getUuid(), e);
+ Log.e(K9.LOG_TAG, "Failed to reset remote store for account " + account.getUuid(), e);
}
try {
- removeInstance(storeConfig);
+ removeInstance(account);
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Failed to reset local store for account " + storeConfig.getUuid(), e);
+ Log.e(K9.LOG_TAG, "Failed to reset local store for account " + account.getUuid(), e);
}
}
diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java
index a5365a33a..4e7959f7f 100644
--- a/src/com/fsck/k9/mail/transport/SmtpTransport.java
+++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java
@@ -17,7 +17,7 @@ import com.fsck.k9.mail.filter.SmtpDataStuffing;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.local.LocalMessage;
-import com.fsck.k9.net.ssl.TrustedSocketFactory;
+import com.fsck.k9.mail.ssl.TrustedSocketFactory;
import javax.net.ssl.SSLException;
diff --git a/tests/src/com/fsck/k9/net/ssl/TrustManagerFactoryTest.java b/tests/src/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java
similarity index 99%
rename from tests/src/com/fsck/k9/net/ssl/TrustManagerFactoryTest.java
rename to tests/src/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java
index 45efc0177..14da17b7f 100644
--- a/tests/src/com/fsck/k9/net/ssl/TrustManagerFactoryTest.java
+++ b/tests/src/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java
@@ -1,7 +1,8 @@
-package com.fsck.k9.net.ssl;
+package com.fsck.k9.mail.ssl;
import javax.net.ssl.X509TrustManager;
+import com.fsck.k9.mail.ssl.TrustManagerFactory;
import com.fsck.k9.security.LocalKeyStore;
import java.io.ByteArrayInputStream;
From 6264527abc61358f1f485f950606e9da33e1534b Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 12:42:48 +0000
Subject: [PATCH 05/29] Remove Preferences dependency
---
src/com/fsck/k9/activity/ChooseFolder.java | 24 +++++++------------
src/com/fsck/k9/activity/FolderList.java | 20 ++++++----------
.../k9/controller/MessagingController.java | 3 +--
src/com/fsck/k9/mail/Folder.java | 5 ----
src/com/fsck/k9/mail/store/StoreConfig.java | 1 +
5 files changed, 18 insertions(+), 35 deletions(-)
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index 83e8070b8..91430796d 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -280,22 +280,16 @@ public class ChooseFolder extends K9ListActivity {
mAccount.getInboxFolderName().equalsIgnoreCase(name)))) {
continue;
}
- try {
- folder.refresh(prefs);
- Folder.FolderClass fMode = folder.getDisplayClass();
+ Folder.FolderClass fMode = folder.getDisplayClass();
- if ((aMode == Account.FolderMode.FIRST_CLASS &&
- fMode != Folder.FolderClass.FIRST_CLASS) || (
- aMode == Account.FolderMode.FIRST_AND_SECOND_CLASS &&
- fMode != Folder.FolderClass.FIRST_CLASS &&
- fMode != Folder.FolderClass.SECOND_CLASS) || (
- aMode == Account.FolderMode.NOT_SECOND_CLASS &&
- fMode == Folder.FolderClass.SECOND_CLASS)) {
- continue;
- }
- } catch (MessagingException me) {
- Log.e(K9.LOG_TAG, "Couldn't get prefs to check for displayability of folder " +
- folder.getName(), me);
+ if ((aMode == FolderMode.FIRST_CLASS &&
+ fMode != Folder.FolderClass.FIRST_CLASS) || (
+ aMode == FolderMode.FIRST_AND_SECOND_CLASS &&
+ fMode != Folder.FolderClass.FIRST_CLASS &&
+ fMode != Folder.FolderClass.SECOND_CLASS) || (
+ aMode == FolderMode.NOT_SECOND_CLASS &&
+ fMode == Folder.FolderClass.SECOND_CLASS)) {
+ continue;
}
if (folder.isInTopGroup()) {
diff --git a/src/com/fsck/k9/activity/FolderList.java b/src/com/fsck/k9/activity/FolderList.java
index 670419cf1..2316b364f 100644
--- a/src/com/fsck/k9/activity/FolderList.java
+++ b/src/com/fsck/k9/activity/FolderList.java
@@ -749,20 +749,14 @@ public class FolderList extends K9ListActivity {
Account.FolderMode aMode = account.getFolderDisplayMode();
Preferences prefs = Preferences.getPreferences(getApplication().getApplicationContext());
for (Folder folder : folders) {
- try {
- folder.refresh(prefs);
+ Folder.FolderClass fMode = folder.getDisplayClass();
- Folder.FolderClass fMode = folder.getDisplayClass();
-
- if ((aMode == Account.FolderMode.FIRST_CLASS && fMode != Folder.FolderClass.FIRST_CLASS)
- || (aMode == Account.FolderMode.FIRST_AND_SECOND_CLASS &&
- fMode != Folder.FolderClass.FIRST_CLASS &&
- fMode != Folder.FolderClass.SECOND_CLASS)
- || (aMode == Account.FolderMode.NOT_SECOND_CLASS && fMode == Folder.FolderClass.SECOND_CLASS)) {
- continue;
- }
- } catch (MessagingException me) {
- Log.e(K9.LOG_TAG, "Couldn't get prefs to check for displayability of folder " + folder.getName(), me);
+ if ((aMode == FolderMode.FIRST_CLASS && fMode != Folder.FolderClass.FIRST_CLASS)
+ || (aMode == FolderMode.FIRST_AND_SECOND_CLASS &&
+ fMode != Folder.FolderClass.FIRST_CLASS &&
+ fMode != Folder.FolderClass.SECOND_CLASS)
+ || (aMode == FolderMode.NOT_SECOND_CLASS && fMode == Folder.FolderClass.SECOND_CLASS)) {
+ continue;
}
FolderInfoHolder holder = null;
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index d776c5fb3..e8cbb048a 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -694,6 +694,7 @@ public class MessagingController implements Runnable {
@Override
public void messagesFinished(int number) {}
@Override
+
public void messageFinished(LocalMessage message, int number, int ofTotal) {
if (!isMessageSuppressed(message)) {
List messages = new ArrayList();
@@ -4391,7 +4392,6 @@ public class MessagingController implements Runnable {
Store localStore = account.getLocalStore();
for (final Folder folder : localStore.getPersonalNamespaces(false)) {
folder.open(Folder.OPEN_MODE_RW);
- folder.refresh(prefs);
Folder.FolderClass fDisplayClass = folder.getDisplayClass();
Folder.FolderClass fSyncClass = folder.getSyncClass();
@@ -5305,7 +5305,6 @@ public class MessagingController implements Runnable {
continue;
}
folder.open(Folder.OPEN_MODE_RW);
- folder.refresh(prefs);
Folder.FolderClass fDisplayClass = folder.getDisplayClass();
Folder.FolderClass fPushClass = folder.getPushClass();
diff --git a/src/com/fsck/k9/mail/Folder.java b/src/com/fsck/k9/mail/Folder.java
index 5669e9794..d8bf087a6 100644
--- a/src/com/fsck/k9/mail/Folder.java
+++ b/src/com/fsck/k9/mail/Folder.java
@@ -8,7 +8,6 @@ import java.util.Set;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.Preferences;
import com.fsck.k9.controller.MessageRetrievalListener;
public abstract class Folder {
@@ -217,10 +216,6 @@ public abstract class Folder {
return getSyncClass();
}
- public void refresh(Preferences preferences) throws MessagingException {
-
- }
-
public boolean isInTopGroup() {
return false;
}
diff --git a/src/com/fsck/k9/mail/store/StoreConfig.java b/src/com/fsck/k9/mail/store/StoreConfig.java
index 23d177d90..12f7a025d 100644
--- a/src/com/fsck/k9/mail/store/StoreConfig.java
+++ b/src/com/fsck/k9/mail/store/StoreConfig.java
@@ -17,6 +17,7 @@ public interface StoreConfig {
void setSpamFolderName(String name);
void setSentFolderName(String name);
void setAutoExpandFolderName(String name);
+ void setInboxFolderName(String name);
int getMaximumAutoDownloadMessageSize();
From 708fb57c0462ca62feae824b36126522ad3124c6 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 12:49:26 +0000
Subject: [PATCH 06/29] Move things into local
---
src/com/fsck/k9/controller/MessagingController.java | 2 ++
src/com/fsck/k9/mail/Folder.java | 2 +-
src/com/fsck/k9/mail/store/ImapStore.java | 2 +-
src/com/fsck/k9/mail/store/Pop3Store.java | 2 +-
src/com/fsck/k9/mail/store/WebDavStore.java | 2 +-
src/com/fsck/k9/mail/store/local/LocalFolder.java | 2 --
src/com/fsck/k9/mail/store/local/LocalStore.java | 1 -
.../store/local}/MessageRemovalListener.java | 2 +-
.../store/local}/MessageRetrievalListener.java | 2 +-
9 files changed, 8 insertions(+), 9 deletions(-)
rename src/com/fsck/k9/{controller => mail/store/local}/MessageRemovalListener.java (77%)
rename src/com/fsck/k9/{controller => mail/store/local}/MessageRetrievalListener.java (92%)
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index e8cbb048a..458c713c7 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -81,6 +81,8 @@ import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
+import com.fsck.k9.mail.store.local.MessageRemovalListener;
+import com.fsck.k9.mail.store.local.MessageRetrievalListener;
import com.fsck.k9.mail.store.local.LocalFolder;
import com.fsck.k9.mail.store.local.LocalMessage;
import com.fsck.k9.mail.store.local.LocalStore;
diff --git a/src/com/fsck/k9/mail/Folder.java b/src/com/fsck/k9/mail/Folder.java
index d8bf087a6..c4f1a3998 100644
--- a/src/com/fsck/k9/mail/Folder.java
+++ b/src/com/fsck/k9/mail/Folder.java
@@ -8,7 +8,7 @@ import java.util.Set;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.controller.MessageRetrievalListener;
+import com.fsck.k9.mail.store.local.MessageRetrievalListener;
public abstract class Folder {
private String status = null;
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index 542f78b83..b8be10039 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -57,7 +57,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.R;
-import com.fsck.k9.controller.MessageRetrievalListener;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.helper.power.TracingPowerManager;
@@ -72,6 +71,7 @@ import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.store.local.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.PushReceiver;
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index e0b290c76..0871579b1 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -5,7 +5,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.R;
-import com.fsck.k9.controller.MessageRetrievalListener;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.*;
@@ -13,6 +12,7 @@ import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.Hex;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
+import com.fsck.k9.mail.store.local.MessageRetrievalListener;
import javax.net.ssl.SSLException;
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index 61dba1088..300a68d18 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -3,13 +3,13 @@ package com.fsck.k9.mail.store;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.controller.MessageRetrievalListener;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
import com.fsck.k9.mail.internet.MimeMessage;
+import com.fsck.k9.mail.store.local.MessageRetrievalListener;
import org.apache.commons.io.IOUtils;
import org.apache.http.*;
diff --git a/src/com/fsck/k9/mail/store/local/LocalFolder.java b/src/com/fsck/k9/mail/store/local/LocalFolder.java
index 22c3674ee..d4273d03f 100644
--- a/src/com/fsck/k9/mail/store/local/LocalFolder.java
+++ b/src/com/fsck/k9/mail/store/local/LocalFolder.java
@@ -32,8 +32,6 @@ import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Account.MessageFormat;
import com.fsck.k9.activity.Search;
-import com.fsck.k9.controller.MessageRemovalListener;
-import com.fsck.k9.controller.MessageRetrievalListener;
import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
diff --git a/src/com/fsck/k9/mail/store/local/LocalStore.java b/src/com/fsck/k9/mail/store/local/LocalStore.java
index 0dded3e3f..64bacb2ef 100644
--- a/src/com/fsck/k9/mail/store/local/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/local/LocalStore.java
@@ -14,7 +14,6 @@ import android.util.Log;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
-import com.fsck.k9.controller.MessageRetrievalListener;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Flag;
diff --git a/src/com/fsck/k9/controller/MessageRemovalListener.java b/src/com/fsck/k9/mail/store/local/MessageRemovalListener.java
similarity index 77%
rename from src/com/fsck/k9/controller/MessageRemovalListener.java
rename to src/com/fsck/k9/mail/store/local/MessageRemovalListener.java
index 38973dde4..95e35fd22 100644
--- a/src/com/fsck/k9/controller/MessageRemovalListener.java
+++ b/src/com/fsck/k9/mail/store/local/MessageRemovalListener.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.controller;
+package com.fsck.k9.mail.store.local;
import com.fsck.k9.mail.Message;
diff --git a/src/com/fsck/k9/controller/MessageRetrievalListener.java b/src/com/fsck/k9/mail/store/local/MessageRetrievalListener.java
similarity index 92%
rename from src/com/fsck/k9/controller/MessageRetrievalListener.java
rename to src/com/fsck/k9/mail/store/local/MessageRetrievalListener.java
index 6af8714af..12679b4e5 100644
--- a/src/com/fsck/k9/controller/MessageRetrievalListener.java
+++ b/src/com/fsck/k9/mail/store/local/MessageRetrievalListener.java
@@ -1,5 +1,5 @@
-package com.fsck.k9.controller;
+package com.fsck.k9.mail.store.local;
import com.fsck.k9.mail.Message;
From 0024f39bc6fc7731d317bb4343b701f132b507a8 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 13:04:59 +0000
Subject: [PATCH 07/29] Local messages
---
src/com/fsck/k9/activity/MessageCompose.java | 6 ++--
src/com/fsck/k9/activity/MessageList.java | 16 ++++-----
.../k9/controller/MessagingController.java | 29 ++++++++--------
.../fsck/k9/fragment/MessageListFragment.java | 28 +++++++---------
.../fsck/k9/fragment/MessageViewFragment.java | 6 ++--
src/com/fsck/k9/mail/Message.java | 20 +----------
.../fsck/k9/mail/internet/MimeMessage.java | 33 +++++++++----------
.../fsck/k9/mail/store/local/LocalFolder.java | 8 ++---
.../k9/mail/store/local/LocalMessage.java | 24 +++++++++++---
.../k9/service/NotificationActionService.java | 4 +--
10 files changed, 82 insertions(+), 92 deletions(-)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 2e6bacf99..9018cba8a 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -442,7 +442,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/
public static Intent getActionReplyIntent(
Context context,
- Message message,
+ LocalMessage message,
boolean replyAll,
String messageBody) {
Intent i = new Intent(context, MessageCompose.class);
@@ -467,7 +467,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/
public static void actionReply(
Context context,
- Message message,
+ LocalMessage message,
boolean replyAll,
String messageBody) {
context.startActivity(getActionReplyIntent(context, message, replyAll, messageBody));
@@ -481,7 +481,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/
public static void actionForward(
Context context,
- Message message,
+ LocalMessage message,
String messageBody) {
Intent i = new Intent(context, MessageCompose.class);
i.putExtra(EXTRA_MESSAGE_BODY, messageBody);
diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index 765d03673..604c1a166 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -42,8 +42,8 @@ import com.fsck.k9.fragment.MessageListFragment;
import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener;
import com.fsck.k9.fragment.MessageViewFragment;
import com.fsck.k9.fragment.MessageViewFragment.MessageViewFragmentListener;
-import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.store.StorageManager;
+import com.fsck.k9.mail.store.local.LocalMessage;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchAccount;
import com.fsck.k9.search.SearchSpecification;
@@ -1193,22 +1193,22 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
}
@Override
- public void onResendMessage(Message message) {
+ public void onResendMessage(LocalMessage message) {
MessageCompose.actionEditDraft(this, message.makeMessageReference());
}
@Override
- public void onForward(Message message) {
+ public void onForward(LocalMessage message) {
MessageCompose.actionForward(this, message, null);
}
@Override
- public void onReply(Message message) {
+ public void onReply(LocalMessage message) {
MessageCompose.actionReply(this, message, false, null);
}
@Override
- public void onReplyAll(Message message) {
+ public void onReplyAll(LocalMessage message) {
MessageCompose.actionReply(this, message, true, null);
}
@@ -1399,17 +1399,17 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
}
@Override
- public void onReply(Message message, PgpData pgpData) {
+ public void onReply(LocalMessage message, PgpData pgpData) {
MessageCompose.actionReply(this, message, false, pgpData.getDecryptedData());
}
@Override
- public void onReplyAll(Message message, PgpData pgpData) {
+ public void onReplyAll(LocalMessage message, PgpData pgpData) {
MessageCompose.actionReply(this, message, true, pgpData.getDecryptedData());
}
@Override
- public void onForward(Message mMessage, PgpData mPgpData) {
+ public void onForward(LocalMessage mMessage, PgpData mPgpData) {
MessageCompose.actionForward(this, mMessage, mPgpData.getDecryptedData());
}
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 458c713c7..d52c24183 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -214,7 +214,7 @@ public class MessagingController implements Runnable {
* Don't modify this list directly, but use {@link addMessage} and
* {@link removeMatchingMessage} instead.
*/
- LinkedList messages;
+ LinkedList messages;
/**
* List of references for messages that the user is still to be notified of,
* but which don't fit into the inbox style anymore. It's sorted from newest
@@ -238,7 +238,7 @@ public class MessagingController implements Runnable {
public NotificationData(int unread) {
unreadBeforeNotification = unread;
droppedMessages = new LinkedList();
- messages = new LinkedList();
+ messages = new LinkedList();
}
/**
@@ -249,9 +249,9 @@ public class MessagingController implements Runnable {
*
* @param m The new message to add.
*/
- public void addMessage(Message m) {
+ public void addMessage(LocalMessage m) {
while (messages.size() >= MAX_MESSAGES) {
- Message dropped = messages.removeLast();
+ LocalMessage dropped = messages.removeLast();
droppedMessages.addFirst(dropped.makeMessageReference());
}
messages.addFirst(m);
@@ -272,10 +272,10 @@ public class MessagingController implements Runnable {
}
}
- for (Message message : messages) {
+ for (LocalMessage message : messages) {
if (message.makeMessageReference().equals(ref)) {
if (messages.remove(message) && !droppedMessages.isEmpty()) {
- Message restoredMessage = droppedMessages.getFirst().restoreToLocalMessage(context);
+ LocalMessage restoredMessage = droppedMessages.getFirst().restoreToLocalMessage(context);
if (restoredMessage != null) {
messages.addLast(restoredMessage);
droppedMessages.removeFirst();
@@ -293,7 +293,7 @@ public class MessagingController implements Runnable {
* List.
*/
public void supplyAllMessageRefs(List refs) {
- for (Message m : messages) {
+ for (LocalMessage m : messages) {
refs.add(m.makeMessageReference());
}
refs.addAll(droppedMessages);
@@ -1621,7 +1621,7 @@ public class MessagingController implements Runnable {
}
// Store the updated message locally
- final Message localMessage = localFolder.storeSmallMessage(message, new Runnable() {
+ final LocalMessage localMessage = localFolder.storeSmallMessage(message, new Runnable() {
@Override
public void run() {
progress.incrementAndGet();
@@ -1769,7 +1769,7 @@ public class MessagingController implements Runnable {
// Update the listener with what we've found
progress.incrementAndGet();
// TODO do we need to re-fetch this here?
- Message localMessage = localFolder.getMessage(message.getUid());
+ LocalMessage localMessage = localFolder.getMessage(message.getUid());
// Increment the number of "new messages" if the newly downloaded message is
// not marked as read.
@@ -4781,8 +4781,7 @@ public class MessagingController implements Runnable {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
- private Message findNewestMessageForNotificationLocked(Context context,
- Account account, NotificationData data) {
+ private LocalMessage findNewestMessageForNotificationLocked(Context context, NotificationData data) {
if (!data.messages.isEmpty()) {
return data.messages.getFirst();
}
@@ -4798,7 +4797,7 @@ public class MessagingController implements Runnable {
* Creates a notification of a newly received message.
*/
private void notifyAccount(Context context, Account account,
- Message message, int previousUnreadMessageCount) {
+ LocalMessage message, int previousUnreadMessageCount) {
final NotificationData data = getNotificationData(account, previousUnreadMessageCount);
synchronized (data) {
notifyAccountWithDataLocked(context, account, message, data);
@@ -4809,12 +4808,12 @@ public class MessagingController implements Runnable {
private static final int NUM_SENDERS_IN_LOCK_SCREEN_NOTIFICATION = 5;
private void notifyAccountWithDataLocked(Context context, Account account,
- Message message, NotificationData data) {
+ LocalMessage message, NotificationData data) {
boolean updateSilently = false;
if (message == null) {
/* this can happen if a message we previously notified for is read or deleted remotely */
- message = findNewestMessageForNotificationLocked(context, account, data);
+ message = findNewestMessageForNotificationLocked(context, data);
updateSilently = true;
if (message == null) {
// seemingly both the message list as well as the overflow list is empty;
@@ -5110,7 +5109,7 @@ public class MessagingController implements Runnable {
int unreadCount,
CharSequence accountDescription,
CharSequence formattedSender,
- List messages) {
+ List extends Message> messages) {
if (!platformSupportsLockScreenNotifications()) {
return;
}
diff --git a/src/com/fsck/k9/fragment/MessageListFragment.java b/src/com/fsck/k9/fragment/MessageListFragment.java
index 48e5b6190..fa70da72c 100644
--- a/src/com/fsck/k9/fragment/MessageListFragment.java
+++ b/src/com/fsck/k9/fragment/MessageListFragment.java
@@ -1190,19 +1190,19 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
}
- public void onReply(Message message) {
+ public void onReply(LocalMessage message) {
mFragmentListener.onReply(message);
}
- public void onReplyAll(Message message) {
+ public void onReplyAll(LocalMessage message) {
mFragmentListener.onReplyAll(message);
}
- public void onForward(Message message) {
+ public void onForward(LocalMessage message) {
mFragmentListener.onForward(message);
}
- public void onResendMessage(Message message) {
+ public void onResendMessage(LocalMessage message) {
mFragmentListener.onResendMessage(message);
}
@@ -1510,23 +1510,19 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
break;
}
case R.id.reply: {
- Message message = getMessageAtPosition(adapterPosition);
- onReply(message);
+ onReply(getMessageAtPosition(adapterPosition));
break;
}
case R.id.reply_all: {
- Message message = getMessageAtPosition(adapterPosition);
- onReplyAll(message);
+ onReplyAll(getMessageAtPosition(adapterPosition));
break;
}
case R.id.forward: {
- Message message = getMessageAtPosition(adapterPosition);
- onForward(message);
+ onForward(getMessageAtPosition(adapterPosition));
break;
}
case R.id.send_again: {
- Message message = getMessageAtPosition(adapterPosition);
- onResendMessage(message);
+ onResendMessage(getMessageAtPosition(adapterPosition));
mSelectedCount = 0;
break;
}
@@ -3113,10 +3109,10 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
void setMessageListProgress(int level);
void showThread(Account account, String folderName, long rootId);
void showMoreFromSameSender(String senderAddress);
- void onResendMessage(Message message);
- void onForward(Message message);
- void onReply(Message message);
- void onReplyAll(Message message);
+ void onResendMessage(LocalMessage message);
+ void onForward(LocalMessage message);
+ void onReply(LocalMessage message);
+ void onReplyAll(LocalMessage message);
void openMessage(MessageReference messageReference);
void setMessageListTitle(String title);
void setMessageListSubTitle(String subTitle);
diff --git a/src/com/fsck/k9/fragment/MessageViewFragment.java b/src/com/fsck/k9/fragment/MessageViewFragment.java
index c8cfea928..5945957e3 100644
--- a/src/com/fsck/k9/fragment/MessageViewFragment.java
+++ b/src/com/fsck/k9/fragment/MessageViewFragment.java
@@ -846,10 +846,10 @@ public class MessageViewFragment extends Fragment implements OnClickListener,
}
public interface MessageViewFragmentListener {
- public void onForward(Message mMessage, PgpData mPgpData);
+ public void onForward(LocalMessage mMessage, PgpData mPgpData);
public void disableDeleteAction();
- public void onReplyAll(Message mMessage, PgpData mPgpData);
- public void onReply(Message mMessage, PgpData mPgpData);
+ public void onReplyAll(LocalMessage mMessage, PgpData mPgpData);
+ public void onReply(LocalMessage mMessage, PgpData mPgpData);
public void displayMessageSubject(String title);
public void setProgress(boolean b);
public void showNextMessageOrReturn();
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index 452d312df..d97982a4d 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -2,26 +2,20 @@
package com.fsck.k9.mail;
import java.io.IOException;
-import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
-import java.util.HashSet;
import java.util.Set;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.mail.filter.CountingOutputStream;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
import com.fsck.k9.mail.store.UnavailableStorageException;
public abstract class Message implements Part, CompositeBody {
- protected MessageReference mReference;
-
-
public enum RecipientType {
TO, CC, BCC,
}
@@ -73,7 +67,6 @@ public abstract class Message implements Part, CompositeBody {
}
public void setUid(String uid) {
- this.mReference = null;
this.mUid = uid;
}
@@ -251,15 +244,6 @@ public abstract class Message implements Part, CompositeBody {
public abstract void setCharset(String charset) throws MessagingException;
- public MessageReference makeMessageReference() {
- if (mReference == null) {
- mReference = new MessageReference();
- mReference.folderName = getFolder().getName();
- mReference.uid = mUid;
- }
- return mReference;
- }
-
public long calculateSize() {
try {
@@ -279,14 +263,12 @@ public abstract class Message implements Part, CompositeBody {
/**
* Copy the contents of this object into another {@code Message} object.
*
- * @param destination
- * The {@code Message} object to receive the contents of this instance.
+ * @param destination The {@code Message} object to receive the contents of this instance.
*/
protected void copy(Message destination) {
destination.mUid = mUid;
destination.mInternalDate = mInternalDate;
destination.mFolder = mFolder;
- destination.mReference = mReference;
// mFlags contents can change during the object lifetime, so copy the Set
destination.mFlags = EnumSet.copyOf(mFlags);
diff --git a/src/com/fsck/k9/mail/internet/MimeMessage.java b/src/com/fsck/k9/mail/internet/MimeMessage.java
index 75fa217d8..0d7bb8bab 100644
--- a/src/com/fsck/k9/mail/internet/MimeMessage.java
+++ b/src/com/fsck/k9/mail/internet/MimeMessage.java
@@ -608,28 +608,27 @@ public class MimeMessage extends Message {
/**
* Copy the contents of this object into another {@code MimeMessage} object.
*
- * @param message
- * The {@code MimeMessage} object to receive the contents of this instance.
+ * @param destination The {@code MimeMessage} object to receive the contents of this instance.
*/
- protected void copy(MimeMessage message) {
- super.copy(message);
+ protected void copy(MimeMessage destination) {
+ super.copy(destination);
- message.mHeader = mHeader.clone();
+ destination.mHeader = mHeader.clone();
- message.mBody = mBody;
- message.mMessageId = mMessageId;
- message.mSentDate = mSentDate;
- message.mDateFormat = mDateFormat;
- message.mSize = mSize;
+ destination.mBody = mBody;
+ destination.mMessageId = mMessageId;
+ destination.mSentDate = mSentDate;
+ destination.mDateFormat = mDateFormat;
+ destination.mSize = mSize;
// These arrays are not supposed to be modified, so it's okay to reuse the references
- message.mFrom = mFrom;
- message.mTo = mTo;
- message.mCc = mCc;
- message.mBcc = mBcc;
- message.mReplyTo = mReplyTo;
- message.mReferences = mReferences;
- message.mInReplyTo = mInReplyTo;
+ destination.mFrom = mFrom;
+ destination.mTo = mTo;
+ destination.mCc = mCc;
+ destination.mBcc = mBcc;
+ destination.mReplyTo = mReplyTo;
+ destination.mReferences = mReferences;
+ destination.mInReplyTo = mInReplyTo;
}
@Override
diff --git a/src/com/fsck/k9/mail/store/local/LocalFolder.java b/src/com/fsck/k9/mail/store/local/LocalFolder.java
index d4273d03f..8ca5c139c 100644
--- a/src/com/fsck/k9/mail/store/local/LocalFolder.java
+++ b/src/com/fsck/k9/mail/store/local/LocalFolder.java
@@ -1138,14 +1138,14 @@ public class LocalFolder extends Folder implements Serializable {
* @return The local version of the message. Never null
.
* @throws MessagingException
*/
- public Message storeSmallMessage(final Message message, final Runnable runnable) throws MessagingException {
- return this.localStore.database.execute(true, new DbCallback() {
+ public LocalMessage storeSmallMessage(final Message message, final Runnable runnable) throws MessagingException {
+ return this.localStore.database.execute(true, new DbCallback() {
@Override
- public Message doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
+ public LocalMessage doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
try {
appendMessages(Collections.singletonList(message));
final String uid = message.getUid();
- final Message result = getMessage(uid);
+ final LocalMessage result = getMessage(uid);
runnable.run();
// Set a flag indicating this message has now be fully downloaded
result.setFlag(Flag.X_DOWNLOADED_FULL, true);
diff --git a/src/com/fsck/k9/mail/store/local/LocalMessage.java b/src/com/fsck/k9/mail/store/local/LocalMessage.java
index 6dd164f14..7391a8646 100644
--- a/src/com/fsck/k9/mail/store/local/LocalMessage.java
+++ b/src/com/fsck/k9/mail/store/local/LocalMessage.java
@@ -27,7 +27,7 @@ import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
public class LocalMessage extends MimeMessage {
-
+ protected MessageReference mReference;
private final LocalStore localStore;
private long mId;
@@ -52,8 +52,7 @@ public class LocalMessage extends MimeMessage {
this.mFolder = folder;
}
- void populateFromGetMessageCursor(Cursor cursor)
- throws MessagingException {
+ void populateFromGetMessageCursor(Cursor cursor) throws MessagingException {
final String subject = cursor.getString(0);
this.setSubject(subject == null ? "" : subject);
@@ -191,6 +190,12 @@ public class LocalMessage extends MimeMessage {
mMessageDirty = true;
}
+ @Override
+ public void setUid(String uid) {
+ super.setUid(uid);
+ this.mReference = null;
+ }
+
@Override
public boolean hasAttachments() {
return (mAttachmentCount > 0);
@@ -564,15 +569,24 @@ public class LocalMessage extends MimeMessage {
return localStore.getAccount();
}
- @Override
public MessageReference makeMessageReference() {
if (mReference == null) {
- mReference = super.makeMessageReference();
+ mReference = new MessageReference();
+ mReference.folderName = getFolder().getName();
+ mReference.uid = mUid;
mReference.accountUuid = getFolder().getUuid();
}
return mReference;
}
+ @Override
+ protected void copy(MimeMessage destination) {
+ super.copy(destination);
+ if (destination instanceof LocalMessage) {
+ ((LocalMessage)destination).mReference = mReference;
+ }
+ }
+
@Override
public LocalFolder getFolder() {
return (LocalFolder) super.getFolder();
diff --git a/src/com/fsck/k9/service/NotificationActionService.java b/src/com/fsck/k9/service/NotificationActionService.java
index 2baef7560..079222e69 100644
--- a/src/com/fsck/k9/service/NotificationActionService.java
+++ b/src/com/fsck/k9/service/NotificationActionService.java
@@ -103,8 +103,8 @@ public class NotificationActionService extends CoreService {
if (K9.DEBUG)
Log.i(K9.LOG_TAG, "NotificationActionService initiating reply");
- MessageReference ref = (MessageReference) intent.getParcelableExtra(EXTRA_MESSAGE);
- Message message = ref.restoreToLocalMessage(this);
+ MessageReference ref = intent.getParcelableExtra(EXTRA_MESSAGE);
+ LocalMessage message = ref.restoreToLocalMessage(this);
if (message != null) {
Intent i = MessageCompose.getActionReplyIntent(this, message, false, null);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
From 2e98ff56e5719692b15cf051e78f74ad2f22c3a9 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 13:35:36 +0000
Subject: [PATCH 08/29] Break dependencies
---
src/com/fsck/k9/activity/MessageCompose.java | 3 ++-
.../fsck/k9/activity/setup/WelcomeMessage.java | 2 +-
src/com/fsck/k9/helper/Contacts.java | 2 +-
src/com/fsck/k9/mail/Address.java | 17 ++++++++---------
.../internet}/HtmlConverter.java | 4 +++-
.../internet}/InsertableHtmlContent.java | 2 +-
src/com/fsck/k9/mail/internet/MimeUtility.java | 1 -
.../fsck/k9/mail/internet/TextBodyBuilder.java | 4 +---
.../fsck/k9/mail/store/local/LocalFolder.java | 2 +-
src/com/fsck/k9/view/MessageWebView.java | 2 +-
src/com/fsck/k9/view/SingleMessageView.java | 3 +--
.../k9/mail/internet/TextBodyBuilderTest.java | 2 +-
.../com/fsck/k9/helper/HtmlConverterTest.java | 2 ++
13 files changed, 23 insertions(+), 23 deletions(-)
rename src/com/fsck/k9/{helper => mail/internet}/HtmlConverter.java (99%)
rename src/com/fsck/k9/{activity => mail/internet}/InsertableHtmlContent.java (99%)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 9018cba8a..076ee4fa6 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -89,12 +89,13 @@ import com.fsck.k9.crypto.PgpData;
import com.fsck.k9.fragment.ProgressDialogFragment;
import com.fsck.k9.helper.ContactItem;
import com.fsck.k9.helper.Contacts;
-import com.fsck.k9.helper.HtmlConverter;
+import com.fsck.k9.mail.internet.HtmlConverter;
import com.fsck.k9.helper.IdentityHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.Flag;
+import com.fsck.k9.mail.internet.InsertableHtmlContent;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.MessagingException;
diff --git a/src/com/fsck/k9/activity/setup/WelcomeMessage.java b/src/com/fsck/k9/activity/setup/WelcomeMessage.java
index 9c30bb0c2..e40a95eb9 100644
--- a/src/com/fsck/k9/activity/setup/WelcomeMessage.java
+++ b/src/com/fsck/k9/activity/setup/WelcomeMessage.java
@@ -12,7 +12,7 @@ import android.widget.TextView;
import com.fsck.k9.R;
import com.fsck.k9.activity.Accounts;
import com.fsck.k9.activity.K9Activity;
-import com.fsck.k9.helper.HtmlConverter;
+import com.fsck.k9.mail.internet.HtmlConverter;
/**
* Displays a welcome message when no accounts have been created yet.
diff --git a/src/com/fsck/k9/helper/Contacts.java b/src/com/fsck/k9/helper/Contacts.java
index 022139f89..f5d25a912 100644
--- a/src/com/fsck/k9/helper/Contacts.java
+++ b/src/com/fsck/k9/helper/Contacts.java
@@ -18,7 +18,7 @@ import java.util.List;
/**
* Helper class to access the contacts stored on the device.
*/
-public class Contacts {
+public class Contacts implements Address.Lookup {
/**
* The order in which the search results are returned by
* {@link #searchContacts(CharSequence)}.
diff --git a/src/com/fsck/k9/mail/Address.java b/src/com/fsck/k9/mail/Address.java
index f3810f051..25929e94e 100644
--- a/src/com/fsck/k9/mail/Address.java
+++ b/src/com/fsck/k9/mail/Address.java
@@ -20,11 +20,14 @@ import android.text.util.Rfc822Tokenizer;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.Utility;
public class Address {
+ public static interface Lookup {
+ String getNameForAddress(String address);
+ }
+
/**
* If the number of addresses exceeds this value the addresses aren't
* resolved to the names of Android contacts.
@@ -34,7 +37,7 @@ public class Address {
* performance tests.
*
*
- * @see Address#toFriendly(Address[], Contacts)
+ * @see Address#toFriendly(Address[], com.fsck.k9.mail.Address.Lookup)
*/
private static final int TOO_MANY_ADDRESSES = 50;
@@ -239,7 +242,7 @@ public class Address {
* @return
*/
public CharSequence toFriendly() {
- return toFriendly((Contacts)null);
+ return toFriendly((Lookup)null);
}
/**
@@ -254,7 +257,7 @@ public class Address {
* @return
* A "friendly" name for this {@link Address}.
*/
- public CharSequence toFriendly(final Contacts contacts) {
+ public CharSequence toFriendly(final Lookup contacts) {
if (!K9.showCorrespondentNames()) {
return mAddress;
@@ -281,11 +284,7 @@ public class Address {
return (!TextUtils.isEmpty(mPersonal)) ? mPersonal : mAddress;
}
- public static CharSequence toFriendly(Address[] addresses) {
- return toFriendly(addresses, null);
- }
-
- public static CharSequence toFriendly(Address[] addresses, Contacts contacts) {
+ public static CharSequence toFriendly(Address[] addresses, Lookup contacts) {
if (addresses == null) {
return null;
}
diff --git a/src/com/fsck/k9/helper/HtmlConverter.java b/src/com/fsck/k9/mail/internet/HtmlConverter.java
similarity index 99%
rename from src/com/fsck/k9/helper/HtmlConverter.java
rename to src/com/fsck/k9/mail/internet/HtmlConverter.java
index 14eb75fda..a217d5b81 100644
--- a/src/com/fsck/k9/helper/HtmlConverter.java
+++ b/src/com/fsck/k9/mail/internet/HtmlConverter.java
@@ -1,9 +1,11 @@
-package com.fsck.k9.helper;
+package com.fsck.k9.mail.internet;
import android.text.*;
import android.text.Html.TagHandler;
import android.util.Log;
import com.fsck.k9.K9;
+import com.fsck.k9.helper.Regex;
+
import org.xml.sax.XMLReader;
import java.io.IOException;
diff --git a/src/com/fsck/k9/activity/InsertableHtmlContent.java b/src/com/fsck/k9/mail/internet/InsertableHtmlContent.java
similarity index 99%
rename from src/com/fsck/k9/activity/InsertableHtmlContent.java
rename to src/com/fsck/k9/mail/internet/InsertableHtmlContent.java
index 9821ad784..fabcc6082 100644
--- a/src/com/fsck/k9/activity/InsertableHtmlContent.java
+++ b/src/com/fsck/k9/mail/internet/InsertableHtmlContent.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.activity;
+package com.fsck.k9.mail.internet;
import java.io.Serializable;
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index c6308a313..6aaa93256 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -5,7 +5,6 @@ import android.content.Context;
import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.R;
-import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.internet.BinaryTempFileBody.BinaryTempFileBodyInputStream;
diff --git a/src/com/fsck/k9/mail/internet/TextBodyBuilder.java b/src/com/fsck/k9/mail/internet/TextBodyBuilder.java
index 7efbc8f5d..962a80e14 100644
--- a/src/com/fsck/k9/mail/internet/TextBodyBuilder.java
+++ b/src/com/fsck/k9/mail/internet/TextBodyBuilder.java
@@ -4,8 +4,6 @@ import android.text.TextUtils;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.activity.InsertableHtmlContent;
-import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.mail.Body;
public class TextBodyBuilder {
@@ -27,7 +25,7 @@ public class TextBodyBuilder {
/**
* Build the {@link Body} that will contain the text of the message.
*
- * @return {@link TextBody} instance that contains the entered text and
+ * @return {@link com.fsck.k9.mail.internet.TextBody} instance that contains the entered text and
* possibly the quoted original message.
*/
public TextBody buildTextHtml() {
diff --git a/src/com/fsck/k9/mail/store/local/LocalFolder.java b/src/com/fsck/k9/mail/store/local/LocalFolder.java
index 8ca5c139c..e68d7d684 100644
--- a/src/com/fsck/k9/mail/store/local/LocalFolder.java
+++ b/src/com/fsck/k9/mail/store/local/LocalFolder.java
@@ -32,7 +32,7 @@ import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Account.MessageFormat;
import com.fsck.k9.activity.Search;
-import com.fsck.k9.helper.HtmlConverter;
+import com.fsck.k9.mail.internet.HtmlConverter;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body;
diff --git a/src/com/fsck/k9/view/MessageWebView.java b/src/com/fsck/k9/view/MessageWebView.java
index 3198d4723..07faaf3e1 100644
--- a/src/com/fsck/k9/view/MessageWebView.java
+++ b/src/com/fsck/k9/view/MessageWebView.java
@@ -10,7 +10,7 @@ import android.widget.Toast;
import com.fsck.k9.K9;
import com.fsck.k9.R;
-import com.fsck.k9.helper.HtmlConverter;
+import com.fsck.k9.mail.internet.HtmlConverter;
public class MessageWebView extends RigidWebView {
diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java
index 1506bd4dd..a351e7921 100644
--- a/src/com/fsck/k9/view/SingleMessageView.java
+++ b/src/com/fsck/k9/view/SingleMessageView.java
@@ -5,7 +5,6 @@ import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
-import java.net.URLDecoder;
import android.app.Activity;
import android.app.Fragment;
@@ -47,7 +46,7 @@ import com.fsck.k9.fragment.MessageViewFragment;
import com.fsck.k9.helper.ClipboardManager;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.FileHelper;
-import com.fsck.k9.helper.HtmlConverter;
+import com.fsck.k9.mail.internet.HtmlConverter;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
diff --git a/tests-on-jvm/src/com/fsck/k9/mail/internet/TextBodyBuilderTest.java b/tests-on-jvm/src/com/fsck/k9/mail/internet/TextBodyBuilderTest.java
index 64882691d..7c3b096dd 100644
--- a/tests-on-jvm/src/com/fsck/k9/mail/internet/TextBodyBuilderTest.java
+++ b/tests-on-jvm/src/com/fsck/k9/mail/internet/TextBodyBuilderTest.java
@@ -7,7 +7,7 @@ import org.junit.experimental.theories.*;
import org.junit.runner.RunWith;
import com.fsck.k9.Account.QuoteStyle;
-import com.fsck.k9.activity.InsertableHtmlContent;
+import com.fsck.k9.activity.TextBodyBuilder;
class TestingTextBodyBuilder extends TextBodyBuilder {
diff --git a/tests/src/com/fsck/k9/helper/HtmlConverterTest.java b/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
index c79958150..7ab254baf 100644
--- a/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
+++ b/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
@@ -1,5 +1,7 @@
package com.fsck.k9.helper;
+import com.fsck.k9.mail.internet.HtmlConverter;
+
import junit.framework.TestCase;
import java.io.BufferedWriter;
From 40041ac0e0930525f2fa1fae2d24852df5cad6e3 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 15:02:59 +0000
Subject: [PATCH 09/29] Move local message code to local package
+ cut some helper dependencies
---
src/com/fsck/k9/Account.java | 17 +--
src/com/fsck/k9/EmailAddressValidator.java | 14 ++-
src/com/fsck/k9/K9.java | 4 +-
src/com/fsck/k9/Preferences.java | 2 +-
src/com/fsck/k9/activity/Accounts.java | 2 +-
src/com/fsck/k9/activity/FolderList.java | 3 +-
src/com/fsck/k9/activity/MessageCompose.java | 19 +--
.../fsck/k9/activity/MessageInfoHolder.java | 4 +-
src/com/fsck/k9/activity/MessageList.java | 4 +-
.../fsck/k9/activity/MessageReference.java | 20 ++--
.../fsck/k9/activity/UpgradeDatabases.java | 2 +-
.../k9/activity/setup/AccountSettings.java | 4 +-
.../k9/activity/setup/FolderSettings.java | 4 +-
src/com/fsck/k9/cache/EmailProviderCache.java | 4 +-
.../k9/controller/MessagingController.java | 15 ++-
.../MessagingControllerPushReceiver.java | 4 +-
.../fsck/k9/controller/MessagingListener.java | 2 +-
.../UnavailableAccountException.java | 8 +-
.../fsck/k9/fragment/MessageListFragment.java | 6 +-
.../fsck/k9/fragment/MessageViewFragment.java | 2 +-
src/com/fsck/k9/helper/MessageHelper.java | 3 +-
src/com/fsck/k9/helper/Regex.java | 109 ------------------
src/com/fsck/k9/helper/Utility.java | 59 ----------
.../local/AttachmentMessageBodyUtil.java | 2 +-
.../local/BinaryAttachmentBody.java | 2 +-
.../store => }/local/LocalAttachmentBody.java | 2 +-
.../local/LocalAttachmentBodyPart.java | 2 +-
.../local/LocalAttachmentMessageBody.java | 2 +-
.../{mail/store => }/local/LocalFolder.java | 17 ++-
.../{mail/store => }/local/LocalMessage.java | 21 ++--
.../k9/{mail/store => }/local/LocalStore.java | 27 +++--
.../{mail/store => }/local/LocalTextBody.java | 2 +-
.../store => }/local/LockableDatabase.java | 11 +-
.../local/MessageRemovalListener.java | 2 +-
.../{mail/store => local}/StorageManager.java | 2 +-
.../local/StoreSchemaDefinition.java | 2 +-
.../{mail/store => }/local/TempFileBody.java | 2 +-
.../store => }/local/TempFileMessageBody.java | 2 +-
.../k9/{mail/store => }/local/ThreadInfo.java | 2 +-
.../UnavailableStorageException.java | 2 +-
src/com/fsck/k9/mail/Address.java | 46 +++++++-
src/com/fsck/k9/mail/Body.java | 4 +-
src/com/fsck/k9/mail/Folder.java | 1 -
src/com/fsck/k9/mail/Message.java | 26 +----
.../local => }/MessageRetrievalListener.java | 3 +-
src/com/fsck/k9/mail/ServerSettings.java | 5 +-
src/com/fsck/k9/mail/Transport.java | 10 +-
src/com/fsck/k9/mail/filter/Base64.java | 16 +++
.../fsck/k9/mail/internet/HtmlConverter.java | 69 ++++++++++-
src/com/fsck/k9/mail/internet/MimeHeader.java | 4 +-
.../fsck/k9/mail/internet/MimeMessage.java | 13 +--
.../{security => mail/ssl}/LocalKeyStore.java | 2 +-
.../fsck/k9/mail/ssl/TrustManagerFactory.java | 1 -
src/com/fsck/k9/mail/store/ImapStore.java | 29 +++--
.../k9/mail/store/{imap => }/ImapUtility.java | 4 +-
src/com/fsck/k9/mail/store/Pop3Store.java | 5 +-
src/com/fsck/k9/mail/store/WebDavStore.java | 6 +-
.../fsck/k9/mail/transport/SmtpTransport.java | 22 ++--
.../fsck/k9/preferences/AccountSettings.java | 2 +-
.../fsck/k9/preferences/SettingsImporter.java | 6 +-
src/com/fsck/k9/preferences/Storage.java | 10 +-
.../fsck/k9/provider/AttachmentProvider.java | 6 +-
src/com/fsck/k9/provider/EmailProvider.java | 20 +++-
src/com/fsck/k9/provider/MessageProvider.java | 6 +-
src/com/fsck/k9/search/SqlQueryBuilder.java | 4 +-
.../k9/service/DatabaseUpgradeService.java | 2 +-
.../k9/service/NotificationActionService.java | 3 +-
.../fsck/k9/service/StorageGoneReceiver.java | 2 +-
src/com/fsck/k9/service/StorageReceiver.java | 2 +-
src/com/fsck/k9/view/AttachmentView.java | 2 +-
src/com/fsck/k9/view/SingleMessageView.java | 4 +-
.../Address.java => mail/AddressTest.java} | 10 +-
.../Address_quoteAtoms.java} | 8 +-
.../k9/mail/ssl/TrustManagerFactoryTest.java | 3 -
.../store/{imap => }/ImapUtilityTest.java | 3 +-
75 files changed, 352 insertions(+), 420 deletions(-)
rename src/com/fsck/k9/{mail/store => controller}/UnavailableAccountException.java (83%)
delete mode 100644 src/com/fsck/k9/helper/Regex.java
rename src/com/fsck/k9/{mail/store => }/local/AttachmentMessageBodyUtil.java (96%)
rename src/com/fsck/k9/{mail/store => }/local/BinaryAttachmentBody.java (97%)
rename src/com/fsck/k9/{mail/store => }/local/LocalAttachmentBody.java (96%)
rename src/com/fsck/k9/{mail/store => }/local/LocalAttachmentBodyPart.java (95%)
rename src/com/fsck/k9/{mail/store => }/local/LocalAttachmentMessageBody.java (97%)
rename src/com/fsck/k9/{mail/store => }/local/LocalFolder.java (99%)
rename src/com/fsck/k9/{mail/store => }/local/LocalMessage.java (96%)
rename src/com/fsck/k9/{mail/store => }/local/LocalStore.java (98%)
rename src/com/fsck/k9/{mail/store => }/local/LocalTextBody.java (92%)
rename src/com/fsck/k9/{mail/store => }/local/LockableDatabase.java (97%)
rename src/com/fsck/k9/{mail/store => }/local/MessageRemovalListener.java (77%)
rename src/com/fsck/k9/{mail/store => local}/StorageManager.java (99%)
rename src/com/fsck/k9/{mail/store => }/local/StoreSchemaDefinition.java (99%)
rename src/com/fsck/k9/{mail/store => }/local/TempFileBody.java (94%)
rename src/com/fsck/k9/{mail/store => }/local/TempFileMessageBody.java (96%)
rename src/com/fsck/k9/{mail/store => }/local/ThreadInfo.java (92%)
rename src/com/fsck/k9/{mail/store => local}/UnavailableStorageException.java (96%)
rename src/com/fsck/k9/mail/{store/local => }/MessageRetrievalListener.java (85%)
rename src/com/fsck/k9/{security => mail/ssl}/LocalKeyStore.java (99%)
rename src/com/fsck/k9/mail/store/{imap => }/ImapUtility.java (98%)
rename tests/src/com/fsck/k9/{helper/Address.java => mail/AddressTest.java} (74%)
rename tests/src/com/fsck/k9/{helper/Utility_quoteAtoms.java => mail/Address_quoteAtoms.java} (87%)
rename tests/src/com/fsck/k9/mail/store/{imap => }/ImapUtilityTest.java (99%)
diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index ac61af945..46f5c5d62 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -29,11 +29,12 @@ import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.Folder.FolderClass;
+import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mail.store.StoreConfig;
-import com.fsck.k9.mail.store.StorageManager;
-import com.fsck.k9.mail.store.StorageManager.StorageProvider;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.StorageManager;
+import com.fsck.k9.local.StorageManager.StorageProvider;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.StatsColumns;
import com.fsck.k9.search.ConditionsTreeNode;
@@ -42,7 +43,7 @@ import com.fsck.k9.search.SqlQueryBuilder;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.fsck.k9.search.SearchSpecification.Searchfield;
-import com.fsck.k9.security.LocalKeyStore;
+import com.fsck.k9.mail.ssl.LocalKeyStore;
import com.fsck.k9.view.ColorChip;
import com.larswerkman.colorpicker.ColorPicker;
@@ -363,9 +364,9 @@ public class Account implements BaseAccount, StoreConfig {
SharedPreferences prefs = preferences.getPreferences();
- mStoreUri = Utility.base64Decode(prefs.getString(mUuid + ".storeUri", null));
+ mStoreUri = Base64.decode(prefs.getString(mUuid + ".storeUri", null));
mLocalStorageProviderId = prefs.getString(mUuid + ".localStorageProvider", StorageManager.getInstance(K9.app).getDefaultProviderId());
- mTransportUri = Utility.base64Decode(prefs.getString(mUuid + ".transportUri", null));
+ mTransportUri = Base64.decode(prefs.getString(mUuid + ".transportUri", null));
mDescription = prefs.getString(mUuid + ".description", null);
mAlwaysBcc = prefs.getString(mUuid + ".alwaysBcc", mAlwaysBcc);
mAutomaticCheckIntervalMinutes = prefs.getInt(mUuid + ".automaticCheckIntervalMinutes", -1);
@@ -691,9 +692,9 @@ public class Account implements BaseAccount, StoreConfig {
editor.putString("accountUuids", accountUuids);
}
- editor.putString(mUuid + ".storeUri", Utility.base64Encode(mStoreUri));
+ editor.putString(mUuid + ".storeUri", Base64.encode(mStoreUri));
editor.putString(mUuid + ".localStorageProvider", mLocalStorageProviderId);
- editor.putString(mUuid + ".transportUri", Utility.base64Encode(mTransportUri));
+ editor.putString(mUuid + ".transportUri", Base64.encode(mTransportUri));
editor.putString(mUuid + ".description", mDescription);
editor.putString(mUuid + ".alwaysBcc", mAlwaysBcc);
editor.putInt(mUuid + ".automaticCheckIntervalMinutes", mAutomaticCheckIntervalMinutes);
diff --git a/src/com/fsck/k9/EmailAddressValidator.java b/src/com/fsck/k9/EmailAddressValidator.java
index 957a1384b..211d99220 100644
--- a/src/com/fsck/k9/EmailAddressValidator.java
+++ b/src/com/fsck/k9/EmailAddressValidator.java
@@ -4,7 +4,19 @@ package com.fsck.k9;
import android.text.util.Rfc822Tokenizer;
import android.widget.AutoCompleteTextView.Validator;
+import java.util.regex.Pattern;
+
public class EmailAddressValidator implements Validator {
+ private static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(
+ "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
+ "\\@" +
+ "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
+ "(" +
+ "\\." +
+ "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
+ ")+"
+ );
+
public CharSequence fixText(CharSequence invalidText) {
return "";
}
@@ -14,6 +26,6 @@ public class EmailAddressValidator implements Validator {
}
public boolean isValidAddressOnly(CharSequence text) {
- return com.fsck.k9.helper.Regex.EMAIL_ADDRESS_PATTERN.matcher(text).matches();
+ return EMAIL_ADDRESS_PATTERN.matcher(text).matches();
}
}
diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java
index 08c49c5ed..7e062d5f9 100644
--- a/src/com/fsck/k9/K9.java
+++ b/src/com/fsck/k9/K9.java
@@ -36,9 +36,9 @@ import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.BinaryTempFileBody;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.provider.UnreadWidgetProvider;
-import com.fsck.k9.security.LocalKeyStore;
+import com.fsck.k9.mail.ssl.LocalKeyStore;
import com.fsck.k9.service.BootReceiver;
import com.fsck.k9.service.MailService;
import com.fsck.k9.service.ShutdownReceiver;
diff --git a/src/com/fsck/k9/Preferences.java b/src/com/fsck/k9/Preferences.java
index 04754af97..a5c0cd4bc 100644
--- a/src/com/fsck/k9/Preferences.java
+++ b/src/com/fsck/k9/Preferences.java
@@ -13,7 +13,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.preferences.Editor;
import com.fsck.k9.preferences.Storage;
diff --git a/src/com/fsck/k9/activity/Accounts.java b/src/com/fsck/k9/activity/Accounts.java
index 5b7a757ae..c2a0ec21b 100644
--- a/src/com/fsck/k9/activity/Accounts.java
+++ b/src/com/fsck/k9/activity/Accounts.java
@@ -80,7 +80,7 @@ import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.store.RemoteStore;
-import com.fsck.k9.mail.store.StorageManager;
+import com.fsck.k9.local.StorageManager;
import com.fsck.k9.mail.store.WebDavStore;
import com.fsck.k9.preferences.SettingsExporter;
import com.fsck.k9.preferences.SettingsImportExportException;
diff --git a/src/com/fsck/k9/activity/FolderList.java b/src/com/fsck/k9/activity/FolderList.java
index 2316b364f..d1d7c17e4 100644
--- a/src/com/fsck/k9/activity/FolderList.java
+++ b/src/com/fsck/k9/activity/FolderList.java
@@ -55,8 +55,7 @@ import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
-import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.mail.store.local.LocalFolder;
+import com.fsck.k9.local.LocalFolder;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.Searchfield;
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 076ee4fa6..d9f489052 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -89,6 +89,7 @@ import com.fsck.k9.crypto.PgpData;
import com.fsck.k9.fragment.ProgressDialogFragment;
import com.fsck.k9.helper.ContactItem;
import com.fsck.k9.helper.Contacts;
+import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.internet.HtmlConverter;
import com.fsck.k9.helper.IdentityHelper;
import com.fsck.k9.helper.Utility;
@@ -108,10 +109,10 @@ import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
import com.fsck.k9.mail.internet.TextBodyBuilder;
-import com.fsck.k9.mail.store.local.LocalAttachmentBody;
-import com.fsck.k9.mail.store.local.LocalMessage;
-import com.fsck.k9.mail.store.local.TempFileBody;
-import com.fsck.k9.mail.store.local.TempFileMessageBody;
+import com.fsck.k9.local.LocalAttachmentBody;
+import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.local.TempFileBody;
+import com.fsck.k9.local.TempFileMessageBody;
import com.fsck.k9.view.MessageWebView;
import org.apache.james.mime4j.codec.EncoderUtil;
@@ -1655,7 +1656,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
// First item is the body length. We use this to separate the composed reply from the quoted text.
if (tokenizer.hasMoreTokens()) {
- String bodyLengthS = Utility.base64Decode(tokenizer.nextToken());
+ String bodyLengthS = Base64.decode(tokenizer.nextToken());
try {
identity.put(IdentityField.LENGTH, Integer.valueOf(bodyLengthS).toString());
} catch (Exception e) {
@@ -1663,16 +1664,16 @@ public class MessageCompose extends K9Activity implements OnClickListener,
}
}
if (tokenizer.hasMoreTokens()) {
- identity.put(IdentityField.SIGNATURE, Utility.base64Decode(tokenizer.nextToken()));
+ identity.put(IdentityField.SIGNATURE, Base64.decode(tokenizer.nextToken()));
}
if (tokenizer.hasMoreTokens()) {
- identity.put(IdentityField.NAME, Utility.base64Decode(tokenizer.nextToken()));
+ identity.put(IdentityField.NAME, Base64.decode(tokenizer.nextToken()));
}
if (tokenizer.hasMoreTokens()) {
- identity.put(IdentityField.EMAIL, Utility.base64Decode(tokenizer.nextToken()));
+ identity.put(IdentityField.EMAIL, Base64.decode(tokenizer.nextToken()));
}
if (tokenizer.hasMoreTokens()) {
- identity.put(IdentityField.QUOTED_TEXT_MODE, Utility.base64Decode(tokenizer.nextToken()));
+ identity.put(IdentityField.QUOTED_TEXT_MODE, Base64.decode(tokenizer.nextToken()));
}
}
diff --git a/src/com/fsck/k9/activity/MessageInfoHolder.java b/src/com/fsck/k9/activity/MessageInfoHolder.java
index e217a0f78..379543525 100644
--- a/src/com/fsck/k9/activity/MessageInfoHolder.java
+++ b/src/com/fsck/k9/activity/MessageInfoHolder.java
@@ -1,8 +1,8 @@
package com.fsck.k9.activity;
import java.util.Date;
-import com.fsck.k9.mail.Message;
-import com.fsck.k9.mail.store.local.LocalMessage;
+
+import com.fsck.k9.local.LocalMessage;
public class MessageInfoHolder {
public String date;
diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index 604c1a166..ebfb3ef3b 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -42,8 +42,8 @@ import com.fsck.k9.fragment.MessageListFragment;
import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener;
import com.fsck.k9.fragment.MessageViewFragment;
import com.fsck.k9.fragment.MessageViewFragment.MessageViewFragmentListener;
-import com.fsck.k9.mail.store.StorageManager;
-import com.fsck.k9.mail.store.local.LocalMessage;
+import com.fsck.k9.local.StorageManager;
+import com.fsck.k9.local.LocalMessage;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchAccount;
import com.fsck.k9.search.SearchSpecification;
diff --git a/src/com/fsck/k9/activity/MessageReference.java b/src/com/fsck/k9/activity/MessageReference.java
index bb2d6264d..0ba73a0c2 100644
--- a/src/com/fsck/k9/activity/MessageReference.java
+++ b/src/com/fsck/k9/activity/MessageReference.java
@@ -8,13 +8,11 @@ import android.util.Log;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
-import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Flag;
-import com.fsck.k9.mail.Folder;
-import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.local.LocalMessage;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mail.filter.Base64;
import java.util.StringTokenizer;
@@ -51,9 +49,9 @@ public class MessageReference implements Parcelable {
// Split the identity, stripping away the first two characters representing the version and delimiter.
StringTokenizer tokens = new StringTokenizer(identity.substring(2), IDENTITY_SEPARATOR, false);
if (tokens.countTokens() >= 3) {
- accountUuid = Utility.base64Decode(tokens.nextToken());
- folderName = Utility.base64Decode(tokens.nextToken());
- uid = Utility.base64Decode(tokens.nextToken());
+ accountUuid = Base64.decode(tokens.nextToken());
+ folderName = Base64.decode(tokens.nextToken());
+ uid = Base64.decode(tokens.nextToken());
if (tokens.hasMoreTokens()) {
final String flagString = tokens.nextToken();
@@ -82,11 +80,11 @@ public class MessageReference implements Parcelable {
refString.append(IDENTITY_VERSION_1);
refString.append(IDENTITY_SEPARATOR);
- refString.append(Utility.base64Encode(accountUuid));
+ refString.append(Base64.encode(accountUuid));
refString.append(IDENTITY_SEPARATOR);
- refString.append(Utility.base64Encode(folderName));
+ refString.append(Base64.encode(folderName));
refString.append(IDENTITY_SEPARATOR);
- refString.append(Utility.base64Encode(uid));
+ refString.append(Base64.encode(uid));
if (flag != null) {
refString.append(IDENTITY_SEPARATOR);
refString.append(flag.name());
diff --git a/src/com/fsck/k9/activity/UpgradeDatabases.java b/src/com/fsck/k9/activity/UpgradeDatabases.java
index b0cf3587a..f5b2b9754 100644
--- a/src/com/fsck/k9/activity/UpgradeDatabases.java
+++ b/src/com/fsck/k9/activity/UpgradeDatabases.java
@@ -30,7 +30,7 @@ import android.widget.TextView;
* {@link #actionUpgradeDatabases(Context, Intent)} will call {@link K9#areDatabasesUpToDate()}
* to check if we already know whether the databases have been upgraded.
* {@link K9#areDatabasesUpToDate()} will compare the last known database version stored in a
- * {@link SharedPreferences} file to {@link com.fsck.k9.mail.store.local.LocalStore#DB_VERSION}. This
+ * {@link SharedPreferences} file to {@link com.fsck.k9.local.LocalStore#DB_VERSION}. This
* is done as an optimization because it's faster than opening all of the accounts' databases
* one by one.
* If there was an error reading the cached database version or if it shows the databases need
diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java
index ba4a82658..2eac23514 100644
--- a/src/com/fsck/k9/activity/setup/AccountSettings.java
+++ b/src/com/fsck/k9/activity/setup/AccountSettings.java
@@ -36,8 +36,8 @@ import com.fsck.k9.activity.K9PreferenceActivity;
import com.fsck.k9.activity.ManageIdentities;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Store;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.StorageManager;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.StorageManager;
import com.fsck.k9.service.MailService;
import org.openintents.openpgp.util.OpenPgpListPreference;
diff --git a/src/com/fsck/k9/activity/setup/FolderSettings.java b/src/com/fsck/k9/activity/setup/FolderSettings.java
index 31bb8e95c..af9ab8b67 100644
--- a/src/com/fsck/k9/activity/setup/FolderSettings.java
+++ b/src/com/fsck/k9/activity/setup/FolderSettings.java
@@ -16,8 +16,8 @@ import com.fsck.k9.mail.Folder.FolderClass;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Store;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.service.MailService;
public class FolderSettings extends K9PreferenceActivity {
diff --git a/src/com/fsck/k9/cache/EmailProviderCache.java b/src/com/fsck/k9/cache/EmailProviderCache.java
index ccd712d12..a37f66acd 100644
--- a/src/com/fsck/k9/cache/EmailProviderCache.java
+++ b/src/com/fsck/k9/cache/EmailProviderCache.java
@@ -11,8 +11,8 @@ import android.support.v4.content.LocalBroadcastManager;
import com.fsck.k9.fragment.MessageListFragment;
import com.fsck.k9.mail.Message;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.local.LocalMessage;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.LocalMessage;
import com.fsck.k9.provider.EmailProvider;
/**
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index d52c24183..a955c9199 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -81,15 +81,14 @@ import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
-import com.fsck.k9.mail.store.local.MessageRemovalListener;
-import com.fsck.k9.mail.store.local.MessageRetrievalListener;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.local.LocalMessage;
-import com.fsck.k9.mail.store.local.LocalStore;
-import com.fsck.k9.mail.store.local.LocalStore.PendingCommand;
+import com.fsck.k9.local.MessageRemovalListener;
+import com.fsck.k9.mail.MessageRetrievalListener;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.local.LocalStore.PendingCommand;
import com.fsck.k9.mail.store.Pop3Store;
-import com.fsck.k9.mail.store.UnavailableAccountException;
-import com.fsck.k9.mail.store.UnavailableStorageException;
+import com.fsck.k9.local.UnavailableStorageException;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.StatsColumns;
import com.fsck.k9.search.ConditionsTreeNode;
diff --git a/src/com/fsck/k9/controller/MessagingControllerPushReceiver.java b/src/com/fsck/k9/controller/MessagingControllerPushReceiver.java
index ccd13a59f..d99f5feb1 100644
--- a/src/com/fsck/k9/controller/MessagingControllerPushReceiver.java
+++ b/src/com/fsck/k9/controller/MessagingControllerPushReceiver.java
@@ -11,8 +11,8 @@ import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.PushReceiver;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.service.SleepService;
import java.util.List;
diff --git a/src/com/fsck/k9/controller/MessagingListener.java b/src/com/fsck/k9/controller/MessagingListener.java
index 470cc6387..a0396b535 100644
--- a/src/com/fsck/k9/controller/MessagingListener.java
+++ b/src/com/fsck/k9/controller/MessagingListener.java
@@ -11,7 +11,7 @@ import com.fsck.k9.BaseAccount;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Part;
-import com.fsck.k9.mail.store.local.LocalMessage;
+import com.fsck.k9.local.LocalMessage;
/**
* Defines the interface that {@link MessagingController} will use to callback to requesters.
diff --git a/src/com/fsck/k9/mail/store/UnavailableAccountException.java b/src/com/fsck/k9/controller/UnavailableAccountException.java
similarity index 83%
rename from src/com/fsck/k9/mail/store/UnavailableAccountException.java
rename to src/com/fsck/k9/controller/UnavailableAccountException.java
index 26e66b1be..55533828e 100644
--- a/src/com/fsck/k9/mail/store/UnavailableAccountException.java
+++ b/src/com/fsck/k9/controller/UnavailableAccountException.java
@@ -1,10 +1,8 @@
-package com.fsck.k9.mail.store;
-
-import com.fsck.k9.Account;
+package com.fsck.k9.controller;
/**
- * An {@link Account} is not
- * {@link Account#isAvailable(android.content.Context)}.
+ * An {@link com.fsck.k9.Account} is not
+ * {@link com.fsck.k9.Account#isAvailable(android.content.Context)}.
* The operation may be retried later.
*/
public class UnavailableAccountException extends RuntimeException {
diff --git a/src/com/fsck/k9/fragment/MessageListFragment.java b/src/com/fsck/k9/fragment/MessageListFragment.java
index fa70da72c..dae7ec49d 100644
--- a/src/com/fsck/k9/fragment/MessageListFragment.java
+++ b/src/com/fsck/k9/fragment/MessageListFragment.java
@@ -88,9 +88,9 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.local.LocalMessage;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.MessageColumns;
import com.fsck.k9.provider.EmailProvider.SpecialColumns;
diff --git a/src/com/fsck/k9/fragment/MessageViewFragment.java b/src/com/fsck/k9/fragment/MessageViewFragment.java
index 5945957e3..5ffee961a 100644
--- a/src/com/fsck/k9/fragment/MessageViewFragment.java
+++ b/src/com/fsck/k9/fragment/MessageViewFragment.java
@@ -38,7 +38,7 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
-import com.fsck.k9.mail.store.local.LocalMessage;
+import com.fsck.k9.local.LocalMessage;
import com.fsck.k9.view.AttachmentView;
import com.fsck.k9.view.AttachmentView.AttachmentFileDownloadCallback;
import com.fsck.k9.view.MessageHeader;
diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java
index 5df0161b8..4cde05621 100644
--- a/src/com/fsck/k9/helper/MessageHelper.java
+++ b/src/com/fsck/k9/helper/MessageHelper.java
@@ -11,10 +11,9 @@ import com.fsck.k9.activity.FolderInfoHolder;
import com.fsck.k9.activity.MessageInfoHolder;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Flag;
-import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Message.RecipientType;
-import com.fsck.k9.mail.store.local.LocalMessage;
+import com.fsck.k9.local.LocalMessage;
public class MessageHelper {
diff --git a/src/com/fsck/k9/helper/Regex.java b/src/com/fsck/k9/helper/Regex.java
deleted file mode 100644
index dd60134a0..000000000
--- a/src/com/fsck/k9/helper/Regex.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Imported from AOSP on 2011-01-12 by JRV.
- * Domain patterns updated from IANA on 2010-01-12
- *
- *
- */
-
-package com.fsck.k9.helper;
-
-import java.util.regex.Pattern;
-
-/**
- * Commonly used regular expression patterns.
- */
-public class Regex {
-
- /**
- * Goegular expression to match all IANA top-level domains for WEB_URL.
- * List accurate as of 2011/01/12. List taken from:
- * http://data.iana.org/TLD/tlds-alpha-by-domain.txt
- * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
- */
- public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
- "(?:"
- + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
- + "|(?:biz|b[abdefghijmnorstvwyz])"
- + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
- + "|d[ejkmoz]"
- + "|(?:edu|e[cegrstu])"
- + "|f[ijkmor]"
- + "|(?:gov|g[abdefghilmnpqrstuwy])"
- + "|h[kmnrtu]"
- + "|(?:info|int|i[delmnoqrst])"
- + "|(?:jobs|j[emop])"
- + "|k[eghimnprwyz]"
- + "|l[abcikrstuvy]"
- + "|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])"
- + "|(?:name|net|n[acefgilopruz])"
- + "|(?:org|om)"
- + "|(?:pro|p[aefghklmnrstwy])"
- + "|qa"
- + "|r[eosuw]"
- + "|s[abcdeghijklmnortuvyz]"
- + "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
- + "|u[agksyz]"
- + "|v[aceginu]"
- + "|w[fs]"
- + "|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah)"
- + "|y[et]"
- + "|z[amw]))";
-
- /* This comprises most common used Unicode characters allowed in IRI
- * as detailed in RFC 3987.
- * Specifically, those two byte Unicode characters are not included.
- */
- public static final String GOOD_IRI_CHAR =
- "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
-
- /**
- * Regular expression pattern to match most part of RFC 3987
- * Internationalized URLs, aka IRIs. Commonly used Unicode characters are
- * added.
- */
- public static final Pattern WEB_URL_PATTERN = Pattern.compile(
- "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
- + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
- + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
- + "((?:(?:[" + GOOD_IRI_CHAR + "][" + GOOD_IRI_CHAR + "\\-]{0,64}\\.)+" // named host
- + TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL
- + "|(?:(?:25[0-5]|2[0-4]" // or ip address
- + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
- + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
- + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
- + "|[1-9][0-9]|[0-9])))"
- + "(?:\\:\\d{1,5})?)" // plus option port number
- + "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
- + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
- + "(?:\\b|$)"); // and finally, a word boundary or end of
- // input. This is to stop foo.sure from
- // matching as foo.su
-
- public static final Pattern EMAIL_ADDRESS_PATTERN
- = Pattern.compile(
- "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
- "\\@" +
- "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
- "(" +
- "\\." +
- "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
- ")+"
- );
-
- public static final String BITCOIN_URI_PATTERN =
- "bitcoin:[1-9a-km-zA-HJ-NP-Z]{27,34}(\\?[a-zA-Z0-9$\\-_.+!*'(),%:@&=]*)?";
-}
diff --git a/src/com/fsck/k9/helper/Utility.java b/src/com/fsck/k9/helper/Utility.java
index 50ca99e3a..ffd6270a2 100644
--- a/src/com/fsck/k9/helper/Utility.java
+++ b/src/com/fsck/k9/helper/Utility.java
@@ -15,7 +15,6 @@ import android.widget.EditText;
import android.widget.TextView;
import com.fsck.k9.K9;
-import com.fsck.k9.mail.filter.Base64;
import java.nio.charset.Charset;
import java.util.ArrayList;
@@ -91,22 +90,6 @@ public class Utility {
return TextUtils.join(String.valueOf(separator), parts);
}
- public static String base64Decode(String encoded) {
- if (encoded == null) {
- return null;
- }
- byte[] decoded = new Base64().decode(encoded.getBytes());
- return new String(decoded);
- }
-
- public static String base64Encode(String s) {
- if (s == null) {
- return s;
- }
- byte[] encoded = new Base64().encode(s.getBytes());
- return new String(encoded);
- }
-
public static boolean requiredFieldValid(TextView view) {
return view.getText() != null && view.getText().length() > 0;
}
@@ -130,48 +113,6 @@ public class Utility {
return false;
}
- private static final Pattern ATOM = Pattern.compile("^(?:[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~]|\\s)+$");
-
- /**
- * Quote a string, if necessary, based upon the definition of an "atom," as defined by RFC2822
- * (http://tools.ietf.org/html/rfc2822#section-3.2.4). Strings that consist purely of atoms are
- * left unquoted; anything else is returned as a quoted string.
- * @param text String to quote.
- * @return Possibly quoted string.
- */
- public static String quoteAtoms(final String text) {
- if (ATOM.matcher(text).matches()) {
- return text;
- } else {
- return quoteString(text);
- }
- }
-
- /**
- * Ensures that the given string starts and ends with the double quote character. The string is not modified in any way except to add the
- * double quote character to start and end if it's not already there.
- * sample -> "sample"
- * "sample" -> "sample"
- * ""sample"" -> "sample"
- * "sample"" -> "sample"
- * sa"mp"le -> "sa"mp"le"
- * "sa"mp"le" -> "sa"mp"le"
- * (empty string) -> ""
- * " -> ""
- * @param s
- * @return
- */
- public static String quoteString(String s) {
- if (s == null) {
- return null;
- }
- if (!s.matches("^\".*\"$")) {
- return "\"" + s + "\"";
- } else {
- return s;
- }
- }
-
/**
* A fast version of URLDecoder.decode() that works only with UTF-8 and does only two
* allocations. This version is around 3x as fast as the standard one and I'm using it
diff --git a/src/com/fsck/k9/mail/store/local/AttachmentMessageBodyUtil.java b/src/com/fsck/k9/local/AttachmentMessageBodyUtil.java
similarity index 96%
rename from src/com/fsck/k9/mail/store/local/AttachmentMessageBodyUtil.java
rename to src/com/fsck/k9/local/AttachmentMessageBodyUtil.java
index a1f4d5b3b..97a8a2394 100644
--- a/src/com/fsck/k9/mail/store/local/AttachmentMessageBodyUtil.java
+++ b/src/com/fsck/k9/local/AttachmentMessageBodyUtil.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.IOException;
import java.io.InputStream;
diff --git a/src/com/fsck/k9/mail/store/local/BinaryAttachmentBody.java b/src/com/fsck/k9/local/BinaryAttachmentBody.java
similarity index 97%
rename from src/com/fsck/k9/mail/store/local/BinaryAttachmentBody.java
rename to src/com/fsck/k9/local/BinaryAttachmentBody.java
index 8efcf8992..466f6e57f 100644
--- a/src/com/fsck/k9/mail/store/local/BinaryAttachmentBody.java
+++ b/src/com/fsck/k9/local/BinaryAttachmentBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.IOException;
import java.io.InputStream;
diff --git a/src/com/fsck/k9/mail/store/local/LocalAttachmentBody.java b/src/com/fsck/k9/local/LocalAttachmentBody.java
similarity index 96%
rename from src/com/fsck/k9/mail/store/local/LocalAttachmentBody.java
rename to src/com/fsck/k9/local/LocalAttachmentBody.java
index 7efdf949c..acfbe7980 100644
--- a/src/com/fsck/k9/mail/store/local/LocalAttachmentBody.java
+++ b/src/com/fsck/k9/local/LocalAttachmentBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
diff --git a/src/com/fsck/k9/mail/store/local/LocalAttachmentBodyPart.java b/src/com/fsck/k9/local/LocalAttachmentBodyPart.java
similarity index 95%
rename from src/com/fsck/k9/mail/store/local/LocalAttachmentBodyPart.java
rename to src/com/fsck/k9/local/LocalAttachmentBodyPart.java
index e72d3b493..7d5a19798 100644
--- a/src/com/fsck/k9/mail/store/local/LocalAttachmentBodyPart.java
+++ b/src/com/fsck/k9/local/LocalAttachmentBodyPart.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.MessagingException;
diff --git a/src/com/fsck/k9/mail/store/local/LocalAttachmentMessageBody.java b/src/com/fsck/k9/local/LocalAttachmentMessageBody.java
similarity index 97%
rename from src/com/fsck/k9/mail/store/local/LocalAttachmentMessageBody.java
rename to src/com/fsck/k9/local/LocalAttachmentMessageBody.java
index d953bfc73..6dc632495 100644
--- a/src/com/fsck/k9/mail/store/local/LocalAttachmentMessageBody.java
+++ b/src/com/fsck/k9/local/LocalAttachmentMessageBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/src/com/fsck/k9/mail/store/local/LocalFolder.java b/src/com/fsck/k9/local/LocalFolder.java
similarity index 99%
rename from src/com/fsck/k9/mail/store/local/LocalFolder.java
rename to src/com/fsck/k9/local/LocalFolder.java
index e68d7d684..33e177f9a 100644
--- a/src/com/fsck/k9/mail/store/local/LocalFolder.java
+++ b/src/com/fsck/k9/local/LocalFolder.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.File;
import java.io.FileOutputStream;
@@ -32,6 +32,7 @@ import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Account.MessageFormat;
import com.fsck.k9.activity.Search;
+import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.internet.HtmlConverter;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
@@ -51,10 +52,8 @@ import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
import com.fsck.k9.mail.internet.MimeUtility.ViewableContainer;
-import com.fsck.k9.mail.store.StorageManager;
-import com.fsck.k9.mail.store.UnavailableStorageException;
-import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
-import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
+import com.fsck.k9.local.LockableDatabase.DbCallback;
+import com.fsck.k9.local.LockableDatabase.WrappedException;
import com.fsck.k9.provider.AttachmentProvider;
public class LocalFolder extends Folder implements Serializable {
@@ -828,10 +827,10 @@ public class LocalFolder extends Folder implements Serializable {
* The messages whose headers should be loaded.
* @throws UnavailableStorageException
*/
- void populateHeaders(final List messages) throws UnavailableStorageException {
+ void populateHeaders(final List messages) throws MessagingException {
this.localStore.database.execute(false, new DbCallback() {
@Override
- public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
+ public Void doDbWork(final SQLiteDatabase db) throws WrappedException, MessagingException {
Cursor cursor = null;
if (messages.isEmpty()) {
return null;
@@ -1488,7 +1487,7 @@ public class LocalFolder extends Folder implements Serializable {
private void saveHeaders(final long id, final MimeMessage message) throws MessagingException {
this.localStore.database.execute(true, new DbCallback() {
@Override
- public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
+ public Void doDbWork(final SQLiteDatabase db) throws WrappedException, MessagingException {
deleteHeaders(id);
for (String name : message.getHeaderNames()) {
@@ -1517,7 +1516,7 @@ public class LocalFolder extends Folder implements Serializable {
});
}
- void deleteHeaders(final long id) throws UnavailableStorageException {
+ void deleteHeaders(final long id) throws MessagingException {
this.localStore.database.execute(false, new DbCallback() {
@Override
public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
diff --git a/src/com/fsck/k9/mail/store/local/LocalMessage.java b/src/com/fsck/k9/local/LocalMessage.java
similarity index 96%
rename from src/com/fsck/k9/mail/store/local/LocalMessage.java
rename to src/com/fsck/k9/local/LocalMessage.java
index 7391a8646..ac3aa5918 100644
--- a/src/com/fsck/k9/mail/store/local/LocalMessage.java
+++ b/src/com/fsck/k9/local/LocalMessage.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.IOException;
import java.io.OutputStream;
@@ -22,9 +22,8 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeUtility;
-import com.fsck.k9.mail.store.UnavailableStorageException;
-import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
-import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
+import com.fsck.k9.local.LockableDatabase.DbCallback;
+import com.fsck.k9.local.LockableDatabase.WrappedException;
public class LocalMessage extends MimeMessage {
protected MessageReference mReference;
@@ -499,44 +498,44 @@ public class LocalMessage extends MimeMessage {
db.delete("threads", "message_id = ?", idArg);
}
- private void loadHeaders() throws UnavailableStorageException {
+ private void loadHeaders() throws MessagingException {
List messages = new ArrayList();
messages.add(this);
mHeadersLoaded = true; // set true before calling populate headers to stop recursion
- ((LocalFolder) mFolder).populateHeaders(messages);
+ getFolder().populateHeaders(messages);
}
@Override
- public void addHeader(String name, String value) throws UnavailableStorageException {
+ public void addHeader(String name, String value) throws MessagingException {
if (!mHeadersLoaded)
loadHeaders();
super.addHeader(name, value);
}
@Override
- public void setHeader(String name, String value) throws UnavailableStorageException {
+ public void setHeader(String name, String value) throws MessagingException {
if (!mHeadersLoaded)
loadHeaders();
super.setHeader(name, value);
}
@Override
- public String[] getHeader(String name) throws UnavailableStorageException {
+ public String[] getHeader(String name) throws MessagingException {
if (!mHeadersLoaded)
loadHeaders();
return super.getHeader(name);
}
@Override
- public void removeHeader(String name) throws UnavailableStorageException {
+ public void removeHeader(String name) throws MessagingException {
if (!mHeadersLoaded)
loadHeaders();
super.removeHeader(name);
}
@Override
- public Set getHeaderNames() throws UnavailableStorageException {
+ public Set getHeaderNames() throws MessagingException {
if (!mHeadersLoaded)
loadHeaders();
return super.getHeaderNames();
diff --git a/src/com/fsck/k9/mail/store/local/LocalStore.java b/src/com/fsck/k9/local/LocalStore.java
similarity index 98%
rename from src/com/fsck/k9/mail/store/local/LocalStore.java
rename to src/com/fsck/k9/local/LocalStore.java
index 64bacb2ef..a7ec36f51 100644
--- a/src/com/fsck/k9/mail/store/local/LocalStore.java
+++ b/src/com/fsck/k9/local/LocalStore.java
@@ -1,5 +1,5 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import android.app.Application;
import android.content.ContentResolver;
@@ -18,15 +18,14 @@ import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
+import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.store.RemoteStore;
-import com.fsck.k9.mail.store.StorageManager;
-import com.fsck.k9.mail.store.StorageManager.StorageProvider;
+import com.fsck.k9.local.StorageManager.StorageProvider;
import com.fsck.k9.mail.store.StoreConfig;
-import com.fsck.k9.mail.store.UnavailableStorageException;
-import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
-import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
+import com.fsck.k9.local.LockableDatabase.DbCallback;
+import com.fsck.k9.local.LockableDatabase.WrappedException;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.MessageColumns;
import com.fsck.k9.search.LocalSearch;
@@ -244,7 +243,7 @@ public class LocalStore extends Store implements Serializable {
return Preferences.getPreferences(mApplication).getPreferences();
}
- public long getSize() throws UnavailableStorageException {
+ public long getSize() throws MessagingException {
final StorageManager storageManager = StorageManager.getInstance(mApplication);
@@ -487,7 +486,7 @@ public class LocalStore extends Store implements Serializable {
});
}
- public void resetVisibleLimits(int visibleLimit) throws UnavailableStorageException {
+ public void resetVisibleLimits(int visibleLimit) throws MessagingException {
final ContentValues cv = new ContentValues();
cv.put("visible_limit", Integer.toString(visibleLimit));
database.execute(false, new DbCallback() {
@@ -499,7 +498,7 @@ public class LocalStore extends Store implements Serializable {
});
}
- public List getPendingCommands() throws UnavailableStorageException {
+ public List getPendingCommands() throws MessagingException {
return database.execute(false, new DbCallback>() {
@Override
public List doDbWork(final SQLiteDatabase db) throws WrappedException {
@@ -532,7 +531,7 @@ public class LocalStore extends Store implements Serializable {
});
}
- public void addPendingCommand(PendingCommand command) throws UnavailableStorageException {
+ public void addPendingCommand(PendingCommand command) throws MessagingException {
for (int i = 0; i < command.arguments.length; i++) {
command.arguments[i] = UrlEncodingHelper.encodeUtf8(command.arguments[i]);
}
@@ -548,7 +547,7 @@ public class LocalStore extends Store implements Serializable {
});
}
- public void removePendingCommand(final PendingCommand command) throws UnavailableStorageException {
+ public void removePendingCommand(final PendingCommand command) throws MessagingException {
database.execute(false, new DbCallback() {
@Override
public Void doDbWork(final SQLiteDatabase db) throws WrappedException {
@@ -558,7 +557,7 @@ public class LocalStore extends Store implements Serializable {
});
}
- public void removePendingCommands() throws UnavailableStorageException {
+ public void removePendingCommands() throws MessagingException {
database.execute(false, new DbCallback() {
@Override
public Void doDbWork(final SQLiteDatabase db) throws WrappedException {
@@ -690,7 +689,7 @@ public class LocalStore extends Store implements Serializable {
return searchForMessages(null, search);
}
- public AttachmentInfo getAttachmentInfo(final String attachmentId) throws UnavailableStorageException {
+ public AttachmentInfo getAttachmentInfo(final String attachmentId) throws MessagingException {
return database.execute(false, new DbCallback() {
@Override
public AttachmentInfo doDbWork(final SQLiteDatabase db) throws WrappedException {
@@ -731,7 +730,7 @@ public class LocalStore extends Store implements Serializable {
public String type;
}
- public void createFolders(final List foldersToCreate, final int visibleLimit) throws UnavailableStorageException {
+ public void createFolders(final List foldersToCreate, final int visibleLimit) throws MessagingException {
database.execute(true, new DbCallback() {
@Override
public Void doDbWork(final SQLiteDatabase db) throws WrappedException {
diff --git a/src/com/fsck/k9/mail/store/local/LocalTextBody.java b/src/com/fsck/k9/local/LocalTextBody.java
similarity index 92%
rename from src/com/fsck/k9/mail/store/local/LocalTextBody.java
rename to src/com/fsck/k9/local/LocalTextBody.java
index 3d83c6eb9..b40d79b8e 100644
--- a/src/com/fsck/k9/mail/store/local/LocalTextBody.java
+++ b/src/com/fsck/k9/local/LocalTextBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import com.fsck.k9.mail.internet.TextBody;
diff --git a/src/com/fsck/k9/mail/store/local/LockableDatabase.java b/src/com/fsck/k9/local/LockableDatabase.java
similarity index 97%
rename from src/com/fsck/k9/mail/store/local/LockableDatabase.java
rename to src/com/fsck/k9/local/LockableDatabase.java
index 57cae16ef..62f013953 100644
--- a/src/com/fsck/k9/mail/store/local/LockableDatabase.java
+++ b/src/com/fsck/k9/local/LockableDatabase.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.File;
import java.util.concurrent.locks.Lock;
@@ -16,8 +16,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.helper.FileHelper;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.mail.store.StorageManager;
-import com.fsck.k9.mail.store.UnavailableStorageException;
public class LockableDatabase {
@@ -35,9 +33,10 @@ public class LockableDatabase {
* null
.
* @return Any relevant data. Can be null
.
* @throws WrappedException
- * @throws com.fsck.k9.mail.store.UnavailableStorageException
+ * @throws com.fsck.k9.mail.MessagingException
+ * @throws com.fsck.k9.local.UnavailableStorageException
*/
- T doDbWork(SQLiteDatabase db) throws WrappedException, UnavailableStorageException;
+ T doDbWork(SQLiteDatabase db) throws WrappedException, MessagingException;
}
public static interface SchemaDefinition {
@@ -272,7 +271,7 @@ public class LockableDatabase {
* @return Whatever {@link DbCallback#doDbWork(SQLiteDatabase)} returns.
* @throws UnavailableStorageException
*/
- public T execute(final boolean transactional, final DbCallback callback) throws UnavailableStorageException {
+ public T execute(final boolean transactional, final DbCallback callback) throws MessagingException {
lockRead();
final boolean doTransaction = transactional && inTransaction.get() == null;
try {
diff --git a/src/com/fsck/k9/mail/store/local/MessageRemovalListener.java b/src/com/fsck/k9/local/MessageRemovalListener.java
similarity index 77%
rename from src/com/fsck/k9/mail/store/local/MessageRemovalListener.java
rename to src/com/fsck/k9/local/MessageRemovalListener.java
index 95e35fd22..3f4d47d0e 100644
--- a/src/com/fsck/k9/mail/store/local/MessageRemovalListener.java
+++ b/src/com/fsck/k9/local/MessageRemovalListener.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import com.fsck.k9.mail.Message;
diff --git a/src/com/fsck/k9/mail/store/StorageManager.java b/src/com/fsck/k9/local/StorageManager.java
similarity index 99%
rename from src/com/fsck/k9/mail/store/StorageManager.java
rename to src/com/fsck/k9/local/StorageManager.java
index 68cc216df..20676d720 100644
--- a/src/com/fsck/k9/mail/store/StorageManager.java
+++ b/src/com/fsck/k9/local/StorageManager.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store;
+package com.fsck.k9.local;
import java.io.File;
import java.io.IOException;
diff --git a/src/com/fsck/k9/mail/store/local/StoreSchemaDefinition.java b/src/com/fsck/k9/local/StoreSchemaDefinition.java
similarity index 99%
rename from src/com/fsck/k9/mail/store/local/StoreSchemaDefinition.java
rename to src/com/fsck/k9/local/StoreSchemaDefinition.java
index aec7390fc..c893e5888 100644
--- a/src/com/fsck/k9/mail/store/local/StoreSchemaDefinition.java
+++ b/src/com/fsck/k9/local/StoreSchemaDefinition.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/fsck/k9/mail/store/local/TempFileBody.java b/src/com/fsck/k9/local/TempFileBody.java
similarity index 94%
rename from src/com/fsck/k9/mail/store/local/TempFileBody.java
rename to src/com/fsck/k9/local/TempFileBody.java
index 9b7916b5a..c687d6082 100644
--- a/src/com/fsck/k9/mail/store/local/TempFileBody.java
+++ b/src/com/fsck/k9/local/TempFileBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.ByteArrayInputStream;
import java.io.File;
diff --git a/src/com/fsck/k9/mail/store/local/TempFileMessageBody.java b/src/com/fsck/k9/local/TempFileMessageBody.java
similarity index 96%
rename from src/com/fsck/k9/mail/store/local/TempFileMessageBody.java
rename to src/com/fsck/k9/local/TempFileMessageBody.java
index 5cd5e207b..55f6b76e4 100644
--- a/src/com/fsck/k9/mail/store/local/TempFileMessageBody.java
+++ b/src/com/fsck/k9/local/TempFileMessageBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/src/com/fsck/k9/mail/store/local/ThreadInfo.java b/src/com/fsck/k9/local/ThreadInfo.java
similarity index 92%
rename from src/com/fsck/k9/mail/store/local/ThreadInfo.java
rename to src/com/fsck/k9/local/ThreadInfo.java
index 4115c16d6..cf72dddc1 100644
--- a/src/com/fsck/k9/mail/store/local/ThreadInfo.java
+++ b/src/com/fsck/k9/local/ThreadInfo.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.local;
class ThreadInfo {
public final long threadId;
diff --git a/src/com/fsck/k9/mail/store/UnavailableStorageException.java b/src/com/fsck/k9/local/UnavailableStorageException.java
similarity index 96%
rename from src/com/fsck/k9/mail/store/UnavailableStorageException.java
rename to src/com/fsck/k9/local/UnavailableStorageException.java
index 90974161b..d6e1cd69d 100644
--- a/src/com/fsck/k9/mail/store/UnavailableStorageException.java
+++ b/src/com/fsck/k9/local/UnavailableStorageException.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.store;
+package com.fsck.k9.local;
import com.fsck.k9.mail.MessagingException;
diff --git a/src/com/fsck/k9/mail/Address.java b/src/com/fsck/k9/mail/Address.java
index 25929e94e..9702c1c8d 100644
--- a/src/com/fsck/k9/mail/Address.java
+++ b/src/com/fsck/k9/mail/Address.java
@@ -3,6 +3,7 @@ package com.fsck.k9.mail;
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.codec.EncoderUtil;
@@ -20,7 +21,6 @@ import android.text.util.Rfc822Tokenizer;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.helper.Utility;
public class Address {
@@ -28,6 +28,8 @@ public class Address {
String getNameForAddress(String address);
}
+ private static final Pattern ATOM = Pattern.compile("^(?:[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~]|\\s)+$");
+
/**
* If the number of addresses exceeds this value the addresses aren't
* resolved to the names of Android contacts.
@@ -201,7 +203,7 @@ public class Address {
@Override
public String toString() {
if (!TextUtils.isEmpty(mPersonal)) {
- return Utility.quoteAtoms(mPersonal) + " <" + mAddress + ">";
+ return quoteAtoms(mPersonal) + " <" + mAddress + ">";
} else {
return mAddress;
}
@@ -367,4 +369,44 @@ public class Address {
}
return sb.toString();
}
+
+ /**
+ * Quote a string, if necessary, based upon the definition of an "atom," as defined by RFC2822
+ * (http://tools.ietf.org/html/rfc2822#section-3.2.4). Strings that consist purely of atoms are
+ * left unquoted; anything else is returned as a quoted string.
+ * @param text String to quote.
+ * @return Possibly quoted string.
+ */
+ public static String quoteAtoms(final String text) {
+ if (ATOM.matcher(text).matches()) {
+ return text;
+ } else {
+ return quoteString(text);
+ }
+ }
+
+ /**
+ * Ensures that the given string starts and ends with the double quote character. The string is not modified in any way except to add the
+ * double quote character to start and end if it's not already there.
+ * sample -> "sample"
+ * "sample" -> "sample"
+ * ""sample"" -> "sample"
+ * "sample"" -> "sample"
+ * sa"mp"le -> "sa"mp"le"
+ * "sa"mp"le" -> "sa"mp"le"
+ * (empty string) -> ""
+ * " -> ""
+ * @param s
+ * @return
+ */
+ private static String quoteString(String s) {
+ if (s == null) {
+ return null;
+ }
+ if (!s.matches("^\".*\"$")) {
+ return "\"" + s + "\"";
+ } else {
+ return s;
+ }
+ }
}
diff --git a/src/com/fsck/k9/mail/Body.java b/src/com/fsck/k9/mail/Body.java
index 93960892c..d86746d66 100644
--- a/src/com/fsck/k9/mail/Body.java
+++ b/src/com/fsck/k9/mail/Body.java
@@ -5,8 +5,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import com.fsck.k9.mail.store.UnavailableStorageException;
-
public interface Body {
/**
* Returns the raw data of the body, without transfer encoding etc applied.
@@ -18,7 +16,7 @@ public interface Body {
/**
* Sets the content transfer encoding (7bit, 8bit, quoted-printable or base64).
*/
- public void setEncoding(String encoding) throws UnavailableStorageException, MessagingException;
+ public void setEncoding(String encoding) throws MessagingException;
/**
* Writes the body's data to the given {@link OutputStream}.
diff --git a/src/com/fsck/k9/mail/Folder.java b/src/com/fsck/k9/mail/Folder.java
index c4f1a3998..a11e7dd32 100644
--- a/src/com/fsck/k9/mail/Folder.java
+++ b/src/com/fsck/k9/mail/Folder.java
@@ -8,7 +8,6 @@ import java.util.Set;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.mail.store.local.MessageRetrievalListener;
public abstract class Folder {
private String status = null;
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index d97982a4d..b0bfe12af 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -12,7 +12,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.mail.filter.CountingOutputStream;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
-import com.fsck.k9.mail.store.UnavailableStorageException;
public abstract class Message implements Part, CompositeBody {
@@ -117,28 +116,7 @@ public abstract class Message implements Part, CompositeBody {
public abstract void setReferences(String references) throws MessagingException;
- @Override
- public abstract Body getBody();
-
- @Override
- public abstract String getContentType() throws MessagingException;
-
- @Override
- public abstract void addHeader(String name, String value) throws MessagingException;
-
- @Override
- public abstract void setHeader(String name, String value) throws MessagingException;
-
- @Override
- public abstract String[] getHeader(String name) throws MessagingException;
-
- public abstract Set getHeaderNames() throws UnavailableStorageException;
-
- @Override
- public abstract void removeHeader(String name) throws MessagingException;
-
- @Override
- public abstract void setBody(Body body) throws MessagingException;
+ public abstract Set getHeaderNames() throws MessagingException;
public abstract long getId();
@@ -287,6 +265,4 @@ public abstract class Message implements Part, CompositeBody {
*/
@Override
public abstract Message clone();
- @Override
- public abstract void setUsing7bitTransport() throws MessagingException;
}
diff --git a/src/com/fsck/k9/mail/store/local/MessageRetrievalListener.java b/src/com/fsck/k9/mail/MessageRetrievalListener.java
similarity index 85%
rename from src/com/fsck/k9/mail/store/local/MessageRetrievalListener.java
rename to src/com/fsck/k9/mail/MessageRetrievalListener.java
index 12679b4e5..0d6b4fff1 100644
--- a/src/com/fsck/k9/mail/store/local/MessageRetrievalListener.java
+++ b/src/com/fsck/k9/mail/MessageRetrievalListener.java
@@ -1,7 +1,6 @@
-package com.fsck.k9.mail.store.local;
+package com.fsck.k9.mail;
-import com.fsck.k9.mail.Message;
public interface MessageRetrievalListener {
public void messageStarted(String uid, int number, int ofTotal);
diff --git a/src/com/fsck/k9/mail/ServerSettings.java b/src/com/fsck/k9/mail/ServerSettings.java
index 43e16847b..59633ffdd 100644
--- a/src/com/fsck/k9/mail/ServerSettings.java
+++ b/src/com/fsck/k9/mail/ServerSettings.java
@@ -3,7 +3,6 @@ package com.fsck.k9.mail;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import com.fsck.k9.Account;
/**
* This is an abstraction to get rid of the store- and transport-specific URIs.
@@ -13,8 +12,8 @@ import com.fsck.k9.Account;
* store/transport URIs altogether.
*
*
- * @see Account#getStoreUri()
- * @see Account#getTransportUri()
+ * @see com.fsck.k9.mail.store.StoreConfig#getStoreUri()
+ * @see com.fsck.k9.mail.store.StoreConfig#getTransportUri()
*/
public class ServerSettings {
/**
diff --git a/src/com/fsck/k9/mail/Transport.java b/src/com/fsck/k9/mail/Transport.java
index 28011dacd..97e4ada1d 100644
--- a/src/com/fsck/k9/mail/Transport.java
+++ b/src/com/fsck/k9/mail/Transport.java
@@ -1,7 +1,7 @@
package com.fsck.k9.mail;
-import com.fsck.k9.Account;
+import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.transport.SmtpTransport;
import com.fsck.k9.mail.transport.WebDavTransport;
@@ -11,12 +11,12 @@ public abstract class Transport {
// RFC 1047
protected static final int SOCKET_READ_TIMEOUT = 300000;
- public synchronized static Transport getInstance(Account account) throws MessagingException {
- String uri = account.getTransportUri();
+ public synchronized static Transport getInstance(StoreConfig storeConfig) throws MessagingException {
+ String uri = storeConfig.getTransportUri();
if (uri.startsWith("smtp")) {
- return new SmtpTransport(account);
+ return new SmtpTransport(storeConfig);
} else if (uri.startsWith("webdav")) {
- return new WebDavTransport(account);
+ return new WebDavTransport(storeConfig);
} else {
throw new MessagingException("Unable to locate an applicable Transport for " + uri);
}
diff --git a/src/com/fsck/k9/mail/filter/Base64.java b/src/com/fsck/k9/mail/filter/Base64.java
index 934c3b222..9f7cadfa5 100644
--- a/src/com/fsck/k9/mail/filter/Base64.java
+++ b/src/com/fsck/k9/mail/filter/Base64.java
@@ -34,6 +34,22 @@ import java.nio.charset.Charset;
* @version $Id$
*/
public class Base64 {
+ public static String decode(String encoded) {
+ if (encoded == null) {
+ return null;
+ }
+ byte[] decoded = new Base64().decode(encoded.getBytes());
+ return new String(decoded);
+ }
+
+ public static String encode(String s) {
+ if (s == null) {
+ return null;
+ }
+ byte[] encoded = new Base64().encode(s.getBytes());
+ return new String(encoded);
+ }
+
/**
* Chunk size per RFC 2045 section 6.8.
*
diff --git a/src/com/fsck/k9/mail/internet/HtmlConverter.java b/src/com/fsck/k9/mail/internet/HtmlConverter.java
index a217d5b81..8d28085c1 100644
--- a/src/com/fsck/k9/mail/internet/HtmlConverter.java
+++ b/src/com/fsck/k9/mail/internet/HtmlConverter.java
@@ -4,7 +4,6 @@ import android.text.*;
import android.text.Html.TagHandler;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.helper.Regex;
import org.xml.sax.XMLReader;
@@ -15,11 +14,75 @@ import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Contains common routines to convert html to text and vice versa.
*/
public class HtmlConverter {
+ /* This comprises most common used Unicode characters allowed in IRI
+ * as detailed in RFC 3987.
+ * Specifically, those two byte Unicode characters are not included.
+ */
+ private static final String GOOD_IRI_CHAR =
+ "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
+ /**
+ * Goegular expression to match all IANA top-level domains for WEB_URL.
+ * List accurate as of 2011/01/12. List taken from:
+ * http://data.iana.org/TLD/tlds-alpha-by-domain.txt
+ * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
+ */
+ private static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
+ "(?:"
+ + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
+ + "|(?:biz|b[abdefghijmnorstvwyz])"
+ + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
+ + "|d[ejkmoz]"
+ + "|(?:edu|e[cegrstu])"
+ + "|f[ijkmor]"
+ + "|(?:gov|g[abdefghilmnpqrstuwy])"
+ + "|h[kmnrtu]"
+ + "|(?:info|int|i[delmnoqrst])"
+ + "|(?:jobs|j[emop])"
+ + "|k[eghimnprwyz]"
+ + "|l[abcikrstuvy]"
+ + "|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])"
+ + "|(?:name|net|n[acefgilopruz])"
+ + "|(?:org|om)"
+ + "|(?:pro|p[aefghklmnrstwy])"
+ + "|qa"
+ + "|r[eosuw]"
+ + "|s[abcdeghijklmnortuvyz]"
+ + "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
+ + "|u[agksyz]"
+ + "|v[aceginu]"
+ + "|w[fs]"
+ + "|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah)"
+ + "|y[et]"
+ + "|z[amw]))";
+ private static final String BITCOIN_URI_PATTERN =
+ "bitcoin:[1-9a-km-zA-HJ-NP-Z]{27,34}(\\?[a-zA-Z0-9$\\-_.+!*'(),%:@&=]*)?";
+ /**
+ * Regular expression pattern to match most part of RFC 3987
+ * Internationalized URLs, aka IRIs. Commonly used Unicode characters are
+ * added.
+ */
+ private static final Pattern WEB_URL_PATTERN = Pattern.compile(
+ "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ + "((?:(?:[" + GOOD_IRI_CHAR + "][" + GOOD_IRI_CHAR + "\\-]{0,64}\\.)+" // named host
+ + TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL
+ + "|(?:(?:25[0-5]|2[0-4]" // or ip address
+ + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
+ + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
+ + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ + "|[1-9][0-9]|[0-9])))"
+ + "(?:\\:\\d{1,5})?)" // plus option port number
+ + "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
+ + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+ + "(?:\\b|$)"); // and finally, a word boundary or end of
+
/**
* When generating previews, Spannable objects that can't be converted into a String are
* represented as 0xfffc. When displayed, these show up as undisplayed squares. These constants
@@ -383,9 +446,9 @@ public class HtmlConverter {
* @param outputBuffer Buffer to append linked text to.
*/
protected static void linkifyText(final String text, final StringBuffer outputBuffer) {
- String prepared = text.replaceAll(Regex.BITCOIN_URI_PATTERN, "$0");
+ String prepared = text.replaceAll(BITCOIN_URI_PATTERN, "$0");
- Matcher m = Regex.WEB_URL_PATTERN.matcher(prepared);
+ Matcher m = WEB_URL_PATTERN.matcher(prepared);
while (m.find()) {
int start = m.start();
if (start == 0 || (start != 0 && prepared.charAt(start - 1) != '@')) {
diff --git a/src/com/fsck/k9/mail/internet/MimeHeader.java b/src/com/fsck/k9/mail/internet/MimeHeader.java
index 12bd5fd31..7c9569df0 100644
--- a/src/com/fsck/k9/mail/internet/MimeHeader.java
+++ b/src/com/fsck/k9/mail/internet/MimeHeader.java
@@ -1,8 +1,6 @@
package com.fsck.k9.mail.internet;
-import com.fsck.k9.helper.Utility;
-
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
@@ -97,7 +95,7 @@ public class MimeHeader {
public void writeTo(OutputStream out) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
for (Field field : mFields) {
- if (!Utility.arrayContains(writeOmitFields, field.name)) {
+ if (!Arrays.asList(writeOmitFields).contains(field.name)) {
String v = field.value;
if (hasToBeEncoded(v)) {
diff --git a/src/com/fsck/k9/mail/internet/MimeMessage.java b/src/com/fsck/k9/mail/internet/MimeMessage.java
index 0d7bb8bab..02c028edf 100644
--- a/src/com/fsck/k9/mail/internet/MimeMessage.java
+++ b/src/com/fsck/k9/mail/internet/MimeMessage.java
@@ -33,7 +33,6 @@ import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Multipart;
import com.fsck.k9.mail.Part;
-import com.fsck.k9.mail.store.UnavailableStorageException;
import com.fsck.k9.K9;
/**
@@ -333,7 +332,7 @@ public class MimeMessage extends Message {
return "<" + UUID.randomUUID().toString().toUpperCase(Locale.US) + "@" + hostname + ">";
}
- public void setMessageId(String messageId) throws UnavailableStorageException {
+ public void setMessageId(String messageId) throws MessagingException {
setHeader("Message-ID", messageId);
mMessageId = messageId;
}
@@ -419,27 +418,27 @@ public class MimeMessage extends Message {
}
@Override
- public void addHeader(String name, String value) throws UnavailableStorageException {
+ public void addHeader(String name, String value) throws MessagingException {
mHeader.addHeader(name, value);
}
@Override
- public void setHeader(String name, String value) throws UnavailableStorageException {
+ public void setHeader(String name, String value) throws MessagingException {
mHeader.setHeader(name, value);
}
@Override
- public String[] getHeader(String name) throws UnavailableStorageException {
+ public String[] getHeader(String name) throws MessagingException {
return mHeader.getHeader(name);
}
@Override
- public void removeHeader(String name) throws UnavailableStorageException {
+ public void removeHeader(String name) throws MessagingException {
mHeader.removeHeader(name);
}
@Override
- public Set getHeaderNames() throws UnavailableStorageException {
+ public Set getHeaderNames() throws MessagingException {
return mHeader.getHeaderNames();
}
diff --git a/src/com/fsck/k9/security/LocalKeyStore.java b/src/com/fsck/k9/mail/ssl/LocalKeyStore.java
similarity index 99%
rename from src/com/fsck/k9/security/LocalKeyStore.java
rename to src/com/fsck/k9/mail/ssl/LocalKeyStore.java
index d432ab294..7133be7b0 100644
--- a/src/com/fsck/k9/security/LocalKeyStore.java
+++ b/src/com/fsck/k9/mail/ssl/LocalKeyStore.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.security;
+package com.fsck.k9.mail.ssl;
import java.io.File;
import java.io.FileInputStream;
diff --git a/src/com/fsck/k9/mail/ssl/TrustManagerFactory.java b/src/com/fsck/k9/mail/ssl/TrustManagerFactory.java
index c1956011c..f6841a2e3 100644
--- a/src/com/fsck/k9/mail/ssl/TrustManagerFactory.java
+++ b/src/com/fsck/k9/mail/ssl/TrustManagerFactory.java
@@ -4,7 +4,6 @@ package com.fsck.k9.mail.ssl;
import android.util.Log;
import com.fsck.k9.mail.CertificateChainException;
-import com.fsck.k9.security.LocalKeyStore;
import javax.net.ssl.SSLException;
import javax.net.ssl.TrustManager;
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index b8be10039..051c29f2d 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -58,7 +58,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.helper.UrlEncodingHelper;
-import com.fsck.k9.helper.Utility;
import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
import com.fsck.k9.mail.AuthType;
@@ -71,7 +70,7 @@ import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
-import com.fsck.k9.mail.store.local.MessageRetrievalListener;
+import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.PushReceiver;
@@ -88,7 +87,6 @@ import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.store.ImapResponseParser.ImapList;
import com.fsck.k9.mail.store.ImapResponseParser.ImapResponse;
-import com.fsck.k9.mail.store.imap.ImapUtility;
import com.fsck.k9.mail.transport.imap.ImapSettings;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
@@ -246,7 +244,7 @@ public class ImapStore extends RemoteStore {
*
* @return An ImapStore URI that holds the same information as the {@code server} parameter.
*
- * @see Account#getStoreUri()
+ * @see com.fsck.k9.mail.store.StoreConfig#getStoreUri()
* @see ImapStore#decodeUri(String)
*/
public static String createUri(ServerSettings server) {
@@ -1125,7 +1123,7 @@ public class ImapStore extends RemoteStore {
//TODO: Split this into multiple commands if the command exceeds a certain length.
List responses = executeSimpleCommand(String.format("UID COPY %s %s",
- Utility.combine(uids, ','),
+ combine(uids, ','),
remoteDestName));
// Get the tagged response for the UID COPY command
@@ -1332,7 +1330,7 @@ public class ImapStore extends RemoteStore {
ImapSearcher searcher = new ImapSearcher() {
@Override
public List search() throws IOException, MessagingException {
- return executeSimpleCommand(String.format("UID SEARCH %s%s", Utility.combine(mesgSeqs.toArray(), ','), includeDeleted ? "" : " NOT DELETED"));
+ return executeSimpleCommand(String.format("UID SEARCH %s%s", combine(mesgSeqs.toArray(), ','), includeDeleted ? "" : " NOT DELETED"));
}
};
return search(searcher, listener);
@@ -1343,7 +1341,7 @@ public class ImapStore extends RemoteStore {
ImapSearcher searcher = new ImapSearcher() {
@Override
public List search() throws IOException, MessagingException {
- return executeSimpleCommand(String.format("UID SEARCH UID %s%s", Utility.combine(mesgUids.toArray(), ','), includeDeleted ? "" : " NOT DELETED"));
+ return executeSimpleCommand(String.format("UID SEARCH UID %s%s", combine(mesgUids.toArray(), ','), includeDeleted ? "" : " NOT DELETED"));
}
};
return search(searcher, listener);
@@ -1483,8 +1481,8 @@ public class ImapStore extends RemoteStore {
try {
mConnection.sendCommand(String.format("UID FETCH %s (%s)",
- Utility.combine(uidWindow.toArray(new String[uidWindow.size()]), ','),
- Utility.combine(fetchFields.toArray(new String[fetchFields.size()]), ' ')
+ combine(uidWindow.toArray(new String[uidWindow.size()]), ','),
+ combine(fetchFields.toArray(new String[fetchFields.size()]), ' ')
), false);
ImapResponse response;
int messageNumber = 0;
@@ -2101,7 +2099,7 @@ public class ImapStore extends RemoteStore {
}
}
- return Utility.combine(flagNames.toArray(new String[flagNames.size()]), ' ');
+ return combine(flagNames.toArray(new String[flagNames.size()]), ' ');
}
@@ -2151,7 +2149,7 @@ public class ImapStore extends RemoteStore {
}
try {
executeSimpleCommand(String.format("UID STORE %s %sFLAGS.SILENT (%s)",
- Utility.combine(uids, ','),
+ combine(uids, ','),
value ? "+" : "-",
combineFlags(flags)));
} catch (IOException ioe) {
@@ -2701,7 +2699,7 @@ public class ImapStore extends RemoteStore {
try {
receiveCapabilities(executeSimpleCommand(
String.format("AUTHENTICATE EXTERNAL %s",
- Utility.base64Encode(mSettings.getUsername())), false));
+ Base64.encode(mSettings.getUsername())), false));
} catch (ImapException e) {
/*
* Provide notification to the user of a problem authenticating
@@ -3599,4 +3597,11 @@ public class ImapStore extends RemoteStore {
return null;
}
}
+
+ private static String combine(Object[] parts, char separator) {
+ if (parts == null) {
+ return null;
+ }
+ return TextUtils.join(String.valueOf(separator), parts);
+ }
}
diff --git a/src/com/fsck/k9/mail/store/imap/ImapUtility.java b/src/com/fsck/k9/mail/store/ImapUtility.java
similarity index 98%
rename from src/com/fsck/k9/mail/store/imap/ImapUtility.java
rename to src/com/fsck/k9/mail/store/ImapUtility.java
index 51d1aa070..971f098cd 100644
--- a/src/com/fsck/k9/mail/store/imap/ImapUtility.java
+++ b/src/com/fsck/k9/mail/store/ImapUtility.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package com.fsck.k9.mail.store.imap;
+package com.fsck.k9.mail.store;
import android.util.Log;
@@ -27,7 +27,7 @@ import java.util.List;
/**
* Utility methods for use with IMAP.
*/
-public class ImapUtility {
+class ImapUtility {
/**
* Gets all of the values in a sequence set per RFC 3501.
*
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index 0871579b1..85c73f0f0 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -6,13 +6,12 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.helper.UrlEncodingHelper;
-import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.Hex;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
-import com.fsck.k9.mail.store.local.MessageRetrievalListener;
+import com.fsck.k9.mail.MessageRetrievalListener;
import javax.net.ssl.SSLException;
@@ -459,7 +458,7 @@ public class Pop3Store extends RemoteStore {
try {
executeSimpleCommand(
String.format("AUTH EXTERNAL %s",
- Utility.base64Encode(mUsername)), false);
+ Base64.encode(mUsername)), false);
} catch (Pop3ErrorResponse e) {
/*
* Provide notification to the user of a problem authenticating
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index 300a68d18..a08d11cbe 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -5,11 +5,11 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.helper.UrlEncodingHelper;
-import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.*;
+import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
import com.fsck.k9.mail.internet.MimeMessage;
-import com.fsck.k9.mail.store.local.MessageRetrievalListener;
+import com.fsck.k9.mail.MessageRetrievalListener;
import org.apache.commons.io.IOUtils;
import org.apache.http.*;
@@ -339,7 +339,7 @@ public class WebDavStore extends RemoteStore {
// The inbox path would look like: "https://mail.domain.com/Exchange/alias/Inbox".
mUrl = getRoot() + mPath + mMailboxPath;
- mAuthString = "Basic " + Utility.base64Encode(mUsername + ":" + mPassword);
+ mAuthString = "Basic " + Base64.encode(mUsername + ":" + mPassword);
}
private String getRoot() {
diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java
index 4e7959f7f..6e30eab20 100644
--- a/src/com/fsck/k9/mail/transport/SmtpTransport.java
+++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java
@@ -3,20 +3,18 @@ package com.fsck.k9.mail.transport;
import android.util.Log;
-import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.helper.UrlEncodingHelper;
-import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.Message.RecipientType;
+import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
import com.fsck.k9.mail.filter.LineWrapOutputStream;
import com.fsck.k9.mail.filter.PeekableInputStream;
import com.fsck.k9.mail.filter.SmtpDataStuffing;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.store.StoreConfig;
-import com.fsck.k9.mail.store.local.LocalMessage;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
import javax.net.ssl.SSLException;
@@ -125,7 +123,7 @@ public class SmtpTransport extends Transport {
*
* @return A SmtpTransport URI that holds the same information as the {@code server} parameter.
*
- * @see Account#getTransportUri()
+ * @see com.fsck.k9.mail.store.StoreConfig#getTransportUri()
* @see SmtpTransport#decodeUri(String)
*/
public static String createUri(ServerSettings server) {
@@ -150,7 +148,7 @@ public class SmtpTransport extends Transport {
break;
}
- String userInfo = null;
+ String userInfo;
AuthType authType = server.authenticationType;
// NOTE: authType is append at last item, in contrast to ImapStore and Pop3Store!
if (authType != null) {
@@ -184,10 +182,10 @@ public class SmtpTransport extends Transport {
private boolean m8bitEncodingAllowed;
private int mLargestAcceptableMessage;
- public SmtpTransport(StoreConfig account) throws MessagingException {
+ public SmtpTransport(StoreConfig storeConfig) throws MessagingException {
ServerSettings settings;
try {
- settings = decodeUri(account.getTransportUri());
+ settings = decodeUri(storeConfig.getTransportUri());
} catch (IllegalArgumentException e) {
throw new MessagingException("Error while decoding transport URI", e);
}
@@ -496,7 +494,7 @@ public class SmtpTransport extends Transport {
}
// If the message has attachments and our server has told us about a limit on
// the size of messages, count the message's size before sending it
- if (mLargestAcceptableMessage > 0 && ((LocalMessage)message).hasAttachments()) {
+ if (mLargestAcceptableMessage > 0 && message.hasAttachments()) {
if (message.calculateSize() > mLargestAcceptableMessage) {
MessagingException me = new MessagingException("Message too large for server");
//TODO this looks rather suspicious... shouldn't it be true?
@@ -702,8 +700,8 @@ public class SmtpTransport extends Transport {
AuthenticationFailedException, IOException {
try {
executeSimpleCommand("AUTH LOGIN");
- executeSimpleCommand(Utility.base64Encode(username), true);
- executeSimpleCommand(Utility.base64Encode(password), true);
+ executeSimpleCommand(Base64.encode(username), true);
+ executeSimpleCommand(Base64.encode(password), true);
} catch (NegativeSmtpReplyException exception) {
if (exception.getReplyCode() == 535) {
// Authentication credentials invalid
@@ -717,7 +715,7 @@ public class SmtpTransport extends Transport {
private void saslAuthPlain(String username, String password) throws MessagingException,
AuthenticationFailedException, IOException {
- String data = Utility.base64Encode("\000" + username + "\000" + password);
+ String data = Base64.encode("\000" + username + "\000" + password);
try {
executeSimpleCommand("AUTH PLAIN " + data, true);
} catch (NegativeSmtpReplyException exception) {
@@ -757,7 +755,7 @@ public class SmtpTransport extends Transport {
private void saslAuthExternal(String username) throws MessagingException, IOException {
executeSimpleCommand(
String.format("AUTH EXTERNAL %s",
- Utility.base64Encode(username)), false);
+ Base64.encode(username)), false);
}
/**
diff --git a/src/com/fsck/k9/preferences/AccountSettings.java b/src/com/fsck/k9/preferences/AccountSettings.java
index c2b6b4983..327ff38b2 100644
--- a/src/com/fsck/k9/preferences/AccountSettings.java
+++ b/src/com/fsck/k9/preferences/AccountSettings.java
@@ -13,7 +13,7 @@ import com.fsck.k9.Account.SortType;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.Account.FolderMode;
-import com.fsck.k9.mail.store.StorageManager;
+import com.fsck.k9.local.StorageManager;
import com.fsck.k9.preferences.Settings.*;
public class AccountSettings {
diff --git a/src/com/fsck/k9/preferences/SettingsImporter.java b/src/com/fsck/k9/preferences/SettingsImporter.java
index 1a7af8d26..1d05cf9dc 100644
--- a/src/com/fsck/k9/preferences/SettingsImporter.java
+++ b/src/com/fsck/k9/preferences/SettingsImporter.java
@@ -22,11 +22,11 @@ import com.fsck.k9.Account;
import com.fsck.k9.Identity;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
-import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.Transport;
+import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mail.store.WebDavStore;
import com.fsck.k9.preferences.Settings.InvalidSettingValueException;
@@ -377,7 +377,7 @@ public class SettingsImporter {
// Write incoming server settings (storeUri)
ServerSettings incoming = new ImportedServerSettings(account.incoming);
String storeUri = RemoteStore.createStoreUri(incoming);
- putString(editor, accountKeyPrefix + Account.STORE_URI_KEY, Utility.base64Encode(storeUri));
+ putString(editor, accountKeyPrefix + Account.STORE_URI_KEY, Base64.encode(storeUri));
// Mark account as disabled if the AuthType isn't EXTERNAL and the
// settings file didn't contain a password
@@ -393,7 +393,7 @@ public class SettingsImporter {
// Write outgoing server settings (transportUri)
ServerSettings outgoing = new ImportedServerSettings(account.outgoing);
String transportUri = Transport.createTransportUri(outgoing);
- putString(editor, accountKeyPrefix + Account.TRANSPORT_URI_KEY, Utility.base64Encode(transportUri));
+ putString(editor, accountKeyPrefix + Account.TRANSPORT_URI_KEY, Base64.encode(transportUri));
/*
* Mark account as disabled if the settings file contained a
diff --git a/src/com/fsck/k9/preferences/Storage.java b/src/com/fsck/k9/preferences/Storage.java
index 88260f7ff..1303fc8e9 100644
--- a/src/com/fsck/k9/preferences/Storage.java
+++ b/src/com/fsck/k9/preferences/Storage.java
@@ -11,9 +11,9 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
+import com.fsck.k9.mail.filter.Base64;
import java.net.URI;
-import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -54,8 +54,8 @@ public class Storage implements SharedPreferences {
String[] uuids = accountUuids.split(",");
for (String uuid : uuids) {
try {
- String storeUriStr = Utility.base64Decode(readValue(mDb, uuid + ".storeUri"));
- String transportUriStr = Utility.base64Decode(readValue(mDb, uuid + ".transportUri"));
+ String storeUriStr = Base64.decode(readValue(mDb, uuid + ".storeUri"));
+ String transportUriStr = Base64.decode(readValue(mDb, uuid + ".transportUri"));
URI uri = new URI(transportUriStr);
String newUserInfo = null;
@@ -77,7 +77,7 @@ public class Storage implements SharedPreferences {
if (newUserInfo != null) {
URI newUri = new URI(uri.getScheme(), newUserInfo, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
- String newTransportUriStr = Utility.base64Encode(newUri.toString());
+ String newTransportUriStr = Base64.encode(newUri.toString());
writeValue(mDb, uuid + ".transportUri", newTransportUriStr);
}
@@ -121,7 +121,7 @@ public class Storage implements SharedPreferences {
if (newUserInfo != null) {
URI newUri = new URI(uri.getScheme(), newUserInfo, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
- String newStoreUriStr = Utility.base64Encode(newUri.toString());
+ String newStoreUriStr = Base64.encode(newUri.toString());
writeValue(mDb, uuid + ".storeUri", newStoreUriStr);
}
} catch (Exception e) {
diff --git a/src/com/fsck/k9/provider/AttachmentProvider.java b/src/com/fsck/k9/provider/AttachmentProvider.java
index bfcdaac9b..792c8885f 100644
--- a/src/com/fsck/k9/provider/AttachmentProvider.java
+++ b/src/com/fsck/k9/provider/AttachmentProvider.java
@@ -15,9 +15,9 @@ import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.MimeUtility;
-import com.fsck.k9.mail.store.local.LocalStore;
-import com.fsck.k9.mail.store.local.LocalStore.AttachmentInfo;
-import com.fsck.k9.mail.store.StorageManager;
+import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.local.LocalStore.AttachmentInfo;
+import com.fsck.k9.local.StorageManager;
import java.io.*;
import java.util.List;
diff --git a/src/com/fsck/k9/provider/EmailProvider.java b/src/com/fsck/k9/provider/EmailProvider.java
index 0164ce4ec..fb025f46c 100644
--- a/src/com/fsck/k9/provider/EmailProvider.java
+++ b/src/com/fsck/k9/provider/EmailProvider.java
@@ -10,11 +10,11 @@ import com.fsck.k9.Preferences;
import com.fsck.k9.cache.EmailProviderCacheCursor;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.mail.store.local.LockableDatabase;
-import com.fsck.k9.mail.store.local.LockableDatabase.DbCallback;
-import com.fsck.k9.mail.store.local.LockableDatabase.WrappedException;
-import com.fsck.k9.mail.store.UnavailableStorageException;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.LockableDatabase;
+import com.fsck.k9.local.LockableDatabase.DbCallback;
+import com.fsck.k9.local.LockableDatabase.WrappedException;
+import com.fsck.k9.local.UnavailableStorageException;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.search.SqlQueryBuilder;
import android.content.ContentProvider;
@@ -357,6 +357,8 @@ public class EmailProvider extends ContentProvider {
});
} catch (UnavailableStorageException e) {
throw new RuntimeException("Storage not available", e);
+ } catch (MessagingException e) {
+ throw new RuntimeException("messaging exception", e);
}
}
@@ -427,6 +429,8 @@ public class EmailProvider extends ContentProvider {
});
} catch (UnavailableStorageException e) {
throw new RuntimeException("Storage not available", e);
+ } catch (MessagingException e) {
+ throw new RuntimeException("messaging exception", e);
}
}
@@ -532,7 +536,10 @@ public class EmailProvider extends ContentProvider {
});
} catch (UnavailableStorageException e) {
throw new RuntimeException("Storage not available", e);
+ } catch (MessagingException e) {
+ throw new RuntimeException("messaging exception", e);
}
+
}
private Cursor getAccountStats(String accountUuid, String[] columns,
@@ -594,7 +601,10 @@ public class EmailProvider extends ContentProvider {
});
} catch (UnavailableStorageException e) {
throw new RuntimeException("Storage not available", e);
+ } catch (MessagingException e) {
+ throw new RuntimeException("messaging exception", e);
}
+
}
private Account getAccount(String accountUuid) {
diff --git a/src/com/fsck/k9/provider/MessageProvider.java b/src/com/fsck/k9/provider/MessageProvider.java
index c75f017df..a02bf5520 100644
--- a/src/com/fsck/k9/provider/MessageProvider.java
+++ b/src/com/fsck/k9/provider/MessageProvider.java
@@ -32,9 +32,9 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.local.LocalMessage;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.search.SearchAccount;
import java.lang.ref.WeakReference;
diff --git a/src/com/fsck/k9/search/SqlQueryBuilder.java b/src/com/fsck/k9/search/SqlQueryBuilder.java
index 1b6ecf6a2..8286f5d9e 100644
--- a/src/com/fsck/k9/search/SqlQueryBuilder.java
+++ b/src/com/fsck/k9/search/SqlQueryBuilder.java
@@ -5,8 +5,8 @@ import java.util.List;
import com.fsck.k9.Account;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Folder;
-import com.fsck.k9.mail.store.local.LocalFolder;
-import com.fsck.k9.mail.store.local.LocalStore;
+import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.local.LocalStore;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.fsck.k9.search.SearchSpecification.Searchfield;
diff --git a/src/com/fsck/k9/service/DatabaseUpgradeService.java b/src/com/fsck/k9/service/DatabaseUpgradeService.java
index ee5b9b26b..15f0e16f1 100644
--- a/src/com/fsck/k9/service/DatabaseUpgradeService.java
+++ b/src/com/fsck/k9/service/DatabaseUpgradeService.java
@@ -17,7 +17,7 @@ import com.fsck.k9.Preferences;
import com.fsck.k9.activity.UpgradeDatabases;
import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
-import com.fsck.k9.mail.store.UnavailableStorageException;
+import com.fsck.k9.local.UnavailableStorageException;
/**
* Service used to upgrade the accounts' databases and/or track the progress of the upgrade.
diff --git a/src/com/fsck/k9/service/NotificationActionService.java b/src/com/fsck/k9/service/NotificationActionService.java
index 079222e69..96d3cf705 100644
--- a/src/com/fsck/k9/service/NotificationActionService.java
+++ b/src/com/fsck/k9/service/NotificationActionService.java
@@ -11,8 +11,7 @@ import com.fsck.k9.activity.MessageCompose;
import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.mail.Flag;
-import com.fsck.k9.mail.Message;
-import com.fsck.k9.mail.store.local.LocalMessage;
+import com.fsck.k9.local.LocalMessage;
import android.app.PendingIntent;
import android.content.Context;
diff --git a/src/com/fsck/k9/service/StorageGoneReceiver.java b/src/com/fsck/k9/service/StorageGoneReceiver.java
index 43f9e49d7..022ae9b9c 100644
--- a/src/com/fsck/k9/service/StorageGoneReceiver.java
+++ b/src/com/fsck/k9/service/StorageGoneReceiver.java
@@ -7,7 +7,7 @@ import android.net.Uri;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.mail.store.StorageManager;
+import com.fsck.k9.local.StorageManager;
/**
* That BroadcastReceiver is only interested in UNMOUNT events.
diff --git a/src/com/fsck/k9/service/StorageReceiver.java b/src/com/fsck/k9/service/StorageReceiver.java
index 515750be4..1cf116dd6 100644
--- a/src/com/fsck/k9/service/StorageReceiver.java
+++ b/src/com/fsck/k9/service/StorageReceiver.java
@@ -7,7 +7,7 @@ import android.net.Uri;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.mail.store.StorageManager;
+import com.fsck.k9.local.StorageManager;
/**
* That BroadcastReceiver is only interested in MOUNT events.
diff --git a/src/com/fsck/k9/view/AttachmentView.java b/src/com/fsck/k9/view/AttachmentView.java
index ea917f334..84d0d9ff8 100644
--- a/src/com/fsck/k9/view/AttachmentView.java
+++ b/src/com/fsck/k9/view/AttachmentView.java
@@ -43,7 +43,7 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MimeHeader;
import com.fsck.k9.mail.internet.MimeUtility;
-import com.fsck.k9.mail.store.local.LocalAttachmentBodyPart;
+import com.fsck.k9.local.LocalAttachmentBodyPart;
import com.fsck.k9.provider.AttachmentProvider;
import org.apache.commons.io.IOUtils;
diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java
index a351e7921..4747415ef 100644
--- a/src/com/fsck/k9/view/SingleMessageView.java
+++ b/src/com/fsck/k9/view/SingleMessageView.java
@@ -56,8 +56,8 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Multipart;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MimeUtility;
-import com.fsck.k9.mail.store.local.LocalAttachmentBodyPart;
-import com.fsck.k9.mail.store.local.LocalMessage;
+import com.fsck.k9.local.LocalAttachmentBodyPart;
+import com.fsck.k9.local.LocalMessage;
import com.fsck.k9.provider.AttachmentProvider.AttachmentProviderColumns;
import org.apache.commons.io.IOUtils;
diff --git a/tests/src/com/fsck/k9/helper/Address.java b/tests/src/com/fsck/k9/mail/AddressTest.java
similarity index 74%
rename from tests/src/com/fsck/k9/helper/Address.java
rename to tests/src/com/fsck/k9/mail/AddressTest.java
index 250cad347..e1a3778e1 100644
--- a/tests/src/com/fsck/k9/helper/Address.java
+++ b/tests/src/com/fsck/k9/mail/AddressTest.java
@@ -1,14 +1,14 @@
-package com.fsck.k9.helper;
+package com.fsck.k9.mail;
import junit.framework.TestCase;
-public class Address extends TestCase {
+public class AddressTest extends TestCase {
/**
* test the possibility to parse "From:" fields with no email.
* for example: From: News for Vector Limited - Google Finance
* http://code.google.com/p/k9mail/issues/detail?id=3814
*/
public void testParseWithMissingEmail() {
- com.fsck.k9.mail.Address[] addresses = com.fsck.k9.mail.Address.parse("NAME ONLY");
+ Address[] addresses = Address.parse("NAME ONLY");
assertEquals(1, addresses.length);
assertEquals(null, addresses[0].getAddress());
assertEquals("NAME ONLY", addresses[0].getPersonal());
@@ -18,7 +18,7 @@ public class Address extends TestCase {
* test name + valid email
*/
public void testPraseWithValidEmail() {
- com.fsck.k9.mail.Address[] addresses = com.fsck.k9.mail.Address.parse("Max Mustermann ");
+ Address[] addresses = Address.parse("Max Mustermann ");
assertEquals(1, addresses.length);
assertEquals("maxmuster@mann.com", addresses[0].getAddress());
assertEquals("Max Mustermann", addresses[0].getPersonal());
@@ -27,7 +27,7 @@ public class Address extends TestCase {
* test with multi email addresses
*/
public void testPraseWithValidEmailMulti() {
- com.fsck.k9.mail.Address[] addresses = com.fsck.k9.mail.Address.parse("lorem@ipsum.us,mark@twain.com");
+ Address[] addresses = Address.parse("lorem@ipsum.us,mark@twain.com");
assertEquals(2, addresses.length);
assertEquals("lorem@ipsum.us", addresses[0].getAddress());
assertEquals(null, addresses[0].getPersonal());
diff --git a/tests/src/com/fsck/k9/helper/Utility_quoteAtoms.java b/tests/src/com/fsck/k9/mail/Address_quoteAtoms.java
similarity index 87%
rename from tests/src/com/fsck/k9/helper/Utility_quoteAtoms.java
rename to tests/src/com/fsck/k9/mail/Address_quoteAtoms.java
index 372c5c0f4..0ea553b2e 100644
--- a/tests/src/com/fsck/k9/helper/Utility_quoteAtoms.java
+++ b/tests/src/com/fsck/k9/mail/Address_quoteAtoms.java
@@ -1,8 +1,8 @@
-package com.fsck.k9.helper;
+package com.fsck.k9.mail;
import junit.framework.TestCase;
-public class Utility_quoteAtoms extends TestCase
+public class Address_quoteAtoms extends TestCase
{
public void testNoQuote() {
// Alpha
@@ -53,10 +53,10 @@ public class Utility_quoteAtoms extends TestCase
}
private void noQuote(final String s) {
- assertEquals(s, Utility.quoteAtoms(s));
+ assertEquals(s, Address.quoteAtoms(s));
}
private String quote(final String s) {
- return Utility.quoteAtoms(s);
+ return Address.quoteAtoms(s);
}
}
diff --git a/tests/src/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java b/tests/src/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java
index 14da17b7f..1574aaf03 100644
--- a/tests/src/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java
+++ b/tests/src/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java
@@ -2,9 +2,6 @@ package com.fsck.k9.mail.ssl;
import javax.net.ssl.X509TrustManager;
-import com.fsck.k9.mail.ssl.TrustManagerFactory;
-import com.fsck.k9.security.LocalKeyStore;
-
import java.io.ByteArrayInputStream;
import java.io.File;
import java.security.cert.CertificateException;
diff --git a/tests/src/com/fsck/k9/mail/store/imap/ImapUtilityTest.java b/tests/src/com/fsck/k9/mail/store/ImapUtilityTest.java
similarity index 99%
rename from tests/src/com/fsck/k9/mail/store/imap/ImapUtilityTest.java
rename to tests/src/com/fsck/k9/mail/store/ImapUtilityTest.java
index feaef05e8..392fdc554 100644
--- a/tests/src/com/fsck/k9/mail/store/imap/ImapUtilityTest.java
+++ b/tests/src/com/fsck/k9/mail/store/ImapUtilityTest.java
@@ -15,10 +15,11 @@
* limitations under the License.
*/
-package com.fsck.k9.mail.store.imap;
+package com.fsck.k9.mail.store;
import java.util.List;
import android.test.MoreAsserts;
+
import junit.framework.TestCase;
public class ImapUtilityTest extends TestCase {
From b644194a3d2866ddc543a696b72ba5efa22432e5 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 15:16:38 +0000
Subject: [PATCH 10/29] Fix LocalMessage equality/hash
---
src/com/fsck/k9/local/LocalFolder.java | 2 --
src/com/fsck/k9/local/LocalMessage.java | 10 +++++++---
src/com/fsck/k9/mail/Message.java | 4 ++--
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/com/fsck/k9/local/LocalFolder.java b/src/com/fsck/k9/local/LocalFolder.java
index 33e177f9a..a35428adb 100644
--- a/src/com/fsck/k9/local/LocalFolder.java
+++ b/src/com/fsck/k9/local/LocalFolder.java
@@ -116,8 +116,6 @@ public class LocalFolder extends Folder implements Serializable {
return getAccount().syncRemoteDeletions();
}
-
-
@Override
public void open(final int mode) throws MessagingException {
diff --git a/src/com/fsck/k9/local/LocalMessage.java b/src/com/fsck/k9/local/LocalMessage.java
index ac3aa5918..cc9cef2de 100644
--- a/src/com/fsck/k9/local/LocalMessage.java
+++ b/src/com/fsck/k9/local/LocalMessage.java
@@ -601,14 +601,18 @@ public class LocalMessage extends MimeMessage {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
- LocalMessage that = (LocalMessage) o;
- return !(getUid() != null ? !getUid().equals(that.getUid()) : that.getUid() != null);
+ final LocalMessage that = (LocalMessage) o;
+ return !(getAccountUuid() != null ? !getAccountUuid().equals(that.getAccountUuid()) : that.getAccountUuid() != null);
}
@Override
public int hashCode() {
int result = super.hashCode();
- result = 31 * result + (getUid() != null ? getUid().hashCode() : 0);
+ result = 31 * result + (getAccountUuid() != null ? getAccountUuid().hashCode() : 0);
return result;
}
+
+ private String getAccountUuid() {
+ return getAccount().getUuid();
+ }
}
\ No newline at end of file
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index b0bfe12af..24a29af5f 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -47,8 +47,8 @@ public abstract class Message implements Part, CompositeBody {
return false;
}
Message other = (Message)o;
- return (mUid.equals(other.getUid())
- && mFolder.getName().equals(other.getFolder().getName()));
+ return (getUid().equals(other.getUid())
+ && getFolder().getName().equals(other.getFolder().getName()));
}
@Override
From 54d62eb7b94e7df35a681efaf08ae424f8c320ff Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 15:19:13 +0000
Subject: [PATCH 11/29] Naming
---
src/com/fsck/k9/mail/transport/WebDavTransport.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/com/fsck/k9/mail/transport/WebDavTransport.java b/src/com/fsck/k9/mail/transport/WebDavTransport.java
index 40b8b6884..839ec00d9 100644
--- a/src/com/fsck/k9/mail/transport/WebDavTransport.java
+++ b/src/com/fsck/k9/mail/transport/WebDavTransport.java
@@ -43,8 +43,8 @@ public class WebDavTransport extends Transport {
private WebDavStore store;
- public WebDavTransport(StoreConfig configInterface) throws MessagingException {
- store = new WebDavStore(configInterface);
+ public WebDavTransport(StoreConfig storeConfig) throws MessagingException {
+ store = new WebDavStore(storeConfig);
if (K9.DEBUG)
Log.d(K9.LOG_TAG, ">>> New WebDavTransport creation complete");
From 12248bca9248bb469d2e24ae49eee697c87a16ef Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Fri, 12 Dec 2014 15:32:36 +0000
Subject: [PATCH 12/29] Fix test location
---
.../fsck/k9/{helper => mail/internet}/HtmlConverterTest.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
rename tests/src/com/fsck/k9/{helper => mail/internet}/HtmlConverterTest.java (99%)
diff --git a/tests/src/com/fsck/k9/helper/HtmlConverterTest.java b/tests/src/com/fsck/k9/mail/internet/HtmlConverterTest.java
similarity index 99%
rename from tests/src/com/fsck/k9/helper/HtmlConverterTest.java
rename to tests/src/com/fsck/k9/mail/internet/HtmlConverterTest.java
index 7ab254baf..7faea3b18 100644
--- a/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
+++ b/tests/src/com/fsck/k9/mail/internet/HtmlConverterTest.java
@@ -1,6 +1,4 @@
-package com.fsck.k9.helper;
-
-import com.fsck.k9.mail.internet.HtmlConverter;
+package com.fsck.k9.mail.internet;
import junit.framework.TestCase;
From bd697bb56d485802dba771ce1e18d09f8d352b3e Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Sun, 14 Dec 2014 15:26:38 +0000
Subject: [PATCH 13/29] getUuid() -> getAccountUuid()
---
src/com/fsck/k9/controller/MessagingController.java | 2 +-
src/com/fsck/k9/fragment/MessageListFragment.java | 4 ++--
src/com/fsck/k9/helper/MessageHelper.java | 2 +-
src/com/fsck/k9/local/LocalFolder.java | 4 ++--
src/com/fsck/k9/local/LocalMessage.java | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index a955c9199..c95748874 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -329,7 +329,7 @@ public class MessagingController implements Runnable {
long messageId = message.getId();
long folderId = message.getFolder().getId();
- EmailProviderCache cache = EmailProviderCache.getCache(message.getFolder().getUuid(),
+ EmailProviderCache cache = EmailProviderCache.getCache(message.getFolder().getAccountUuid(),
mApplication.getApplicationContext());
return cache.isMessageHidden(messageId, folderId);
}
diff --git a/src/com/fsck/k9/fragment/MessageListFragment.java b/src/com/fsck/k9/fragment/MessageListFragment.java
index dae7ec49d..46760b3fa 100644
--- a/src/com/fsck/k9/fragment/MessageListFragment.java
+++ b/src/com/fsck/k9/fragment/MessageListFragment.java
@@ -2434,7 +2434,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_MOVE, folder,
- messages.get(0).getFolder().getUuid(), null,
+ messages.get(0).getFolder().getAccountUuid(), null,
messages);
}
@@ -2463,7 +2463,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
}
displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_COPY, folder,
- messages.get(0).getFolder().getUuid(),
+ messages.get(0).getFolder().getAccountUuid(),
null,
messages);
}
diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java
index 4cde05621..5e88d3b5e 100644
--- a/src/com/fsck/k9/helper/MessageHelper.java
+++ b/src/com/fsck/k9/helper/MessageHelper.java
@@ -71,7 +71,7 @@ public class MessageHelper {
}
target.uid = message.getUid();
- target.account = message.getFolder().getUuid();
+ target.account = message.getFolder().getAccountUuid();
target.uri = message.getUri();
} catch (MessagingException me) {
Log.w(K9.LOG_TAG, "Unable to load message info", me);
diff --git a/src/com/fsck/k9/local/LocalFolder.java b/src/com/fsck/k9/local/LocalFolder.java
index a35428adb..9fa2bcc79 100644
--- a/src/com/fsck/k9/local/LocalFolder.java
+++ b/src/com/fsck/k9/local/LocalFolder.java
@@ -99,7 +99,7 @@ public class LocalFolder extends Folder implements Serializable {
return mFolderId;
}
- public String getUuid()
+ public String getAccountUuid()
{
return getAccount().getUuid();
}
@@ -1890,7 +1890,7 @@ public class LocalFolder extends Folder implements Serializable {
public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
Cursor attachmentsCursor = null;
try {
- String accountUuid = getUuid();
+ String accountUuid = getAccountUuid();
Context context = LocalFolder.this.localStore.mApplication;
// Get attachment IDs
diff --git a/src/com/fsck/k9/local/LocalMessage.java b/src/com/fsck/k9/local/LocalMessage.java
index cc9cef2de..292be2c51 100644
--- a/src/com/fsck/k9/local/LocalMessage.java
+++ b/src/com/fsck/k9/local/LocalMessage.java
@@ -573,7 +573,7 @@ public class LocalMessage extends MimeMessage {
mReference = new MessageReference();
mReference.folderName = getFolder().getName();
mReference.uid = mUid;
- mReference.accountUuid = getFolder().getUuid();
+ mReference.accountUuid = getFolder().getAccountUuid();
}
return mReference;
}
From 8ef9eae0d64585b2ffa94b883760c2ff6375224c Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Sun, 14 Dec 2014 15:28:42 +0000
Subject: [PATCH 14/29] local -> mailstore
---
src/com/fsck/k9/Account.java | 6 +++---
src/com/fsck/k9/K9.java | 2 +-
src/com/fsck/k9/Preferences.java | 2 +-
src/com/fsck/k9/activity/Accounts.java | 2 +-
src/com/fsck/k9/activity/FolderList.java | 2 +-
src/com/fsck/k9/activity/MessageCompose.java | 8 ++++----
src/com/fsck/k9/activity/MessageInfoHolder.java | 2 +-
src/com/fsck/k9/activity/MessageList.java | 4 ++--
src/com/fsck/k9/activity/MessageReference.java | 4 ++--
src/com/fsck/k9/activity/UpgradeDatabases.java | 2 +-
src/com/fsck/k9/activity/setup/AccountSettings.java | 4 ++--
src/com/fsck/k9/activity/setup/FolderSettings.java | 4 ++--
src/com/fsck/k9/cache/EmailProviderCache.java | 4 ++--
src/com/fsck/k9/controller/MessagingController.java | 12 ++++++------
.../controller/MessagingControllerPushReceiver.java | 4 ++--
src/com/fsck/k9/controller/MessagingListener.java | 2 +-
src/com/fsck/k9/fragment/MessageListFragment.java | 6 +++---
src/com/fsck/k9/fragment/MessageViewFragment.java | 2 +-
src/com/fsck/k9/helper/MessageHelper.java | 2 +-
.../AttachmentMessageBodyUtil.java | 2 +-
.../{local => mailstore}/BinaryAttachmentBody.java | 2 +-
.../k9/{local => mailstore}/LocalAttachmentBody.java | 2 +-
.../LocalAttachmentBodyPart.java | 2 +-
.../LocalAttachmentMessageBody.java | 2 +-
.../fsck/k9/{local => mailstore}/LocalFolder.java | 6 +++---
.../fsck/k9/{local => mailstore}/LocalMessage.java | 6 +++---
src/com/fsck/k9/{local => mailstore}/LocalStore.java | 8 ++++----
.../fsck/k9/{local => mailstore}/LocalTextBody.java | 2 +-
.../k9/{local => mailstore}/LockableDatabase.java | 4 ++--
.../{local => mailstore}/MessageRemovalListener.java | 2 +-
.../fsck/k9/{local => mailstore}/StorageManager.java | 2 +-
.../{local => mailstore}/StoreSchemaDefinition.java | 2 +-
.../fsck/k9/{local => mailstore}/TempFileBody.java | 2 +-
.../k9/{local => mailstore}/TempFileMessageBody.java | 2 +-
src/com/fsck/k9/{local => mailstore}/ThreadInfo.java | 2 +-
.../UnavailableStorageException.java | 2 +-
src/com/fsck/k9/preferences/AccountSettings.java | 2 +-
src/com/fsck/k9/provider/AttachmentProvider.java | 6 +++---
src/com/fsck/k9/provider/EmailProvider.java | 10 +++++-----
src/com/fsck/k9/provider/MessageProvider.java | 6 +++---
src/com/fsck/k9/search/SqlQueryBuilder.java | 4 ++--
src/com/fsck/k9/service/DatabaseUpgradeService.java | 2 +-
.../fsck/k9/service/NotificationActionService.java | 2 +-
src/com/fsck/k9/service/StorageGoneReceiver.java | 2 +-
src/com/fsck/k9/service/StorageReceiver.java | 2 +-
src/com/fsck/k9/view/AttachmentView.java | 2 +-
src/com/fsck/k9/view/SingleMessageView.java | 4 ++--
47 files changed, 83 insertions(+), 83 deletions(-)
rename src/com/fsck/k9/{local => mailstore}/AttachmentMessageBodyUtil.java (97%)
rename src/com/fsck/k9/{local => mailstore}/BinaryAttachmentBody.java (98%)
rename src/com/fsck/k9/{local => mailstore}/LocalAttachmentBody.java (97%)
rename src/com/fsck/k9/{local => mailstore}/LocalAttachmentBodyPart.java (96%)
rename src/com/fsck/k9/{local => mailstore}/LocalAttachmentMessageBody.java (97%)
rename src/com/fsck/k9/{local => mailstore}/LocalFolder.java (99%)
rename src/com/fsck/k9/{local => mailstore}/LocalMessage.java (99%)
rename src/com/fsck/k9/{local => mailstore}/LocalStore.java (99%)
rename src/com/fsck/k9/{local => mailstore}/LocalTextBody.java (93%)
rename src/com/fsck/k9/{local => mailstore}/LockableDatabase.java (99%)
rename src/com/fsck/k9/{local => mailstore}/MessageRemovalListener.java (80%)
rename src/com/fsck/k9/{local => mailstore}/StorageManager.java (99%)
rename src/com/fsck/k9/{local => mailstore}/StoreSchemaDefinition.java (99%)
rename src/com/fsck/k9/{local => mailstore}/TempFileBody.java (95%)
rename src/com/fsck/k9/{local => mailstore}/TempFileMessageBody.java (97%)
rename src/com/fsck/k9/{local => mailstore}/ThreadInfo.java (93%)
rename src/com/fsck/k9/{local => mailstore}/UnavailableStorageException.java (96%)
diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index 46f5c5d62..e86ee07a1 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -32,9 +32,9 @@ import com.fsck.k9.mail.Folder.FolderClass;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mail.store.StoreConfig;
-import com.fsck.k9.local.StorageManager;
-import com.fsck.k9.local.StorageManager.StorageProvider;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.StorageManager;
+import com.fsck.k9.mailstore.StorageManager.StorageProvider;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.StatsColumns;
import com.fsck.k9.search.ConditionsTreeNode;
diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java
index 7e062d5f9..b565ffc8c 100644
--- a/src/com/fsck/k9/K9.java
+++ b/src/com/fsck/k9/K9.java
@@ -36,7 +36,7 @@ import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.BinaryTempFileBody;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.provider.UnreadWidgetProvider;
import com.fsck.k9.mail.ssl.LocalKeyStore;
import com.fsck.k9.service.BootReceiver;
diff --git a/src/com/fsck/k9/Preferences.java b/src/com/fsck/k9/Preferences.java
index a5c0cd4bc..016928eb0 100644
--- a/src/com/fsck/k9/Preferences.java
+++ b/src/com/fsck/k9/Preferences.java
@@ -13,7 +13,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.preferences.Editor;
import com.fsck.k9.preferences.Storage;
diff --git a/src/com/fsck/k9/activity/Accounts.java b/src/com/fsck/k9/activity/Accounts.java
index c2a0ec21b..0a7041165 100644
--- a/src/com/fsck/k9/activity/Accounts.java
+++ b/src/com/fsck/k9/activity/Accounts.java
@@ -80,7 +80,7 @@ import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.store.RemoteStore;
-import com.fsck.k9.local.StorageManager;
+import com.fsck.k9.mailstore.StorageManager;
import com.fsck.k9.mail.store.WebDavStore;
import com.fsck.k9.preferences.SettingsExporter;
import com.fsck.k9.preferences.SettingsImportExportException;
diff --git a/src/com/fsck/k9/activity/FolderList.java b/src/com/fsck/k9/activity/FolderList.java
index d1d7c17e4..254b87745 100644
--- a/src/com/fsck/k9/activity/FolderList.java
+++ b/src/com/fsck/k9/activity/FolderList.java
@@ -55,7 +55,7 @@ import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
-import com.fsck.k9.local.LocalFolder;
+import com.fsck.k9.mailstore.LocalFolder;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.Searchfield;
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index d9f489052..30f3e11cb 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -109,10 +109,10 @@ import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
import com.fsck.k9.mail.internet.TextBodyBuilder;
-import com.fsck.k9.local.LocalAttachmentBody;
-import com.fsck.k9.local.LocalMessage;
-import com.fsck.k9.local.TempFileBody;
-import com.fsck.k9.local.TempFileMessageBody;
+import com.fsck.k9.mailstore.LocalAttachmentBody;
+import com.fsck.k9.mailstore.LocalMessage;
+import com.fsck.k9.mailstore.TempFileBody;
+import com.fsck.k9.mailstore.TempFileMessageBody;
import com.fsck.k9.view.MessageWebView;
import org.apache.james.mime4j.codec.EncoderUtil;
diff --git a/src/com/fsck/k9/activity/MessageInfoHolder.java b/src/com/fsck/k9/activity/MessageInfoHolder.java
index 379543525..09708fbe6 100644
--- a/src/com/fsck/k9/activity/MessageInfoHolder.java
+++ b/src/com/fsck/k9/activity/MessageInfoHolder.java
@@ -2,7 +2,7 @@ package com.fsck.k9.activity;
import java.util.Date;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.LocalMessage;
public class MessageInfoHolder {
public String date;
diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index ebfb3ef3b..569753f7b 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -42,8 +42,8 @@ import com.fsck.k9.fragment.MessageListFragment;
import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener;
import com.fsck.k9.fragment.MessageViewFragment;
import com.fsck.k9.fragment.MessageViewFragment.MessageViewFragmentListener;
-import com.fsck.k9.local.StorageManager;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.StorageManager;
+import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchAccount;
import com.fsck.k9.search.SearchSpecification;
diff --git a/src/com/fsck/k9/activity/MessageReference.java b/src/com/fsck/k9/activity/MessageReference.java
index 0ba73a0c2..131b0715a 100644
--- a/src/com/fsck/k9/activity/MessageReference.java
+++ b/src/com/fsck/k9/activity/MessageReference.java
@@ -10,8 +10,8 @@ import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.mail.filter.Base64;
import java.util.StringTokenizer;
diff --git a/src/com/fsck/k9/activity/UpgradeDatabases.java b/src/com/fsck/k9/activity/UpgradeDatabases.java
index f5b2b9754..ae8cd6fd7 100644
--- a/src/com/fsck/k9/activity/UpgradeDatabases.java
+++ b/src/com/fsck/k9/activity/UpgradeDatabases.java
@@ -30,7 +30,7 @@ import android.widget.TextView;
* {@link #actionUpgradeDatabases(Context, Intent)} will call {@link K9#areDatabasesUpToDate()}
* to check if we already know whether the databases have been upgraded.
* {@link K9#areDatabasesUpToDate()} will compare the last known database version stored in a
- * {@link SharedPreferences} file to {@link com.fsck.k9.local.LocalStore#DB_VERSION}. This
+ * {@link SharedPreferences} file to {@link com.fsck.k9.mailstore.LocalStore#DB_VERSION}. This
* is done as an optimization because it's faster than opening all of the accounts' databases
* one by one.
* If there was an error reading the cached database version or if it shows the databases need
diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java
index 2eac23514..c6ee715de 100644
--- a/src/com/fsck/k9/activity/setup/AccountSettings.java
+++ b/src/com/fsck/k9/activity/setup/AccountSettings.java
@@ -36,8 +36,8 @@ import com.fsck.k9.activity.K9PreferenceActivity;
import com.fsck.k9.activity.ManageIdentities;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Store;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.StorageManager;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.StorageManager;
import com.fsck.k9.service.MailService;
import org.openintents.openpgp.util.OpenPgpListPreference;
diff --git a/src/com/fsck/k9/activity/setup/FolderSettings.java b/src/com/fsck/k9/activity/setup/FolderSettings.java
index af9ab8b67..737e2ffc3 100644
--- a/src/com/fsck/k9/activity/setup/FolderSettings.java
+++ b/src/com/fsck/k9/activity/setup/FolderSettings.java
@@ -16,8 +16,8 @@ import com.fsck.k9.mail.Folder.FolderClass;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Store;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.service.MailService;
public class FolderSettings extends K9PreferenceActivity {
diff --git a/src/com/fsck/k9/cache/EmailProviderCache.java b/src/com/fsck/k9/cache/EmailProviderCache.java
index a37f66acd..81b785997 100644
--- a/src/com/fsck/k9/cache/EmailProviderCache.java
+++ b/src/com/fsck/k9/cache/EmailProviderCache.java
@@ -11,8 +11,8 @@ import android.support.v4.content.LocalBroadcastManager;
import com.fsck.k9.fragment.MessageListFragment;
import com.fsck.k9.mail.Message;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.provider.EmailProvider;
/**
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index c95748874..1e7e98885 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -81,14 +81,14 @@ import com.fsck.k9.mail.Transport;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
-import com.fsck.k9.local.MessageRemovalListener;
+import com.fsck.k9.mailstore.MessageRemovalListener;
import com.fsck.k9.mail.MessageRetrievalListener;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.LocalMessage;
-import com.fsck.k9.local.LocalStore;
-import com.fsck.k9.local.LocalStore.PendingCommand;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.LocalMessage;
+import com.fsck.k9.mailstore.LocalStore;
+import com.fsck.k9.mailstore.LocalStore.PendingCommand;
import com.fsck.k9.mail.store.Pop3Store;
-import com.fsck.k9.local.UnavailableStorageException;
+import com.fsck.k9.mailstore.UnavailableStorageException;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.StatsColumns;
import com.fsck.k9.search.ConditionsTreeNode;
diff --git a/src/com/fsck/k9/controller/MessagingControllerPushReceiver.java b/src/com/fsck/k9/controller/MessagingControllerPushReceiver.java
index d99f5feb1..3bdec8c22 100644
--- a/src/com/fsck/k9/controller/MessagingControllerPushReceiver.java
+++ b/src/com/fsck/k9/controller/MessagingControllerPushReceiver.java
@@ -11,8 +11,8 @@ import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.PushReceiver;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.service.SleepService;
import java.util.List;
diff --git a/src/com/fsck/k9/controller/MessagingListener.java b/src/com/fsck/k9/controller/MessagingListener.java
index a0396b535..72bd93d18 100644
--- a/src/com/fsck/k9/controller/MessagingListener.java
+++ b/src/com/fsck/k9/controller/MessagingListener.java
@@ -11,7 +11,7 @@ import com.fsck.k9.BaseAccount;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Part;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.LocalMessage;
/**
* Defines the interface that {@link MessagingController} will use to callback to requesters.
diff --git a/src/com/fsck/k9/fragment/MessageListFragment.java b/src/com/fsck/k9/fragment/MessageListFragment.java
index 46760b3fa..f697b6f2e 100644
--- a/src/com/fsck/k9/fragment/MessageListFragment.java
+++ b/src/com/fsck/k9/fragment/MessageListFragment.java
@@ -88,9 +88,9 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.LocalMessage;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.LocalMessage;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.MessageColumns;
import com.fsck.k9.provider.EmailProvider.SpecialColumns;
diff --git a/src/com/fsck/k9/fragment/MessageViewFragment.java b/src/com/fsck/k9/fragment/MessageViewFragment.java
index 5ffee961a..961a38555 100644
--- a/src/com/fsck/k9/fragment/MessageViewFragment.java
+++ b/src/com/fsck/k9/fragment/MessageViewFragment.java
@@ -38,7 +38,7 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.view.AttachmentView;
import com.fsck.k9.view.AttachmentView.AttachmentFileDownloadCallback;
import com.fsck.k9.view.MessageHeader;
diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java
index 5e88d3b5e..55caf8f66 100644
--- a/src/com/fsck/k9/helper/MessageHelper.java
+++ b/src/com/fsck/k9/helper/MessageHelper.java
@@ -13,7 +13,7 @@ import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Message.RecipientType;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.LocalMessage;
public class MessageHelper {
diff --git a/src/com/fsck/k9/local/AttachmentMessageBodyUtil.java b/src/com/fsck/k9/mailstore/AttachmentMessageBodyUtil.java
similarity index 97%
rename from src/com/fsck/k9/local/AttachmentMessageBodyUtil.java
rename to src/com/fsck/k9/mailstore/AttachmentMessageBodyUtil.java
index 97a8a2394..71fc418d6 100644
--- a/src/com/fsck/k9/local/AttachmentMessageBodyUtil.java
+++ b/src/com/fsck/k9/mailstore/AttachmentMessageBodyUtil.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.IOException;
import java.io.InputStream;
diff --git a/src/com/fsck/k9/local/BinaryAttachmentBody.java b/src/com/fsck/k9/mailstore/BinaryAttachmentBody.java
similarity index 98%
rename from src/com/fsck/k9/local/BinaryAttachmentBody.java
rename to src/com/fsck/k9/mailstore/BinaryAttachmentBody.java
index 466f6e57f..ecf40c75f 100644
--- a/src/com/fsck/k9/local/BinaryAttachmentBody.java
+++ b/src/com/fsck/k9/mailstore/BinaryAttachmentBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.IOException;
import java.io.InputStream;
diff --git a/src/com/fsck/k9/local/LocalAttachmentBody.java b/src/com/fsck/k9/mailstore/LocalAttachmentBody.java
similarity index 97%
rename from src/com/fsck/k9/local/LocalAttachmentBody.java
rename to src/com/fsck/k9/mailstore/LocalAttachmentBody.java
index acfbe7980..0accef810 100644
--- a/src/com/fsck/k9/local/LocalAttachmentBody.java
+++ b/src/com/fsck/k9/mailstore/LocalAttachmentBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
diff --git a/src/com/fsck/k9/local/LocalAttachmentBodyPart.java b/src/com/fsck/k9/mailstore/LocalAttachmentBodyPart.java
similarity index 96%
rename from src/com/fsck/k9/local/LocalAttachmentBodyPart.java
rename to src/com/fsck/k9/mailstore/LocalAttachmentBodyPart.java
index 7d5a19798..ab6eae968 100644
--- a/src/com/fsck/k9/local/LocalAttachmentBodyPart.java
+++ b/src/com/fsck/k9/mailstore/LocalAttachmentBodyPart.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.MessagingException;
diff --git a/src/com/fsck/k9/local/LocalAttachmentMessageBody.java b/src/com/fsck/k9/mailstore/LocalAttachmentMessageBody.java
similarity index 97%
rename from src/com/fsck/k9/local/LocalAttachmentMessageBody.java
rename to src/com/fsck/k9/mailstore/LocalAttachmentMessageBody.java
index 6dc632495..bd0a4329f 100644
--- a/src/com/fsck/k9/local/LocalAttachmentMessageBody.java
+++ b/src/com/fsck/k9/mailstore/LocalAttachmentMessageBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/src/com/fsck/k9/local/LocalFolder.java b/src/com/fsck/k9/mailstore/LocalFolder.java
similarity index 99%
rename from src/com/fsck/k9/local/LocalFolder.java
rename to src/com/fsck/k9/mailstore/LocalFolder.java
index 9fa2bcc79..edf81d931 100644
--- a/src/com/fsck/k9/local/LocalFolder.java
+++ b/src/com/fsck/k9/mailstore/LocalFolder.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.File;
import java.io.FileOutputStream;
@@ -52,8 +52,8 @@ import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
import com.fsck.k9.mail.internet.MimeUtility.ViewableContainer;
-import com.fsck.k9.local.LockableDatabase.DbCallback;
-import com.fsck.k9.local.LockableDatabase.WrappedException;
+import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
+import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
import com.fsck.k9.provider.AttachmentProvider;
public class LocalFolder extends Folder implements Serializable {
diff --git a/src/com/fsck/k9/local/LocalMessage.java b/src/com/fsck/k9/mailstore/LocalMessage.java
similarity index 99%
rename from src/com/fsck/k9/local/LocalMessage.java
rename to src/com/fsck/k9/mailstore/LocalMessage.java
index 292be2c51..464a6b1e9 100644
--- a/src/com/fsck/k9/local/LocalMessage.java
+++ b/src/com/fsck/k9/mailstore/LocalMessage.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.IOException;
import java.io.OutputStream;
@@ -22,8 +22,8 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeUtility;
-import com.fsck.k9.local.LockableDatabase.DbCallback;
-import com.fsck.k9.local.LockableDatabase.WrappedException;
+import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
+import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
public class LocalMessage extends MimeMessage {
protected MessageReference mReference;
diff --git a/src/com/fsck/k9/local/LocalStore.java b/src/com/fsck/k9/mailstore/LocalStore.java
similarity index 99%
rename from src/com/fsck/k9/local/LocalStore.java
rename to src/com/fsck/k9/mailstore/LocalStore.java
index a7ec36f51..45ce9ad42 100644
--- a/src/com/fsck/k9/local/LocalStore.java
+++ b/src/com/fsck/k9/mailstore/LocalStore.java
@@ -1,5 +1,5 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import android.app.Application;
import android.content.ContentResolver;
@@ -22,10 +22,10 @@ import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.store.RemoteStore;
-import com.fsck.k9.local.StorageManager.StorageProvider;
+import com.fsck.k9.mailstore.StorageManager.StorageProvider;
import com.fsck.k9.mail.store.StoreConfig;
-import com.fsck.k9.local.LockableDatabase.DbCallback;
-import com.fsck.k9.local.LockableDatabase.WrappedException;
+import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
+import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.MessageColumns;
import com.fsck.k9.search.LocalSearch;
diff --git a/src/com/fsck/k9/local/LocalTextBody.java b/src/com/fsck/k9/mailstore/LocalTextBody.java
similarity index 93%
rename from src/com/fsck/k9/local/LocalTextBody.java
rename to src/com/fsck/k9/mailstore/LocalTextBody.java
index b40d79b8e..57c4963cf 100644
--- a/src/com/fsck/k9/local/LocalTextBody.java
+++ b/src/com/fsck/k9/mailstore/LocalTextBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import com.fsck.k9.mail.internet.TextBody;
diff --git a/src/com/fsck/k9/local/LockableDatabase.java b/src/com/fsck/k9/mailstore/LockableDatabase.java
similarity index 99%
rename from src/com/fsck/k9/local/LockableDatabase.java
rename to src/com/fsck/k9/mailstore/LockableDatabase.java
index 62f013953..f7c0a2258 100644
--- a/src/com/fsck/k9/local/LockableDatabase.java
+++ b/src/com/fsck/k9/mailstore/LockableDatabase.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.File;
import java.util.concurrent.locks.Lock;
@@ -34,7 +34,7 @@ public class LockableDatabase {
* @return Any relevant data. Can be null
.
* @throws WrappedException
* @throws com.fsck.k9.mail.MessagingException
- * @throws com.fsck.k9.local.UnavailableStorageException
+ * @throws com.fsck.k9.mailstore.UnavailableStorageException
*/
T doDbWork(SQLiteDatabase db) throws WrappedException, MessagingException;
}
diff --git a/src/com/fsck/k9/local/MessageRemovalListener.java b/src/com/fsck/k9/mailstore/MessageRemovalListener.java
similarity index 80%
rename from src/com/fsck/k9/local/MessageRemovalListener.java
rename to src/com/fsck/k9/mailstore/MessageRemovalListener.java
index 3f4d47d0e..51ad9a15e 100644
--- a/src/com/fsck/k9/local/MessageRemovalListener.java
+++ b/src/com/fsck/k9/mailstore/MessageRemovalListener.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import com.fsck.k9.mail.Message;
diff --git a/src/com/fsck/k9/local/StorageManager.java b/src/com/fsck/k9/mailstore/StorageManager.java
similarity index 99%
rename from src/com/fsck/k9/local/StorageManager.java
rename to src/com/fsck/k9/mailstore/StorageManager.java
index 20676d720..3aaf663dc 100644
--- a/src/com/fsck/k9/local/StorageManager.java
+++ b/src/com/fsck/k9/mailstore/StorageManager.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.File;
import java.io.IOException;
diff --git a/src/com/fsck/k9/local/StoreSchemaDefinition.java b/src/com/fsck/k9/mailstore/StoreSchemaDefinition.java
similarity index 99%
rename from src/com/fsck/k9/local/StoreSchemaDefinition.java
rename to src/com/fsck/k9/mailstore/StoreSchemaDefinition.java
index c893e5888..f9e786dba 100644
--- a/src/com/fsck/k9/local/StoreSchemaDefinition.java
+++ b/src/com/fsck/k9/mailstore/StoreSchemaDefinition.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/fsck/k9/local/TempFileBody.java b/src/com/fsck/k9/mailstore/TempFileBody.java
similarity index 95%
rename from src/com/fsck/k9/local/TempFileBody.java
rename to src/com/fsck/k9/mailstore/TempFileBody.java
index c687d6082..934b3bd68 100644
--- a/src/com/fsck/k9/local/TempFileBody.java
+++ b/src/com/fsck/k9/mailstore/TempFileBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.ByteArrayInputStream;
import java.io.File;
diff --git a/src/com/fsck/k9/local/TempFileMessageBody.java b/src/com/fsck/k9/mailstore/TempFileMessageBody.java
similarity index 97%
rename from src/com/fsck/k9/local/TempFileMessageBody.java
rename to src/com/fsck/k9/mailstore/TempFileMessageBody.java
index 55f6b76e4..c310ae2e4 100644
--- a/src/com/fsck/k9/local/TempFileMessageBody.java
+++ b/src/com/fsck/k9/mailstore/TempFileMessageBody.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/src/com/fsck/k9/local/ThreadInfo.java b/src/com/fsck/k9/mailstore/ThreadInfo.java
similarity index 93%
rename from src/com/fsck/k9/local/ThreadInfo.java
rename to src/com/fsck/k9/mailstore/ThreadInfo.java
index cf72dddc1..9f9ee2204 100644
--- a/src/com/fsck/k9/local/ThreadInfo.java
+++ b/src/com/fsck/k9/mailstore/ThreadInfo.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
class ThreadInfo {
public final long threadId;
diff --git a/src/com/fsck/k9/local/UnavailableStorageException.java b/src/com/fsck/k9/mailstore/UnavailableStorageException.java
similarity index 96%
rename from src/com/fsck/k9/local/UnavailableStorageException.java
rename to src/com/fsck/k9/mailstore/UnavailableStorageException.java
index d6e1cd69d..d764a0e39 100644
--- a/src/com/fsck/k9/local/UnavailableStorageException.java
+++ b/src/com/fsck/k9/mailstore/UnavailableStorageException.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.local;
+package com.fsck.k9.mailstore;
import com.fsck.k9.mail.MessagingException;
diff --git a/src/com/fsck/k9/preferences/AccountSettings.java b/src/com/fsck/k9/preferences/AccountSettings.java
index 327ff38b2..6bdcb4699 100644
--- a/src/com/fsck/k9/preferences/AccountSettings.java
+++ b/src/com/fsck/k9/preferences/AccountSettings.java
@@ -13,7 +13,7 @@ import com.fsck.k9.Account.SortType;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.Account.FolderMode;
-import com.fsck.k9.local.StorageManager;
+import com.fsck.k9.mailstore.StorageManager;
import com.fsck.k9.preferences.Settings.*;
public class AccountSettings {
diff --git a/src/com/fsck/k9/provider/AttachmentProvider.java b/src/com/fsck/k9/provider/AttachmentProvider.java
index 792c8885f..6516f60ef 100644
--- a/src/com/fsck/k9/provider/AttachmentProvider.java
+++ b/src/com/fsck/k9/provider/AttachmentProvider.java
@@ -15,9 +15,9 @@ import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.MimeUtility;
-import com.fsck.k9.local.LocalStore;
-import com.fsck.k9.local.LocalStore.AttachmentInfo;
-import com.fsck.k9.local.StorageManager;
+import com.fsck.k9.mailstore.LocalStore;
+import com.fsck.k9.mailstore.LocalStore.AttachmentInfo;
+import com.fsck.k9.mailstore.StorageManager;
import java.io.*;
import java.util.List;
diff --git a/src/com/fsck/k9/provider/EmailProvider.java b/src/com/fsck/k9/provider/EmailProvider.java
index fb025f46c..d599f4ac7 100644
--- a/src/com/fsck/k9/provider/EmailProvider.java
+++ b/src/com/fsck/k9/provider/EmailProvider.java
@@ -10,11 +10,11 @@ import com.fsck.k9.Preferences;
import com.fsck.k9.cache.EmailProviderCacheCursor;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.local.LockableDatabase;
-import com.fsck.k9.local.LockableDatabase.DbCallback;
-import com.fsck.k9.local.LockableDatabase.WrappedException;
-import com.fsck.k9.local.UnavailableStorageException;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.LockableDatabase;
+import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
+import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
+import com.fsck.k9.mailstore.UnavailableStorageException;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.search.SqlQueryBuilder;
import android.content.ContentProvider;
diff --git a/src/com/fsck/k9/provider/MessageProvider.java b/src/com/fsck/k9/provider/MessageProvider.java
index a02bf5520..4508edf1b 100644
--- a/src/com/fsck/k9/provider/MessageProvider.java
+++ b/src/com/fsck/k9/provider/MessageProvider.java
@@ -32,9 +32,9 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.LocalMessage;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.LocalMessage;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.search.SearchAccount;
import java.lang.ref.WeakReference;
diff --git a/src/com/fsck/k9/search/SqlQueryBuilder.java b/src/com/fsck/k9/search/SqlQueryBuilder.java
index 8286f5d9e..118467301 100644
--- a/src/com/fsck/k9/search/SqlQueryBuilder.java
+++ b/src/com/fsck/k9/search/SqlQueryBuilder.java
@@ -5,8 +5,8 @@ import java.util.List;
import com.fsck.k9.Account;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Folder;
-import com.fsck.k9.local.LocalFolder;
-import com.fsck.k9.local.LocalStore;
+import com.fsck.k9.mailstore.LocalFolder;
+import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.fsck.k9.search.SearchSpecification.Searchfield;
diff --git a/src/com/fsck/k9/service/DatabaseUpgradeService.java b/src/com/fsck/k9/service/DatabaseUpgradeService.java
index 15f0e16f1..d0fe0b5b4 100644
--- a/src/com/fsck/k9/service/DatabaseUpgradeService.java
+++ b/src/com/fsck/k9/service/DatabaseUpgradeService.java
@@ -17,7 +17,7 @@ import com.fsck.k9.Preferences;
import com.fsck.k9.activity.UpgradeDatabases;
import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
-import com.fsck.k9.local.UnavailableStorageException;
+import com.fsck.k9.mailstore.UnavailableStorageException;
/**
* Service used to upgrade the accounts' databases and/or track the progress of the upgrade.
diff --git a/src/com/fsck/k9/service/NotificationActionService.java b/src/com/fsck/k9/service/NotificationActionService.java
index 96d3cf705..50f14bc15 100644
--- a/src/com/fsck/k9/service/NotificationActionService.java
+++ b/src/com/fsck/k9/service/NotificationActionService.java
@@ -11,7 +11,7 @@ import com.fsck.k9.activity.MessageCompose;
import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.mail.Flag;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.LocalMessage;
import android.app.PendingIntent;
import android.content.Context;
diff --git a/src/com/fsck/k9/service/StorageGoneReceiver.java b/src/com/fsck/k9/service/StorageGoneReceiver.java
index 022ae9b9c..592656f9d 100644
--- a/src/com/fsck/k9/service/StorageGoneReceiver.java
+++ b/src/com/fsck/k9/service/StorageGoneReceiver.java
@@ -7,7 +7,7 @@ import android.net.Uri;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.local.StorageManager;
+import com.fsck.k9.mailstore.StorageManager;
/**
* That BroadcastReceiver is only interested in UNMOUNT events.
diff --git a/src/com/fsck/k9/service/StorageReceiver.java b/src/com/fsck/k9/service/StorageReceiver.java
index 1cf116dd6..abf36dd13 100644
--- a/src/com/fsck/k9/service/StorageReceiver.java
+++ b/src/com/fsck/k9/service/StorageReceiver.java
@@ -7,7 +7,7 @@ import android.net.Uri;
import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.local.StorageManager;
+import com.fsck.k9.mailstore.StorageManager;
/**
* That BroadcastReceiver is only interested in MOUNT events.
diff --git a/src/com/fsck/k9/view/AttachmentView.java b/src/com/fsck/k9/view/AttachmentView.java
index 84d0d9ff8..7552c23b5 100644
--- a/src/com/fsck/k9/view/AttachmentView.java
+++ b/src/com/fsck/k9/view/AttachmentView.java
@@ -43,7 +43,7 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MimeHeader;
import com.fsck.k9.mail.internet.MimeUtility;
-import com.fsck.k9.local.LocalAttachmentBodyPart;
+import com.fsck.k9.mailstore.LocalAttachmentBodyPart;
import com.fsck.k9.provider.AttachmentProvider;
import org.apache.commons.io.IOUtils;
diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java
index 4747415ef..3ebdd89a3 100644
--- a/src/com/fsck/k9/view/SingleMessageView.java
+++ b/src/com/fsck/k9/view/SingleMessageView.java
@@ -56,8 +56,8 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Multipart;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MimeUtility;
-import com.fsck.k9.local.LocalAttachmentBodyPart;
-import com.fsck.k9.local.LocalMessage;
+import com.fsck.k9.mailstore.LocalAttachmentBodyPart;
+import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.provider.AttachmentProvider.AttachmentProviderColumns;
import org.apache.commons.io.IOUtils;
From 238c1650c53bb3b99d3a2c19e4ced01a3511258f Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Sun, 14 Dec 2014 15:54:27 +0000
Subject: [PATCH 15/29] Remove URLEncodingHelper dependency
---
src/com/fsck/k9/mail/Store.java | 19 ++++++++++++++
src/com/fsck/k9/mail/Transport.java | 19 ++++++++++++++
src/com/fsck/k9/mail/store/ImapStore.java | 19 +++++++-------
src/com/fsck/k9/mail/store/Pop3Store.java | 13 +++++-----
src/com/fsck/k9/mail/store/WebDavStore.java | 25 +++++++++----------
.../fsck/k9/mail/transport/SmtpTransport.java | 19 +++++++-------
6 files changed, 74 insertions(+), 40 deletions(-)
diff --git a/src/com/fsck/k9/mail/Store.java b/src/com/fsck/k9/mail/Store.java
index 424b6bca1..0892279c5 100644
--- a/src/com/fsck/k9/mail/Store.java
+++ b/src/com/fsck/k9/mail/Store.java
@@ -1,6 +1,9 @@
package com.fsck.k9.mail;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
import java.util.List;
/**
@@ -47,4 +50,20 @@ public abstract class Store {
public Pusher getPusher(PushReceiver receiver) {
return null;
}
+
+ protected static String decodeUtf8(String s) {
+ try {
+ return URLDecoder.decode(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not found");
+ }
+ }
+
+ protected static String encodeUtf8(String s) {
+ try {
+ return URLEncoder.encode(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not found");
+ }
+ }
}
diff --git a/src/com/fsck/k9/mail/Transport.java b/src/com/fsck/k9/mail/Transport.java
index 97e4ada1d..17d3e6866 100644
--- a/src/com/fsck/k9/mail/Transport.java
+++ b/src/com/fsck/k9/mail/Transport.java
@@ -5,6 +5,10 @@ import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.transport.SmtpTransport;
import com.fsck.k9.mail.transport.WebDavTransport;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
public abstract class Transport {
protected static final int SOCKET_CONNECT_TIMEOUT = 10000;
@@ -71,4 +75,19 @@ public abstract class Transport {
public abstract void sendMessage(Message message) throws MessagingException;
public abstract void close();
+
+ protected static String encodeUtf8(String s) {
+ try {
+ return URLEncoder.encode(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not found");
+ }
+ }
+ protected static String decodeUtf8(String s) {
+ try {
+ return URLDecoder.decode(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not found");
+ }
+ }
}
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index 051c29f2d..c5eb8ead3 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -57,7 +57,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.R;
-import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
import com.fsck.k9.mail.AuthType;
@@ -197,19 +196,19 @@ public class ImapStore extends RemoteStore {
if (userinfo.endsWith(":")) {
// Password is empty. This can only happen after an account was imported.
authenticationType = AuthType.valueOf(userInfoParts[0]);
- username = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
+ username = decodeUtf8(userInfoParts[1]);
} else if (userInfoParts.length == 2) {
authenticationType = AuthType.PLAIN;
- username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
- password = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
+ username = decodeUtf8(userInfoParts[0]);
+ password = decodeUtf8(userInfoParts[1]);
} else if (userInfoParts.length == 3) {
authenticationType = AuthType.valueOf(userInfoParts[0]);
- username = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
+ username = decodeUtf8(userInfoParts[1]);
if (AuthType.EXTERNAL == authenticationType) {
- clientCertificateAlias = UrlEncodingHelper.decodeUtf8(userInfoParts[2]);
+ clientCertificateAlias = decodeUtf8(userInfoParts[2]);
} else {
- password = UrlEncodingHelper.decodeUtf8(userInfoParts[2]);
+ password = decodeUtf8(userInfoParts[2]);
}
}
}
@@ -248,11 +247,11 @@ public class ImapStore extends RemoteStore {
* @see ImapStore#decodeUri(String)
*/
public static String createUri(ServerSettings server) {
- String userEnc = UrlEncodingHelper.encodeUtf8(server.username);
+ String userEnc = encodeUtf8(server.username);
String passwordEnc = (server.password != null) ?
- UrlEncodingHelper.encodeUtf8(server.password) : "";
+ encodeUtf8(server.password) : "";
String clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
- UrlEncodingHelper.encodeUtf8(server.clientCertificateAlias) : "";
+ encodeUtf8(server.clientCertificateAlias) : "";
String scheme;
switch (server.connectionSecurity) {
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index 85c73f0f0..b2d687fce 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -5,7 +5,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.R;
-import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.Hex;
@@ -125,12 +124,12 @@ public class Pop3Store extends RemoteStore {
passwordIndex++;
authType = AuthType.valueOf(userInfoParts[0]);
}
- username = UrlEncodingHelper.decodeUtf8(userInfoParts[userIndex]);
+ username = decodeUtf8(userInfoParts[userIndex]);
if (userInfoParts.length > passwordIndex) {
if (authType == AuthType.EXTERNAL) {
- clientCertificateAlias = UrlEncodingHelper.decodeUtf8(userInfoParts[passwordIndex]);
+ clientCertificateAlias = decodeUtf8(userInfoParts[passwordIndex]);
} else {
- password = UrlEncodingHelper.decodeUtf8(userInfoParts[passwordIndex]);
+ password = decodeUtf8(userInfoParts[passwordIndex]);
}
}
}
@@ -151,11 +150,11 @@ public class Pop3Store extends RemoteStore {
* @see Pop3Store#decodeUri(String)
*/
public static String createUri(ServerSettings server) {
- String userEnc = UrlEncodingHelper.encodeUtf8(server.username);
+ String userEnc = encodeUtf8(server.username);
String passwordEnc = (server.password != null) ?
- UrlEncodingHelper.encodeUtf8(server.password) : "";
+ encodeUtf8(server.password) : "";
String clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
- UrlEncodingHelper.encodeUtf8(server.clientCertificateAlias) : "";
+ encodeUtf8(server.clientCertificateAlias) : "";
String scheme;
switch (server.connectionSecurity) {
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index a08d11cbe..f1202ff45 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -4,7 +4,6 @@ import android.util.Log;
import com.fsck.k9.K9;
-import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
@@ -137,7 +136,7 @@ public class WebDavStore extends RemoteStore {
String userInfo = webDavUri.getUserInfo();
if (userInfo != null) {
String[] userInfoParts = userInfo.split(":");
- username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
+ username = decodeUtf8(userInfoParts[0]);
String userParts[] = username.split("\\\\", 2);
if (userParts.length > 1) {
@@ -146,7 +145,7 @@ public class WebDavStore extends RemoteStore {
alias = username;
}
if (userInfoParts.length > 1) {
- password = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
+ password = decodeUtf8(userInfoParts[1]);
}
}
@@ -186,9 +185,9 @@ public class WebDavStore extends RemoteStore {
* @see WebDavStore#decodeUri(String)
*/
public static String createUri(ServerSettings server) {
- String userEnc = UrlEncodingHelper.encodeUtf8(server.username);
+ String userEnc = encodeUtf8(server.username);
String passwordEnc = (server.password != null) ?
- UrlEncodingHelper.encodeUtf8(server.password) : "";
+ encodeUtf8(server.password) : "";
String scheme;
switch (server.connectionSecurity) {
@@ -474,7 +473,7 @@ public class WebDavStore extends RemoteStore {
// Decodes the url-encoded folder name (i.e. "My%20folder" => "My Folder"
- return UrlEncodingHelper.decodeUtf8(fullPathName);
+ return decodeUtf8(fullPathName);
}
return null;
@@ -1237,9 +1236,9 @@ public class WebDavStore extends RemoteStore {
String url = "";
for (int i = 0, count = urlParts.length; i < count; i++) {
if (i != 0) {
- url = url + "/" + UrlEncodingHelper.encodeUtf8(urlParts[i]);
+ url = url + "/" + encodeUtf8(urlParts[i]);
} else {
- url = UrlEncodingHelper.encodeUtf8(urlParts[i]);
+ url = encodeUtf8(urlParts[i]);
}
}
encodedName = url;
@@ -1880,7 +1879,7 @@ public class WebDavStore extends RemoteStore {
if (!messageURL.endsWith("/")) {
messageURL += "/";
}
- messageURL += UrlEncodingHelper.encodeUtf8(message.getUid() + ":" + System.currentTimeMillis() + ".eml");
+ messageURL += encodeUtf8(message.getUid() + ":" + System.currentTimeMillis() + ".eml");
Log.i(K9.LOG_TAG, "Uploading message as " + messageURL);
@@ -1967,8 +1966,8 @@ public class WebDavStore extends RemoteStore {
* We have to decode, then encode the URL because Exchange likes to not properly encode all characters
*/
try {
- end = UrlEncodingHelper.decodeUtf8(end);
- end = UrlEncodingHelper.encodeUtf8(end);
+ end = decodeUtf8(end);
+ end = encodeUtf8(end);
end = end.replaceAll("\\+", "%20");
} catch (IllegalArgumentException iae) {
Log.e(K9.LOG_TAG, "IllegalArgumentException caught in setUrl: " + iae + "\nTrace: "
@@ -2372,8 +2371,8 @@ public class WebDavStore extends RemoteStore {
*/
try {
if (length > 3) {
- end = UrlEncodingHelper.decodeUtf8(end);
- end = UrlEncodingHelper.encodeUtf8(end);
+ end = decodeUtf8(end);
+ end = encodeUtf8(end);
end = end.replaceAll("\\+", "%20");
}
} catch (IllegalArgumentException iae) {
diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java
index 6e30eab20..568f30b5e 100644
--- a/src/com/fsck/k9/mail/transport/SmtpTransport.java
+++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java
@@ -5,7 +5,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.R;
-import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.filter.Base64;
@@ -94,19 +93,19 @@ public class SmtpTransport extends Transport {
String[] userInfoParts = smtpUri.getUserInfo().split(":");
if (userInfoParts.length == 1) {
authType = AuthType.PLAIN;
- username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
+ username = decodeUtf8(userInfoParts[0]);
} else if (userInfoParts.length == 2) {
authType = AuthType.PLAIN;
- username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
- password = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
+ username = decodeUtf8(userInfoParts[0]);
+ password = decodeUtf8(userInfoParts[1]);
} else if (userInfoParts.length == 3) {
// NOTE: In SmptTransport URIs, the authType comes last!
authType = AuthType.valueOf(userInfoParts[2]);
- username = UrlEncodingHelper.decodeUtf8(userInfoParts[0]);
+ username = decodeUtf8(userInfoParts[0]);
if (authType == AuthType.EXTERNAL) {
- clientCertificateAlias = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
+ clientCertificateAlias = decodeUtf8(userInfoParts[1]);
} else {
- password = UrlEncodingHelper.decodeUtf8(userInfoParts[1]);
+ password = decodeUtf8(userInfoParts[1]);
}
}
}
@@ -128,11 +127,11 @@ public class SmtpTransport extends Transport {
*/
public static String createUri(ServerSettings server) {
String userEnc = (server.username != null) ?
- UrlEncodingHelper.encodeUtf8(server.username) : "";
+ encodeUtf8(server.username) : "";
String passwordEnc = (server.password != null) ?
- UrlEncodingHelper.encodeUtf8(server.password) : "";
+ encodeUtf8(server.password) : "";
String clientCertificateAliasEnc = (server.clientCertificateAlias != null) ?
- UrlEncodingHelper.encodeUtf8(server.clientCertificateAlias) : "";
+ encodeUtf8(server.clientCertificateAlias) : "";
String scheme;
switch (server.connectionSecurity) {
From 476cb1d4ce6a2f1236b8b193362ac604e33bb13a Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Sun, 14 Dec 2014 15:58:08 +0000
Subject: [PATCH 16/29] Tidy responsibilities
---
src/com/fsck/k9/Preferences.java | 6 ++++++
src/com/fsck/k9/mail/store/RemoteStore.java | 2 --
src/com/fsck/k9/mailstore/LocalStore.java | 7 -------
3 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/src/com/fsck/k9/Preferences.java b/src/com/fsck/k9/Preferences.java
index 016928eb0..03a3cd1be 100644
--- a/src/com/fsck/k9/Preferences.java
+++ b/src/com/fsck/k9/Preferences.java
@@ -13,6 +13,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
+import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.preferences.Editor;
import com.fsck.k9.preferences.Storage;
@@ -121,6 +122,11 @@ public class Preferences {
accountsInOrder.remove(account);
}
+ try {
+ RemoteStore.removeInstance(account);
+ } catch (Exception e) {
+ Log.e(K9.LOG_TAG, "Failed to reset remote store for account " + account.getUuid(), e);
+ }
LocalStore.removeAccount(account);
account.deleteCertificates();
diff --git a/src/com/fsck/k9/mail/store/RemoteStore.java b/src/com/fsck/k9/mail/store/RemoteStore.java
index 9cad2aac2..a1f32722e 100644
--- a/src/com/fsck/k9/mail/store/RemoteStore.java
+++ b/src/com/fsck/k9/mail/store/RemoteStore.java
@@ -62,12 +62,10 @@ public abstract class RemoteStore extends Store {
*/
public static void removeInstance(StoreConfig storeConfig) {
String uri = storeConfig.getStoreUri();
-
if (uri.startsWith("local")) {
throw new RuntimeException("Asked to get non-local Store object but given " +
"LocalStore URI");
}
-
sStores.remove(uri);
}
diff --git a/src/com/fsck/k9/mailstore/LocalStore.java b/src/com/fsck/k9/mailstore/LocalStore.java
index 45ce9ad42..b05a9efa2 100644
--- a/src/com/fsck/k9/mailstore/LocalStore.java
+++ b/src/com/fsck/k9/mailstore/LocalStore.java
@@ -21,7 +21,6 @@ import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Store;
-import com.fsck.k9.mail.store.RemoteStore;
import com.fsck.k9.mailstore.StorageManager.StorageProvider;
import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
@@ -207,12 +206,6 @@ public class LocalStore extends Store implements Serializable {
}
public static void removeAccount(Account account) {
- try {
- RemoteStore.removeInstance(account);
- } catch (Exception e) {
- Log.e(K9.LOG_TAG, "Failed to reset remote store for account " + account.getUuid(), e);
- }
-
try {
removeInstance(account);
} catch (Exception e) {
From 7d6e6b8abea0e9072de911ee061e78d86c6e66f3 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Mon, 15 Dec 2014 12:05:21 +0100
Subject: [PATCH 17/29] MimeUtility / Message refactor
* break MimeUtility class into manageable pieces (MessageExtractor/CharsetSupport)
* move HTML related code out of the mail package
---
.../InsertableHtmlContent.java | 4 +-
src/com/fsck/k9/activity/MessageCompose.java | 30 +-
.../TextBodyBuilder.java | 6 +-
.../k9/activity/setup/WelcomeMessage.java | 2 +-
.../k9/controller/MessagingController.java | 11 +-
src/com/fsck/k9/crypto/CryptoHelper.java | 12 +-
.../internet => helper}/HtmlConverter.java | 2 +-
src/com/fsck/k9/mail/BodyPart.java | 23 +-
src/com/fsck/k9/mail/Message.java | 69 +
src/com/fsck/k9/mail/Multipart.java | 4 +-
src/com/fsck/k9/mail/Part.java | 38 +-
.../fsck/k9/mail/internet/CharsetSupport.java | 1121 ++++++++
.../fsck/k9/mail/internet/DecoderUtil.java | 6 +-
.../fsck/k9/mail/internet/EncoderUtil.java | 2 +-
src/com/fsck/k9/mail/internet/JisSupport.java | 103 +
.../k9/mail/internet/MessageExtractor.java | 410 +++
.../fsck/k9/mail/internet/MimeMessage.java | 2 +-
.../fsck/k9/mail/internet/MimeUtility.java | 2353 +----------------
src/com/fsck/k9/mail/internet/TextBody.java | 6 +-
src/com/fsck/k9/mail/internet/Viewable.java | 105 +
.../fsck/k9/mail/transport/SmtpTransport.java | 4 +-
src/com/fsck/k9/mailstore/LocalFolder.java | 10 +-
src/com/fsck/k9/mailstore/LocalMessage.java | 6 +-
.../k9/mailstore/LocalMessageExtractor.java | 464 ++++
.../fsck/k9/mailstore/ViewableContainer.java | 34 +
src/com/fsck/k9/view/MessageOpenPgpView.java | 9 +-
src/com/fsck/k9/view/MessageWebView.java | 2 +-
src/com/fsck/k9/view/SingleMessageView.java | 2 +-
.../TextBodyBuilderTest.java | 3 +-
.../k9/mail/internet/CharsetSupportTest.java | 94 +
.../k9/mail/internet/MimeUtilityTest.java | 98 -
.../HtmlConverterTest.java | 4 +-
tests/src/com/fsck/k9/mail/MessageTest.java | 4 +-
.../LocalMessageExtractorTest.java} | 19 +-
34 files changed, 2549 insertions(+), 2513 deletions(-)
rename src/com/fsck/k9/{mail/internet => activity}/InsertableHtmlContent.java (98%)
rename src/com/fsck/k9/{mail/internet => activity}/TextBodyBuilder.java (98%)
rename src/com/fsck/k9/{mail/internet => helper}/HtmlConverter.java (99%)
create mode 100644 src/com/fsck/k9/mail/internet/CharsetSupport.java
create mode 100644 src/com/fsck/k9/mail/internet/JisSupport.java
create mode 100644 src/com/fsck/k9/mail/internet/MessageExtractor.java
create mode 100644 src/com/fsck/k9/mail/internet/Viewable.java
create mode 100644 src/com/fsck/k9/mailstore/LocalMessageExtractor.java
create mode 100644 src/com/fsck/k9/mailstore/ViewableContainer.java
rename tests-on-jvm/src/com/fsck/k9/{mail/internet => activity}/TextBodyBuilderTest.java (99%)
create mode 100644 tests-on-jvm/src/com/fsck/k9/mail/internet/CharsetSupportTest.java
rename tests/src/com/fsck/k9/{mail/internet => helper}/HtmlConverterTest.java (99%)
rename tests/src/com/fsck/k9/{mail/internet/ViewablesTest.java => mailstore/LocalMessageExtractorTest.java} (89%)
diff --git a/src/com/fsck/k9/mail/internet/InsertableHtmlContent.java b/src/com/fsck/k9/activity/InsertableHtmlContent.java
similarity index 98%
rename from src/com/fsck/k9/mail/internet/InsertableHtmlContent.java
rename to src/com/fsck/k9/activity/InsertableHtmlContent.java
index fabcc6082..851f0ca9a 100644
--- a/src/com/fsck/k9/mail/internet/InsertableHtmlContent.java
+++ b/src/com/fsck/k9/activity/InsertableHtmlContent.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.internet;
+package com.fsck.k9.activity;
import java.io.Serializable;
@@ -12,7 +12,7 @@ import java.io.Serializable;
*
* TODO: This container should also have a text part, along with its insertion point. Or maybe a generic InsertableContent and maintain one each for Html and Text?
*/
-public class InsertableHtmlContent implements Serializable {
+class InsertableHtmlContent implements Serializable {
private static final long serialVersionUID = 2397327034L;
// Default to a headerInsertionPoint at the beginning of the message.
private int headerInsertionPoint = 0;
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 30f3e11cb..ffdc95878 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -90,13 +90,12 @@ import com.fsck.k9.fragment.ProgressDialogFragment;
import com.fsck.k9.helper.ContactItem;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.mail.filter.Base64;
-import com.fsck.k9.mail.internet.HtmlConverter;
+import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.helper.IdentityHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.Flag;
-import com.fsck.k9.mail.internet.InsertableHtmlContent;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.MessagingException;
@@ -108,7 +107,6 @@ import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
-import com.fsck.k9.mail.internet.TextBodyBuilder;
import com.fsck.k9.mailstore.LocalAttachmentBody;
import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.mailstore.TempFileBody;
@@ -2957,10 +2955,10 @@ public class MessageCompose extends K9Activity implements OnClickListener,
if (messageFormat == MessageFormat.HTML) {
- Part part = MimeUtility.findFirstPartByMimeType(message, "text/html");
+ Part part = message.findFirstPartByMimeType("text/html");
if (part != null) { // Shouldn't happen if we were the one who saved it.
mQuotedTextFormat = SimpleMessageFormat.HTML;
- String text = MimeUtility.getTextFromPart(part);
+ String text = part.getText();
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "Loading message with offset " + bodyOffset + ", length " + bodyLength + ". Text length is " + text.length() + ".");
}
@@ -3023,9 +3021,9 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/
private void processSourceMessageText(Message message, Integer bodyOffset, Integer bodyLength,
boolean viewMessageContent) throws MessagingException {
- Part textPart = MimeUtility.findFirstPartByMimeType(message, "text/plain");
+ Part textPart = message.findFirstPartByMimeType("text/plain");
if (textPart != null) {
- String text = MimeUtility.getTextFromPart(textPart);
+ String text = textPart.getText();
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "Loading message with offset " + bodyOffset + ", length " + bodyLength + ". Text length is " + text.length() + ".");
}
@@ -3093,7 +3091,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
// Figure out which message format to use for the quoted text by looking if the source
// message contains a text/html part. If it does, we use that.
mQuotedTextFormat =
- (MimeUtility.findFirstPartByMimeType(mSourceMessage, "text/html") == null) ?
+ (mSourceMessage.findFirstPartByMimeType("text/html") == null) ?
SimpleMessageFormat.TEXT : SimpleMessageFormat.HTML;
} else {
mQuotedTextFormat = SimpleMessageFormat.HTML;
@@ -3223,37 +3221,37 @@ public class MessageCompose extends K9Activity implements OnClickListener,
Part part;
if (format == SimpleMessageFormat.HTML) {
// HTML takes precedence, then text.
- part = MimeUtility.findFirstPartByMimeType(message, "text/html");
+ part = message.findFirstPartByMimeType("text/html");
if (part != null) {
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: HTML requested, HTML found.");
}
- return MimeUtility.getTextFromPart(part);
+ return part.getText();
}
- part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
+ part = message.findFirstPartByMimeType("text/plain");
if (part != null) {
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: HTML requested, text found.");
}
- return HtmlConverter.textToHtml(MimeUtility.getTextFromPart(part));
+ return HtmlConverter.textToHtml(part.getText());
}
} else if (format == SimpleMessageFormat.TEXT) {
// Text takes precedence, then html.
- part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
+ part = message.findFirstPartByMimeType("text/plain");
if (part != null) {
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: Text requested, text found.");
}
- return MimeUtility.getTextFromPart(part);
+ return part.getText();
}
- part = MimeUtility.findFirstPartByMimeType(message, "text/html");
+ part = message.findFirstPartByMimeType("text/html");
if (part != null) {
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: Text requested, HTML found.");
}
- return HtmlConverter.htmlToText(MimeUtility.getTextFromPart(part));
+ return HtmlConverter.htmlToText(part.getText());
}
}
diff --git a/src/com/fsck/k9/mail/internet/TextBodyBuilder.java b/src/com/fsck/k9/activity/TextBodyBuilder.java
similarity index 98%
rename from src/com/fsck/k9/mail/internet/TextBodyBuilder.java
rename to src/com/fsck/k9/activity/TextBodyBuilder.java
index 962a80e14..4dc0a0666 100644
--- a/src/com/fsck/k9/mail/internet/TextBodyBuilder.java
+++ b/src/com/fsck/k9/activity/TextBodyBuilder.java
@@ -1,12 +1,14 @@
-package com.fsck.k9.mail.internet;
+package com.fsck.k9.activity;
import android.text.TextUtils;
import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.mail.Body;
+import com.fsck.k9.helper.HtmlConverter;
+import com.fsck.k9.mail.internet.TextBody;
-public class TextBodyBuilder {
+class TextBodyBuilder {
private boolean mIncludeQuotedText = true;
private boolean mReplyAfterQuote = false;
private boolean mSignatureBeforeQuotedText = false;
diff --git a/src/com/fsck/k9/activity/setup/WelcomeMessage.java b/src/com/fsck/k9/activity/setup/WelcomeMessage.java
index e40a95eb9..9c30bb0c2 100644
--- a/src/com/fsck/k9/activity/setup/WelcomeMessage.java
+++ b/src/com/fsck/k9/activity/setup/WelcomeMessage.java
@@ -12,7 +12,7 @@ import android.widget.TextView;
import com.fsck.k9.R;
import com.fsck.k9.activity.Accounts;
import com.fsck.k9.activity.K9Activity;
-import com.fsck.k9.mail.internet.HtmlConverter;
+import com.fsck.k9.helper.HtmlConverter;
/**
* Displays a welcome message when no accounts have been created yet.
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 1e7e98885..76c151c8a 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -1744,7 +1744,7 @@ public class MessagingController implements Runnable {
* right now, attachments will be left for later.
*/
- Set viewables = MimeUtility.collectTextParts(message);
+ Set viewables = message.collectTextParts();
/*
* Now download the parts we're interested in storing.
@@ -3197,7 +3197,7 @@ public class MessagingController implements Runnable {
try {
LocalStore localStore = account.getLocalStore();
- List attachments = MimeUtility.collectAttachments(message);
+ List attachments = message.collectAttachments();
for (Part attachment : attachments) {
attachment.setBody(null);
}
@@ -4244,13 +4244,12 @@ public class MessagingController implements Runnable {
try {
Intent msg = new Intent(Intent.ACTION_SEND);
String quotedText = null;
- Part part = MimeUtility.findFirstPartByMimeType(message,
- "text/plain");
+ Part part = message.findFirstPartByMimeType("text/plain");
if (part == null) {
- part = MimeUtility.findFirstPartByMimeType(message, "text/html");
+ part = message.findFirstPartByMimeType("text/html");
}
if (part != null) {
- quotedText = MimeUtility.getTextFromPart(part);
+ quotedText = part.getText();
}
if (quotedText != null) {
msg.putExtra(Intent.EXTRA_TEXT, quotedText);
diff --git a/src/com/fsck/k9/crypto/CryptoHelper.java b/src/com/fsck/k9/crypto/CryptoHelper.java
index 3ce2787c7..9bc421127 100644
--- a/src/com/fsck/k9/crypto/CryptoHelper.java
+++ b/src/com/fsck/k9/crypto/CryptoHelper.java
@@ -32,12 +32,12 @@ public class CryptoHelper {
public boolean isEncrypted(Message message) {
String data = null;
try {
- Part part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
+ Part part = message.findFirstPartByMimeType("text/plain");
if (part == null) {
- part = MimeUtility.findFirstPartByMimeType(message, "text/html");
+ part = message.findFirstPartByMimeType("text/html");
}
if (part != null) {
- data = MimeUtility.getTextFromPart(part);
+ data = part.getText();
}
} catch (MessagingException e) {
// guess not...
@@ -55,12 +55,12 @@ public class CryptoHelper {
public boolean isSigned(Message message) {
String data = null;
try {
- Part part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
+ Part part = message.findFirstPartByMimeType("text/plain");
if (part == null) {
- part = MimeUtility.findFirstPartByMimeType(message, "text/html");
+ part = message.findFirstPartByMimeType("text/html");
}
if (part != null) {
- data = MimeUtility.getTextFromPart(part);
+ data = part.getText();
}
} catch (MessagingException e) {
// guess not...
diff --git a/src/com/fsck/k9/mail/internet/HtmlConverter.java b/src/com/fsck/k9/helper/HtmlConverter.java
similarity index 99%
rename from src/com/fsck/k9/mail/internet/HtmlConverter.java
rename to src/com/fsck/k9/helper/HtmlConverter.java
index 8d28085c1..28bf875b4 100644
--- a/src/com/fsck/k9/mail/internet/HtmlConverter.java
+++ b/src/com/fsck/k9/helper/HtmlConverter.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.internet;
+package com.fsck.k9.helper;
import android.text.*;
import android.text.Html.TagHandler;
diff --git a/src/com/fsck/k9/mail/BodyPart.java b/src/com/fsck/k9/mail/BodyPart.java
index 1118304ba..84e4324f5 100644
--- a/src/com/fsck/k9/mail/BodyPart.java
+++ b/src/com/fsck/k9/mail/BodyPart.java
@@ -1,6 +1,9 @@
package com.fsck.k9.mail;
+import com.fsck.k9.mail.internet.MessageExtractor;
+import com.fsck.k9.mail.internet.MimeUtility;
+
public abstract class BodyPart implements Part {
private Multipart mParent;
@@ -15,5 +18,23 @@ public abstract class BodyPart implements Part {
public abstract void setEncoding(String encoding) throws MessagingException;
@Override
- public abstract void setUsing7bitTransport() throws MessagingException;
+ public String getContentDisposition() {
+ try {
+ String disposition = getDisposition();
+ if (disposition != null) {
+ return MimeUtility.getHeaderParameter(disposition, null);
+ }
+ } catch (MessagingException e) { /* ignore */ }
+ return null;
+ }
+
+ @Override
+ public String getText() {
+ return MessageExtractor.getTextFromPart(this);
+ }
+
+ @Override
+ public Part findFirstPartByMimeType(String mimeType) throws MessagingException {
+ return MimeUtility.findFirstPartByMimeType(this, mimeType);
+ }
}
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index 24a29af5f..f48eaf559 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -2,9 +2,11 @@
package com.fsck.k9.mail;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
+import java.util.List;
import java.util.Set;
import android.util.Log;
@@ -12,6 +14,8 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.mail.filter.CountingOutputStream;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
+import com.fsck.k9.mail.internet.MessageExtractor;
+import com.fsck.k9.mail.internet.MimeUtility;
public abstract class Message implements Part, CompositeBody {
@@ -265,4 +269,69 @@ public abstract class Message implements Part, CompositeBody {
*/
@Override
public abstract Message clone();
+
+ /**
+ * Get the value of the {@code Content-Disposition} header.
+ * @return The value of the {@code Content-Disposition} header if available. {@code null}, otherwise.
+ */
+ public String getContentDisposition() {
+ try {
+ String disposition = getDisposition();
+ if (disposition != null) {
+ return MimeUtility.getHeaderParameter(disposition, null);
+ }
+ }
+ catch (MessagingException e) { /* ignore */ }
+ return null;
+ }
+
+ @Override
+ public String getText() {
+ return MessageExtractor.getTextFromPart(this);
+ }
+
+ @Override
+ public Part findFirstPartByMimeType(String mimeType) throws MessagingException {
+ return MimeUtility.findFirstPartByMimeType(this, mimeType);
+ }
+
+ /**
+ * Collect attachment parts of a message.
+ *
+ * @param message
+ * The message to collect the attachment parts from.
+ *
+ * @return A list of parts regarded as attachments.
+ *
+ * @throws MessagingException
+ * In case of an error.
+ */
+ public List collectAttachments() throws MessagingException {
+ try {
+ List attachments = new ArrayList();
+ MessageExtractor.getViewables(this, attachments);
+ return attachments;
+ } catch (Exception e) {
+ throw new MessagingException("Couldn't collect attachment parts", e);
+ }
+ }
+
+ /**
+ * Collect the viewable textual parts of a message.
+ *
+ * @param message
+ * The message to extract the viewable parts from.
+ *
+ * @return A set of viewable parts of the message.
+ *
+ * @throws MessagingException
+ * In case of an error.
+ */
+ public Set collectTextParts() throws MessagingException {
+ try {
+ return MessageExtractor.getTextParts(this);
+ } catch (Exception e) {
+ throw new MessagingException("Couldn't extract viewable parts", e);
+ }
+ }
}
diff --git a/src/com/fsck/k9/mail/Multipart.java b/src/com/fsck/k9/mail/Multipart.java
index 567b0902d..8bcba92b3 100644
--- a/src/com/fsck/k9/mail/Multipart.java
+++ b/src/com/fsck/k9/mail/Multipart.java
@@ -7,7 +7,7 @@ import java.util.List;
import org.apache.james.mime4j.util.MimeUtil;
-import com.fsck.k9.mail.internet.MimeUtility;
+import com.fsck.k9.mail.internet.CharsetSupport;
import com.fsck.k9.mail.internet.TextBody;
public abstract class Multipart implements CompositeBody {
@@ -64,7 +64,7 @@ public abstract class Multipart implements CompositeBody {
BodyPart part = mParts.get(0);
Body body = part.getBody();
if (body instanceof TextBody) {
- MimeUtility.setCharset(charset, part);
+ CharsetSupport.setCharset(charset, part);
((TextBody)body).setCharset(charset);
}
}
diff --git a/src/com/fsck/k9/mail/Part.java b/src/com/fsck/k9/mail/Part.java
index 38c1ad9da..c890cd56e 100644
--- a/src/com/fsck/k9/mail/Part.java
+++ b/src/com/fsck/k9/mail/Part.java
@@ -5,29 +5,41 @@ import java.io.IOException;
import java.io.OutputStream;
public interface Part {
- public void addHeader(String name, String value) throws MessagingException;
+ void addHeader(String name, String value) throws MessagingException;
- public void removeHeader(String name) throws MessagingException;
+ void removeHeader(String name) throws MessagingException;
- public void setHeader(String name, String value) throws MessagingException;
+ void setHeader(String name, String value) throws MessagingException;
- public Body getBody();
+ Body getBody();
- public String getContentType() throws MessagingException;
+ String getContentType() throws MessagingException;
- public String getDisposition() throws MessagingException;
+ String getDisposition() throws MessagingException;
- public String getContentId() throws MessagingException;
+ String getContentDisposition();
- public String[] getHeader(String name) throws MessagingException;
+ String getContentId() throws MessagingException;
- public boolean isMimeType(String mimeType) throws MessagingException;
+ String[] getHeader(String name) throws MessagingException;
- public String getMimeType() throws MessagingException;
+ boolean isMimeType(String mimeType) throws MessagingException;
- public void setBody(Body body) throws MessagingException;
+ String getMimeType() throws MessagingException;
- public void writeTo(OutputStream out) throws IOException, MessagingException;
+ void setBody(Body body) throws MessagingException;
+
+ void writeTo(OutputStream out) throws IOException, MessagingException;
+
+ /**
+ * Reads the Part's body and returns a String based on any charset conversion that needed
+ * to be done. Note, this does not return a text representation of HTML.
+ * @return a String containing the converted text in the body, or null if there was no text
+ * or an error during conversion.
+ */
+ String getText();
+
+ Part findFirstPartByMimeType(String mimeType) throws MessagingException;
/**
* Called just prior to transmission, once the type of transport is known to
@@ -41,5 +53,5 @@ public interface Part {
*
*/
//TODO perhaps it would be clearer to use a flag "force7bit" in writeTo
- public abstract void setUsing7bitTransport() throws MessagingException;
+ void setUsing7bitTransport() throws MessagingException;
}
diff --git a/src/com/fsck/k9/mail/internet/CharsetSupport.java b/src/com/fsck/k9/mail/internet/CharsetSupport.java
new file mode 100644
index 000000000..5346566f3
--- /dev/null
+++ b/src/com/fsck/k9/mail/internet/CharsetSupport.java
@@ -0,0 +1,1121 @@
+package com.fsck.k9.mail.internet;
+
+import android.util.Log;
+
+import com.fsck.k9.K9;
+import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.Part;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.util.Locale;
+
+import static com.fsck.k9.mail.internet.JisSupport.SHIFT_JIS;
+
+public class CharsetSupport {
+ /**
+ * Table for character set fall-back.
+ *
+ * Table format: unsupported charset (regular expression), fall-back charset
+ */
+ private static final String[][] CHARSET_FALLBACK_MAP = new String[][] {
+ // Some Android versions don't support KOI8-U
+ {"koi8-u", "koi8-r"},
+ {"iso-2022-jp-[\\d]+", "iso-2022-jp"},
+ // Default fall-back is US-ASCII
+ {".*", "US-ASCII"}
+ };
+
+
+ public static void setCharset(String charset, Part part) throws MessagingException {
+ part.setHeader(MimeHeader.HEADER_CONTENT_TYPE,
+ part.getMimeType() + ";\r\n charset=" + getExternalCharset(charset));
+ }
+
+
+ public static String getCharsetFromAddress(String address) {
+ String variant = JisSupport.getJisVariantFromAddress(address);
+ if (variant != null) {
+ String charset = "x-" + variant + "-shift_jis-2007";
+ if (Charset.isSupported(charset))
+ return charset;
+ }
+
+ return "UTF-8";
+ }
+
+ static String getExternalCharset(String charset) {
+ if (JisSupport.isShiftJis(charset)) {
+ return SHIFT_JIS;
+ } else {
+ return charset;
+ }
+ }
+
+ static String fixupCharset(String charset, Message message) throws MessagingException {
+ if (charset == null || "0".equals(charset))
+ charset = "US-ASCII"; // No encoding, so use us-ascii, which is the standard.
+
+ charset = charset.toLowerCase(Locale.US);
+ if (charset.equals("cp932"))
+ charset = SHIFT_JIS;
+
+ if (charset.equals(SHIFT_JIS) || charset.equals("iso-2022-jp")) {
+ String variant = JisSupport.getJisVariantFromMessage(message);
+ if (variant != null)
+ charset = "x-" + variant + "-" + charset + "-2007";
+ }
+ return charset;
+ }
+
+
+ static String readToString(InputStream in, String charset) throws IOException {
+ boolean isIphoneString = false;
+
+ // iso-2022-jp variants are supported by no versions as of Dec 2010.
+ if (charset.length() > 19 && charset.startsWith("x-") &&
+ charset.endsWith("-iso-2022-jp-2007") && !Charset.isSupported(charset)) {
+ in = new Iso2022JpToShiftJisInputStream(in);
+ charset = "x-" + charset.substring(2, charset.length() - 17) + "-shift_jis-2007";
+ }
+
+ // shift_jis variants are supported by Eclair and later.
+ if (JisSupport.isShiftJis(charset) && !Charset.isSupported(charset)) {
+ // If the JIS variant is iPhone, map the Unicode private use area in iPhone to the one in Android after
+ // converting the character set from the standard Shift JIS to Unicode.
+ if (charset.substring(2, charset.length() - 15).equals("iphone"))
+ isIphoneString = true;
+
+ charset = SHIFT_JIS;
+ }
+
+ /*
+ * See if there is conversion from the MIME charset to the Java one.
+ * this function may also throw an exception if the charset name is not known
+ */
+ boolean supported;
+ try {
+ supported = Charset.isSupported(charset);
+ } catch (IllegalCharsetNameException e) {
+ supported = false;
+ }
+
+ for (String[] rule: CHARSET_FALLBACK_MAP) {
+ if (supported) {
+ break;
+ }
+
+ if (charset.matches(rule[0])) {
+ Log.e(K9.LOG_TAG, "I don't know how to deal with the charset " + charset +
+ ". Falling back to " + rule[1]);
+ charset = rule[1];
+ try {
+ supported = Charset.isSupported(charset);
+ } catch (IllegalCharsetNameException e) {
+ supported = false;
+ }
+ }
+ }
+
+ /*
+ * Convert and return as new String
+ */
+ String str = IOUtils.toString(in, charset);
+
+ if (isIphoneString)
+ str = importStringFromIphone(str);
+ return str;
+ }
+
+ private static String importStringFromIphone(String str) {
+ StringBuilder buff = new StringBuilder(str.length());
+ for (int i = 0; i < str.length(); i = str.offsetByCodePoints(i, 1)) {
+ int codePoint = str.codePointAt(i);
+ buff.appendCodePoint(importCodePointFromIphone(codePoint));
+ }
+ return buff.toString();
+ }
+
+ private static int importCodePointFromIphone(int codePoint) {
+ switch (codePoint) {
+ case 0xE001:
+ return 0xFE19B;
+ case 0xE002:
+ return 0xFE19C;
+ case 0xE003:
+ return 0xFE823;
+ case 0xE004:
+ return 0xFE19D;
+ case 0xE005:
+ return 0xFE19E;
+ case 0xE006:
+ return 0xFE4CF;
+ case 0xE007:
+ return 0xFE4CD;
+ case 0xE008:
+ return 0xFE4EF;
+ case 0xE009:
+ return 0xFE523;
+ case 0xE00A:
+ return 0xFE525;
+ case 0xE00B:
+ return 0xFE528;
+ case 0xE00C:
+ return 0xFE538;
+ case 0xE00D:
+ return 0xFEB96;
+ case 0xE00E:
+ return 0xFEB97;
+ case 0xE00F:
+ return 0xFEB98;
+ case 0xE010:
+ return 0xFEB93;
+ case 0xE011:
+ return 0xFEB94;
+ case 0xE012:
+ return 0xFEB95;
+ case 0xE013:
+ return 0xFE7D5;
+ case 0xE014:
+ return 0xFE7D2;
+ case 0xE015:
+ return 0xFE7D3;
+ case 0xE016:
+ return 0xFE7D1;
+ case 0xE017:
+ return 0xFE7DA;
+ case 0xE018:
+ return 0xFE7D4;
+ case 0xE019:
+ return 0xFE1BD;
+ case 0xE01A:
+ return 0xFE1BE;
+ case 0xE01B:
+ return 0xFE7E4;
+ case 0xE01C:
+ return 0xFE7EA;
+ case 0xE01D:
+ return 0xFE7E9;
+ case 0xE01E:
+ return 0xFE7DF;
+ case 0xE01F:
+ return 0xFE7E3;
+ case 0xE020:
+ return 0xFEB09;
+ case 0xE021:
+ return 0xFEB04;
+ case 0xE022:
+ return 0xFEB0C;
+ case 0xE023:
+ return 0xFEB0E;
+ case 0xE024:
+ return 0xFE01E;
+ case 0xE025:
+ return 0xFE01F;
+ case 0xE026:
+ return 0xFE020;
+ case 0xE027:
+ return 0xFE021;
+ case 0xE028:
+ return 0xFE022;
+ case 0xE029:
+ return 0xFE023;
+ case 0xE02A:
+ return 0xFE024;
+ case 0xE02B:
+ return 0xFE025;
+ case 0xE02C:
+ return 0xFE026;
+ case 0xE02D:
+ return 0xFE027;
+ case 0xE02E:
+ return 0xFE028;
+ case 0xE02F:
+ return 0xFE029;
+ case 0xE030:
+ return 0xFE040;
+ case 0xE031:
+ return 0xFE4D2;
+ case 0xE032:
+ return 0xFE041;
+ case 0xE033:
+ return 0xFE512;
+ case 0xE034:
+ return 0xFE825;
+ case 0xE035:
+ return 0xFE826;
+ case 0xE036:
+ return 0xFE4B0;
+ case 0xE037:
+ return 0xFE4BB;
+ case 0xE038:
+ return 0xFE4B2;
+ case 0xE039:
+ return 0xFE7EC;
+ case 0xE03A:
+ return 0xFE7F5;
+ case 0xE03B:
+ return 0xFE4C3;
+ case 0xE03C:
+ return 0xFE800;
+ case 0xE03D:
+ return 0xFE801;
+ case 0xE03E:
+ return 0xFE813;
+ case 0xE03F:
+ return 0xFEB82;
+ case 0xE040:
+ return 0xFE815;
+ case 0xE041:
+ return 0xFE816;
+ case 0xE042:
+ return 0xFE818;
+ case 0xE043:
+ return 0xFE980;
+ case 0xE044:
+ return 0xFE982;
+ case 0xE045:
+ return 0xFE981;
+ case 0xE046:
+ return 0xFE962;
+ case 0xE047:
+ return 0xFE983;
+ case 0xE048:
+ return 0xFE003;
+ case 0xE049:
+ return 0xFE001;
+ case 0xE04A:
+ return 0xFE000;
+ case 0xE04B:
+ return 0xFE002;
+ case 0xE04C:
+ return 0xFE014;
+ case 0xE04D:
+ return 0xFE009;
+ case 0xE04E:
+ return 0xFE1AF;
+ case 0xE04F:
+ return 0xFE1B8;
+ case 0xE050:
+ return 0xFE1C0;
+ case 0xE051:
+ return 0xFE1C1;
+ case 0xE052:
+ return 0xFE1B7;
+ case 0xE053:
+ return 0xFE1C2;
+ case 0xE054:
+ return 0xFE1C3;
+ case 0xE055:
+ return 0xFE1BC;
+ case 0xE056:
+ return 0xFE335;
+ case 0xE057:
+ return 0xFE330;
+ case 0xE058:
+ return 0xFE323;
+ case 0xE059:
+ return 0xFE320;
+ case 0xE05A:
+ return 0xFE4F4;
+ case 0xE101:
+ return 0xFE52D;
+ case 0xE102:
+ return 0xFE52E;
+ case 0xE103:
+ return 0xFE52B;
+ case 0xE104:
+ return 0xFE526;
+ case 0xE105:
+ return 0xFE329;
+ case 0xE106:
+ return 0xFE327;
+ case 0xE107:
+ return 0xFE341;
+ case 0xE108:
+ return 0xFE344;
+ case 0xE109:
+ return 0xFE1C4;
+ case 0xE10A:
+ return 0xFE1C5;
+ case 0xE10B:
+ return 0xFE1BF;
+ case 0xE10C:
+ return 0xFE1B0;
+ case 0xE10D:
+ return 0xFE7ED;
+ case 0xE10E:
+ return 0xFE4D1;
+ case 0xE10F:
+ return 0xFEB56;
+ case 0xE110:
+ return 0xFE03C;
+ case 0xE111:
+ return 0xFE827;
+ case 0xE112:
+ return 0xFE510;
+ case 0xE113:
+ return 0xFE4F5;
+ case 0xE114:
+ return 0xFEB85;
+ case 0xE115:
+ return 0xFE7D9;
+ case 0xE116:
+ return 0xFE4CA;
+ case 0xE117:
+ return 0xFE515;
+ case 0xE118:
+ return 0xFE03F;
+ case 0xE119:
+ return 0xFE042;
+ case 0xE11A:
+ return 0xFE1B2;
+ case 0xE11B:
+ return 0xFE1AE;
+ case 0xE11C:
+ return 0xFE1B3;
+ case 0xE11D:
+ return 0xFE4F6;
+ case 0xE11E:
+ return 0xFE53B;
+ case 0xE11F:
+ return 0xFE537;
+ case 0xE120:
+ return 0xFE960;
+ case 0xE121:
+ return 0xFE4BC;
+ case 0xE122:
+ return 0xFE7FB;
+ case 0xE123:
+ return 0xFE7FA;
+ case 0xE124:
+ return 0xFE7FD;
+ case 0xE125:
+ return 0xFE807;
+ case 0xE126:
+ return 0xFE81D;
+ case 0xE127:
+ return 0xFE81E;
+ case 0xE128:
+ return 0xFE81F;
+ case 0xE129:
+ return 0xFE820;
+ case 0xE12A:
+ return 0xFE81C;
+ case 0xE12B:
+ return 0xFE1B1;
+ case 0xE12C:
+ return 0xFE81B;
+ case 0xE12D:
+ return 0xFE80B;
+ case 0xE12E:
+ return 0xFEB32;
+ case 0xE12F:
+ return 0xFE4DD;
+ case 0xE130:
+ return 0xFE80C;
+ case 0xE131:
+ return 0xFE7DB;
+ case 0xE132:
+ return 0xFE7D7;
+ case 0xE133:
+ return 0xFE80D;
+ case 0xE134:
+ return 0xFE7DC;
+ case 0xE135:
+ return 0xFE7EE;
+ case 0xE136:
+ return 0xFE7EB;
+ case 0xE137:
+ return 0xFE7F8;
+ case 0xE138:
+ return 0xFEB33;
+ case 0xE139:
+ return 0xFEB34;
+ case 0xE13A:
+ return 0xFEB35;
+ case 0xE13B:
+ return 0xFE509;
+ case 0xE13C:
+ return 0xFEB59;
+ case 0xE13D:
+ return 0xFE004;
+ case 0xE13E:
+ return 0xFE4D6;
+ case 0xE13F:
+ return 0xFE505;
+ case 0xE140:
+ return 0xFE507;
+ case 0xE141:
+ return 0xFE821;
+ case 0xE142:
+ return 0xFE52F;
+ case 0xE143:
+ return 0xFE514;
+ case 0xE144:
+ return 0xFEB86;
+ case 0xE145:
+ return 0xFEB87;
+ case 0xE146:
+ return 0xFE00B;
+ case 0xE147:
+ return 0xFE965;
+ case 0xE148:
+ return 0xFE546;
+ case 0xE149:
+ return 0xFE4DE;
+ case 0xE14A:
+ return 0xFE4DF;
+ case 0xE14B:
+ return 0xFE531;
+ case 0xE14C:
+ return 0xFEB5E;
+ case 0xE14D:
+ return 0xFE4B5;
+ case 0xE14E:
+ return 0xFE7F7;
+ case 0xE14F:
+ return 0xFE7F6;
+ case 0xE150:
+ return 0xFE7E7;
+ case 0xE151:
+ return 0xFE506;
+ case 0xE152:
+ return 0xFE1A1;
+ case 0xE153:
+ return 0xFE4B3;
+ case 0xE154:
+ return 0xFE4B6;
+ case 0xE155:
+ return 0xFE4B4;
+ case 0xE156:
+ return 0xFE4B9;
+ case 0xE157:
+ return 0xFE4BA;
+ case 0xE158:
+ return 0xFE4B7;
+ case 0xE159:
+ return 0xFE7E6;
+ case 0xE15A:
+ return 0xFE7EF;
+ case 0xE201:
+ return 0xFE7F0;
+ case 0xE202:
+ return 0xFE7E8;
+ case 0xE203:
+ return 0xFEB24;
+ case 0xE204:
+ return 0xFEB19;
+ case 0xE205:
+ return 0xFEB61;
+ case 0xE206:
+ return 0xFEB62;
+ case 0xE207:
+ return 0xFEB25;
+ case 0xE208:
+ return 0xFEB1F;
+ case 0xE209:
+ return 0xFE044;
+ case 0xE20A:
+ return 0xFEB20;
+ case 0xE20B:
+ return 0xFE838;
+ case 0xE20C:
+ return 0xFEB1A;
+ case 0xE20D:
+ return 0xFEB1C;
+ case 0xE20E:
+ return 0xFEB1B;
+ case 0xE20F:
+ return 0xFEB1D;
+ case 0xE210:
+ return 0xFE82C;
+ case 0xE211:
+ return 0xFE82B;
+ case 0xE212:
+ return 0xFEB36;
+ case 0xE213:
+ return 0xFEB37;
+ case 0xE214:
+ return 0xFEB38;
+ case 0xE215:
+ return 0xFEB39;
+ case 0xE216:
+ return 0xFEB3A;
+ case 0xE217:
+ return 0xFEB3B;
+ case 0xE218:
+ return 0xFEB3C;
+ case 0xE219:
+ return 0xFEB63;
+ case 0xE21A:
+ return 0xFEB64;
+ case 0xE21B:
+ return 0xFEB67;
+ case 0xE21C:
+ return 0xFE82E;
+ case 0xE21D:
+ return 0xFE82F;
+ case 0xE21E:
+ return 0xFE830;
+ case 0xE21F:
+ return 0xFE831;
+ case 0xE220:
+ return 0xFE832;
+ case 0xE221:
+ return 0xFE833;
+ case 0xE222:
+ return 0xFE834;
+ case 0xE223:
+ return 0xFE835;
+ case 0xE224:
+ return 0xFE836;
+ case 0xE225:
+ return 0xFE837;
+ case 0xE226:
+ return 0xFEB3D;
+ case 0xE227:
+ return 0xFEB3E;
+ case 0xE228:
+ return 0xFEB3F;
+ case 0xE229:
+ return 0xFEB81;
+ case 0xE22A:
+ return 0xFEB31;
+ case 0xE22B:
+ return 0xFEB2F;
+ case 0xE22C:
+ return 0xFEB40;
+ case 0xE22D:
+ return 0xFEB41;
+ case 0xE22E:
+ return 0xFEB99;
+ case 0xE22F:
+ return 0xFEB9A;
+ case 0xE230:
+ return 0xFEB9B;
+ case 0xE231:
+ return 0xFEB9C;
+ case 0xE232:
+ return 0xFEAF8;
+ case 0xE233:
+ return 0xFEAF9;
+ case 0xE234:
+ return 0xFEAFA;
+ case 0xE235:
+ return 0xFEAFB;
+ case 0xE236:
+ return 0xFEAF0;
+ case 0xE237:
+ return 0xFEAF2;
+ case 0xE238:
+ return 0xFEAF1;
+ case 0xE239:
+ return 0xFEAF3;
+ case 0xE23A:
+ return 0xFEAFC;
+ case 0xE23B:
+ return 0xFEAFD;
+ case 0xE23C:
+ return 0xFEAFE;
+ case 0xE23D:
+ return 0xFEAFF;
+ case 0xE23E:
+ return 0xFE4F8;
+ case 0xE23F:
+ return 0xFE02B;
+ case 0xE240:
+ return 0xFE02C;
+ case 0xE241:
+ return 0xFE02D;
+ case 0xE242:
+ return 0xFE02E;
+ case 0xE243:
+ return 0xFE02F;
+ case 0xE244:
+ return 0xFE030;
+ case 0xE245:
+ return 0xFE031;
+ case 0xE246:
+ return 0xFE032;
+ case 0xE247:
+ return 0xFE033;
+ case 0xE248:
+ return 0xFE034;
+ case 0xE249:
+ return 0xFE035;
+ case 0xE24A:
+ return 0xFE036;
+ case 0xE24B:
+ return 0xFE037;
+ case 0xE24C:
+ return 0xFEB42;
+ case 0xE24D:
+ return 0xFEB27;
+ case 0xE24E:
+ return 0xFEB29;
+ case 0xE24F:
+ return 0xFEB2D;
+ case 0xE250:
+ return 0xFE839;
+ case 0xE251:
+ return 0xFE83A;
+ case 0xE252:
+ return 0xFEB23;
+ case 0xE253:
+ return 0xFE1B4;
+ case 0xE254:
+ return 0xFEE77;
+ case 0xE255:
+ return 0xFEE78;
+ case 0xE256:
+ return 0xFEE79;
+ case 0xE257:
+ return 0xFEE7A;
+ case 0xE258:
+ return 0xFEE7B;
+ case 0xE259:
+ return 0xFEE7C;
+ case 0xE25A:
+ return 0xFEE7D;
+ case 0xE301:
+ return 0xFE527;
+ case 0xE302:
+ return 0xFE4D3;
+ case 0xE303:
+ return 0xFE045;
+ case 0xE304:
+ return 0xFE03D;
+ case 0xE305:
+ return 0xFE046;
+ case 0xE306:
+ return 0xFE828;
+ case 0xE307:
+ return 0xFE047;
+ case 0xE308:
+ return 0xFE048;
+ case 0xE309:
+ return 0xFE508;
+ case 0xE30A:
+ return 0xFE803;
+ case 0xE30B:
+ return 0xFE985;
+ case 0xE30C:
+ return 0xFE987;
+ case 0xE30D:
+ return 0xFEB43;
+ case 0xE30E:
+ return 0xFEB1E;
+ case 0xE30F:
+ return 0xFE50A;
+ case 0xE310:
+ return 0xFE516;
+ case 0xE311:
+ return 0xFEB58;
+ case 0xE312:
+ return 0xFE517;
+ case 0xE313:
+ return 0xFE53E;
+ case 0xE314:
+ return 0xFE50F;
+ case 0xE315:
+ return 0xFEB2B;
+ case 0xE316:
+ return 0xFE53C;
+ case 0xE317:
+ return 0xFE530;
+ case 0xE318:
+ return 0xFE4D4;
+ case 0xE319:
+ return 0xFE4D5;
+ case 0xE31A:
+ return 0xFE4D7;
+ case 0xE31B:
+ return 0xFE4D8;
+ case 0xE31C:
+ return 0xFE195;
+ case 0xE31D:
+ return 0xFE196;
+ case 0xE31E:
+ return 0xFE197;
+ case 0xE31F:
+ return 0xFE198;
+ case 0xE320:
+ return 0xFE199;
+ case 0xE321:
+ return 0xFE4D9;
+ case 0xE322:
+ return 0xFE4DA;
+ case 0xE323:
+ return 0xFE4F0;
+ case 0xE324:
+ return 0xFE808;
+ case 0xE325:
+ return 0xFE4F2;
+ case 0xE326:
+ return 0xFE814;
+ case 0xE327:
+ return 0xFEB0D;
+ case 0xE328:
+ return 0xFEB11;
+ case 0xE329:
+ return 0xFEB12;
+ case 0xE32A:
+ return 0xFEB13;
+ case 0xE32B:
+ return 0xFEB14;
+ case 0xE32C:
+ return 0xFEB15;
+ case 0xE32D:
+ return 0xFEB16;
+ case 0xE32E:
+ return 0xFEB60;
+ case 0xE32F:
+ return 0xFEB68;
+ case 0xE330:
+ return 0xFEB5D;
+ case 0xE331:
+ return 0xFEB5B;
+ case 0xE332:
+ return 0xFEB44;
+ case 0xE333:
+ return 0xFEB45;
+ case 0xE334:
+ return 0xFEB57;
+ case 0xE335:
+ return 0xFEB69;
+ case 0xE336:
+ return 0xFEB0A;
+ case 0xE337:
+ return 0xFEB0B;
+ case 0xE338:
+ return 0xFE984;
+ case 0xE339:
+ return 0xFE964;
+ case 0xE33A:
+ return 0xFE966;
+ case 0xE33B:
+ return 0xFE967;
+ case 0xE33C:
+ return 0xFE968;
+ case 0xE33D:
+ return 0xFE969;
+ case 0xE33E:
+ return 0xFE96A;
+ case 0xE33F:
+ return 0xFE96B;
+ case 0xE340:
+ return 0xFE963;
+ case 0xE341:
+ return 0xFE96C;
+ case 0xE342:
+ return 0xFE961;
+ case 0xE343:
+ return 0xFE96D;
+ case 0xE344:
+ return 0xFE96E;
+ case 0xE345:
+ return 0xFE051;
+ case 0xE346:
+ return 0xFE052;
+ case 0xE347:
+ return 0xFE053;
+ case 0xE348:
+ return 0xFE054;
+ case 0xE349:
+ return 0xFE055;
+ case 0xE34A:
+ return 0xFE056;
+ case 0xE34B:
+ return 0xFE511;
+ case 0xE34C:
+ return 0xFE96F;
+ case 0xE34D:
+ return 0xFE970;
+ case 0xE401:
+ return 0xFE345;
+ case 0xE402:
+ return 0xFE343;
+ case 0xE403:
+ return 0xFE340;
+ case 0xE404:
+ return 0xFE333;
+ case 0xE405:
+ return 0xFE347;
+ case 0xE406:
+ return 0xFE33C;
+ case 0xE407:
+ return 0xFE33F;
+ case 0xE408:
+ return 0xFE342;
+ case 0xE409:
+ return 0xFE32A;
+ case 0xE40A:
+ return 0xFE33E;
+ case 0xE40B:
+ return 0xFE33B;
+ case 0xE40C:
+ return 0xFE32E;
+ case 0xE40D:
+ return 0xFE32F;
+ case 0xE40E:
+ return 0xFE326;
+ case 0xE40F:
+ return 0xFE325;
+ case 0xE410:
+ return 0xFE322;
+ case 0xE411:
+ return 0xFE33A;
+ case 0xE412:
+ return 0xFE334;
+ case 0xE413:
+ return 0xFE339;
+ case 0xE414:
+ return 0xFE336;
+ case 0xE415:
+ return 0xFE338;
+ case 0xE416:
+ return 0xFE33D;
+ case 0xE417:
+ return 0xFE32D;
+ case 0xE418:
+ return 0xFE32C;
+ case 0xE419:
+ return 0xFE190;
+ case 0xE41A:
+ return 0xFE192;
+ case 0xE41B:
+ return 0xFE191;
+ case 0xE41C:
+ return 0xFE193;
+ case 0xE41D:
+ return 0xFE35B;
+ case 0xE41E:
+ return 0xFEB9D;
+ case 0xE41F:
+ return 0xFEB9E;
+ case 0xE420:
+ return 0xFEB9F;
+ case 0xE421:
+ return 0xFEBA0;
+ case 0xE422:
+ return 0xFEBA1;
+ case 0xE423:
+ return 0xFE351;
+ case 0xE424:
+ return 0xFE352;
+ case 0xE425:
+ return 0xFE829;
+ case 0xE426:
+ return 0xFE353;
+ case 0xE427:
+ return 0xFE358;
+ case 0xE428:
+ return 0xFE1A0;
+ case 0xE429:
+ return 0xFE1A2;
+ case 0xE42A:
+ return 0xFE7D6;
+ case 0xE42B:
+ return 0xFE7DD;
+ case 0xE42C:
+ return 0xFE80E;
+ case 0xE42D:
+ return 0xFE7DE;
+ case 0xE42E:
+ return 0xFE7E5;
+ case 0xE42F:
+ return 0xFE7F1;
+ case 0xE430:
+ return 0xFE7F2;
+ case 0xE431:
+ return 0xFE7F3;
+ case 0xE432:
+ return 0xFE7F4;
+ case 0xE433:
+ return 0xFE7FE;
+ case 0xE434:
+ return 0xFE7E0;
+ case 0xE435:
+ return 0xFE7E2;
+ case 0xE436:
+ return 0xFE518;
+ case 0xE437:
+ return 0xFEB17;
+ case 0xE438:
+ return 0xFE519;
+ case 0xE439:
+ return 0xFE51A;
+ case 0xE43A:
+ return 0xFE51B;
+ case 0xE43B:
+ return 0xFE51C;
+ case 0xE43C:
+ return 0xFE007;
+ case 0xE43D:
+ return 0xFE82A;
+ case 0xE43E:
+ return 0xFE038;
+ case 0xE43F:
+ return 0xFE971;
+ case 0xE440:
+ return 0xFE51D;
+ case 0xE441:
+ return 0xFE1C6;
+ case 0xE442:
+ return 0xFE51E;
+ case 0xE443:
+ return 0xFE005;
+ case 0xE444:
+ return 0xFE049;
+ case 0xE445:
+ return 0xFE51F;
+ case 0xE446:
+ return 0xFE017;
+ case 0xE447:
+ return 0xFE043;
+ case 0xE448:
+ return 0xFE513;
+ case 0xE449:
+ return 0xFE00A;
+ case 0xE44A:
+ return 0xFE00C;
+ case 0xE44B:
+ return 0xFE008;
+ case 0xE44C:
+ return 0xFE00D;
+ case 0xE501:
+ return 0xFE4B8;
+ case 0xE502:
+ return 0xFE804;
+ case 0xE503:
+ return 0xFE805;
+ case 0xE504:
+ return 0xFE4BD;
+ case 0xE505:
+ return 0xFE4BE;
+ case 0xE506:
+ return 0xFE4BF;
+ case 0xE507:
+ return 0xFE802;
+ case 0xE508:
+ return 0xFE4C0;
+ case 0xE509:
+ return 0xFE4C4;
+ case 0xE50A:
+ return 0xFE4C5;
+ case 0xE50B:
+ return 0xFE4E5;
+ case 0xE50C:
+ return 0xFE4E6;
+ case 0xE50D:
+ return 0xFE4E7;
+ case 0xE50E:
+ return 0xFE4E8;
+ case 0xE50F:
+ return 0xFE4E9;
+ case 0xE510:
+ return 0xFE4EA;
+ case 0xE511:
+ return 0xFE4EB;
+ case 0xE512:
+ return 0xFE4EC;
+ case 0xE513:
+ return 0xFE4ED;
+ case 0xE514:
+ return 0xFE4EE;
+ case 0xE515:
+ return 0xFE1A4;
+ case 0xE516:
+ return 0xFE1A5;
+ case 0xE517:
+ return 0xFE1A6;
+ case 0xE518:
+ return 0xFE1A7;
+ case 0xE519:
+ return 0xFE1A8;
+ case 0xE51A:
+ return 0xFE1A9;
+ case 0xE51B:
+ return 0xFE1AA;
+ case 0xE51C:
+ return 0xFE1AB;
+ case 0xE51D:
+ return 0xFE4C6;
+ case 0xE51E:
+ return 0xFE1B5;
+ case 0xE51F:
+ return 0xFE1B6;
+ case 0xE520:
+ return 0xFE1C7;
+ case 0xE521:
+ return 0xFE1C8;
+ case 0xE522:
+ return 0xFE1C9;
+ case 0xE523:
+ return 0xFE1BA;
+ case 0xE524:
+ return 0xFE1CA;
+ case 0xE525:
+ return 0xFE1CB;
+ case 0xE526:
+ return 0xFE1CC;
+ case 0xE527:
+ return 0xFE1CD;
+ case 0xE528:
+ return 0xFE1CE;
+ case 0xE529:
+ return 0xFE1CF;
+ case 0xE52A:
+ return 0xFE1D0;
+ case 0xE52B:
+ return 0xFE1D1;
+ case 0xE52C:
+ return 0xFE1D2;
+ case 0xE52D:
+ return 0xFE1D3;
+ case 0xE52E:
+ return 0xFE1D4;
+ case 0xE52F:
+ return 0xFE1D5;
+ case 0xE530:
+ return 0xFE1D6;
+ case 0xE531:
+ return 0xFE1D7;
+ case 0xE532:
+ return 0xFE50B;
+ case 0xE533:
+ return 0xFE50C;
+ case 0xE534:
+ return 0xFE50D;
+ case 0xE535:
+ return 0xFE50E;
+ case 0xE536:
+ return 0xFE553;
+ case 0xE537:
+ return 0xFEB2A;
+ case 0xE538:
+ return 0xFEE70;
+ case 0xE539:
+ return 0xFEE71;
+ case 0xE53A:
+ return 0xFEE72;
+ case 0xE53B:
+ return 0xFEE73;
+ case 0xE53C:
+ return 0xFEE74;
+ case 0xE53D:
+ return 0xFEE75;
+ case 0xE53E:
+ return 0xFEE76;
+ default:
+ return codePoint;
+ }
+ }
+
+}
diff --git a/src/com/fsck/k9/mail/internet/DecoderUtil.java b/src/com/fsck/k9/mail/internet/DecoderUtil.java
index 3ac74947d..3e439ab99 100644
--- a/src/com/fsck/k9/mail/internet/DecoderUtil.java
+++ b/src/com/fsck/k9/mail/internet/DecoderUtil.java
@@ -35,7 +35,7 @@ class DecoderUtil {
Base64InputStream is = new Base64InputStream(new ByteArrayInputStream(bytes));
try {
- return MimeUtility.readToString(is, charset);
+ return CharsetSupport.readToString(is, charset);
} catch (IOException e) {
return null;
}
@@ -68,7 +68,7 @@ class DecoderUtil {
QuotedPrintableInputStream is = new QuotedPrintableInputStream(new ByteArrayInputStream(bytes));
try {
- return MimeUtility.readToString(is, charset);
+ return CharsetSupport.readToString(is, charset);
} catch (IOException e) {
return null;
}
@@ -162,7 +162,7 @@ class DecoderUtil {
String charset;
try {
- charset = MimeUtility.fixupCharset(mimeCharset, message);
+ charset = CharsetSupport.fixupCharset(mimeCharset, message);
} catch (MessagingException e) {
return null;
}
diff --git a/src/com/fsck/k9/mail/internet/EncoderUtil.java b/src/com/fsck/k9/mail/internet/EncoderUtil.java
index 5e7672715..2c71ecc2d 100644
--- a/src/com/fsck/k9/mail/internet/EncoderUtil.java
+++ b/src/com/fsck/k9/mail/internet/EncoderUtil.java
@@ -68,7 +68,7 @@ class EncoderUtil {
if (charset == null)
charset = determineCharset(text);
- String mimeCharset = MimeUtility.getExternalCharset(charset.name());
+ String mimeCharset = CharsetSupport.getExternalCharset(charset.name());
byte[] bytes = encode(text, charset);
diff --git a/src/com/fsck/k9/mail/internet/JisSupport.java b/src/com/fsck/k9/mail/internet/JisSupport.java
new file mode 100644
index 000000000..a6a30329a
--- /dev/null
+++ b/src/com/fsck/k9/mail/internet/JisSupport.java
@@ -0,0 +1,103 @@
+package com.fsck.k9.mail.internet;
+
+import com.fsck.k9.mail.Address;
+import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.Part;
+
+class JisSupport {
+ public static final String SHIFT_JIS = "shift_jis";
+
+ public static String getJisVariantFromMessage(Message message) throws MessagingException {
+ if (message == null)
+ return null;
+
+ // If a receiver is known to use a JIS variant, the sender transfers the message after converting the
+ // charset as a convention.
+ String variant = getJisVariantFromReceivedHeaders(message);
+ if (variant != null)
+ return variant;
+
+ // If a receiver is not known to use any JIS variants, the sender transfers the message without converting
+ // the charset.
+ variant = getJisVariantFromFromHeaders(message);
+ if (variant != null)
+ return variant;
+
+ return getJisVariantFromMailerHeaders(message);
+ }
+
+ public static boolean isShiftJis(String charset) {
+ return charset.length() > 17 && charset.startsWith("x-")
+ && charset.endsWith("-shift_jis-2007");
+ }
+
+ public static String getJisVariantFromAddress(String address) {
+ if (address == null)
+ return null;
+ if (isInDomain(address, "docomo.ne.jp") || isInDomain(address, "dwmail.jp") ||
+ isInDomain(address, "pdx.ne.jp") || isInDomain(address, "willcom.com") ||
+ isInDomain(address, "emnet.ne.jp") || isInDomain(address, "emobile.ne.jp"))
+ return "docomo";
+ else if (isInDomain(address, "softbank.ne.jp") || isInDomain(address, "vodafone.ne.jp") ||
+ isInDomain(address, "disney.ne.jp") || isInDomain(address, "vertuclub.ne.jp"))
+ return "softbank";
+ else if (isInDomain(address, "ezweb.ne.jp") || isInDomain(address, "ido.ne.jp"))
+ return "kddi";
+ return null;
+ }
+
+
+ private static String getJisVariantFromMailerHeaders(Message message) throws MessagingException {
+ String mailerHeaders[] = message.getHeader("X-Mailer");
+ if (mailerHeaders == null || mailerHeaders.length == 0)
+ return null;
+
+ if (mailerHeaders[0].startsWith("iPhone Mail ") || mailerHeaders[0].startsWith("iPad Mail "))
+ return "iphone";
+
+ return null;
+ }
+
+
+ private static String getJisVariantFromReceivedHeaders(Part message) throws MessagingException {
+ String receivedHeaders[] = message.getHeader("Received");
+ if (receivedHeaders == null)
+ return null;
+
+ for (String receivedHeader : receivedHeaders) {
+ String address = getAddressFromReceivedHeader(receivedHeader);
+ if (address == null)
+ continue;
+ String variant = getJisVariantFromAddress(address);
+ if (variant != null)
+ return variant;
+ }
+ return null;
+ }
+
+ private static String getAddressFromReceivedHeader(String receivedHeader) {
+ // Not implemented yet! Extract an address from the FOR clause of the given Received header.
+ return null;
+ }
+
+ private static String getJisVariantFromFromHeaders(Message message) throws MessagingException {
+ Address addresses[] = message.getFrom();
+ if (addresses == null || addresses.length == 0)
+ return null;
+
+ return getJisVariantFromAddress(addresses[0].getAddress());
+ }
+
+ private static boolean isInDomain(String address, String domain) {
+ int index = address.length() - domain.length() - 1;
+ if (index < 0)
+ return false;
+
+ char c = address.charAt(index);
+ if (c != '@' && c != '.')
+ return false;
+
+ return address.endsWith(domain);
+ }
+}
diff --git a/src/com/fsck/k9/mail/internet/MessageExtractor.java b/src/com/fsck/k9/mail/internet/MessageExtractor.java
new file mode 100644
index 000000000..5fedd3d28
--- /dev/null
+++ b/src/com/fsck/k9/mail/internet/MessageExtractor.java
@@ -0,0 +1,410 @@
+package com.fsck.k9.mail.internet;
+
+import android.util.Log;
+
+import com.fsck.k9.K9;
+import com.fsck.k9.mail.Body;
+import com.fsck.k9.mail.BodyPart;
+import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.Multipart;
+import com.fsck.k9.mail.Part;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.fsck.k9.mail.internet.CharsetSupport.fixupCharset;
+import static com.fsck.k9.mail.internet.MimeUtility.getHeaderParameter;
+import static com.fsck.k9.mail.internet.Viewable.Alternative;
+import static com.fsck.k9.mail.internet.Viewable.Textual;
+
+public class MessageExtractor {
+ public static String getTextFromPart(Part part) {
+ try {
+ if ((part != null) && (part.getBody() != null)) {
+ final Body body = part.getBody();
+ if (body instanceof TextBody) {
+ return ((TextBody)body).getText();
+ }
+
+ final String mimeType = part.getMimeType();
+ if ((mimeType != null) && MimeUtility.mimeTypeMatches(mimeType, "text/*")) {
+ /*
+ * We've got a text part, so let's see if it needs to be processed further.
+ */
+ String charset = getHeaderParameter(part.getContentType(), "charset");
+ /*
+ * determine the charset from HTML message.
+ */
+ if (mimeType.equalsIgnoreCase("text/html") && charset == null) {
+ InputStream in = part.getBody().getInputStream();
+ try {
+ byte[] buf = new byte[256];
+ in.read(buf, 0, buf.length);
+ String str = new String(buf, "US-ASCII");
+
+ if (str.isEmpty()) {
+ return "";
+ }
+ Pattern p = Pattern.compile("", Pattern.CASE_INSENSITIVE);
+ Matcher m = p.matcher(str);
+ if (m.find()) {
+ charset = m.group(1);
+ }
+ } finally {
+ try {
+ if (in instanceof BinaryTempFileBody.BinaryTempFileBodyInputStream) {
+ /*
+ * If this is a BinaryTempFileBodyInputStream, calling close()
+ * will delete the file. But we can't let that happen because
+ * the file needs to be opened again by the code a few lines
+ * down.
+ */
+ ((BinaryTempFileBody.BinaryTempFileBodyInputStream) in).closeWithoutDeleting();
+ } else {
+ in.close();
+ }
+ } catch (Exception e) { /* ignore */ }
+ }
+ }
+ charset = fixupCharset(charset, getMessageFromPart(part));
+
+ /*
+ * Now we read the part into a buffer for further processing. Because
+ * the stream is now wrapped we'll remove any transfer encoding at this point.
+ */
+ InputStream in = part.getBody().getInputStream();
+ try {
+ String text = CharsetSupport.readToString(in, charset);
+
+ // Replace the body with a TextBody that already contains the decoded text
+ part.setBody(new TextBody(text));
+
+ return text;
+ } finally {
+ try {
+ /*
+ * This time we don't care if it's a BinaryTempFileBodyInputStream. We
+ * replaced the body with a TextBody instance and hence don't need the
+ * file anymore.
+ */
+ in.close();
+ } catch (IOException e) { /* Ignore */ }
+ }
+ }
+ }
+
+ } catch (OutOfMemoryError oom) {
+ /*
+ * If we are not able to process the body there's nothing we can do about it. Return
+ * null and let the upper layers handle the missing content.
+ */
+ Log.e(K9.LOG_TAG, "Unable to getTextFromPart " + oom.toString());
+ } catch (Exception e) {
+ /*
+ * If we are not able to process the body there's nothing we can do about it. Return
+ * null and let the upper layers handle the missing content.
+ */
+ Log.e(K9.LOG_TAG, "Unable to getTextFromPart", e);
+ }
+ return null;
+ }
+
+
+ /**
+ * Traverse the MIME tree of a message an extract viewable parts.
+ *
+ * @param part
+ * The message part to start from.
+ * @param attachments
+ * A list that will receive the parts that are considered attachments.
+ *
+ * @return A list of {@link Viewable}s.
+ *
+ * @throws MessagingException
+ * In case of an error.
+ */
+ public static List getViewables(Part part, List attachments) throws MessagingException {
+ List viewables = new ArrayList();
+
+ Body body = part.getBody();
+ if (body instanceof Multipart) {
+ Multipart multipart = (Multipart) body;
+ if (part.getMimeType().equalsIgnoreCase("multipart/alternative")) {
+ /*
+ * For multipart/alternative parts we try to find a text/plain and a text/html
+ * child. Everything else we find is put into 'attachments'.
+ */
+ List text = findTextPart(multipart, true);
+
+ Set knownTextParts = getParts(text);
+ List html = findHtmlPart(multipart, knownTextParts, attachments, true);
+
+ if (!text.isEmpty() || !html.isEmpty()) {
+ Alternative alternative = new Alternative(text, html);
+ viewables.add(alternative);
+ }
+ } else {
+ // For all other multipart parts we recurse to grab all viewable children.
+ for (Part bodyPart : multipart.getBodyParts()) {
+ viewables.addAll(getViewables(bodyPart, attachments));
+ }
+ }
+ } else if (body instanceof Message &&
+ !("attachment".equalsIgnoreCase(part.getContentDisposition()))) {
+ /*
+ * We only care about message/rfc822 parts whose Content-Disposition header has a value
+ * other than "attachment".
+ */
+ Message message = (Message) body;
+
+ // We add the Message object so we can extract the filename later.
+ viewables.add(new Viewable.MessageHeader(part, message));
+
+ // Recurse to grab all viewable parts and attachments from that message.
+ viewables.addAll(getViewables(message, attachments));
+ } else if (isPartTextualBody(part)) {
+ /*
+ * Save text/plain and text/html
+ */
+ String mimeType = part.getMimeType();
+ if (mimeType.equalsIgnoreCase("text/plain")) {
+ Viewable.Text text = new Viewable.Text(part);
+ viewables.add(text);
+ } else {
+ Viewable.Html html = new Viewable.Html(part);
+ viewables.add(html);
+ }
+ } else {
+ // Everything else is treated as attachment.
+ attachments.add(part);
+ }
+
+ return viewables;
+ }
+
+ public static Set getTextParts(Part part) throws MessagingException {
+ List attachments = new ArrayList();
+ return getParts(getViewables(part, attachments));
+ }
+
+ private static Message getMessageFromPart(Part part) {
+ while (part != null) {
+ if (part instanceof Message)
+ return (Message)part;
+
+ if (!(part instanceof BodyPart))
+ return null;
+
+ Multipart multipart = ((BodyPart)part).getParent();
+ if (multipart == null)
+ return null;
+
+ part = multipart.getParent();
+ }
+ return null;
+ }
+
+ /**
+ * Search the children of a {@link Multipart} for {@code text/plain} parts.
+ *
+ * @param multipart The {@code Multipart} to search through.
+ * @param directChild If {@code true}, this method will return after the first {@code text/plain} was
+ * found.
+ *
+ * @return A list of {@link Viewable.Text} viewables.
+ *
+ * @throws MessagingException
+ * In case of an error.
+ */
+ private static List findTextPart(Multipart multipart, boolean directChild)
+ throws MessagingException {
+ List viewables = new ArrayList();
+
+ for (Part part : multipart.getBodyParts()) {
+ Body body = part.getBody();
+ if (body instanceof Multipart) {
+ Multipart innerMultipart = (Multipart) body;
+
+ /*
+ * Recurse to find text parts. Since this is a multipart that is a child of a
+ * multipart/alternative we don't want to stop after the first text/plain part
+ * we find. This will allow to get all text parts for constructions like this:
+ *
+ * 1. multipart/alternative
+ * 1.1. multipart/mixed
+ * 1.1.1. text/plain
+ * 1.1.2. text/plain
+ * 1.2. text/html
+ */
+ List textViewables = findTextPart(innerMultipart, false);
+
+ if (!textViewables.isEmpty()) {
+ viewables.addAll(textViewables);
+ if (directChild) {
+ break;
+ }
+ }
+ } else if (isPartTextualBody(part) && part.getMimeType().equalsIgnoreCase("text/plain")) {
+ Viewable.Text text = new Viewable.Text(part);
+ viewables.add(text);
+ if (directChild) {
+ break;
+ }
+ }
+ }
+ return viewables;
+ }
+
+ /**
+ * Search the children of a {@link Multipart} for {@code text/html} parts.
+ * Every part that is not a {@code text/html} we want to display, we add to 'attachments'.
+ *
+ * @param multipart The {@code Multipart} to search through.
+ * @param knownTextParts A set of {@code text/plain} parts that shouldn't be added to 'attachments'.
+ * @param attachments A list that will receive the parts that are considered attachments.
+ * @param directChild If {@code true}, this method will add all {@code text/html} parts except the first
+ * found to 'attachments'.
+ *
+ * @return A list of {@link Viewable.Text} viewables.
+ *
+ * @throws MessagingException In case of an error.
+ */
+ private static List findHtmlPart(Multipart multipart, Set knownTextParts,
+ List attachments, boolean directChild) throws MessagingException {
+ List viewables = new ArrayList();
+
+ boolean partFound = false;
+ for (Part part : multipart.getBodyParts()) {
+ Body body = part.getBody();
+ if (body instanceof Multipart) {
+ Multipart innerMultipart = (Multipart) body;
+
+ if (directChild && partFound) {
+ // We already found our text/html part. Now we're only looking for attachments.
+ findAttachments(innerMultipart, knownTextParts, attachments);
+ } else {
+ /*
+ * Recurse to find HTML parts. Since this is a multipart that is a child of a
+ * multipart/alternative we don't want to stop after the first text/html part
+ * we find. This will allow to get all text parts for constructions like this:
+ *
+ * 1. multipart/alternative
+ * 1.1. text/plain
+ * 1.2. multipart/mixed
+ * 1.2.1. text/html
+ * 1.2.2. text/html
+ * 1.3. image/jpeg
+ */
+ List htmlViewables = findHtmlPart(innerMultipart, knownTextParts,
+ attachments, false);
+
+ if (!htmlViewables.isEmpty()) {
+ partFound = true;
+ viewables.addAll(htmlViewables);
+ }
+ }
+ } else if (!(directChild && partFound) && isPartTextualBody(part) &&
+ part.getMimeType().equalsIgnoreCase("text/html")) {
+ Viewable.Html html = new Viewable.Html(part);
+ viewables.add(html);
+ partFound = true;
+ } else if (!knownTextParts.contains(part)) {
+ // Only add this part as attachment if it's not a viewable text/plain part found
+ // earlier.
+ attachments.add(part);
+ }
+ }
+
+ return viewables;
+ }
+
+ /**
+ * Traverse the MIME tree and add everything that's not a known text part to 'attachments'.
+ *
+ * @param multipart
+ * The {@link Multipart} to start from.
+ * @param knownTextParts
+ * A set of known text parts we don't want to end up in 'attachments'.
+ * @param attachments
+ * A list that will receive the parts that are considered attachments.
+ */
+ private static void findAttachments(Multipart multipart, Set knownTextParts,
+ List attachments) {
+ for (Part part : multipart.getBodyParts()) {
+ Body body = part.getBody();
+ if (body instanceof Multipart) {
+ Multipart innerMultipart = (Multipart) body;
+ findAttachments(innerMultipart, knownTextParts, attachments);
+ } else if (!knownTextParts.contains(part)) {
+ attachments.add(part);
+ }
+ }
+ }
+
+ /**
+ * Build a set of message parts for fast lookups.
+ *
+ * @param viewables
+ * A list of {@link Viewable}s containing references to the message parts to include in
+ * the set.
+ *
+ * @return The set of viewable {@code Part}s.
+ *
+ * @see MimeUtility#findHtmlPart(Multipart, Set, List, boolean)
+ * @see MimeUtility#findAttachments(Multipart, Set, List)
+ */
+ private static Set getParts(List viewables) {
+ Set parts = new HashSet();
+
+ for (Viewable viewable : viewables) {
+ if (viewable instanceof Textual) {
+ parts.add(((Textual) viewable).getPart());
+ } else if (viewable instanceof Alternative) {
+ Alternative alternative = (Alternative) viewable;
+ parts.addAll(getParts(alternative.getText()));
+ parts.addAll(getParts(alternative.getHtml()));
+ }
+ }
+
+ return parts;
+ }
+
+ private static Boolean isPartTextualBody(Part part) throws MessagingException {
+ String disposition = part.getDisposition();
+ String dispositionType = null;
+ String dispositionFilename = null;
+ if (disposition != null) {
+ dispositionType = MimeUtility.getHeaderParameter(disposition, null);
+ dispositionFilename = MimeUtility.getHeaderParameter(disposition, "filename");
+ }
+
+ /*
+ * A best guess that this part is intended to be an attachment and not inline.
+ */
+ boolean attachment = ("attachment".equalsIgnoreCase(dispositionType) || (dispositionFilename != null));
+
+ if ((!attachment) && (part.getMimeType().equalsIgnoreCase("text/html"))) {
+ return true;
+ }
+ /*
+ * If the part is plain text and it got this far it's part of a
+ * mixed (et al) and should be rendered inline.
+ */
+ else if ((!attachment) && (part.getMimeType().equalsIgnoreCase("text/plain"))) {
+ return true;
+ }
+ /*
+ * Finally, if it's nothing else we will include it as an attachment.
+ */
+ else {
+ return false;
+ }
+ }
+}
diff --git a/src/com/fsck/k9/mail/internet/MimeMessage.java b/src/com/fsck/k9/mail/internet/MimeMessage.java
index 02c028edf..c58a46080 100644
--- a/src/com/fsck/k9/mail/internet/MimeMessage.java
+++ b/src/com/fsck/k9/mail/internet/MimeMessage.java
@@ -473,7 +473,7 @@ public class MimeMessage extends Message {
if (mBody instanceof Multipart) {
((Multipart)mBody).setCharset(charset);
} else if (mBody instanceof TextBody) {
- MimeUtility.setCharset(charset, this);
+ CharsetSupport.setCharset(charset, this);
((TextBody)mBody).setCharset(charset);
}
}
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 6aaa93256..e56476878 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -1,13 +1,12 @@
package com.fsck.k9.mail.internet;
-import android.content.Context;
-import android.util.Log;
-import com.fsck.k9.K9;
-import com.fsck.k9.R;
-import com.fsck.k9.mail.*;
-import com.fsck.k9.mail.Message.RecipientType;
-import com.fsck.k9.mail.internet.BinaryTempFileBody.BinaryTempFileBodyInputStream;
+import com.fsck.k9.mail.Body;
+import com.fsck.k9.mail.BodyPart;
+import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.Multipart;
+import com.fsck.k9.mail.Part;
import org.apache.commons.io.IOUtils;
import org.apache.james.mime4j.codec.Base64InputStream;
@@ -17,32 +16,20 @@ import org.apache.james.mime4j.util.MimeUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
import java.util.Locale;
-import java.util.Set;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.nio.charset.Charset;
-import java.nio.charset.IllegalCharsetNameException;
public class MimeUtility {
public static final String DEFAULT_ATTACHMENT_MIME_TYPE = "application/octet-stream";
-
public static final String K9_SETTINGS_MIME_TYPE = "application/x-k9settings";
- private static final String TEXT_DIVIDER =
- "------------------------------------------------------------------------";
-
/*
* http://www.w3schools.com/media/media_mimeref.asp
* +
* http://www.stdicon.com/mimetypes
*/
- public static final String[][] MIME_TYPE_BY_EXTENSION_MAP = new String[][] {
+ private static final String[][] MIME_TYPE_BY_EXTENSION_MAP = new String[][] {
//* Do not delete the next two lines
{ "", DEFAULT_ATTACHMENT_MIME_TYPE },
{ "k9s", K9_SETTINGS_MIME_TYPE},
@@ -895,29 +882,6 @@ public class MimeUtility {
{ "zmm", "application/vnd.handheld-entertainment+xml"}
};
- /**
- * Table for MIME type replacements.
- *
- * Table format: wrong type, correct type
- */
- private static final String[][] MIME_TYPE_REPLACEMENT_MAP = new String[][] {
- {"image/jpg", "image/jpeg"},
- {"image/pjpeg", "image/jpeg"}, // see issue 1712
- {"application/x-zip-compressed", "application/zip"} // see issue 3791
- };
-
- /**
- * Table for character set fall-back.
- *
- * Table format: unsupported charset (regular expression), fall-back charset
- */
- private static final String[][] CHARSET_FALLBACK_MAP = new String[][] {
- // Some Android versions don't support KOI8-U
- {"koi8-u", "koi8-r"},
- {"iso-2022-jp-[\\d]+", "iso-2022-jp"},
- // Default fall-back is US-ASCII
- {".*", "US-ASCII"}
- };
public static String unfold(String s) {
if (s == null) {
@@ -929,9 +893,9 @@ public class MimeUtility {
private static String decode(String s, Message message) {
if (s == null) {
return null;
+ } else {
+ return DecoderUtil.decodeEncodedWords(s, message);
}
-
- return DecoderUtil.decodeEncodedWords(s, message);
}
public static String unfoldAndDecode(String s) {
@@ -951,24 +915,24 @@ public class MimeUtility {
* Returns the named parameter of a header field. If name is null the first
* parameter is returned, or if there are no additional parameters in the
* field the entire field is returned. Otherwise the named parameter is
- * searched for in a case insensitive fashion and returned. If the parameter
- * cannot be found the method returns null.
+ * searched for in a case insensitive fashion and returned.
*
- * @param header
- * @param name
- * @return
+ * @param headerValue the header value
+ * @param parameterName the parameter name
+ * @return the value. if the parameter cannot be found the method returns null.
*/
- public static String getHeaderParameter(String header, String name) {
- if (header == null) {
+ public static String getHeaderParameter(String headerValue, String parameterName) {
+ if (headerValue == null) {
return null;
}
- header = header.replaceAll("\r|\n", "");
- String[] parts = header.split(";");
- if (name == null && parts.length > 0) {
+ headerValue = headerValue.replaceAll("\r|\n", "");
+ String[] parts = headerValue.split(";");
+ if (parameterName == null && parts.length > 0) {
return parts[0].trim();
}
for (String part : parts) {
- if (part.trim().toLowerCase(Locale.US).startsWith(name.toLowerCase(Locale.US))) {
+ if (parameterName != null &&
+ part.trim().toLowerCase(Locale.US).startsWith(parameterName.toLowerCase(Locale.US))) {
String[] partParts = part.split("=", 2);
if (partParts.length == 2) {
String parameter = partParts[1].trim();
@@ -984,12 +948,11 @@ public class MimeUtility {
return null;
}
- public static Part findFirstPartByMimeType(Part part, String mimeType)
- throws MessagingException {
+ public static Part findFirstPartByMimeType(Part part, String mimeType) throws MessagingException {
if (part.getBody() instanceof Multipart) {
Multipart multipart = (Multipart)part.getBody();
for (BodyPart bodyPart : multipart.getBodyParts()) {
- Part ret = findFirstPartByMimeType(bodyPart, mimeType);
+ Part ret = bodyPart.findFirstPartByMimeType(mimeType);
if (ret != null) {
return ret;
}
@@ -1000,104 +963,6 @@ public class MimeUtility {
return null;
}
- /**
- * Reads the Part's body and returns a String based on any charset conversion that needed
- * to be done. Note, this does not return a text representation of HTML.
- * @param part The part containing a body
- * @return a String containing the converted text in the body, or null if there was no text
- * or an error during conversion.
- */
- public static String getTextFromPart(Part part) {
- try {
- if ((part != null) && (part.getBody() != null)) {
- final Body body = part.getBody();
- if (body instanceof TextBody) {
- return ((TextBody)body).getText();
- }
-
- final String mimeType = part.getMimeType();
- if ((mimeType != null) && MimeUtility.mimeTypeMatches(mimeType, "text/*")) {
- /*
- * We've got a text part, so let's see if it needs to be processed further.
- */
- String charset = getHeaderParameter(part.getContentType(), "charset");
- /*
- * determine the charset from HTML message.
- */
- if (mimeType.equalsIgnoreCase("text/html") && charset == null) {
- InputStream in = part.getBody().getInputStream();
- try {
- byte[] buf = new byte[256];
- in.read(buf, 0, buf.length);
- String str = new String(buf, "US-ASCII");
-
- if (str.isEmpty()) {
- return "";
- }
- Pattern p = Pattern.compile("", Pattern.CASE_INSENSITIVE);
- Matcher m = p.matcher(str);
- if (m.find()) {
- charset = m.group(1);
- }
- } finally {
- try {
- if (in instanceof BinaryTempFileBodyInputStream) {
- /*
- * If this is a BinaryTempFileBodyInputStream, calling close()
- * will delete the file. But we can't let that happen because
- * the file needs to be opened again by the code a few lines
- * down.
- */
- ((BinaryTempFileBodyInputStream) in).closeWithoutDeleting();
- } else {
- in.close();
- }
- } catch (Exception e) { /* ignore */ }
- }
- }
- charset = fixupCharset(charset, getMessageFromPart(part));
-
- /*
- * Now we read the part into a buffer for further processing. Because
- * the stream is now wrapped we'll remove any transfer encoding at this point.
- */
- InputStream in = part.getBody().getInputStream();
- try {
- String text = readToString(in, charset);
-
- // Replace the body with a TextBody that already contains the decoded text
- part.setBody(new TextBody(text));
-
- return text;
- } finally {
- try {
- /*
- * This time we don't care if it's a BinaryTempFileBodyInputStream. We
- * replaced the body with a TextBody instance and hence don't need the
- * file anymore.
- */
- in.close();
- } catch (IOException e) { /* Ignore */ }
- }
- }
- }
-
- } catch (OutOfMemoryError oom) {
- /*
- * If we are not able to process the body there's nothing we can do about it. Return
- * null and let the upper layers handle the missing content.
- */
- Log.e(K9.LOG_TAG, "Unable to getTextFromPart " + oom.toString());
- } catch (Exception e) {
- /*
- * If we are not able to process the body there's nothing we can do about it. Return
- * null and let the upper layers handle the missing content.
- */
- Log.e(K9.LOG_TAG, "Unable to getTextFromPart", e);
- }
- return null;
- }
-
/**
* Returns true if the given mimeType matches the matchAgainst specification.
* @param mimeType A MIME type to check.
@@ -1150,900 +1015,6 @@ public class MimeUtility {
return tempBody;
}
-
- /**
- * Empty base class for the class hierarchy used by
- * {@link MimeUtility#extractTextAndAttachments(Context, Message)}.
- *
- * @see Text
- * @see Html
- * @see MessageHeader
- * @see Alternative
- */
- static abstract class Viewable { /* empty */ }
-
- /**
- * Class representing textual parts of a message that aren't marked as attachments.
- *
- * @see MimeUtility#isPartTextualBody(Part)
- */
- static abstract class Textual extends Viewable {
- private Part mPart;
-
- public Textual(Part part) {
- mPart = part;
- }
-
- public Part getPart() {
- return mPart;
- }
- }
-
- /**
- * Class representing a {@code text/plain} part of a message.
- */
- static class Text extends Textual {
- public Text(Part part) {
- super(part);
- }
- }
-
- /**
- * Class representing a {@code text/html} part of a message.
- */
- static class Html extends Textual {
- public Html(Part part) {
- super(part);
- }
- }
-
- /**
- * Class representing a {@code message/rfc822} part of a message.
- *
- *
- * This is used to extract basic header information when the message contents are displayed
- * inline.
- *
- */
- static class MessageHeader extends Viewable {
- private Part mContainerPart;
- private Message mMessage;
-
- public MessageHeader(Part containerPart, Message message) {
- mContainerPart = containerPart;
- mMessage = message;
- }
-
- public Part getContainerPart() {
- return mContainerPart;
- }
-
- public Message getMessage() {
- return mMessage;
- }
- }
-
- /**
- * Class representing a {@code multipart/alternative} part of a message.
- *
- *
- * Only relevant {@code text/plain} and {@code text/html} children are stored in this container
- * class.
- *
- */
- static class Alternative extends Viewable {
- private List mText;
- private List mHtml;
-
- public Alternative(List text, List html) {
- mText = text;
- mHtml = html;
- }
-
- public List getText() {
- return mText;
- }
-
- public List getHtml() {
- return mHtml;
- }
- }
-
- /**
- * Store viewable text of a message as plain text and HTML, and the parts considered
- * attachments.
- *
- * @see MimeUtility#extractTextAndAttachments(Context, Message)
- */
- public static class ViewableContainer {
- /**
- * The viewable text of the message in plain text.
- */
- public final String text;
-
- /**
- * The viewable text of the message in HTML.
- */
- public final String html;
-
- /**
- * The parts of the message considered attachments (everything not viewable).
- */
- public final List attachments;
-
- ViewableContainer(String text, String html, List attachments) {
- this.text = text;
- this.html = html;
- this.attachments = attachments;
- }
- }
-
- /**
- * Collect attachment parts of a message.
- *
- * @param message
- * The message to collect the attachment parts from.
- *
- * @return A list of parts regarded as attachments.
- *
- * @throws MessagingException
- * In case of an error.
- */
- public static List collectAttachments(Message message)
- throws MessagingException {
- try {
- List attachments = new ArrayList();
- getViewables(message, attachments);
-
- return attachments;
- } catch (Exception e) {
- throw new MessagingException("Couldn't collect attachment parts", e);
- }
- }
-
- /**
- * Collect the viewable textual parts of a message.
- *
- * @param message
- * The message to extract the viewable parts from.
- *
- * @return A set of viewable parts of the message.
- *
- * @throws MessagingException
- * In case of an error.
- */
- public static Set collectTextParts(Message message)
- throws MessagingException {
- try {
- List attachments = new ArrayList();
-
- // Collect all viewable parts
- List viewables = getViewables(message, attachments);
-
- // Extract the Part references
- return getParts(viewables);
- } catch (Exception e) {
- throw new MessagingException("Couldn't extract viewable parts", e);
- }
- }
-
- /**
- * Extract the viewable textual parts of a message and return the rest as attachments.
- *
- * @param context
- * A {@link Context} instance that will be used to get localized strings.
- * @param message
- * The message to extract the text and attachments from.
- *
- * @return A {@link ViewableContainer} instance containing the textual parts of the message as
- * plain text and HTML, and a list of message parts considered attachments.
- *
- * @throws MessagingException
- * In case of an error.
- */
- public static ViewableContainer extractTextAndAttachments(Context context, Message message)
- throws MessagingException {
- try {
- List attachments = new ArrayList();
-
- // Collect all viewable parts
- List viewables = getViewables(message, attachments);
-
- /*
- * Convert the tree of viewable parts into text and HTML
- */
-
- // Used to suppress the divider for the first viewable part
- boolean hideDivider = true;
-
- StringBuilder text = new StringBuilder();
- StringBuilder html = new StringBuilder();
-
- for (Viewable viewable : viewables) {
- if (viewable instanceof Textual) {
- // This is either a text/plain or text/html part. Fill the variables 'text' and
- // 'html', converting between plain text and HTML as necessary.
- text.append(buildText(viewable, !hideDivider));
- html.append(buildHtml(viewable, !hideDivider));
- hideDivider = false;
- } else if (viewable instanceof MessageHeader) {
- MessageHeader header = (MessageHeader) viewable;
- Part containerPart = header.getContainerPart();
- Message innerMessage = header.getMessage();
-
- addTextDivider(text, containerPart, !hideDivider);
- addMessageHeaderText(context, text, innerMessage);
-
- addHtmlDivider(html, containerPart, !hideDivider);
- addMessageHeaderHtml(context, html, innerMessage);
-
- hideDivider = true;
- } else if (viewable instanceof Alternative) {
- // Handle multipart/alternative contents
- Alternative alternative = (Alternative) viewable;
-
- /*
- * We made sure at least one of text/plain or text/html is present when
- * creating the Alternative object. If one part is not present we convert the
- * other one to make sure 'text' and 'html' always contain the same text.
- */
- List textAlternative = alternative.getText().isEmpty() ?
- alternative.getHtml() : alternative.getText();
- List htmlAlternative = alternative.getHtml().isEmpty() ?
- alternative.getText() : alternative.getHtml();
-
- // Fill the 'text' variable
- boolean divider = !hideDivider;
- for (Viewable textViewable : textAlternative) {
- text.append(buildText(textViewable, divider));
- divider = true;
- }
-
- // Fill the 'html' variable
- divider = !hideDivider;
- for (Viewable htmlViewable : htmlAlternative) {
- html.append(buildHtml(htmlViewable, divider));
- divider = true;
- }
- hideDivider = false;
- }
- }
-
- return new ViewableContainer(text.toString(), html.toString(), attachments);
- } catch (Exception e) {
- throw new MessagingException("Couldn't extract viewable parts", e);
- }
- }
-
- /**
- * Traverse the MIME tree of a message an extract viewable parts.
- *
- * @param part
- * The message part to start from.
- * @param attachments
- * A list that will receive the parts that are considered attachments.
- *
- * @return A list of {@link Viewable}s.
- *
- * @throws MessagingException
- * In case of an error.
- */
- private static List getViewables(Part part, List attachments) throws MessagingException {
- List viewables = new ArrayList();
-
- Body body = part.getBody();
- if (body instanceof Multipart) {
- Multipart multipart = (Multipart) body;
- if (part.getMimeType().equalsIgnoreCase("multipart/alternative")) {
- /*
- * For multipart/alternative parts we try to find a text/plain and a text/html
- * child. Everything else we find is put into 'attachments'.
- */
- List text = findTextPart(multipart, true);
-
- Set knownTextParts = getParts(text);
- List html = findHtmlPart(multipart, knownTextParts, attachments, true);
-
- if (!text.isEmpty() || !html.isEmpty()) {
- Alternative alternative = new Alternative(text, html);
- viewables.add(alternative);
- }
- } else {
- // For all other multipart parts we recurse to grab all viewable children.
- for (Part bodyPart : multipart.getBodyParts()) {
- viewables.addAll(getViewables(bodyPart, attachments));
- }
- }
- } else if (body instanceof Message &&
- !("attachment".equalsIgnoreCase(getContentDisposition(part)))) {
- /*
- * We only care about message/rfc822 parts whose Content-Disposition header has a value
- * other than "attachment".
- */
- Message message = (Message) body;
-
- // We add the Message object so we can extract the filename later.
- viewables.add(new MessageHeader(part, message));
-
- // Recurse to grab all viewable parts and attachments from that message.
- viewables.addAll(getViewables(message, attachments));
- } else if (isPartTextualBody(part)) {
- /*
- * Save text/plain and text/html
- */
- String mimeType = part.getMimeType();
- if (mimeType.equalsIgnoreCase("text/plain")) {
- Text text = new Text(part);
- viewables.add(text);
- } else {
- Html html = new Html(part);
- viewables.add(html);
- }
- } else {
- // Everything else is treated as attachment.
- attachments.add(part);
- }
-
- return viewables;
- }
-
- /**
- * Search the children of a {@link Multipart} for {@code text/plain} parts.
- *
- * @param multipart
- * The {@code Multipart} to search through.
- * @param directChild
- * If {@code true}, this method will return after the first {@code text/plain} was
- * found.
- *
- * @return A list of {@link Text} viewables.
- *
- * @throws MessagingException
- * In case of an error.
- */
- private static List findTextPart(Multipart multipart, boolean directChild)
- throws MessagingException {
- List viewables = new ArrayList();
-
- for (Part part : multipart.getBodyParts()) {
- Body body = part.getBody();
- if (body instanceof Multipart) {
- Multipart innerMultipart = (Multipart) body;
-
- /*
- * Recurse to find text parts. Since this is a multipart that is a child of a
- * multipart/alternative we don't want to stop after the first text/plain part
- * we find. This will allow to get all text parts for constructions like this:
- *
- * 1. multipart/alternative
- * 1.1. multipart/mixed
- * 1.1.1. text/plain
- * 1.1.2. text/plain
- * 1.2. text/html
- */
- List textViewables = findTextPart(innerMultipart, false);
-
- if (!textViewables.isEmpty()) {
- viewables.addAll(textViewables);
- if (directChild) {
- break;
- }
- }
- } else if (isPartTextualBody(part) && part.getMimeType().equalsIgnoreCase("text/plain")) {
- Text text = new Text(part);
- viewables.add(text);
- if (directChild) {
- break;
- }
- }
- }
-
- return viewables;
- }
-
- /**
- * Search the children of a {@link Multipart} for {@code text/html} parts.
- *
- *
- * Every part that is not a {@code text/html} we want to display, we add to 'attachments'.
- *
- *
- * @param multipart
- * The {@code Multipart} to search through.
- * @param knownTextParts
- * A set of {@code text/plain} parts that shouldn't be added to 'attachments'.
- * @param attachments
- * A list that will receive the parts that are considered attachments.
- * @param directChild
- * If {@code true}, this method will add all {@code text/html} parts except the first
- * found to 'attachments'.
- *
- * @return A list of {@link Text} viewables.
- *
- * @throws MessagingException
- * In case of an error.
- */
- private static List findHtmlPart(Multipart multipart, Set knownTextParts,
- List attachments, boolean directChild) throws MessagingException {
- List viewables = new ArrayList();
-
- boolean partFound = false;
- for (Part part : multipart.getBodyParts()) {
- Body body = part.getBody();
- if (body instanceof Multipart) {
- Multipart innerMultipart = (Multipart) body;
-
- if (directChild && partFound) {
- // We already found our text/html part. Now we're only looking for attachments.
- findAttachments(innerMultipart, knownTextParts, attachments);
- } else {
- /*
- * Recurse to find HTML parts. Since this is a multipart that is a child of a
- * multipart/alternative we don't want to stop after the first text/html part
- * we find. This will allow to get all text parts for constructions like this:
- *
- * 1. multipart/alternative
- * 1.1. text/plain
- * 1.2. multipart/mixed
- * 1.2.1. text/html
- * 1.2.2. text/html
- * 1.3. image/jpeg
- */
- List htmlViewables = findHtmlPart(innerMultipart, knownTextParts,
- attachments, false);
-
- if (!htmlViewables.isEmpty()) {
- partFound = true;
- viewables.addAll(htmlViewables);
- }
- }
- } else if (!(directChild && partFound) && isPartTextualBody(part) &&
- part.getMimeType().equalsIgnoreCase("text/html")) {
- Html html = new Html(part);
- viewables.add(html);
- partFound = true;
- } else if (!knownTextParts.contains(part)) {
- // Only add this part as attachment if it's not a viewable text/plain part found
- // earlier.
- attachments.add(part);
- }
- }
-
- return viewables;
- }
-
- /**
- * Build a set of message parts for fast lookups.
- *
- * @param viewables
- * A list of {@link Viewable}s containing references to the message parts to include in
- * the set.
- *
- * @return The set of viewable {@code Part}s.
- *
- * @see MimeUtility#findHtmlPart(Multipart, Set, List, boolean)
- * @see MimeUtility#findAttachments(Multipart, Set, List)
- */
- private static Set getParts(List viewables) {
- Set parts = new HashSet();
-
- for (Viewable viewable : viewables) {
- if (viewable instanceof Textual) {
- parts.add(((Textual) viewable).getPart());
- } else if (viewable instanceof Alternative) {
- Alternative alternative = (Alternative) viewable;
- parts.addAll(getParts(alternative.getText()));
- parts.addAll(getParts(alternative.getHtml()));
- }
- }
-
- return parts;
- }
-
- /**
- * Traverse the MIME tree and add everything that's not a known text part to 'attachments'.
- *
- * @param multipart
- * The {@link Multipart} to start from.
- * @param knownTextParts
- * A set of known text parts we don't want to end up in 'attachments'.
- * @param attachments
- * A list that will receive the parts that are considered attachments.
- */
- private static void findAttachments(Multipart multipart, Set knownTextParts,
- List attachments) {
- for (Part part : multipart.getBodyParts()) {
- Body body = part.getBody();
- if (body instanceof Multipart) {
- Multipart innerMultipart = (Multipart) body;
- findAttachments(innerMultipart, knownTextParts, attachments);
- } else if (!knownTextParts.contains(part)) {
- attachments.add(part);
- }
- }
- }
-
- /**
- * Extract important header values from a message to display inline (plain text version).
- *
- * @param context
- * A {@link Context} instance that will be used to get localized strings.
- * @param text
- * The {@link StringBuilder} that will receive the (plain text) output.
- * @param message
- * The message to extract the header values from.
- *
- * @throws MessagingException
- * In case of an error.
- */
- private static void addMessageHeaderText(Context context, StringBuilder text, Message message)
- throws MessagingException {
- // From:
- Address[] from = message.getFrom();
- if (from != null && from.length > 0) {
- text.append(context.getString(R.string.message_compose_quote_header_from));
- text.append(' ');
- text.append(Address.toString(from));
- text.append("\r\n");
- }
-
- // To:
- Address[] to = message.getRecipients(RecipientType.TO);
- if (to != null && to.length > 0) {
- text.append(context.getString(R.string.message_compose_quote_header_to));
- text.append(' ');
- text.append(Address.toString(to));
- text.append("\r\n");
- }
-
- // Cc:
- Address[] cc = message.getRecipients(RecipientType.CC);
- if (cc != null && cc.length > 0) {
- text.append(context.getString(R.string.message_compose_quote_header_cc));
- text.append(' ');
- text.append(Address.toString(cc));
- text.append("\r\n");
- }
-
- // Date:
- Date date = message.getSentDate();
- if (date != null) {
- text.append(context.getString(R.string.message_compose_quote_header_send_date));
- text.append(' ');
- text.append(date.toString());
- text.append("\r\n");
- }
-
- // Subject:
- String subject = message.getSubject();
- text.append(context.getString(R.string.message_compose_quote_header_subject));
- text.append(' ');
- if (subject == null) {
- text.append(context.getString(R.string.general_no_subject));
- } else {
- text.append(subject);
- }
- text.append("\r\n\r\n");
- }
-
- /**
- * Extract important header values from a message to display inline (HTML version).
- *
- * @param context
- * A {@link Context} instance that will be used to get localized strings.
- * @param html
- * The {@link StringBuilder} that will receive the (HTML) output.
- * @param message
- * The message to extract the header values from.
- *
- * @throws MessagingException
- * In case of an error.
- */
- private static void addMessageHeaderHtml(Context context, StringBuilder html, Message message)
- throws MessagingException {
-
- html.append("");
-
- // From:
- Address[] from = message.getFrom();
- if (from != null && from.length > 0) {
- addTableRow(html, context.getString(R.string.message_compose_quote_header_from),
- Address.toString(from));
- }
-
- // To:
- Address[] to = message.getRecipients(RecipientType.TO);
- if (to != null && to.length > 0) {
- addTableRow(html, context.getString(R.string.message_compose_quote_header_to),
- Address.toString(to));
- }
-
- // Cc:
- Address[] cc = message.getRecipients(RecipientType.CC);
- if (cc != null && cc.length > 0) {
- addTableRow(html, context.getString(R.string.message_compose_quote_header_cc),
- Address.toString(cc));
- }
-
- // Date:
- Date date = message.getSentDate();
- if (date != null) {
- addTableRow(html, context.getString(R.string.message_compose_quote_header_send_date),
- date.toString());
- }
-
- // Subject:
- String subject = message.getSubject();
- addTableRow(html, context.getString(R.string.message_compose_quote_header_subject),
- (subject == null) ? context.getString(R.string.general_no_subject) : subject);
-
- html.append("
");
- }
-
- /**
- * Output an HTML table two column row with some hardcoded style.
- *
- * @param html
- * The {@link StringBuilder} that will receive the output.
- * @param header
- * The string to be put in the {@code TH} element.
- * @param value
- * The string to be put in the {@code TD} element.
- */
- private static void addTableRow(StringBuilder html, String header, String value) {
- html.append("");
- html.append(header);
- html.append(" | ");
- html.append("");
- html.append(value);
- html.append(" |
");
- }
-
- /**
- * Use the contents of a {@link Viewable} to create the plain text to be displayed.
- *
- *
- * This will use {@link HtmlConverter#htmlToText(String)} to convert HTML parts to plain text
- * if necessary.
- *
- *
- * @param viewable
- * The viewable part to build the text from.
- * @param prependDivider
- * {@code true}, if the text divider should be inserted as first element.
- * {@code false}, otherwise.
- *
- * @return The contents of the supplied viewable instance as plain text.
- */
- private static StringBuilder buildText(Viewable viewable, boolean prependDivider)
- {
- StringBuilder text = new StringBuilder();
- if (viewable instanceof Textual) {
- Part part = ((Textual)viewable).getPart();
- addTextDivider(text, part, prependDivider);
-
- String t = getTextFromPart(part);
- if (t == null) {
- t = "";
- } else if (viewable instanceof Html) {
- t = HtmlConverter.htmlToText(t);
- }
- text.append(t);
- } else if (viewable instanceof Alternative) {
- // That's odd - an Alternative as child of an Alternative; go ahead and try to use the
- // text/plain child; fall-back to the text/html part.
- Alternative alternative = (Alternative) viewable;
-
- List textAlternative = alternative.getText().isEmpty() ?
- alternative.getHtml() : alternative.getText();
-
- boolean divider = prependDivider;
- for (Viewable textViewable : textAlternative) {
- text.append(buildText(textViewable, divider));
- divider = true;
- }
- }
-
- return text;
- }
-
- /*
- * Some constants that are used by addTextDivider() below.
- */
- private static final int TEXT_DIVIDER_LENGTH = TEXT_DIVIDER.length();
- private static final String FILENAME_PREFIX = "----- ";
- private static final int FILENAME_PREFIX_LENGTH = FILENAME_PREFIX.length();
- private static final String FILENAME_SUFFIX = " ";
- private static final int FILENAME_SUFFIX_LENGTH = FILENAME_SUFFIX.length();
-
- /**
- * Add a plain text divider between two plain text message parts.
- *
- * @param text
- * The {@link StringBuilder} to append the divider to.
- * @param part
- * The message part that will follow after the divider. This is used to extract the
- * part's name.
- * @param prependDivider
- * {@code true}, if the divider should be appended. {@code false}, otherwise.
- */
- private static void addTextDivider(StringBuilder text, Part part, boolean prependDivider) {
- if (prependDivider) {
- String filename = getPartName(part);
-
- text.append("\r\n\r\n");
- int len = filename.length();
- if (len > 0) {
- if (len > TEXT_DIVIDER_LENGTH - FILENAME_PREFIX_LENGTH - FILENAME_SUFFIX_LENGTH) {
- filename = filename.substring(0, TEXT_DIVIDER_LENGTH - FILENAME_PREFIX_LENGTH -
- FILENAME_SUFFIX_LENGTH - 3) + "...";
- }
- text.append(FILENAME_PREFIX);
- text.append(filename);
- text.append(FILENAME_SUFFIX);
- text.append(TEXT_DIVIDER.substring(0, TEXT_DIVIDER_LENGTH -
- FILENAME_PREFIX_LENGTH - filename.length() - FILENAME_SUFFIX_LENGTH));
- } else {
- text.append(TEXT_DIVIDER);
- }
- text.append("\r\n\r\n");
- }
- }
-
- /**
- * Use the contents of a {@link Viewable} to create the HTML to be displayed.
- *
- *
- * This will use {@link HtmlConverter#textToHtml(String)} to convert plain text parts
- * to HTML if necessary.
- *
- *
- * @param viewable
- * The viewable part to build the HTML from.
- * @param prependDivider
- * {@code true}, if the HTML divider should be inserted as first element.
- * {@code false}, otherwise.
- *
- * @return The contents of the supplied viewable instance as HTML.
- */
- private static StringBuilder buildHtml(Viewable viewable, boolean prependDivider)
- {
- StringBuilder html = new StringBuilder();
- if (viewable instanceof Textual) {
- Part part = ((Textual)viewable).getPart();
- addHtmlDivider(html, part, prependDivider);
-
- String t = getTextFromPart(part);
- if (t == null) {
- t = "";
- } else if (viewable instanceof Text) {
- t = HtmlConverter.textToHtml(t);
- }
- html.append(t);
- } else if (viewable instanceof Alternative) {
- // That's odd - an Alternative as child of an Alternative; go ahead and try to use the
- // text/html child; fall-back to the text/plain part.
- Alternative alternative = (Alternative) viewable;
-
- List htmlAlternative = alternative.getHtml().isEmpty() ?
- alternative.getText() : alternative.getHtml();
-
- boolean divider = prependDivider;
- for (Viewable htmlViewable : htmlAlternative) {
- html.append(buildHtml(htmlViewable, divider));
- divider = true;
- }
- }
-
- return html;
- }
-
- /**
- * Add an HTML divider between two HTML message parts.
- *
- * @param html
- * The {@link StringBuilder} to append the divider to.
- * @param part
- * The message part that will follow after the divider. This is used to extract the
- * part's name.
- * @param prependDivider
- * {@code true}, if the divider should be appended. {@code false}, otherwise.
- */
- private static void addHtmlDivider(StringBuilder html, Part part, boolean prependDivider) {
- if (prependDivider) {
- String filename = getPartName(part);
-
- html.append("");
- html.append(filename);
- html.append("
");
- }
- }
-
- /**
- * Get the name of the message part.
- *
- * @param part
- * The part to get the name for.
- *
- * @return The (file)name of the part if available. An empty string, otherwise.
- */
- private static String getPartName(Part part) {
- try {
- String disposition = part.getDisposition();
- if (disposition != null) {
- String name = MimeUtility.getHeaderParameter(disposition, "filename");
- return (name == null) ? "" : name;
- }
- }
- catch (MessagingException e) { /* ignore */ }
-
- return "";
- }
-
- /**
- * Get the value of the {@code Content-Disposition} header.
- *
- * @param part
- * The message part to read the header from.
- *
- * @return The value of the {@code Content-Disposition} header if available. {@code null},
- * otherwise.
- */
- private static String getContentDisposition(Part part) {
- try {
- String disposition = part.getDisposition();
- if (disposition != null) {
- return MimeUtility.getHeaderParameter(disposition, null);
- }
- }
- catch (MessagingException e) { /* ignore */ }
-
- return null;
- }
-
- private static Boolean isPartTextualBody(Part part) throws MessagingException {
- String disposition = part.getDisposition();
- String dispositionType = null;
- String dispositionFilename = null;
- if (disposition != null) {
- dispositionType = MimeUtility.getHeaderParameter(disposition, null);
- dispositionFilename = MimeUtility.getHeaderParameter(disposition, "filename");
- }
-
- /*
- * A best guess that this part is intended to be an attachment and not inline.
- */
- boolean attachment = ("attachment".equalsIgnoreCase(dispositionType) || (dispositionFilename != null));
-
- if ((!attachment) && (part.getMimeType().equalsIgnoreCase("text/html"))) {
- return true;
- }
- /*
- * If the part is plain text and it got this far it's part of a
- * mixed (et al) and should be rendered inline.
- */
- else if ((!attachment) && (part.getMimeType().equalsIgnoreCase("text/plain"))) {
- return true;
- }
- /*
- * Finally, if it's nothing else we will include it as an attachment.
- */
- else {
- return false;
- }
- }
-
- public static String getCharsetFromAddress(String address) {
- String variant = getJisVariantFromAddress(address);
- if (variant != null) {
- String charset = "x-" + variant + "-shift_jis-2007";
- if (Charset.isSupported(charset))
- return charset;
- }
-
- return "UTF-8";
- }
-
public static String getMimeTypeByExtension(String filename) {
String returnedType = null;
String extension = null;
@@ -2078,50 +1049,6 @@ public class MimeUtility {
return null;
}
- /**
- * Convert some wrong MIME types encountered in the wild to canonical MIME types.
- *
- * @param mimeType
- * The original MIME type
- *
- * @return If {@code mimeType} is known to be wrong the correct MIME type is returned.
- * Otherwise the lower case version of {@code mimeType} is returned.
- *
- * @see #MIME_TYPE_REPLACEMENT_MAP
- */
- private static String canonicalizeMimeType(String mimeType) {
- String lowerCaseMimeType = mimeType.toLowerCase(Locale.US);
- for (String[] mimeTypeMapEntry : MIME_TYPE_REPLACEMENT_MAP) {
- if (mimeTypeMapEntry[0].equals(lowerCaseMimeType)) {
- return mimeTypeMapEntry[1];
- }
- }
- return lowerCaseMimeType;
- }
-
- /**
- * When viewing the attachment we want the MIME type to be as sensible as possible. So we fix
- * it up if necessary.
- *
- * @param mimeType
- * The original MIME type of the attachment.
- * @param name
- * The (file)name of the attachment.
- *
- * @return The best MIME type we can come up with.
- */
- public static String getMimeTypeForViewing(String mimeType, String name) {
- if (DEFAULT_ATTACHMENT_MIME_TYPE.equalsIgnoreCase(mimeType)) {
- // If the MIME type is the generic "application/octet-stream"
- // we try to find a better one by looking at the file extension.
- return getMimeTypeByExtension(name);
- }
-
- // Some messages contain wrong MIME types. See if we know better.
- return canonicalizeMimeType(mimeType);
- }
-
-
/**
* Get a default content-transfer-encoding for use with a given content-type
* when adding an unencoded attachment. It's possible that 8bit encodings
@@ -2152,1240 +1079,4 @@ public class MimeUtility {
return (MimeUtil.ENC_BASE64);
}
}
-
- private static Message getMessageFromPart(Part part) {
- while (part != null) {
- if (part instanceof Message)
- return (Message)part;
-
- if (!(part instanceof BodyPart))
- return null;
-
- Multipart multipart = ((BodyPart)part).getParent();
- if (multipart == null)
- return null;
-
- part = multipart.getParent();
- }
- return null;
- }
-
- public static String fixupCharset(String charset, Message message) throws MessagingException {
- if (charset == null || "0".equals(charset))
- charset = "US-ASCII"; // No encoding, so use us-ascii, which is the standard.
-
- charset = charset.toLowerCase(Locale.US);
- if (charset.equals("cp932"))
- charset = "shift_jis";
-
- if (charset.equals("shift_jis") || charset.equals("iso-2022-jp")) {
- String variant = getJisVariantFromMessage(message);
- if (variant != null)
- charset = "x-" + variant + "-" + charset + "-2007";
- }
- return charset;
- }
-
- private static String getJisVariantFromMessage(Message message) throws MessagingException {
- if (message == null)
- return null;
-
- // If a receiver is known to use a JIS variant, the sender transfers the message after converting the
- // charset as a convention.
- String variant = getJisVariantFromReceivedHeaders(message);
- if (variant != null)
- return variant;
-
- // If a receiver is not known to use any JIS variants, the sender transfers the message without converting
- // the charset.
- variant = getJisVariantFromFromHeaders(message);
- if (variant != null)
- return variant;
-
- return getJisVariantFromMailerHeaders(message);
- }
-
- private static String getJisVariantFromReceivedHeaders(Message message) throws MessagingException {
- String receivedHeaders[] = message.getHeader("Received");
- if (receivedHeaders == null)
- return null;
-
- for (String receivedHeader : receivedHeaders) {
- String address = getAddressFromReceivedHeader(receivedHeader);
- if (address == null)
- continue;
- String variant = getJisVariantFromAddress(address);
- if (variant != null)
- return variant;
- }
- return null;
- }
-
- private static String getAddressFromReceivedHeader(String receivedHeader) {
- // Not implemented yet! Extract an address from the FOR clause of the given Received header.
- return null;
- }
-
- private static String getJisVariantFromFromHeaders(Message message) throws MessagingException {
- Address addresses[] = message.getFrom();
- if (addresses == null || addresses.length == 0)
- return null;
-
- return getJisVariantFromAddress(addresses[0].getAddress());
- }
-
- private static String getJisVariantFromAddress(String address) {
- if (address == null)
- return null;
- if (isInDomain(address, "docomo.ne.jp") || isInDomain(address, "dwmail.jp") ||
- isInDomain(address, "pdx.ne.jp") || isInDomain(address, "willcom.com") ||
- isInDomain(address, "emnet.ne.jp") || isInDomain(address, "emobile.ne.jp"))
- return "docomo";
- else if (isInDomain(address, "softbank.ne.jp") || isInDomain(address, "vodafone.ne.jp") ||
- isInDomain(address, "disney.ne.jp") || isInDomain(address, "vertuclub.ne.jp"))
- return "softbank";
- else if (isInDomain(address, "ezweb.ne.jp") || isInDomain(address, "ido.ne.jp"))
- return "kddi";
- return null;
- }
-
- private static boolean isInDomain(String address, String domain) {
- int index = address.length() - domain.length() - 1;
- if (index < 0)
- return false;
-
- char c = address.charAt(index);
- if (c != '@' && c != '.')
- return false;
-
- return address.endsWith(domain);
- }
-
- private static String getJisVariantFromMailerHeaders(Message message) throws MessagingException {
- String mailerHeaders[] = message.getHeader("X-Mailer");
- if (mailerHeaders == null || mailerHeaders.length == 0)
- return null;
-
- if (mailerHeaders[0].startsWith("iPhone Mail ") || mailerHeaders[0].startsWith("iPad Mail "))
- return "iphone";
-
- return null;
- }
-
- public static String readToString(InputStream in, String charset) throws IOException {
- boolean isIphoneString = false;
-
- // iso-2022-jp variants are supported by no versions as of Dec 2010.
- if (charset.length() > 19 && charset.startsWith("x-") &&
- charset.endsWith("-iso-2022-jp-2007") && !Charset.isSupported(charset)) {
- in = new Iso2022JpToShiftJisInputStream(in);
- charset = "x-" + charset.substring(2, charset.length() - 17) + "-shift_jis-2007";
- }
-
- // shift_jis variants are supported by Eclair and later.
- if (charset.length() > 17 && charset.startsWith("x-") &&
- charset.endsWith("-shift_jis-2007") && !Charset.isSupported(charset)) {
- // If the JIS variant is iPhone, map the Unicode private use area in iPhone to the one in Android after
- // converting the character set from the standard Shift JIS to Unicode.
- if (charset.substring(2, charset.length() - 15).equals("iphone"))
- isIphoneString = true;
-
- charset = "shift_jis";
- }
-
- /*
- * See if there is conversion from the MIME charset to the Java one.
- * this function may also throw an exception if the charset name is not known
- */
- boolean supported;
- try {
- supported = Charset.isSupported(charset);
- } catch (IllegalCharsetNameException e) {
- supported = false;
- }
-
- for (String[] rule: CHARSET_FALLBACK_MAP) {
- if (supported) {
- break;
- }
-
- if (charset.matches(rule[0])) {
- Log.e(K9.LOG_TAG, "I don't know how to deal with the charset " + charset +
- ". Falling back to " + rule[1]);
- charset = rule[1];
- try {
- supported = Charset.isSupported(charset);
- } catch (IllegalCharsetNameException e) {
- supported = false;
- }
- }
- }
-
- /*
- * Convert and return as new String
- */
- String str = IOUtils.toString(in, charset);
-
- if (isIphoneString)
- str = importStringFromIphone(str);
- return str;
- }
-
- static private String importStringFromIphone(String str) {
- StringBuilder buff = new StringBuilder(str.length());
- for (int i = 0; i < str.length(); i = str.offsetByCodePoints(i, 1)) {
- int codePoint = str.codePointAt(i);
- buff.appendCodePoint(importCodePointFromIphone(codePoint));
- }
- return buff.toString();
- }
-
- static private int importCodePointFromIphone(int codePoint) {
- switch (codePoint) {
- case 0xE001:
- return 0xFE19B;
- case 0xE002:
- return 0xFE19C;
- case 0xE003:
- return 0xFE823;
- case 0xE004:
- return 0xFE19D;
- case 0xE005:
- return 0xFE19E;
- case 0xE006:
- return 0xFE4CF;
- case 0xE007:
- return 0xFE4CD;
- case 0xE008:
- return 0xFE4EF;
- case 0xE009:
- return 0xFE523;
- case 0xE00A:
- return 0xFE525;
- case 0xE00B:
- return 0xFE528;
- case 0xE00C:
- return 0xFE538;
- case 0xE00D:
- return 0xFEB96;
- case 0xE00E:
- return 0xFEB97;
- case 0xE00F:
- return 0xFEB98;
- case 0xE010:
- return 0xFEB93;
- case 0xE011:
- return 0xFEB94;
- case 0xE012:
- return 0xFEB95;
- case 0xE013:
- return 0xFE7D5;
- case 0xE014:
- return 0xFE7D2;
- case 0xE015:
- return 0xFE7D3;
- case 0xE016:
- return 0xFE7D1;
- case 0xE017:
- return 0xFE7DA;
- case 0xE018:
- return 0xFE7D4;
- case 0xE019:
- return 0xFE1BD;
- case 0xE01A:
- return 0xFE1BE;
- case 0xE01B:
- return 0xFE7E4;
- case 0xE01C:
- return 0xFE7EA;
- case 0xE01D:
- return 0xFE7E9;
- case 0xE01E:
- return 0xFE7DF;
- case 0xE01F:
- return 0xFE7E3;
- case 0xE020:
- return 0xFEB09;
- case 0xE021:
- return 0xFEB04;
- case 0xE022:
- return 0xFEB0C;
- case 0xE023:
- return 0xFEB0E;
- case 0xE024:
- return 0xFE01E;
- case 0xE025:
- return 0xFE01F;
- case 0xE026:
- return 0xFE020;
- case 0xE027:
- return 0xFE021;
- case 0xE028:
- return 0xFE022;
- case 0xE029:
- return 0xFE023;
- case 0xE02A:
- return 0xFE024;
- case 0xE02B:
- return 0xFE025;
- case 0xE02C:
- return 0xFE026;
- case 0xE02D:
- return 0xFE027;
- case 0xE02E:
- return 0xFE028;
- case 0xE02F:
- return 0xFE029;
- case 0xE030:
- return 0xFE040;
- case 0xE031:
- return 0xFE4D2;
- case 0xE032:
- return 0xFE041;
- case 0xE033:
- return 0xFE512;
- case 0xE034:
- return 0xFE825;
- case 0xE035:
- return 0xFE826;
- case 0xE036:
- return 0xFE4B0;
- case 0xE037:
- return 0xFE4BB;
- case 0xE038:
- return 0xFE4B2;
- case 0xE039:
- return 0xFE7EC;
- case 0xE03A:
- return 0xFE7F5;
- case 0xE03B:
- return 0xFE4C3;
- case 0xE03C:
- return 0xFE800;
- case 0xE03D:
- return 0xFE801;
- case 0xE03E:
- return 0xFE813;
- case 0xE03F:
- return 0xFEB82;
- case 0xE040:
- return 0xFE815;
- case 0xE041:
- return 0xFE816;
- case 0xE042:
- return 0xFE818;
- case 0xE043:
- return 0xFE980;
- case 0xE044:
- return 0xFE982;
- case 0xE045:
- return 0xFE981;
- case 0xE046:
- return 0xFE962;
- case 0xE047:
- return 0xFE983;
- case 0xE048:
- return 0xFE003;
- case 0xE049:
- return 0xFE001;
- case 0xE04A:
- return 0xFE000;
- case 0xE04B:
- return 0xFE002;
- case 0xE04C:
- return 0xFE014;
- case 0xE04D:
- return 0xFE009;
- case 0xE04E:
- return 0xFE1AF;
- case 0xE04F:
- return 0xFE1B8;
- case 0xE050:
- return 0xFE1C0;
- case 0xE051:
- return 0xFE1C1;
- case 0xE052:
- return 0xFE1B7;
- case 0xE053:
- return 0xFE1C2;
- case 0xE054:
- return 0xFE1C3;
- case 0xE055:
- return 0xFE1BC;
- case 0xE056:
- return 0xFE335;
- case 0xE057:
- return 0xFE330;
- case 0xE058:
- return 0xFE323;
- case 0xE059:
- return 0xFE320;
- case 0xE05A:
- return 0xFE4F4;
- case 0xE101:
- return 0xFE52D;
- case 0xE102:
- return 0xFE52E;
- case 0xE103:
- return 0xFE52B;
- case 0xE104:
- return 0xFE526;
- case 0xE105:
- return 0xFE329;
- case 0xE106:
- return 0xFE327;
- case 0xE107:
- return 0xFE341;
- case 0xE108:
- return 0xFE344;
- case 0xE109:
- return 0xFE1C4;
- case 0xE10A:
- return 0xFE1C5;
- case 0xE10B:
- return 0xFE1BF;
- case 0xE10C:
- return 0xFE1B0;
- case 0xE10D:
- return 0xFE7ED;
- case 0xE10E:
- return 0xFE4D1;
- case 0xE10F:
- return 0xFEB56;
- case 0xE110:
- return 0xFE03C;
- case 0xE111:
- return 0xFE827;
- case 0xE112:
- return 0xFE510;
- case 0xE113:
- return 0xFE4F5;
- case 0xE114:
- return 0xFEB85;
- case 0xE115:
- return 0xFE7D9;
- case 0xE116:
- return 0xFE4CA;
- case 0xE117:
- return 0xFE515;
- case 0xE118:
- return 0xFE03F;
- case 0xE119:
- return 0xFE042;
- case 0xE11A:
- return 0xFE1B2;
- case 0xE11B:
- return 0xFE1AE;
- case 0xE11C:
- return 0xFE1B3;
- case 0xE11D:
- return 0xFE4F6;
- case 0xE11E:
- return 0xFE53B;
- case 0xE11F:
- return 0xFE537;
- case 0xE120:
- return 0xFE960;
- case 0xE121:
- return 0xFE4BC;
- case 0xE122:
- return 0xFE7FB;
- case 0xE123:
- return 0xFE7FA;
- case 0xE124:
- return 0xFE7FD;
- case 0xE125:
- return 0xFE807;
- case 0xE126:
- return 0xFE81D;
- case 0xE127:
- return 0xFE81E;
- case 0xE128:
- return 0xFE81F;
- case 0xE129:
- return 0xFE820;
- case 0xE12A:
- return 0xFE81C;
- case 0xE12B:
- return 0xFE1B1;
- case 0xE12C:
- return 0xFE81B;
- case 0xE12D:
- return 0xFE80B;
- case 0xE12E:
- return 0xFEB32;
- case 0xE12F:
- return 0xFE4DD;
- case 0xE130:
- return 0xFE80C;
- case 0xE131:
- return 0xFE7DB;
- case 0xE132:
- return 0xFE7D7;
- case 0xE133:
- return 0xFE80D;
- case 0xE134:
- return 0xFE7DC;
- case 0xE135:
- return 0xFE7EE;
- case 0xE136:
- return 0xFE7EB;
- case 0xE137:
- return 0xFE7F8;
- case 0xE138:
- return 0xFEB33;
- case 0xE139:
- return 0xFEB34;
- case 0xE13A:
- return 0xFEB35;
- case 0xE13B:
- return 0xFE509;
- case 0xE13C:
- return 0xFEB59;
- case 0xE13D:
- return 0xFE004;
- case 0xE13E:
- return 0xFE4D6;
- case 0xE13F:
- return 0xFE505;
- case 0xE140:
- return 0xFE507;
- case 0xE141:
- return 0xFE821;
- case 0xE142:
- return 0xFE52F;
- case 0xE143:
- return 0xFE514;
- case 0xE144:
- return 0xFEB86;
- case 0xE145:
- return 0xFEB87;
- case 0xE146:
- return 0xFE00B;
- case 0xE147:
- return 0xFE965;
- case 0xE148:
- return 0xFE546;
- case 0xE149:
- return 0xFE4DE;
- case 0xE14A:
- return 0xFE4DF;
- case 0xE14B:
- return 0xFE531;
- case 0xE14C:
- return 0xFEB5E;
- case 0xE14D:
- return 0xFE4B5;
- case 0xE14E:
- return 0xFE7F7;
- case 0xE14F:
- return 0xFE7F6;
- case 0xE150:
- return 0xFE7E7;
- case 0xE151:
- return 0xFE506;
- case 0xE152:
- return 0xFE1A1;
- case 0xE153:
- return 0xFE4B3;
- case 0xE154:
- return 0xFE4B6;
- case 0xE155:
- return 0xFE4B4;
- case 0xE156:
- return 0xFE4B9;
- case 0xE157:
- return 0xFE4BA;
- case 0xE158:
- return 0xFE4B7;
- case 0xE159:
- return 0xFE7E6;
- case 0xE15A:
- return 0xFE7EF;
- case 0xE201:
- return 0xFE7F0;
- case 0xE202:
- return 0xFE7E8;
- case 0xE203:
- return 0xFEB24;
- case 0xE204:
- return 0xFEB19;
- case 0xE205:
- return 0xFEB61;
- case 0xE206:
- return 0xFEB62;
- case 0xE207:
- return 0xFEB25;
- case 0xE208:
- return 0xFEB1F;
- case 0xE209:
- return 0xFE044;
- case 0xE20A:
- return 0xFEB20;
- case 0xE20B:
- return 0xFE838;
- case 0xE20C:
- return 0xFEB1A;
- case 0xE20D:
- return 0xFEB1C;
- case 0xE20E:
- return 0xFEB1B;
- case 0xE20F:
- return 0xFEB1D;
- case 0xE210:
- return 0xFE82C;
- case 0xE211:
- return 0xFE82B;
- case 0xE212:
- return 0xFEB36;
- case 0xE213:
- return 0xFEB37;
- case 0xE214:
- return 0xFEB38;
- case 0xE215:
- return 0xFEB39;
- case 0xE216:
- return 0xFEB3A;
- case 0xE217:
- return 0xFEB3B;
- case 0xE218:
- return 0xFEB3C;
- case 0xE219:
- return 0xFEB63;
- case 0xE21A:
- return 0xFEB64;
- case 0xE21B:
- return 0xFEB67;
- case 0xE21C:
- return 0xFE82E;
- case 0xE21D:
- return 0xFE82F;
- case 0xE21E:
- return 0xFE830;
- case 0xE21F:
- return 0xFE831;
- case 0xE220:
- return 0xFE832;
- case 0xE221:
- return 0xFE833;
- case 0xE222:
- return 0xFE834;
- case 0xE223:
- return 0xFE835;
- case 0xE224:
- return 0xFE836;
- case 0xE225:
- return 0xFE837;
- case 0xE226:
- return 0xFEB3D;
- case 0xE227:
- return 0xFEB3E;
- case 0xE228:
- return 0xFEB3F;
- case 0xE229:
- return 0xFEB81;
- case 0xE22A:
- return 0xFEB31;
- case 0xE22B:
- return 0xFEB2F;
- case 0xE22C:
- return 0xFEB40;
- case 0xE22D:
- return 0xFEB41;
- case 0xE22E:
- return 0xFEB99;
- case 0xE22F:
- return 0xFEB9A;
- case 0xE230:
- return 0xFEB9B;
- case 0xE231:
- return 0xFEB9C;
- case 0xE232:
- return 0xFEAF8;
- case 0xE233:
- return 0xFEAF9;
- case 0xE234:
- return 0xFEAFA;
- case 0xE235:
- return 0xFEAFB;
- case 0xE236:
- return 0xFEAF0;
- case 0xE237:
- return 0xFEAF2;
- case 0xE238:
- return 0xFEAF1;
- case 0xE239:
- return 0xFEAF3;
- case 0xE23A:
- return 0xFEAFC;
- case 0xE23B:
- return 0xFEAFD;
- case 0xE23C:
- return 0xFEAFE;
- case 0xE23D:
- return 0xFEAFF;
- case 0xE23E:
- return 0xFE4F8;
- case 0xE23F:
- return 0xFE02B;
- case 0xE240:
- return 0xFE02C;
- case 0xE241:
- return 0xFE02D;
- case 0xE242:
- return 0xFE02E;
- case 0xE243:
- return 0xFE02F;
- case 0xE244:
- return 0xFE030;
- case 0xE245:
- return 0xFE031;
- case 0xE246:
- return 0xFE032;
- case 0xE247:
- return 0xFE033;
- case 0xE248:
- return 0xFE034;
- case 0xE249:
- return 0xFE035;
- case 0xE24A:
- return 0xFE036;
- case 0xE24B:
- return 0xFE037;
- case 0xE24C:
- return 0xFEB42;
- case 0xE24D:
- return 0xFEB27;
- case 0xE24E:
- return 0xFEB29;
- case 0xE24F:
- return 0xFEB2D;
- case 0xE250:
- return 0xFE839;
- case 0xE251:
- return 0xFE83A;
- case 0xE252:
- return 0xFEB23;
- case 0xE253:
- return 0xFE1B4;
- case 0xE254:
- return 0xFEE77;
- case 0xE255:
- return 0xFEE78;
- case 0xE256:
- return 0xFEE79;
- case 0xE257:
- return 0xFEE7A;
- case 0xE258:
- return 0xFEE7B;
- case 0xE259:
- return 0xFEE7C;
- case 0xE25A:
- return 0xFEE7D;
- case 0xE301:
- return 0xFE527;
- case 0xE302:
- return 0xFE4D3;
- case 0xE303:
- return 0xFE045;
- case 0xE304:
- return 0xFE03D;
- case 0xE305:
- return 0xFE046;
- case 0xE306:
- return 0xFE828;
- case 0xE307:
- return 0xFE047;
- case 0xE308:
- return 0xFE048;
- case 0xE309:
- return 0xFE508;
- case 0xE30A:
- return 0xFE803;
- case 0xE30B:
- return 0xFE985;
- case 0xE30C:
- return 0xFE987;
- case 0xE30D:
- return 0xFEB43;
- case 0xE30E:
- return 0xFEB1E;
- case 0xE30F:
- return 0xFE50A;
- case 0xE310:
- return 0xFE516;
- case 0xE311:
- return 0xFEB58;
- case 0xE312:
- return 0xFE517;
- case 0xE313:
- return 0xFE53E;
- case 0xE314:
- return 0xFE50F;
- case 0xE315:
- return 0xFEB2B;
- case 0xE316:
- return 0xFE53C;
- case 0xE317:
- return 0xFE530;
- case 0xE318:
- return 0xFE4D4;
- case 0xE319:
- return 0xFE4D5;
- case 0xE31A:
- return 0xFE4D7;
- case 0xE31B:
- return 0xFE4D8;
- case 0xE31C:
- return 0xFE195;
- case 0xE31D:
- return 0xFE196;
- case 0xE31E:
- return 0xFE197;
- case 0xE31F:
- return 0xFE198;
- case 0xE320:
- return 0xFE199;
- case 0xE321:
- return 0xFE4D9;
- case 0xE322:
- return 0xFE4DA;
- case 0xE323:
- return 0xFE4F0;
- case 0xE324:
- return 0xFE808;
- case 0xE325:
- return 0xFE4F2;
- case 0xE326:
- return 0xFE814;
- case 0xE327:
- return 0xFEB0D;
- case 0xE328:
- return 0xFEB11;
- case 0xE329:
- return 0xFEB12;
- case 0xE32A:
- return 0xFEB13;
- case 0xE32B:
- return 0xFEB14;
- case 0xE32C:
- return 0xFEB15;
- case 0xE32D:
- return 0xFEB16;
- case 0xE32E:
- return 0xFEB60;
- case 0xE32F:
- return 0xFEB68;
- case 0xE330:
- return 0xFEB5D;
- case 0xE331:
- return 0xFEB5B;
- case 0xE332:
- return 0xFEB44;
- case 0xE333:
- return 0xFEB45;
- case 0xE334:
- return 0xFEB57;
- case 0xE335:
- return 0xFEB69;
- case 0xE336:
- return 0xFEB0A;
- case 0xE337:
- return 0xFEB0B;
- case 0xE338:
- return 0xFE984;
- case 0xE339:
- return 0xFE964;
- case 0xE33A:
- return 0xFE966;
- case 0xE33B:
- return 0xFE967;
- case 0xE33C:
- return 0xFE968;
- case 0xE33D:
- return 0xFE969;
- case 0xE33E:
- return 0xFE96A;
- case 0xE33F:
- return 0xFE96B;
- case 0xE340:
- return 0xFE963;
- case 0xE341:
- return 0xFE96C;
- case 0xE342:
- return 0xFE961;
- case 0xE343:
- return 0xFE96D;
- case 0xE344:
- return 0xFE96E;
- case 0xE345:
- return 0xFE051;
- case 0xE346:
- return 0xFE052;
- case 0xE347:
- return 0xFE053;
- case 0xE348:
- return 0xFE054;
- case 0xE349:
- return 0xFE055;
- case 0xE34A:
- return 0xFE056;
- case 0xE34B:
- return 0xFE511;
- case 0xE34C:
- return 0xFE96F;
- case 0xE34D:
- return 0xFE970;
- case 0xE401:
- return 0xFE345;
- case 0xE402:
- return 0xFE343;
- case 0xE403:
- return 0xFE340;
- case 0xE404:
- return 0xFE333;
- case 0xE405:
- return 0xFE347;
- case 0xE406:
- return 0xFE33C;
- case 0xE407:
- return 0xFE33F;
- case 0xE408:
- return 0xFE342;
- case 0xE409:
- return 0xFE32A;
- case 0xE40A:
- return 0xFE33E;
- case 0xE40B:
- return 0xFE33B;
- case 0xE40C:
- return 0xFE32E;
- case 0xE40D:
- return 0xFE32F;
- case 0xE40E:
- return 0xFE326;
- case 0xE40F:
- return 0xFE325;
- case 0xE410:
- return 0xFE322;
- case 0xE411:
- return 0xFE33A;
- case 0xE412:
- return 0xFE334;
- case 0xE413:
- return 0xFE339;
- case 0xE414:
- return 0xFE336;
- case 0xE415:
- return 0xFE338;
- case 0xE416:
- return 0xFE33D;
- case 0xE417:
- return 0xFE32D;
- case 0xE418:
- return 0xFE32C;
- case 0xE419:
- return 0xFE190;
- case 0xE41A:
- return 0xFE192;
- case 0xE41B:
- return 0xFE191;
- case 0xE41C:
- return 0xFE193;
- case 0xE41D:
- return 0xFE35B;
- case 0xE41E:
- return 0xFEB9D;
- case 0xE41F:
- return 0xFEB9E;
- case 0xE420:
- return 0xFEB9F;
- case 0xE421:
- return 0xFEBA0;
- case 0xE422:
- return 0xFEBA1;
- case 0xE423:
- return 0xFE351;
- case 0xE424:
- return 0xFE352;
- case 0xE425:
- return 0xFE829;
- case 0xE426:
- return 0xFE353;
- case 0xE427:
- return 0xFE358;
- case 0xE428:
- return 0xFE1A0;
- case 0xE429:
- return 0xFE1A2;
- case 0xE42A:
- return 0xFE7D6;
- case 0xE42B:
- return 0xFE7DD;
- case 0xE42C:
- return 0xFE80E;
- case 0xE42D:
- return 0xFE7DE;
- case 0xE42E:
- return 0xFE7E5;
- case 0xE42F:
- return 0xFE7F1;
- case 0xE430:
- return 0xFE7F2;
- case 0xE431:
- return 0xFE7F3;
- case 0xE432:
- return 0xFE7F4;
- case 0xE433:
- return 0xFE7FE;
- case 0xE434:
- return 0xFE7E0;
- case 0xE435:
- return 0xFE7E2;
- case 0xE436:
- return 0xFE518;
- case 0xE437:
- return 0xFEB17;
- case 0xE438:
- return 0xFE519;
- case 0xE439:
- return 0xFE51A;
- case 0xE43A:
- return 0xFE51B;
- case 0xE43B:
- return 0xFE51C;
- case 0xE43C:
- return 0xFE007;
- case 0xE43D:
- return 0xFE82A;
- case 0xE43E:
- return 0xFE038;
- case 0xE43F:
- return 0xFE971;
- case 0xE440:
- return 0xFE51D;
- case 0xE441:
- return 0xFE1C6;
- case 0xE442:
- return 0xFE51E;
- case 0xE443:
- return 0xFE005;
- case 0xE444:
- return 0xFE049;
- case 0xE445:
- return 0xFE51F;
- case 0xE446:
- return 0xFE017;
- case 0xE447:
- return 0xFE043;
- case 0xE448:
- return 0xFE513;
- case 0xE449:
- return 0xFE00A;
- case 0xE44A:
- return 0xFE00C;
- case 0xE44B:
- return 0xFE008;
- case 0xE44C:
- return 0xFE00D;
- case 0xE501:
- return 0xFE4B8;
- case 0xE502:
- return 0xFE804;
- case 0xE503:
- return 0xFE805;
- case 0xE504:
- return 0xFE4BD;
- case 0xE505:
- return 0xFE4BE;
- case 0xE506:
- return 0xFE4BF;
- case 0xE507:
- return 0xFE802;
- case 0xE508:
- return 0xFE4C0;
- case 0xE509:
- return 0xFE4C4;
- case 0xE50A:
- return 0xFE4C5;
- case 0xE50B:
- return 0xFE4E5;
- case 0xE50C:
- return 0xFE4E6;
- case 0xE50D:
- return 0xFE4E7;
- case 0xE50E:
- return 0xFE4E8;
- case 0xE50F:
- return 0xFE4E9;
- case 0xE510:
- return 0xFE4EA;
- case 0xE511:
- return 0xFE4EB;
- case 0xE512:
- return 0xFE4EC;
- case 0xE513:
- return 0xFE4ED;
- case 0xE514:
- return 0xFE4EE;
- case 0xE515:
- return 0xFE1A4;
- case 0xE516:
- return 0xFE1A5;
- case 0xE517:
- return 0xFE1A6;
- case 0xE518:
- return 0xFE1A7;
- case 0xE519:
- return 0xFE1A8;
- case 0xE51A:
- return 0xFE1A9;
- case 0xE51B:
- return 0xFE1AA;
- case 0xE51C:
- return 0xFE1AB;
- case 0xE51D:
- return 0xFE4C6;
- case 0xE51E:
- return 0xFE1B5;
- case 0xE51F:
- return 0xFE1B6;
- case 0xE520:
- return 0xFE1C7;
- case 0xE521:
- return 0xFE1C8;
- case 0xE522:
- return 0xFE1C9;
- case 0xE523:
- return 0xFE1BA;
- case 0xE524:
- return 0xFE1CA;
- case 0xE525:
- return 0xFE1CB;
- case 0xE526:
- return 0xFE1CC;
- case 0xE527:
- return 0xFE1CD;
- case 0xE528:
- return 0xFE1CE;
- case 0xE529:
- return 0xFE1CF;
- case 0xE52A:
- return 0xFE1D0;
- case 0xE52B:
- return 0xFE1D1;
- case 0xE52C:
- return 0xFE1D2;
- case 0xE52D:
- return 0xFE1D3;
- case 0xE52E:
- return 0xFE1D4;
- case 0xE52F:
- return 0xFE1D5;
- case 0xE530:
- return 0xFE1D6;
- case 0xE531:
- return 0xFE1D7;
- case 0xE532:
- return 0xFE50B;
- case 0xE533:
- return 0xFE50C;
- case 0xE534:
- return 0xFE50D;
- case 0xE535:
- return 0xFE50E;
- case 0xE536:
- return 0xFE553;
- case 0xE537:
- return 0xFEB2A;
- case 0xE538:
- return 0xFEE70;
- case 0xE539:
- return 0xFEE71;
- case 0xE53A:
- return 0xFEE72;
- case 0xE53B:
- return 0xFEE73;
- case 0xE53C:
- return 0xFEE74;
- case 0xE53D:
- return 0xFEE75;
- case 0xE53E:
- return 0xFEE76;
- default:
- return codePoint;
- }
- }
-
- public static void setCharset(String charset, Part part) throws MessagingException {
- part.setHeader(MimeHeader.HEADER_CONTENT_TYPE,
- part.getMimeType() + ";\r\n charset=" + getExternalCharset(charset));
- }
-
- public static String getExternalCharset(String charset) {
- if (charset.length() > 17 && charset.startsWith("x-") &&
- charset.endsWith("-shift_jis-2007"))
- return "shift_jis";
-
- return charset;
- }
-
- public static ViewableContainer extractPartsFromDraft(Message message)
- throws MessagingException {
-
- Body body = message.getBody();
- if (message.isMimeType("multipart/mixed") && body instanceof MimeMultipart) {
- MimeMultipart multipart = (MimeMultipart) body;
-
- ViewableContainer container;
- int count = multipart.getCount();
- if (count >= 1) {
- // The first part is either a text/plain or a multipart/alternative
- BodyPart firstPart = multipart.getBodyPart(0);
- container = extractTextual(firstPart);
-
- // The rest should be attachments
- for (int i = 1; i < count; i++) {
- BodyPart bodyPart = multipart.getBodyPart(i);
- container.attachments.add(bodyPart);
- }
- } else {
- container = new ViewableContainer("", "", new ArrayList());
- }
-
- return container;
- }
-
- return extractTextual(message);
- }
-
- private static ViewableContainer extractTextual(Part part) throws MessagingException {
- String text = "";
- String html = "";
- List attachments = new ArrayList();
-
- Body firstBody = part.getBody();
- if (part.isMimeType("text/plain")) {
- String bodyText = getTextFromPart(part);
- if (bodyText != null) {
- text = bodyText;
- html = HtmlConverter.textToHtml(text);
- }
- } else if (part.isMimeType("multipart/alternative") &&
- firstBody instanceof MimeMultipart) {
- MimeMultipart multipart = (MimeMultipart) firstBody;
- for (BodyPart bodyPart : multipart.getBodyParts()) {
- String bodyText = getTextFromPart(bodyPart);
- if (bodyText != null) {
- if (text.isEmpty() && bodyPart.isMimeType("text/plain")) {
- text = bodyText;
- } else if (html.isEmpty() && bodyPart.isMimeType("text/html")) {
- html = bodyText;
- }
- }
- }
- }
-
- return new ViewableContainer(text, html, attachments);
- }
}
diff --git a/src/com/fsck/k9/mail/internet/TextBody.java b/src/com/fsck/k9/mail/internet/TextBody.java
index ad6e474ac..d6355662f 100644
--- a/src/com/fsck/k9/mail/internet/TextBody.java
+++ b/src/com/fsck/k9/mail/internet/TextBody.java
@@ -4,7 +4,11 @@ package com.fsck.k9.mail.internet;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.MessagingException;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
import org.apache.james.mime4j.codec.QuotedPrintableOutputStream;
import org.apache.james.mime4j.util.MimeUtil;
diff --git a/src/com/fsck/k9/mail/internet/Viewable.java b/src/com/fsck/k9/mail/internet/Viewable.java
new file mode 100644
index 000000000..6ec32b926
--- /dev/null
+++ b/src/com/fsck/k9/mail/internet/Viewable.java
@@ -0,0 +1,105 @@
+package com.fsck.k9.mail.internet;
+
+import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.Part;
+
+import java.util.List;
+
+/**
+ * Empty marker class interface the class hierarchy used by
+ * {@link com.fsck.k9.mailstore.LocalMessageExtractor#extractTextAndAttachments(android.content.Context, com.fsck.k9.mail.Message)}.
+ *
+ * @see Viewable.Text
+ * @see Viewable.Html
+ * @see Viewable.MessageHeader
+ * @see Viewable.Alternative
+ */
+public interface Viewable {
+ /**
+ * Class representing textual parts of a message that aren't marked as attachments.
+ *
+ * @see com.fsck.k9.mail.internet.MessageExtractor#isPartTextualBody(com.fsck.k9.mail.Part)
+ */
+ static abstract class Textual implements Viewable {
+ private Part mPart;
+
+ public Textual(Part part) {
+ mPart = part;
+ }
+
+ public Part getPart() {
+ return mPart;
+ }
+ }
+
+ /**
+ * Class representing a {@code text/plain} part of a message.
+ */
+ static class Text extends Textual {
+ public Text(Part part) {
+ super(part);
+ }
+ }
+
+ /**
+ * Class representing a {@code text/html} part of a message.
+ */
+ static class Html extends Textual {
+ public Html(Part part) {
+ super(part);
+ }
+ }
+
+ /**
+ * Class representing a {@code message/rfc822} part of a message.
+ *
+ *
+ * This is used to extract basic header information when the message contents are displayed
+ * inline.
+ *
+ */
+ static class MessageHeader implements Viewable {
+ private Part mContainerPart;
+ private Message mMessage;
+
+ public MessageHeader(Part containerPart, Message message) {
+ mContainerPart = containerPart;
+ mMessage = message;
+ }
+
+ public Part getContainerPart() {
+ return mContainerPart;
+ }
+
+ public Message getMessage() {
+ return mMessage;
+ }
+ }
+
+ /**
+ * Class representing a {@code multipart/alternative} part of a message.
+ *
+ *
+ * Only relevant {@code text/plain} and {@code text/html} children are stored in this container
+ * class.
+ *
+ */
+ static class Alternative implements Viewable {
+ private List mText;
+ private List mHtml;
+
+ public Alternative(List text, List html) {
+ mText = text;
+ mHtml = html;
+ }
+
+ public List getText() {
+ return mText;
+ }
+
+ public List getHtml() {
+ return mHtml;
+ }
+ }
+
+}
diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java
index 568f30b5e..29fae5f1c 100644
--- a/src/com/fsck/k9/mail/transport/SmtpTransport.java
+++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java
@@ -12,7 +12,7 @@ import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
import com.fsck.k9.mail.filter.LineWrapOutputStream;
import com.fsck.k9.mail.filter.PeekableInputStream;
import com.fsck.k9.mail.filter.SmtpDataStuffing;
-import com.fsck.k9.mail.internet.MimeUtility;
+import com.fsck.k9.mail.internet.CharsetSupport;
import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
@@ -463,7 +463,7 @@ public class SmtpTransport extends Transport {
new HashMap>();
for (Address address : addresses) {
String addressString = address.getAddress();
- String charset = MimeUtility.getCharsetFromAddress(addressString);
+ String charset = CharsetSupport.getCharsetFromAddress(addressString);
List addressesOfCharset = charsetAddressesMap.get(charset);
if (addressesOfCharset == null) {
addressesOfCharset = new ArrayList();
diff --git a/src/com/fsck/k9/mailstore/LocalFolder.java b/src/com/fsck/k9/mailstore/LocalFolder.java
index edf81d931..63e958ec9 100644
--- a/src/com/fsck/k9/mailstore/LocalFolder.java
+++ b/src/com/fsck/k9/mailstore/LocalFolder.java
@@ -33,7 +33,7 @@ import com.fsck.k9.K9;
import com.fsck.k9.Account.MessageFormat;
import com.fsck.k9.activity.Search;
import com.fsck.k9.mail.MessageRetrievalListener;
-import com.fsck.k9.mail.internet.HtmlConverter;
+import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body;
@@ -51,11 +51,11 @@ import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
-import com.fsck.k9.mail.internet.MimeUtility.ViewableContainer;
import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
import com.fsck.k9.provider.AttachmentProvider;
+
public class LocalFolder extends Folder implements Serializable {
private static final long serialVersionUID = -1973296520918624767L;
@@ -1299,14 +1299,14 @@ public class LocalFolder extends Folder implements Serializable {
// draft messages because this will cause the values stored in
// the identity header to be wrong.
ViewableContainer container =
- MimeUtility.extractPartsFromDraft(message);
+ LocalMessageExtractor.extractPartsFromDraft(message);
text = container.text;
html = container.html;
attachments = container.attachments;
} else {
ViewableContainer container =
- MimeUtility.extractTextAndAttachments(LocalFolder.this.localStore.mApplication, message);
+ LocalMessageExtractor.extractTextAndAttachments(LocalFolder.this.localStore.mApplication, message);
attachments = container.attachments;
text = container.text;
@@ -1412,7 +1412,7 @@ public class LocalFolder extends Folder implements Serializable {
message.buildMimeRepresentation();
ViewableContainer container =
- MimeUtility.extractTextAndAttachments(LocalFolder.this.localStore.mApplication, message);
+ LocalMessageExtractor.extractTextAndAttachments(LocalFolder.this.localStore.mApplication, message);
List attachments = container.attachments;
String text = container.text;
diff --git a/src/com/fsck/k9/mailstore/LocalMessage.java b/src/com/fsck/k9/mailstore/LocalMessage.java
index 464a6b1e9..05dfacec1 100644
--- a/src/com/fsck/k9/mailstore/LocalMessage.java
+++ b/src/com/fsck/k9/mailstore/LocalMessage.java
@@ -120,16 +120,16 @@ public class LocalMessage extends MimeMessage {
*/
public String getTextForDisplay() throws MessagingException {
String text = null; // First try and fetch an HTML part.
- Part part = MimeUtility.findFirstPartByMimeType(this, "text/html");
+ Part part = findFirstPartByMimeType("text/html");
if (part == null) {
// If that fails, try and get a text part.
- part = MimeUtility.findFirstPartByMimeType(this, "text/plain");
+ part = findFirstPartByMimeType("text/plain");
if (part != null && part.getBody() instanceof LocalTextBody) {
text = ((LocalTextBody) part.getBody()).getBodyForDisplay();
}
} else {
// We successfully found an HTML part; do the necessary character set decoding.
- text = MimeUtility.getTextFromPart(part);
+ text = part.getText();
}
return text;
}
diff --git a/src/com/fsck/k9/mailstore/LocalMessageExtractor.java b/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
new file mode 100644
index 000000000..546c1f62d
--- /dev/null
+++ b/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
@@ -0,0 +1,464 @@
+package com.fsck.k9.mailstore;
+
+import android.content.Context;
+
+import com.fsck.k9.R;
+import com.fsck.k9.mail.Address;
+import com.fsck.k9.mail.Body;
+import com.fsck.k9.mail.BodyPart;
+import com.fsck.k9.mail.Message;
+import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.Part;
+import com.fsck.k9.helper.HtmlConverter;
+import com.fsck.k9.mail.internet.MessageExtractor;
+import com.fsck.k9.mail.internet.MimeMultipart;
+import com.fsck.k9.mail.internet.Viewable;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import static com.fsck.k9.mail.internet.MimeUtility.getHeaderParameter;
+
+class LocalMessageExtractor {
+ private static final String TEXT_DIVIDER =
+ "------------------------------------------------------------------------";
+ private static final int TEXT_DIVIDER_LENGTH = TEXT_DIVIDER.length();
+ private static final String FILENAME_PREFIX = "----- ";
+ private static final int FILENAME_PREFIX_LENGTH = FILENAME_PREFIX.length();
+ private static final String FILENAME_SUFFIX = " ";
+ private static final int FILENAME_SUFFIX_LENGTH = FILENAME_SUFFIX.length();
+
+ /**
+ * Extract the viewable textual parts of a message and return the rest as attachments.
+ *
+ * @param context A {@link android.content.Context} instance that will be used to get localized strings.
+ * @return A {@link ViewableContainer} instance containing the textual parts of the message as
+ * plain text and HTML, and a list of message parts considered attachments.
+ *
+ * @throws com.fsck.k9.mail.MessagingException
+ * In case of an error.
+ */
+ public static ViewableContainer extractTextAndAttachments(Context context, Message message) throws MessagingException {
+ try {
+ List attachments = new ArrayList();
+
+ // Collect all viewable parts
+ List viewables = MessageExtractor.getViewables(message, attachments);
+
+ /*
+ * Convert the tree of viewable parts into text and HTML
+ */
+
+ // Used to suppress the divider for the first viewable part
+ boolean hideDivider = true;
+
+ StringBuilder text = new StringBuilder();
+ StringBuilder html = new StringBuilder();
+
+ for (Viewable viewable : viewables) {
+ if (viewable instanceof Viewable.Textual) {
+ // This is either a text/plain or text/html part. Fill the variables 'text' and
+ // 'html', converting between plain text and HTML as necessary.
+ text.append(buildText(viewable, !hideDivider));
+ html.append(buildHtml(viewable, !hideDivider));
+ hideDivider = false;
+ } else if (viewable instanceof Viewable.MessageHeader) {
+ Viewable.MessageHeader header = (Viewable.MessageHeader) viewable;
+ Part containerPart = header.getContainerPart();
+ Message innerMessage = header.getMessage();
+
+ addTextDivider(text, containerPart, !hideDivider);
+ addMessageHeaderText(context, text, innerMessage);
+
+ addHtmlDivider(html, containerPart, !hideDivider);
+ addMessageHeaderHtml(context, html, innerMessage);
+
+ hideDivider = true;
+ } else if (viewable instanceof Viewable.Alternative) {
+ // Handle multipart/alternative contents
+ Viewable.Alternative alternative = (Viewable.Alternative) viewable;
+
+ /*
+ * We made sure at least one of text/plain or text/html is present when
+ * creating the Alternative object. If one part is not present we convert the
+ * other one to make sure 'text' and 'html' always contain the same text.
+ */
+ List textAlternative = alternative.getText().isEmpty() ?
+ alternative.getHtml() : alternative.getText();
+ List htmlAlternative = alternative.getHtml().isEmpty() ?
+ alternative.getText() : alternative.getHtml();
+
+ // Fill the 'text' variable
+ boolean divider = !hideDivider;
+ for (Viewable textViewable : textAlternative) {
+ text.append(buildText(textViewable, divider));
+ divider = true;
+ }
+
+ // Fill the 'html' variable
+ divider = !hideDivider;
+ for (Viewable htmlViewable : htmlAlternative) {
+ html.append(buildHtml(htmlViewable, divider));
+ divider = true;
+ }
+ hideDivider = false;
+ }
+ }
+
+ return new ViewableContainer(text.toString(), html.toString(), attachments);
+ } catch (Exception e) {
+ throw new MessagingException("Couldn't extract viewable parts", e);
+ }
+ }
+
+ public static ViewableContainer extractPartsFromDraft(Message message)
+ throws MessagingException {
+
+ Body body = message.getBody();
+ if (message.isMimeType("multipart/mixed") && body instanceof MimeMultipart) {
+ MimeMultipart multipart = (MimeMultipart) body;
+
+ ViewableContainer container;
+ int count = multipart.getCount();
+ if (count >= 1) {
+ // The first part is either a text/plain or a multipart/alternative
+ BodyPart firstPart = multipart.getBodyPart(0);
+ container = extractTextual(firstPart);
+
+ // The rest should be attachments
+ for (int i = 1; i < count; i++) {
+ BodyPart bodyPart = multipart.getBodyPart(i);
+ container.attachments.add(bodyPart);
+ }
+ } else {
+ container = new ViewableContainer("", "", new ArrayList());
+ }
+
+ return container;
+ }
+
+ return extractTextual(message);
+ }
+
+ /**
+ * Use the contents of a {@link com.fsck.k9.mail.internet.Viewable} to create the HTML to be displayed.
+ *
+ *
+ * This will use {@link com.fsck.k9.helper.HtmlConverter#textToHtml(String)} to convert plain text parts
+ * to HTML if necessary.
+ *
+ *
+ * @param viewable
+ * The viewable part to build the HTML from.
+ * @param prependDivider
+ * {@code true}, if the HTML divider should be inserted as first element.
+ * {@code false}, otherwise.
+ *
+ * @return The contents of the supplied viewable instance as HTML.
+ */
+ private static StringBuilder buildHtml(Viewable viewable, boolean prependDivider)
+ {
+ StringBuilder html = new StringBuilder();
+ if (viewable instanceof Viewable.Textual) {
+ Part part = ((Viewable.Textual)viewable).getPart();
+ addHtmlDivider(html, part, prependDivider);
+
+ String t = part.getText();
+ if (t == null) {
+ t = "";
+ } else if (viewable instanceof Viewable.Text) {
+ t = HtmlConverter.textToHtml(t);
+ }
+ html.append(t);
+ } else if (viewable instanceof Viewable.Alternative) {
+ // That's odd - an Alternative as child of an Alternative; go ahead and try to use the
+ // text/html child; fall-back to the text/plain part.
+ Viewable.Alternative alternative = (Viewable.Alternative) viewable;
+
+ List htmlAlternative = alternative.getHtml().isEmpty() ?
+ alternative.getText() : alternative.getHtml();
+
+ boolean divider = prependDivider;
+ for (Viewable htmlViewable : htmlAlternative) {
+ html.append(buildHtml(htmlViewable, divider));
+ divider = true;
+ }
+ }
+
+ return html;
+ }
+
+ private static StringBuilder buildText(Viewable viewable, boolean prependDivider)
+ {
+ StringBuilder text = new StringBuilder();
+ if (viewable instanceof Viewable.Textual) {
+ Part part = ((Viewable.Textual)viewable).getPart();
+ addTextDivider(text, part, prependDivider);
+
+ String t = part.getText();
+ if (t == null) {
+ t = "";
+ } else if (viewable instanceof Viewable.Html) {
+ t = HtmlConverter.htmlToText(t);
+ }
+ text.append(t);
+ } else if (viewable instanceof Viewable.Alternative) {
+ // That's odd - an Alternative as child of an Alternative; go ahead and try to use the
+ // text/plain child; fall-back to the text/html part.
+ Viewable.Alternative alternative = (Viewable.Alternative) viewable;
+
+ List textAlternative = alternative.getText().isEmpty() ?
+ alternative.getHtml() : alternative.getText();
+
+ boolean divider = prependDivider;
+ for (Viewable textViewable : textAlternative) {
+ text.append(buildText(textViewable, divider));
+ divider = true;
+ }
+ }
+
+ return text;
+ }
+
+ /**
+ * Add an HTML divider between two HTML message parts.
+ *
+ * @param html
+ * The {@link StringBuilder} to append the divider to.
+ * @param part
+ * The message part that will follow after the divider. This is used to extract the
+ * part's name.
+ * @param prependDivider
+ * {@code true}, if the divider should be appended. {@code false}, otherwise.
+ */
+ private static void addHtmlDivider(StringBuilder html, Part part, boolean prependDivider) {
+ if (prependDivider) {
+ String filename = getPartName(part);
+
+ html.append("");
+ html.append(filename);
+ html.append("
");
+ }
+ }
+
+ /**
+ * Get the name of the message part.
+ *
+ * @param part
+ * The part to get the name for.
+ *
+ * @return The (file)name of the part if available. An empty string, otherwise.
+ */
+ private static String getPartName(Part part) {
+ try {
+ String disposition = part.getDisposition();
+ if (disposition != null) {
+ String name = getHeaderParameter(disposition, "filename");
+ return (name == null) ? "" : name;
+ }
+ }
+ catch (MessagingException e) { /* ignore */ }
+
+ return "";
+ }
+
+ /**
+ * Add a plain text divider between two plain text message parts.
+ *
+ * @param text
+ * The {@link StringBuilder} to append the divider to.
+ * @param part
+ * The message part that will follow after the divider. This is used to extract the
+ * part's name.
+ * @param prependDivider
+ * {@code true}, if the divider should be appended. {@code false}, otherwise.
+ */
+ private static void addTextDivider(StringBuilder text, Part part, boolean prependDivider) {
+ if (prependDivider) {
+ String filename = getPartName(part);
+
+ text.append("\r\n\r\n");
+ int len = filename.length();
+ if (len > 0) {
+ if (len > TEXT_DIVIDER_LENGTH - FILENAME_PREFIX_LENGTH - FILENAME_SUFFIX_LENGTH) {
+ filename = filename.substring(0, TEXT_DIVIDER_LENGTH - FILENAME_PREFIX_LENGTH -
+ FILENAME_SUFFIX_LENGTH - 3) + "...";
+ }
+ text.append(FILENAME_PREFIX);
+ text.append(filename);
+ text.append(FILENAME_SUFFIX);
+ text.append(TEXT_DIVIDER.substring(0, TEXT_DIVIDER_LENGTH -
+ FILENAME_PREFIX_LENGTH - filename.length() - FILENAME_SUFFIX_LENGTH));
+ } else {
+ text.append(TEXT_DIVIDER);
+ }
+ text.append("\r\n\r\n");
+ }
+ }
+
+ /**
+ * Extract important header values from a message to display inline (plain text version).
+ *
+ * @param context
+ * A {@link android.content.Context} instance that will be used to get localized strings.
+ * @param text
+ * The {@link StringBuilder} that will receive the (plain text) output.
+ * @param message
+ * The message to extract the header values from.
+ *
+ * @throws com.fsck.k9.mail.MessagingException
+ * In case of an error.
+ */
+ private static void addMessageHeaderText(Context context, StringBuilder text, Message message)
+ throws MessagingException {
+ // From:
+ Address[] from = message.getFrom();
+ if (from != null && from.length > 0) {
+ text.append(context.getString(R.string.message_compose_quote_header_from));
+ text.append(' ');
+ text.append(Address.toString(from));
+ text.append("\r\n");
+ }
+
+ // To:
+ Address[] to = message.getRecipients(Message.RecipientType.TO);
+ if (to != null && to.length > 0) {
+ text.append(context.getString(R.string.message_compose_quote_header_to));
+ text.append(' ');
+ text.append(Address.toString(to));
+ text.append("\r\n");
+ }
+
+ // Cc:
+ Address[] cc = message.getRecipients(Message.RecipientType.CC);
+ if (cc != null && cc.length > 0) {
+ text.append(context.getString(R.string.message_compose_quote_header_cc));
+ text.append(' ');
+ text.append(Address.toString(cc));
+ text.append("\r\n");
+ }
+
+ // Date:
+ Date date = message.getSentDate();
+ if (date != null) {
+ text.append(context.getString(R.string.message_compose_quote_header_send_date));
+ text.append(' ');
+ text.append(date.toString());
+ text.append("\r\n");
+ }
+
+ // Subject:
+ String subject = message.getSubject();
+ text.append(context.getString(R.string.message_compose_quote_header_subject));
+ text.append(' ');
+ if (subject == null) {
+ text.append(context.getString(R.string.general_no_subject));
+ } else {
+ text.append(subject);
+ }
+ text.append("\r\n\r\n");
+ }
+
+ /**
+ * Extract important header values from a message to display inline (HTML version).
+ *
+ * @param context
+ * A {@link android.content.Context} instance that will be used to get localized strings.
+ * @param html
+ * The {@link StringBuilder} that will receive the (HTML) output.
+ * @param message
+ * The message to extract the header values from.
+ *
+ * @throws com.fsck.k9.mail.MessagingException
+ * In case of an error.
+ */
+ private static void addMessageHeaderHtml(Context context, StringBuilder html, Message message)
+ throws MessagingException {
+
+ html.append("");
+
+ // From:
+ Address[] from = message.getFrom();
+ if (from != null && from.length > 0) {
+ addTableRow(html, context.getString(R.string.message_compose_quote_header_from),
+ Address.toString(from));
+ }
+
+ // To:
+ Address[] to = message.getRecipients(Message.RecipientType.TO);
+ if (to != null && to.length > 0) {
+ addTableRow(html, context.getString(R.string.message_compose_quote_header_to),
+ Address.toString(to));
+ }
+
+ // Cc:
+ Address[] cc = message.getRecipients(Message.RecipientType.CC);
+ if (cc != null && cc.length > 0) {
+ addTableRow(html, context.getString(R.string.message_compose_quote_header_cc),
+ Address.toString(cc));
+ }
+
+ // Date:
+ Date date = message.getSentDate();
+ if (date != null) {
+ addTableRow(html, context.getString(R.string.message_compose_quote_header_send_date),
+ date.toString());
+ }
+
+ // Subject:
+ String subject = message.getSubject();
+ addTableRow(html, context.getString(R.string.message_compose_quote_header_subject),
+ (subject == null) ? context.getString(R.string.general_no_subject) : subject);
+
+ html.append("
");
+ }
+
+ /**
+ * Output an HTML table two column row with some hardcoded style.
+ *
+ * @param html
+ * The {@link StringBuilder} that will receive the output.
+ * @param header
+ * The string to be put in the {@code TH} element.
+ * @param value
+ * The string to be put in the {@code TD} element.
+ */
+ private static void addTableRow(StringBuilder html, String header, String value) {
+ html.append("");
+ html.append(header);
+ html.append(" | ");
+ html.append("");
+ html.append(value);
+ html.append(" |
");
+ }
+
+ private static ViewableContainer extractTextual(Part part) throws MessagingException {
+ String text = "";
+ String html = "";
+ List attachments = new ArrayList();
+
+ Body firstBody = part.getBody();
+ if (part.isMimeType("text/plain")) {
+ String bodyText = part.getText();
+ if (bodyText != null) {
+ text = bodyText;
+ html = HtmlConverter.textToHtml(text);
+ }
+ } else if (part.isMimeType("multipart/alternative") &&
+ firstBody instanceof MimeMultipart) {
+ MimeMultipart multipart = (MimeMultipart) firstBody;
+ for (BodyPart bodyPart : multipart.getBodyParts()) {
+ String bodyText = bodyPart.getText();
+ if (bodyText != null) {
+ if (text.isEmpty() && bodyPart.isMimeType("text/plain")) {
+ text = bodyText;
+ } else if (html.isEmpty() && bodyPart.isMimeType("text/html")) {
+ html = bodyText;
+ }
+ }
+ }
+ }
+ return new ViewableContainer(text, html, attachments);
+ }
+}
diff --git a/src/com/fsck/k9/mailstore/ViewableContainer.java b/src/com/fsck/k9/mailstore/ViewableContainer.java
new file mode 100644
index 000000000..2e538cd22
--- /dev/null
+++ b/src/com/fsck/k9/mailstore/ViewableContainer.java
@@ -0,0 +1,34 @@
+package com.fsck.k9.mailstore;
+
+import com.fsck.k9.mail.Part;
+
+import java.util.List;
+
+/**
+ * Store viewable text of a message as plain text and HTML, and the parts considered
+ * attachments.
+ *
+ * @see LocalMessageExtractor#extractTextAndAttachments(android.content.Context, com.fsck.k9.mail.Message)
+ */
+class ViewableContainer {
+ /**
+ * The viewable text of the message in plain text.
+ */
+ public final String text;
+
+ /**
+ * The viewable text of the message in HTML.
+ */
+ public final String html;
+
+ /**
+ * The parts of the message considered attachments (everything not viewable).
+ */
+ public final List attachments;
+
+ public ViewableContainer(String text, String html, List attachments) {
+ this.text = text;
+ this.html = html;
+ this.attachments = attachments;
+ }
+}
diff --git a/src/com/fsck/k9/view/MessageOpenPgpView.java b/src/com/fsck/k9/view/MessageOpenPgpView.java
index 1b224112f..65bff60c8 100644
--- a/src/com/fsck/k9/view/MessageOpenPgpView.java
+++ b/src/com/fsck/k9/view/MessageOpenPgpView.java
@@ -215,8 +215,7 @@ public class MessageOpenPgpView extends LinearLayout {
} else {
try {
// check for PGP/MIME encryption
- Part pgp = MimeUtility
- .findFirstPartByMimeType(message, "application/pgp-encrypted");
+ Part pgp = message.findFirstPartByMimeType("application/pgp-encrypted");
if (pgp != null) {
Toast.makeText(mContext, R.string.pgp_mime_unsupported, Toast.LENGTH_LONG)
.show();
@@ -241,12 +240,12 @@ public class MessageOpenPgpView extends LinearLayout {
public void run() {
try {
// get data String
- Part part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
+ Part part = message.findFirstPartByMimeType("text/plain");
if (part == null) {
- part = MimeUtility.findFirstPartByMimeType(message, "text/html");
+ part = message.findFirstPartByMimeType("text/html");
}
if (part != null) {
- mData = MimeUtility.getTextFromPart(part);
+ mData = part.getText();
}
// wait for service to be bound
diff --git a/src/com/fsck/k9/view/MessageWebView.java b/src/com/fsck/k9/view/MessageWebView.java
index 07faaf3e1..3198d4723 100644
--- a/src/com/fsck/k9/view/MessageWebView.java
+++ b/src/com/fsck/k9/view/MessageWebView.java
@@ -10,7 +10,7 @@ import android.widget.Toast;
import com.fsck.k9.K9;
import com.fsck.k9.R;
-import com.fsck.k9.mail.internet.HtmlConverter;
+import com.fsck.k9.helper.HtmlConverter;
public class MessageWebView extends RigidWebView {
diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java
index 3ebdd89a3..25852ee17 100644
--- a/src/com/fsck/k9/view/SingleMessageView.java
+++ b/src/com/fsck/k9/view/SingleMessageView.java
@@ -46,7 +46,7 @@ import com.fsck.k9.fragment.MessageViewFragment;
import com.fsck.k9.helper.ClipboardManager;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.FileHelper;
-import com.fsck.k9.mail.internet.HtmlConverter;
+import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
diff --git a/tests-on-jvm/src/com/fsck/k9/mail/internet/TextBodyBuilderTest.java b/tests-on-jvm/src/com/fsck/k9/activity/TextBodyBuilderTest.java
similarity index 99%
rename from tests-on-jvm/src/com/fsck/k9/mail/internet/TextBodyBuilderTest.java
rename to tests-on-jvm/src/com/fsck/k9/activity/TextBodyBuilderTest.java
index 7c3b096dd..1a924ea0c 100644
--- a/tests-on-jvm/src/com/fsck/k9/mail/internet/TextBodyBuilderTest.java
+++ b/tests-on-jvm/src/com/fsck/k9/activity/TextBodyBuilderTest.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.internet;
+package com.fsck.k9.activity;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
@@ -8,6 +8,7 @@ import org.junit.runner.RunWith;
import com.fsck.k9.Account.QuoteStyle;
import com.fsck.k9.activity.TextBodyBuilder;
+import com.fsck.k9.mail.internet.TextBody;
class TestingTextBodyBuilder extends TextBodyBuilder {
diff --git a/tests-on-jvm/src/com/fsck/k9/mail/internet/CharsetSupportTest.java b/tests-on-jvm/src/com/fsck/k9/mail/internet/CharsetSupportTest.java
new file mode 100644
index 000000000..1b314642c
--- /dev/null
+++ b/tests-on-jvm/src/com/fsck/k9/mail/internet/CharsetSupportTest.java
@@ -0,0 +1,94 @@
+package com.fsck.k9.mail.internet;
+
+import junit.framework.TestCase;
+
+public class CharsetSupportTest extends TestCase {
+
+ public void testFixupCharset() throws Exception {
+ String charsetOnMail;
+ String expect;
+
+ charsetOnMail = "CP932";
+ expect = "shift_jis";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, new MimeMessage()));
+
+// charsetOnMail = "koi8-u";
+// expect = "koi8-r";
+// assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, new MimeMessage()));
+
+ MimeMessage message;
+
+ message= new MimeMessage();
+ message.setHeader("From", "aaa@docomo.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-docomo-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@dwmail.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-docomo-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@pdx.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-docomo-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@willcom.com");
+ charsetOnMail = "shift_jis";
+ expect = "x-docomo-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@emnet.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-docomo-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@emobile.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-docomo-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@softbank.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-softbank-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@vodafone.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-softbank-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@disney.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-softbank-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@vertuclub.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-softbank-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@ezweb.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-kddi-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ message = new MimeMessage();
+ message.setHeader("From", "aaa@ido.ne.jp");
+ charsetOnMail = "shift_jis";
+ expect = "x-kddi-shift_jis-2007";
+ assertEquals(expect, CharsetSupport.fixupCharset(charsetOnMail, message));
+
+ }
+}
\ No newline at end of file
diff --git a/tests-on-jvm/src/com/fsck/k9/mail/internet/MimeUtilityTest.java b/tests-on-jvm/src/com/fsck/k9/mail/internet/MimeUtilityTest.java
index e723cb562..fe07dddcb 100644
--- a/tests-on-jvm/src/com/fsck/k9/mail/internet/MimeUtilityTest.java
+++ b/tests-on-jvm/src/com/fsck/k9/mail/internet/MimeUtilityTest.java
@@ -8,15 +8,6 @@ import com.fsck.k9.mail.MessagingException;
import junit.framework.TestCase;
public class MimeUtilityTest extends TestCase {
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
public void testGetHeaderParameter() {
String result;
@@ -55,93 +46,4 @@ public class MimeUtilityTest extends TestCase {
result = MimeUtility.getHeaderParameter("text/HTML ; charset=\"windows-1251\"", null);
assertEquals("text/HTML", result);
}
-
- public void testFixupCharset() throws MessagingException {
- String charsetOnMail;
- String expect;
-
- charsetOnMail = "CP932";
- expect = "shift_jis";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, new MimeMessage()));
-
-// charsetOnMail = "koi8-u";
-// expect = "koi8-r";
-// assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, new MimeMessage()));
-
- MimeMessage message;
-
- message= new MimeMessage();
- message.setHeader("From", "aaa@docomo.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-docomo-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@dwmail.jp");
- charsetOnMail = "shift_jis";
- expect = "x-docomo-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@pdx.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-docomo-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@willcom.com");
- charsetOnMail = "shift_jis";
- expect = "x-docomo-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@emnet.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-docomo-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@emobile.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-docomo-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@softbank.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-softbank-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@vodafone.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-softbank-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@disney.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-softbank-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@vertuclub.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-softbank-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@ezweb.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-kddi-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- message = new MimeMessage();
- message.setHeader("From", "aaa@ido.ne.jp");
- charsetOnMail = "shift_jis";
- expect = "x-kddi-shift_jis-2007";
- assertEquals(expect, MimeUtility.fixupCharset(charsetOnMail, message));
-
- }
-
}
diff --git a/tests/src/com/fsck/k9/mail/internet/HtmlConverterTest.java b/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
similarity index 99%
rename from tests/src/com/fsck/k9/mail/internet/HtmlConverterTest.java
rename to tests/src/com/fsck/k9/helper/HtmlConverterTest.java
index 7faea3b18..32aa241ed 100644
--- a/tests/src/com/fsck/k9/mail/internet/HtmlConverterTest.java
+++ b/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
@@ -1,4 +1,6 @@
-package com.fsck.k9.mail.internet;
+package com.fsck.k9.helper;
+
+import com.fsck.k9.helper.HtmlConverter;
import junit.framework.TestCase;
diff --git a/tests/src/com/fsck/k9/mail/MessageTest.java b/tests/src/com/fsck/k9/mail/MessageTest.java
index 3e56b228d..1fabfc534 100644
--- a/tests/src/com/fsck/k9/mail/MessageTest.java
+++ b/tests/src/com/fsck/k9/mail/MessageTest.java
@@ -14,11 +14,11 @@ import android.test.AndroidTestCase;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.internet.BinaryTempFileBody;
import com.fsck.k9.mail.internet.BinaryTempFileMessageBody;
+import com.fsck.k9.mail.internet.CharsetSupport;
import com.fsck.k9.mail.internet.MimeBodyPart;
import com.fsck.k9.mail.internet.MimeHeader;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeMultipart;
-import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
public class MessageTest extends AndroidTestCase {
@@ -356,7 +356,7 @@ public class MessageTest extends AndroidTestCase {
+ "End of test.\r\n");
textBody.setCharset("utf-8");
MimeBodyPart bodyPart = new MimeBodyPart(textBody, "text/plain");
- MimeUtility.setCharset("utf-8", bodyPart);
+ CharsetSupport.setCharset("utf-8", bodyPart);
bodyPart.setEncoding(encoding);
return bodyPart;
}
diff --git a/tests/src/com/fsck/k9/mail/internet/ViewablesTest.java b/tests/src/com/fsck/k9/mailstore/LocalMessageExtractorTest.java
similarity index 89%
rename from tests/src/com/fsck/k9/mail/internet/ViewablesTest.java
rename to tests/src/com/fsck/k9/mailstore/LocalMessageExtractorTest.java
index cceb4bff5..2fc007caf 100644
--- a/tests/src/com/fsck/k9/mail/internet/ViewablesTest.java
+++ b/tests/src/com/fsck/k9/mailstore/LocalMessageExtractorTest.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.internet;
+package com.fsck.k9.mailstore;
import java.util.Date;
import java.util.Locale;
@@ -9,9 +9,14 @@ import com.fsck.k9.activity.K9ActivityCommon;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Message.RecipientType;
-import com.fsck.k9.mail.internet.MimeUtility.ViewableContainer;
+import com.fsck.k9.mail.internet.MimeBodyPart;
+import com.fsck.k9.mail.internet.MimeMessage;
+import com.fsck.k9.mail.internet.MimeMultipart;
+import com.fsck.k9.mail.internet.TextBody;
-public class ViewablesTest extends AndroidTestCase {
+import static com.fsck.k9.mailstore.LocalMessageExtractor.extractTextAndAttachments;
+
+public class LocalMessageExtractorTest extends AndroidTestCase {
public void testSimplePlainTextMessage() throws MessagingException {
String bodyText = "K-9 Mail rocks :>";
@@ -24,7 +29,7 @@ public class ViewablesTest extends AndroidTestCase {
message.setBody(body);
// Extract text
- ViewableContainer container = MimeUtility.extractTextAndAttachments(getContext(), message);
+ ViewableContainer container = extractTextAndAttachments(getContext(), message);
String expectedText = bodyText;
String expectedHtml =
@@ -48,7 +53,7 @@ public class ViewablesTest extends AndroidTestCase {
message.setBody(body);
// Extract text
- ViewableContainer container = MimeUtility.extractTextAndAttachments(getContext(), message);
+ ViewableContainer container = extractTextAndAttachments(getContext(), message);
String expectedText = "K-9 Mail rocks :>";
String expectedHtml =
@@ -78,7 +83,7 @@ public class ViewablesTest extends AndroidTestCase {
message.setBody(multipart);
// Extract text
- ViewableContainer container = MimeUtility.extractTextAndAttachments(getContext(), message);
+ ViewableContainer container = extractTextAndAttachments(getContext(), message);
String expectedText =
bodyText1 + "\r\n\r\n" +
@@ -134,7 +139,7 @@ public class ViewablesTest extends AndroidTestCase {
message.setBody(multipart);
// Extract text
- ViewableContainer container = MimeUtility.extractTextAndAttachments(getContext(), message);
+ ViewableContainer container = extractTextAndAttachments(getContext(), message);
String expectedText =
bodyText +
From 36ef6df01837c277ece20f9a064c29f451a6e094 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Mon, 15 Dec 2014 12:42:05 +0100
Subject: [PATCH 18/29] Remove unused method
---
src/com/fsck/k9/mail/BodyPart.java | 11 -----------
src/com/fsck/k9/mail/Message.java | 15 ---------------
src/com/fsck/k9/mail/Part.java | 2 --
.../fsck/k9/mail/internet/MessageExtractor.java | 16 +++++++++++++++-
.../fsck/k9/mailstore/LocalMessageExtractor.java | 1 +
5 files changed, 16 insertions(+), 29 deletions(-)
diff --git a/src/com/fsck/k9/mail/BodyPart.java b/src/com/fsck/k9/mail/BodyPart.java
index 84e4324f5..884b03ae1 100644
--- a/src/com/fsck/k9/mail/BodyPart.java
+++ b/src/com/fsck/k9/mail/BodyPart.java
@@ -17,17 +17,6 @@ public abstract class BodyPart implements Part {
public abstract void setEncoding(String encoding) throws MessagingException;
- @Override
- public String getContentDisposition() {
- try {
- String disposition = getDisposition();
- if (disposition != null) {
- return MimeUtility.getHeaderParameter(disposition, null);
- }
- } catch (MessagingException e) { /* ignore */ }
- return null;
- }
-
@Override
public String getText() {
return MessageExtractor.getTextFromPart(this);
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index f48eaf559..c1b4a09a5 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -270,21 +270,6 @@ public abstract class Message implements Part, CompositeBody {
@Override
public abstract Message clone();
- /**
- * Get the value of the {@code Content-Disposition} header.
- * @return The value of the {@code Content-Disposition} header if available. {@code null}, otherwise.
- */
- public String getContentDisposition() {
- try {
- String disposition = getDisposition();
- if (disposition != null) {
- return MimeUtility.getHeaderParameter(disposition, null);
- }
- }
- catch (MessagingException e) { /* ignore */ }
- return null;
- }
-
@Override
public String getText() {
return MessageExtractor.getTextFromPart(this);
diff --git a/src/com/fsck/k9/mail/Part.java b/src/com/fsck/k9/mail/Part.java
index c890cd56e..bcf5dcc5e 100644
--- a/src/com/fsck/k9/mail/Part.java
+++ b/src/com/fsck/k9/mail/Part.java
@@ -17,8 +17,6 @@ public interface Part {
String getDisposition() throws MessagingException;
- String getContentDisposition();
-
String getContentId() throws MessagingException;
String[] getHeader(String name) throws MessagingException;
diff --git a/src/com/fsck/k9/mail/internet/MessageExtractor.java b/src/com/fsck/k9/mail/internet/MessageExtractor.java
index 5fedd3d28..2f21763ed 100644
--- a/src/com/fsck/k9/mail/internet/MessageExtractor.java
+++ b/src/com/fsck/k9/mail/internet/MessageExtractor.java
@@ -25,6 +25,8 @@ import static com.fsck.k9.mail.internet.Viewable.Alternative;
import static com.fsck.k9.mail.internet.Viewable.Textual;
public class MessageExtractor {
+ private MessageExtractor() {}
+
public static String getTextFromPart(Part part) {
try {
if ((part != null) && (part.getBody() != null)) {
@@ -157,7 +159,7 @@ public class MessageExtractor {
}
}
} else if (body instanceof Message &&
- !("attachment".equalsIgnoreCase(part.getContentDisposition()))) {
+ !("attachment".equalsIgnoreCase(getContentDisposition(part)))) {
/*
* We only care about message/rfc822 parts whose Content-Disposition header has a value
* other than "attachment".
@@ -407,4 +409,16 @@ public class MessageExtractor {
return false;
}
}
+
+
+
+ public static String getContentDisposition(Part part) {
+ try {
+ String disposition = part.getDisposition();
+ if (disposition != null) {
+ return MimeUtility.getHeaderParameter(disposition, null);
+ }
+ } catch (MessagingException e) { /* ignore */ }
+ return null;
+ }
}
diff --git a/src/com/fsck/k9/mailstore/LocalMessageExtractor.java b/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
index 546c1f62d..f0e11902b 100644
--- a/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
+++ b/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
@@ -29,6 +29,7 @@ class LocalMessageExtractor {
private static final String FILENAME_SUFFIX = " ";
private static final int FILENAME_SUFFIX_LENGTH = FILENAME_SUFFIX.length();
+ private LocalMessageExtractor() {}
/**
* Extract the viewable textual parts of a message and return the rest as attachments.
*
From 2a2e18e8b68aca453685c6741abd632d6bc500db Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Mon, 15 Dec 2014 12:45:04 +0100
Subject: [PATCH 19/29] WS / visibility
---
src/com/fsck/k9/mail/internet/MessageExtractor.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/com/fsck/k9/mail/internet/MessageExtractor.java b/src/com/fsck/k9/mail/internet/MessageExtractor.java
index 2f21763ed..b710171af 100644
--- a/src/com/fsck/k9/mail/internet/MessageExtractor.java
+++ b/src/com/fsck/k9/mail/internet/MessageExtractor.java
@@ -410,9 +410,7 @@ public class MessageExtractor {
}
}
-
-
- public static String getContentDisposition(Part part) {
+ private static String getContentDisposition(Part part) {
try {
String disposition = part.getDisposition();
if (disposition != null) {
From b443af43aed63f25a82bda13c50c807f6c619fb8 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Mon, 15 Dec 2014 13:01:13 +0100
Subject: [PATCH 20/29] Cleanup
---
.../k9/mail/internet/MessageExtractor.java | 21 ++++++-----
.../fsck/k9/mail/internet/MimeUtility.java | 2 +-
src/com/fsck/k9/mail/internet/Viewable.java | 13 ++++---
.../k9/mailstore/LocalMessageExtractor.java | 35 +++++++++++--------
4 files changed, 39 insertions(+), 32 deletions(-)
diff --git a/src/com/fsck/k9/mail/internet/MessageExtractor.java b/src/com/fsck/k9/mail/internet/MessageExtractor.java
index b710171af..a4b997116 100644
--- a/src/com/fsck/k9/mail/internet/MessageExtractor.java
+++ b/src/com/fsck/k9/mail/internet/MessageExtractor.java
@@ -22,6 +22,9 @@ import java.util.regex.Pattern;
import static com.fsck.k9.mail.internet.CharsetSupport.fixupCharset;
import static com.fsck.k9.mail.internet.MimeUtility.getHeaderParameter;
import static com.fsck.k9.mail.internet.Viewable.Alternative;
+import static com.fsck.k9.mail.internet.Viewable.Html;
+import static com.fsck.k9.mail.internet.Viewable.MessageHeader;
+import static com.fsck.k9.mail.internet.Viewable.Text;
import static com.fsck.k9.mail.internet.Viewable.Textual;
public class MessageExtractor {
@@ -167,7 +170,7 @@ public class MessageExtractor {
Message message = (Message) body;
// We add the Message object so we can extract the filename later.
- viewables.add(new Viewable.MessageHeader(part, message));
+ viewables.add(new MessageHeader(part, message));
// Recurse to grab all viewable parts and attachments from that message.
viewables.addAll(getViewables(message, attachments));
@@ -177,10 +180,10 @@ public class MessageExtractor {
*/
String mimeType = part.getMimeType();
if (mimeType.equalsIgnoreCase("text/plain")) {
- Viewable.Text text = new Viewable.Text(part);
+ Text text = new Text(part);
viewables.add(text);
} else {
- Viewable.Html html = new Viewable.Html(part);
+ Html html = new Html(part);
viewables.add(html);
}
} else {
@@ -220,7 +223,7 @@ public class MessageExtractor {
* @param directChild If {@code true}, this method will return after the first {@code text/plain} was
* found.
*
- * @return A list of {@link Viewable.Text} viewables.
+ * @return A list of {@link Text} viewables.
*
* @throws MessagingException
* In case of an error.
@@ -254,7 +257,7 @@ public class MessageExtractor {
}
}
} else if (isPartTextualBody(part) && part.getMimeType().equalsIgnoreCase("text/plain")) {
- Viewable.Text text = new Viewable.Text(part);
+ Text text = new Text(part);
viewables.add(text);
if (directChild) {
break;
@@ -274,7 +277,7 @@ public class MessageExtractor {
* @param directChild If {@code true}, this method will add all {@code text/html} parts except the first
* found to 'attachments'.
*
- * @return A list of {@link Viewable.Text} viewables.
+ * @return A list of {@link Text} viewables.
*
* @throws MessagingException In case of an error.
*/
@@ -314,7 +317,7 @@ public class MessageExtractor {
}
} else if (!(directChild && partFound) && isPartTextualBody(part) &&
part.getMimeType().equalsIgnoreCase("text/html")) {
- Viewable.Html html = new Viewable.Html(part);
+ Html html = new Html(part);
viewables.add(html);
partFound = true;
} else if (!knownTextParts.contains(part)) {
@@ -359,8 +362,8 @@ public class MessageExtractor {
*
* @return The set of viewable {@code Part}s.
*
- * @see MimeUtility#findHtmlPart(Multipart, Set, List, boolean)
- * @see MimeUtility#findAttachments(Multipart, Set, List)
+ * @see MessageExtractor#findHtmlPart(Multipart, Set, List, boolean)
+ * @see MessageExtractor#findAttachments(Multipart, Set, List)
*/
private static Set getParts(List viewables) {
Set parts = new HashSet();
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index e56476878..00f037108 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -991,7 +991,7 @@ public class MimeUtility {
*/
if (contentTransferEncoding != null) {
contentTransferEncoding =
- MimeUtility.getHeaderParameter(contentTransferEncoding, null);
+ getHeaderParameter(contentTransferEncoding, null);
if (MimeUtil.ENC_QUOTED_PRINTABLE.equalsIgnoreCase(contentTransferEncoding)) {
in = new QuotedPrintableInputStream(in);
} else if (MimeUtil.ENC_BASE64.equalsIgnoreCase(contentTransferEncoding)) {
diff --git a/src/com/fsck/k9/mail/internet/Viewable.java b/src/com/fsck/k9/mail/internet/Viewable.java
index 6ec32b926..ec21b7c71 100644
--- a/src/com/fsck/k9/mail/internet/Viewable.java
+++ b/src/com/fsck/k9/mail/internet/Viewable.java
@@ -7,7 +7,7 @@ import java.util.List;
/**
* Empty marker class interface the class hierarchy used by
- * {@link com.fsck.k9.mailstore.LocalMessageExtractor#extractTextAndAttachments(android.content.Context, com.fsck.k9.mail.Message)}.
+ * {@link MessageExtractor#getViewables(com.fsck.k9.mail.Part, java.util.List)}
*
* @see Viewable.Text
* @see Viewable.Html
@@ -20,7 +20,7 @@ public interface Viewable {
*
* @see com.fsck.k9.mail.internet.MessageExtractor#isPartTextualBody(com.fsck.k9.mail.Part)
*/
- static abstract class Textual implements Viewable {
+ abstract class Textual implements Viewable {
private Part mPart;
public Textual(Part part) {
@@ -35,7 +35,7 @@ public interface Viewable {
/**
* Class representing a {@code text/plain} part of a message.
*/
- static class Text extends Textual {
+ class Text extends Textual {
public Text(Part part) {
super(part);
}
@@ -44,7 +44,7 @@ public interface Viewable {
/**
* Class representing a {@code text/html} part of a message.
*/
- static class Html extends Textual {
+ class Html extends Textual {
public Html(Part part) {
super(part);
}
@@ -58,7 +58,7 @@ public interface Viewable {
* inline.
*
*/
- static class MessageHeader implements Viewable {
+ class MessageHeader implements Viewable {
private Part mContainerPart;
private Message mMessage;
@@ -84,7 +84,7 @@ public interface Viewable {
* class.
*
*/
- static class Alternative implements Viewable {
+ class Alternative implements Viewable {
private List mText;
private List mHtml;
@@ -101,5 +101,4 @@ public interface Viewable {
return mHtml;
}
}
-
}
diff --git a/src/com/fsck/k9/mailstore/LocalMessageExtractor.java b/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
index f0e11902b..f5d1a9108 100644
--- a/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
+++ b/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
@@ -19,6 +19,11 @@ import java.util.Date;
import java.util.List;
import static com.fsck.k9.mail.internet.MimeUtility.getHeaderParameter;
+import static com.fsck.k9.mail.internet.Viewable.Alternative;
+import static com.fsck.k9.mail.internet.Viewable.Html;
+import static com.fsck.k9.mail.internet.Viewable.MessageHeader;
+import static com.fsck.k9.mail.internet.Viewable.Text;
+import static com.fsck.k9.mail.internet.Viewable.Textual;
class LocalMessageExtractor {
private static final String TEXT_DIVIDER =
@@ -58,14 +63,14 @@ class LocalMessageExtractor {
StringBuilder html = new StringBuilder();
for (Viewable viewable : viewables) {
- if (viewable instanceof Viewable.Textual) {
+ if (viewable instanceof Textual) {
// This is either a text/plain or text/html part. Fill the variables 'text' and
// 'html', converting between plain text and HTML as necessary.
text.append(buildText(viewable, !hideDivider));
html.append(buildHtml(viewable, !hideDivider));
hideDivider = false;
- } else if (viewable instanceof Viewable.MessageHeader) {
- Viewable.MessageHeader header = (Viewable.MessageHeader) viewable;
+ } else if (viewable instanceof MessageHeader) {
+ MessageHeader header = (MessageHeader) viewable;
Part containerPart = header.getContainerPart();
Message innerMessage = header.getMessage();
@@ -76,9 +81,9 @@ class LocalMessageExtractor {
addMessageHeaderHtml(context, html, innerMessage);
hideDivider = true;
- } else if (viewable instanceof Viewable.Alternative) {
+ } else if (viewable instanceof Alternative) {
// Handle multipart/alternative contents
- Viewable.Alternative alternative = (Viewable.Alternative) viewable;
+ Alternative alternative = (Alternative) viewable;
/*
* We made sure at least one of text/plain or text/html is present when
@@ -161,21 +166,21 @@ class LocalMessageExtractor {
private static StringBuilder buildHtml(Viewable viewable, boolean prependDivider)
{
StringBuilder html = new StringBuilder();
- if (viewable instanceof Viewable.Textual) {
- Part part = ((Viewable.Textual)viewable).getPart();
+ if (viewable instanceof Textual) {
+ Part part = ((Textual)viewable).getPart();
addHtmlDivider(html, part, prependDivider);
String t = part.getText();
if (t == null) {
t = "";
- } else if (viewable instanceof Viewable.Text) {
+ } else if (viewable instanceof Text) {
t = HtmlConverter.textToHtml(t);
}
html.append(t);
- } else if (viewable instanceof Viewable.Alternative) {
+ } else if (viewable instanceof Alternative) {
// That's odd - an Alternative as child of an Alternative; go ahead and try to use the
// text/html child; fall-back to the text/plain part.
- Viewable.Alternative alternative = (Viewable.Alternative) viewable;
+ Alternative alternative = (Alternative) viewable;
List htmlAlternative = alternative.getHtml().isEmpty() ?
alternative.getText() : alternative.getHtml();
@@ -193,21 +198,21 @@ class LocalMessageExtractor {
private static StringBuilder buildText(Viewable viewable, boolean prependDivider)
{
StringBuilder text = new StringBuilder();
- if (viewable instanceof Viewable.Textual) {
- Part part = ((Viewable.Textual)viewable).getPart();
+ if (viewable instanceof Textual) {
+ Part part = ((Textual)viewable).getPart();
addTextDivider(text, part, prependDivider);
String t = part.getText();
if (t == null) {
t = "";
- } else if (viewable instanceof Viewable.Html) {
+ } else if (viewable instanceof Html) {
t = HtmlConverter.htmlToText(t);
}
text.append(t);
- } else if (viewable instanceof Viewable.Alternative) {
+ } else if (viewable instanceof Alternative) {
// That's odd - an Alternative as child of an Alternative; go ahead and try to use the
// text/plain child; fall-back to the text/html part.
- Viewable.Alternative alternative = (Viewable.Alternative) viewable;
+ Alternative alternative = (Alternative) viewable;
List textAlternative = alternative.getText().isEmpty() ?
alternative.getHtml() : alternative.getText();
From 15a4c90f27e75473ed9b863486a54f5092ad0ac1 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Mon, 15 Dec 2014 13:20:42 +0100
Subject: [PATCH 21/29] Update javadoc
---
src/com/fsck/k9/mail/Message.java | 16 ++--------------
1 file changed, 2 insertions(+), 14 deletions(-)
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index c1b4a09a5..368b25dc2 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -282,14 +282,8 @@ public abstract class Message implements Part, CompositeBody {
/**
* Collect attachment parts of a message.
- *
- * @param message
- * The message to collect the attachment parts from.
- *
* @return A list of parts regarded as attachments.
- *
- * @throws MessagingException
- * In case of an error.
+ * @throws MessagingException In case of an error.
*/
public List collectAttachments() throws MessagingException {
try {
@@ -303,14 +297,8 @@ public abstract class Message implements Part, CompositeBody {
/**
* Collect the viewable textual parts of a message.
- *
- * @param message
- * The message to extract the viewable parts from.
- *
* @return A set of viewable parts of the message.
- *
- * @throws MessagingException
- * In case of an error.
+ * @throws MessagingException In case of an error.
*/
public Set collectTextParts() throws MessagingException {
try {
From c6082584947822cc57ee43d65213881fc715bef6 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Mon, 15 Dec 2014 13:46:23 +0100
Subject: [PATCH 22/29] Unused imports
---
src/com/fsck/k9/crypto/CryptoHelper.java | 1 -
src/com/fsck/k9/mailstore/LocalMessage.java | 3 +--
src/com/fsck/k9/view/MessageOpenPgpView.java | 1 -
3 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/com/fsck/k9/crypto/CryptoHelper.java b/src/com/fsck/k9/crypto/CryptoHelper.java
index 9bc421127..a03e6fff9 100644
--- a/src/com/fsck/k9/crypto/CryptoHelper.java
+++ b/src/com/fsck/k9/crypto/CryptoHelper.java
@@ -7,7 +7,6 @@ import java.util.regex.Pattern;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
-import com.fsck.k9.mail.internet.MimeUtility;
public class CryptoHelper {
diff --git a/src/com/fsck/k9/mailstore/LocalMessage.java b/src/com/fsck/k9/mailstore/LocalMessage.java
index 05dfacec1..555254c8f 100644
--- a/src/com/fsck/k9/mailstore/LocalMessage.java
+++ b/src/com/fsck/k9/mailstore/LocalMessage.java
@@ -21,7 +21,6 @@ import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MimeMessage;
-import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
@@ -615,4 +614,4 @@ public class LocalMessage extends MimeMessage {
private String getAccountUuid() {
return getAccount().getUuid();
}
-}
\ No newline at end of file
+}
diff --git a/src/com/fsck/k9/view/MessageOpenPgpView.java b/src/com/fsck/k9/view/MessageOpenPgpView.java
index 65bff60c8..cb9be859b 100644
--- a/src/com/fsck/k9/view/MessageOpenPgpView.java
+++ b/src/com/fsck/k9/view/MessageOpenPgpView.java
@@ -35,7 +35,6 @@ import com.fsck.k9.helper.IdentityHelper;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
-import com.fsck.k9.mail.internet.MimeUtility;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
From 23d9310c6146ccb9711730e3a775151eeaa8c0a5 Mon Sep 17 00:00:00 2001
From: cketti
Date: Tue, 16 Dec 2014 03:32:57 +0100
Subject: [PATCH 23/29] Remove getUuid() from StoreConfig
---
src/com/fsck/k9/mail/store/StoreConfig.java | 1 -
src/com/fsck/k9/mailstore/LocalStore.java | 8 +-------
2 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/com/fsck/k9/mail/store/StoreConfig.java b/src/com/fsck/k9/mail/store/StoreConfig.java
index 12f7a025d..d8531d978 100644
--- a/src/com/fsck/k9/mail/store/StoreConfig.java
+++ b/src/com/fsck/k9/mail/store/StoreConfig.java
@@ -1,7 +1,6 @@
package com.fsck.k9.mail.store;
public interface StoreConfig {
- String getUuid();
String getStoreUri();
String getTransportUri();
diff --git a/src/com/fsck/k9/mailstore/LocalStore.java b/src/com/fsck/k9/mailstore/LocalStore.java
index b05a9efa2..46dfaa0b3 100644
--- a/src/com/fsck/k9/mailstore/LocalStore.java
+++ b/src/com/fsck/k9/mailstore/LocalStore.java
@@ -213,13 +213,7 @@ public class LocalStore extends Store implements Serializable {
}
}
- /**
- * Release reference to a local mail store instance.
- *
- * @param account
- * {@link Account} instance that is used to get the local mail store instance.
- */
- private static void removeInstance(StoreConfig account) {
+ private static void removeInstance(Account account) {
String accountUuid = account.getUuid();
sLocalStores.remove(accountUuid);
}
From 62c5ac8e5fa56b7af3cecd7610fd12bc4c279084 Mon Sep 17 00:00:00 2001
From: cketti
Date: Tue, 16 Dec 2014 04:02:54 +0100
Subject: [PATCH 24/29] Rename 'accountId' to 'accountUuid'
---
src/com/fsck/k9/fragment/MessageListFragment.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/com/fsck/k9/fragment/MessageListFragment.java b/src/com/fsck/k9/fragment/MessageListFragment.java
index f697b6f2e..c14c4fc96 100644
--- a/src/com/fsck/k9/fragment/MessageListFragment.java
+++ b/src/com/fsck/k9/fragment/MessageListFragment.java
@@ -2483,11 +2483,11 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
* @see #startActivityForResult(Intent, int)
*/
private void displayFolderChoice(int requestCode, Folder folder,
- String accountId, String lastSelectedFolderName,
+ String accountUuid, String lastSelectedFolderName,
List messages) {
Intent intent = new Intent(getActivity(), ChooseFolder.class);
- intent.putExtra(ChooseFolder.EXTRA_ACCOUNT, accountId);
+ intent.putExtra(ChooseFolder.EXTRA_ACCOUNT, accountUuid);
intent.putExtra(ChooseFolder.EXTRA_SEL_FOLDER, lastSelectedFolderName);
if (folder == null) {
From d24998d5843cc8adca12499e0199f0887ae54244 Mon Sep 17 00:00:00 2001
From: cketti
Date: Tue, 16 Dec 2014 05:16:09 +0100
Subject: [PATCH 25/29] Fix tests-on-jvm
---
tests-on-jvm/src/android/text/TextUtils.java | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 tests-on-jvm/src/android/text/TextUtils.java
diff --git a/tests-on-jvm/src/android/text/TextUtils.java b/tests-on-jvm/src/android/text/TextUtils.java
new file mode 100644
index 000000000..cdc2ddc19
--- /dev/null
+++ b/tests-on-jvm/src/android/text/TextUtils.java
@@ -0,0 +1,7 @@
+package android.text;
+
+public class TextUtils {
+ public static boolean isEmpty(CharSequence str) {
+ return (str == null || str.length() == 0);
+ }
+}
From 946565347a758a0ff239b809a3c4fa6278af962e Mon Sep 17 00:00:00 2001
From: cketti
Date: Tue, 16 Dec 2014 05:40:44 +0100
Subject: [PATCH 26/29] Revert adding methods to Message and Part
---
src/com/fsck/k9/activity/MessageCompose.java | 29 +++++++------
.../k9/controller/MessagingController.java | 11 ++---
src/com/fsck/k9/crypto/CryptoHelper.java | 15 ++++---
src/com/fsck/k9/mail/BodyPart.java | 13 ------
src/com/fsck/k9/mail/Message.java | 41 -------------------
src/com/fsck/k9/mail/Part.java | 10 -----
.../k9/mail/internet/MessageExtractor.java | 28 +++++++++++++
.../fsck/k9/mail/internet/MimeUtility.java | 5 ++-
src/com/fsck/k9/mailstore/LocalMessage.java | 8 ++--
.../k9/mailstore/LocalMessageExtractor.java | 8 ++--
src/com/fsck/k9/view/MessageOpenPgpView.java | 10 +++--
11 files changed, 78 insertions(+), 100 deletions(-)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index ffdc95878..db2ee4e67 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -101,6 +101,7 @@ import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Multipart;
import com.fsck.k9.mail.Part;
+import com.fsck.k9.mail.internet.MessageExtractor;
import com.fsck.k9.mail.internet.MimeBodyPart;
import com.fsck.k9.mail.internet.MimeHeader;
import com.fsck.k9.mail.internet.MimeMessage;
@@ -2955,10 +2956,10 @@ public class MessageCompose extends K9Activity implements OnClickListener,
if (messageFormat == MessageFormat.HTML) {
- Part part = message.findFirstPartByMimeType("text/html");
+ Part part = MimeUtility.findFirstPartByMimeType(message, "text/html");
if (part != null) { // Shouldn't happen if we were the one who saved it.
mQuotedTextFormat = SimpleMessageFormat.HTML;
- String text = part.getText();
+ String text = MessageExtractor.getTextFromPart(part);
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "Loading message with offset " + bodyOffset + ", length " + bodyLength + ". Text length is " + text.length() + ".");
}
@@ -3021,9 +3022,9 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/
private void processSourceMessageText(Message message, Integer bodyOffset, Integer bodyLength,
boolean viewMessageContent) throws MessagingException {
- Part textPart = message.findFirstPartByMimeType("text/plain");
+ Part textPart = MimeUtility.findFirstPartByMimeType(message, "text/plain");
if (textPart != null) {
- String text = textPart.getText();
+ String text = MessageExtractor.getTextFromPart(textPart);
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "Loading message with offset " + bodyOffset + ", length " + bodyLength + ". Text length is " + text.length() + ".");
}
@@ -3091,7 +3092,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
// Figure out which message format to use for the quoted text by looking if the source
// message contains a text/html part. If it does, we use that.
mQuotedTextFormat =
- (mSourceMessage.findFirstPartByMimeType("text/html") == null) ?
+ (MimeUtility.findFirstPartByMimeType(mSourceMessage, "text/html") == null) ?
SimpleMessageFormat.TEXT : SimpleMessageFormat.HTML;
} else {
mQuotedTextFormat = SimpleMessageFormat.HTML;
@@ -3221,37 +3222,39 @@ public class MessageCompose extends K9Activity implements OnClickListener,
Part part;
if (format == SimpleMessageFormat.HTML) {
// HTML takes precedence, then text.
- part = message.findFirstPartByMimeType("text/html");
+ part = MimeUtility.findFirstPartByMimeType(message, "text/html");
if (part != null) {
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: HTML requested, HTML found.");
}
- return part.getText();
+ return MessageExtractor.getTextFromPart(part);
}
- part = message.findFirstPartByMimeType("text/plain");
+ part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
if (part != null) {
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: HTML requested, text found.");
}
- return HtmlConverter.textToHtml(part.getText());
+ String text = MessageExtractor.getTextFromPart(part);
+ return HtmlConverter.textToHtml(text);
}
} else if (format == SimpleMessageFormat.TEXT) {
// Text takes precedence, then html.
- part = message.findFirstPartByMimeType("text/plain");
+ part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
if (part != null) {
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: Text requested, text found.");
}
- return part.getText();
+ return MessageExtractor.getTextFromPart(part);
}
- part = message.findFirstPartByMimeType("text/html");
+ part = MimeUtility.findFirstPartByMimeType(message, "text/html");
if (part != null) {
if (K9.DEBUG) {
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: Text requested, HTML found.");
}
- return HtmlConverter.htmlToText(part.getText());
+ String text = MessageExtractor.getTextFromPart(part);
+ return HtmlConverter.htmlToText(text);
}
}
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 76c151c8a..b10d68c07 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -78,6 +78,7 @@ import com.fsck.k9.mail.PushReceiver;
import com.fsck.k9.mail.Pusher;
import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.Transport;
+import com.fsck.k9.mail.internet.MessageExtractor;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.internet.TextBody;
@@ -1744,7 +1745,7 @@ public class MessagingController implements Runnable {
* right now, attachments will be left for later.
*/
- Set viewables = message.collectTextParts();
+ Set viewables = MessageExtractor.collectTextParts(message);
/*
* Now download the parts we're interested in storing.
@@ -3197,7 +3198,7 @@ public class MessagingController implements Runnable {
try {
LocalStore localStore = account.getLocalStore();
- List attachments = message.collectAttachments();
+ List attachments = MessageExtractor.collectAttachments(message);
for (Part attachment : attachments) {
attachment.setBody(null);
}
@@ -4244,12 +4245,12 @@ public class MessagingController implements Runnable {
try {
Intent msg = new Intent(Intent.ACTION_SEND);
String quotedText = null;
- Part part = message.findFirstPartByMimeType("text/plain");
+ Part part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
if (part == null) {
- part = message.findFirstPartByMimeType("text/html");
+ part = MimeUtility.findFirstPartByMimeType(message, "text/html");
}
if (part != null) {
- quotedText = part.getText();
+ quotedText = MessageExtractor.getTextFromPart(part);
}
if (quotedText != null) {
msg.putExtra(Intent.EXTRA_TEXT, quotedText);
diff --git a/src/com/fsck/k9/crypto/CryptoHelper.java b/src/com/fsck/k9/crypto/CryptoHelper.java
index a03e6fff9..612c4ba3d 100644
--- a/src/com/fsck/k9/crypto/CryptoHelper.java
+++ b/src/com/fsck/k9/crypto/CryptoHelper.java
@@ -7,6 +7,9 @@ import java.util.regex.Pattern;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
+import com.fsck.k9.mail.internet.MessageExtractor;
+import com.fsck.k9.mail.internet.MimeUtility;
+
public class CryptoHelper {
@@ -31,12 +34,12 @@ public class CryptoHelper {
public boolean isEncrypted(Message message) {
String data = null;
try {
- Part part = message.findFirstPartByMimeType("text/plain");
+ Part part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
if (part == null) {
- part = message.findFirstPartByMimeType("text/html");
+ part = MimeUtility.findFirstPartByMimeType(message, "text/html");
}
if (part != null) {
- data = part.getText();
+ data = MessageExtractor.getTextFromPart(part);
}
} catch (MessagingException e) {
// guess not...
@@ -54,12 +57,12 @@ public class CryptoHelper {
public boolean isSigned(Message message) {
String data = null;
try {
- Part part = message.findFirstPartByMimeType("text/plain");
+ Part part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
if (part == null) {
- part = message.findFirstPartByMimeType("text/html");
+ part = MimeUtility.findFirstPartByMimeType(message, "text/html");
}
if (part != null) {
- data = part.getText();
+ data = MessageExtractor.getTextFromPart(part);
}
} catch (MessagingException e) {
// guess not...
diff --git a/src/com/fsck/k9/mail/BodyPart.java b/src/com/fsck/k9/mail/BodyPart.java
index 884b03ae1..551866829 100644
--- a/src/com/fsck/k9/mail/BodyPart.java
+++ b/src/com/fsck/k9/mail/BodyPart.java
@@ -1,8 +1,5 @@
-
package com.fsck.k9.mail;
-import com.fsck.k9.mail.internet.MessageExtractor;
-import com.fsck.k9.mail.internet.MimeUtility;
public abstract class BodyPart implements Part {
private Multipart mParent;
@@ -16,14 +13,4 @@ public abstract class BodyPart implements Part {
}
public abstract void setEncoding(String encoding) throws MessagingException;
-
- @Override
- public String getText() {
- return MessageExtractor.getTextFromPart(this);
- }
-
- @Override
- public Part findFirstPartByMimeType(String mimeType) throws MessagingException {
- return MimeUtility.findFirstPartByMimeType(this, mimeType);
- }
}
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index 368b25dc2..ecc35f193 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -2,11 +2,9 @@
package com.fsck.k9.mail;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
-import java.util.List;
import java.util.Set;
import android.util.Log;
@@ -14,8 +12,6 @@ import android.util.Log;
import com.fsck.k9.K9;
import com.fsck.k9.mail.filter.CountingOutputStream;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
-import com.fsck.k9.mail.internet.MessageExtractor;
-import com.fsck.k9.mail.internet.MimeUtility;
public abstract class Message implements Part, CompositeBody {
@@ -270,41 +266,4 @@ public abstract class Message implements Part, CompositeBody {
@Override
public abstract Message clone();
- @Override
- public String getText() {
- return MessageExtractor.getTextFromPart(this);
- }
-
- @Override
- public Part findFirstPartByMimeType(String mimeType) throws MessagingException {
- return MimeUtility.findFirstPartByMimeType(this, mimeType);
- }
-
- /**
- * Collect attachment parts of a message.
- * @return A list of parts regarded as attachments.
- * @throws MessagingException In case of an error.
- */
- public List collectAttachments() throws MessagingException {
- try {
- List attachments = new ArrayList();
- MessageExtractor.getViewables(this, attachments);
- return attachments;
- } catch (Exception e) {
- throw new MessagingException("Couldn't collect attachment parts", e);
- }
- }
-
- /**
- * Collect the viewable textual parts of a message.
- * @return A set of viewable parts of the message.
- * @throws MessagingException In case of an error.
- */
- public Set collectTextParts() throws MessagingException {
- try {
- return MessageExtractor.getTextParts(this);
- } catch (Exception e) {
- throw new MessagingException("Couldn't extract viewable parts", e);
- }
- }
}
diff --git a/src/com/fsck/k9/mail/Part.java b/src/com/fsck/k9/mail/Part.java
index bcf5dcc5e..4c692b724 100644
--- a/src/com/fsck/k9/mail/Part.java
+++ b/src/com/fsck/k9/mail/Part.java
@@ -29,16 +29,6 @@ public interface Part {
void writeTo(OutputStream out) throws IOException, MessagingException;
- /**
- * Reads the Part's body and returns a String based on any charset conversion that needed
- * to be done. Note, this does not return a text representation of HTML.
- * @return a String containing the converted text in the body, or null if there was no text
- * or an error during conversion.
- */
- String getText();
-
- Part findFirstPartByMimeType(String mimeType) throws MessagingException;
-
/**
* Called just prior to transmission, once the type of transport is known to
* be 7bit.
diff --git a/src/com/fsck/k9/mail/internet/MessageExtractor.java b/src/com/fsck/k9/mail/internet/MessageExtractor.java
index a4b997116..1f35c0491 100644
--- a/src/com/fsck/k9/mail/internet/MessageExtractor.java
+++ b/src/com/fsck/k9/mail/internet/MessageExtractor.java
@@ -199,6 +199,34 @@ public class MessageExtractor {
return getParts(getViewables(part, attachments));
}
+ /**
+ * Collect attachment parts of a message.
+ * @return A list of parts regarded as attachments.
+ * @throws MessagingException In case of an error.
+ */
+ public static List collectAttachments(Message message) throws MessagingException {
+ try {
+ List attachments = new ArrayList();
+ getViewables(message, attachments);
+ return attachments;
+ } catch (Exception e) {
+ throw new MessagingException("Couldn't collect attachment parts", e);
+ }
+ }
+
+ /**
+ * Collect the viewable textual parts of a message.
+ * @return A set of viewable parts of the message.
+ * @throws MessagingException In case of an error.
+ */
+ public static Set collectTextParts(Message message) throws MessagingException {
+ try {
+ return getTextParts(message);
+ } catch (Exception e) {
+ throw new MessagingException("Couldn't extract viewable parts", e);
+ }
+ }
+
private static Message getMessageFromPart(Part part) {
while (part != null) {
if (part instanceof Message)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 00f037108..a5ac8efa7 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -16,7 +16,10 @@ import org.apache.james.mime4j.util.MimeUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
+import java.util.Set;
import java.util.regex.Pattern;
@@ -952,7 +955,7 @@ public class MimeUtility {
if (part.getBody() instanceof Multipart) {
Multipart multipart = (Multipart)part.getBody();
for (BodyPart bodyPart : multipart.getBodyParts()) {
- Part ret = bodyPart.findFirstPartByMimeType(mimeType);
+ Part ret = MimeUtility.findFirstPartByMimeType(bodyPart, mimeType);
if (ret != null) {
return ret;
}
diff --git a/src/com/fsck/k9/mailstore/LocalMessage.java b/src/com/fsck/k9/mailstore/LocalMessage.java
index 555254c8f..75365d922 100644
--- a/src/com/fsck/k9/mailstore/LocalMessage.java
+++ b/src/com/fsck/k9/mailstore/LocalMessage.java
@@ -20,7 +20,9 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
+import com.fsck.k9.mail.internet.MessageExtractor;
import com.fsck.k9.mail.internet.MimeMessage;
+import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
@@ -119,16 +121,16 @@ public class LocalMessage extends MimeMessage {
*/
public String getTextForDisplay() throws MessagingException {
String text = null; // First try and fetch an HTML part.
- Part part = findFirstPartByMimeType("text/html");
+ Part part = MimeUtility.findFirstPartByMimeType(this, "text/html");
if (part == null) {
// If that fails, try and get a text part.
- part = findFirstPartByMimeType("text/plain");
+ part = MimeUtility.findFirstPartByMimeType(this, "text/plain");
if (part != null && part.getBody() instanceof LocalTextBody) {
text = ((LocalTextBody) part.getBody()).getBodyForDisplay();
}
} else {
// We successfully found an HTML part; do the necessary character set decoding.
- text = part.getText();
+ text = MessageExtractor.getTextFromPart(this);
}
return text;
}
diff --git a/src/com/fsck/k9/mailstore/LocalMessageExtractor.java b/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
index f5d1a9108..864b9132f 100644
--- a/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
+++ b/src/com/fsck/k9/mailstore/LocalMessageExtractor.java
@@ -170,7 +170,7 @@ class LocalMessageExtractor {
Part part = ((Textual)viewable).getPart();
addHtmlDivider(html, part, prependDivider);
- String t = part.getText();
+ String t = MessageExtractor.getTextFromPart(part);
if (t == null) {
t = "";
} else if (viewable instanceof Text) {
@@ -202,7 +202,7 @@ class LocalMessageExtractor {
Part part = ((Textual)viewable).getPart();
addTextDivider(text, part, prependDivider);
- String t = part.getText();
+ String t = MessageExtractor.getTextFromPart(part);
if (t == null) {
t = "";
} else if (viewable instanceof Html) {
@@ -446,7 +446,7 @@ class LocalMessageExtractor {
Body firstBody = part.getBody();
if (part.isMimeType("text/plain")) {
- String bodyText = part.getText();
+ String bodyText = MessageExtractor.getTextFromPart(part);
if (bodyText != null) {
text = bodyText;
html = HtmlConverter.textToHtml(text);
@@ -455,7 +455,7 @@ class LocalMessageExtractor {
firstBody instanceof MimeMultipart) {
MimeMultipart multipart = (MimeMultipart) firstBody;
for (BodyPart bodyPart : multipart.getBodyParts()) {
- String bodyText = bodyPart.getText();
+ String bodyText = MessageExtractor.getTextFromPart(bodyPart);
if (bodyText != null) {
if (text.isEmpty() && bodyPart.isMimeType("text/plain")) {
text = bodyText;
diff --git a/src/com/fsck/k9/view/MessageOpenPgpView.java b/src/com/fsck/k9/view/MessageOpenPgpView.java
index cb9be859b..3c0e857da 100644
--- a/src/com/fsck/k9/view/MessageOpenPgpView.java
+++ b/src/com/fsck/k9/view/MessageOpenPgpView.java
@@ -36,6 +36,8 @@ import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
+import com.fsck.k9.mail.internet.MessageExtractor;
+import com.fsck.k9.mail.internet.MimeUtility;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi;
@@ -214,7 +216,7 @@ public class MessageOpenPgpView extends LinearLayout {
} else {
try {
// check for PGP/MIME encryption
- Part pgp = message.findFirstPartByMimeType("application/pgp-encrypted");
+ Part pgp = MimeUtility.findFirstPartByMimeType(message, "application/pgp-encrypted");
if (pgp != null) {
Toast.makeText(mContext, R.string.pgp_mime_unsupported, Toast.LENGTH_LONG)
.show();
@@ -239,12 +241,12 @@ public class MessageOpenPgpView extends LinearLayout {
public void run() {
try {
// get data String
- Part part = message.findFirstPartByMimeType("text/plain");
+ Part part = MimeUtility.findFirstPartByMimeType(message, "text/plain");
if (part == null) {
- part = message.findFirstPartByMimeType("text/html");
+ part = MimeUtility.findFirstPartByMimeType(message, "text/html");
}
if (part != null) {
- mData = part.getText();
+ mData = MessageExtractor.getTextFromPart(part);
}
// wait for service to be bound
From 44f6a2479b5628c9d0b78da09590902d044a7616 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Tue, 16 Dec 2014 10:56:13 +0100
Subject: [PATCH 27/29] Remove reference to K9#hideTimeZone() + test
---
src/com/fsck/k9/activity/MessageCompose.java | 2 +-
.../k9/controller/MessagingController.java | 2 +-
src/com/fsck/k9/mail/Message.java | 2 +-
.../fsck/k9/mail/internet/MimeMessage.java | 9 +++---
src/com/fsck/k9/mailstore/LocalMessage.java | 2 +-
tests/src/com/fsck/k9/mail/MessageTest.java | 32 +++++++++++++++++--
.../mailstore/LocalMessageExtractorTest.java | 2 +-
7 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index db2ee4e67..ff8cbc28d 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -1336,7 +1336,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/
private MimeMessage createMessage(boolean isDraft) throws MessagingException {
MimeMessage message = new MimeMessage();
- message.addSentDate(new Date());
+ message.addSentDate(new Date(), K9.hideTimeZone());
Address from = new Address(mIdentity.getEmail(), mIdentity.getName());
message.setFrom(from);
message.setRecipients(RecipientType.TO, getAddresses(mToView));
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index b10d68c07..103808d85 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -2723,7 +2723,7 @@ public class MessagingController implements Runnable {
long nowTime = System.currentTimeMillis();
Date nowDate = new Date(nowTime);
message.setInternalDate(nowDate);
- message.addSentDate(nowDate);
+ message.addSentDate(nowDate, K9.hideTimeZone());
message.setFrom(new Address(account.getEmail(), "K9mail internal"));
localFolder.appendMessages(Collections.singletonList(message));
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index ecc35f193..7815d16c9 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -87,7 +87,7 @@ public abstract class Message implements Part, CompositeBody {
public abstract Date getSentDate();
- public abstract void setSentDate(Date sentDate) throws MessagingException;
+ public abstract void setSentDate(Date sentDate, boolean hideTimeZone) throws MessagingException;
public abstract Address[] getRecipients(RecipientType type) throws MessagingException;
diff --git a/src/com/fsck/k9/mail/internet/MimeMessage.java b/src/com/fsck/k9/mail/internet/MimeMessage.java
index c58a46080..eff4ffa2e 100644
--- a/src/com/fsck/k9/mail/internet/MimeMessage.java
+++ b/src/com/fsck/k9/mail/internet/MimeMessage.java
@@ -33,7 +33,6 @@ import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Multipart;
import com.fsck.k9.mail.Part;
-import com.fsck.k9.K9;
/**
* An implementation of Message that stores all of it's metadata in RFC 822 and
@@ -137,12 +136,12 @@ public class MimeMessage extends Message {
* @param sentDate
* @throws com.fsck.k9.mail.MessagingException
*/
- public void addSentDate(Date sentDate) throws MessagingException {
+ public void addSentDate(Date sentDate, boolean hideTimeZone) throws MessagingException {
if (mDateFormat == null) {
mDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
}
- if (K9.hideTimeZone()) {
+ if (hideTimeZone) {
mDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@@ -151,9 +150,9 @@ public class MimeMessage extends Message {
}
@Override
- public void setSentDate(Date sentDate) throws MessagingException {
+ public void setSentDate(Date sentDate, boolean hideTimeZone) throws MessagingException {
removeHeader("Date");
- addSentDate(sentDate);
+ addSentDate(sentDate, hideTimeZone);
}
public void setInternalSentDate(Date sentDate) {
diff --git a/src/com/fsck/k9/mailstore/LocalMessage.java b/src/com/fsck/k9/mailstore/LocalMessage.java
index 75365d922..ca28ce812 100644
--- a/src/com/fsck/k9/mailstore/LocalMessage.java
+++ b/src/com/fsck/k9/mailstore/LocalMessage.java
@@ -157,7 +157,7 @@ public class LocalMessage extends MimeMessage {
}
super.setReplyTo(mReplyTo);
- super.setSentDate(this.getSentDate());
+ super.setSentDate(this.getSentDate(), K9.hideTimeZone());
super.setRecipients(RecipientType.TO, mTo);
super.setRecipients(RecipientType.CC, mCc);
super.setRecipients(RecipientType.BCC, mBcc);
diff --git a/tests/src/com/fsck/k9/mail/MessageTest.java b/tests/src/com/fsck/k9/mail/MessageTest.java
index 1fabfc534..70d771df4 100644
--- a/tests/src/com/fsck/k9/mail/MessageTest.java
+++ b/tests/src/com/fsck/k9/mail/MessageTest.java
@@ -5,6 +5,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Date;
+import java.util.TimeZone;
+
import org.apache.commons.io.IOUtils;
import org.apache.james.mime4j.codec.Base64InputStream;
import org.apache.james.mime4j.util.MimeUtil;
@@ -22,6 +25,11 @@ import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.TextBody;
public class MessageTest extends AndroidTestCase {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo"));
+ }
private static final String EIGHT_BIT_RESULT =
"From: from@example.com\r\n"
@@ -263,6 +271,28 @@ public class MessageTest extends AndroidTestCase {
super();
}
+ public void testSetSendDateSetsSentDate() throws Exception {
+ Message message = sampleMessage();
+ final int milliseconds = 0;
+ Date date = new Date(milliseconds);
+ message.setSentDate(date, false);
+ Date sentDate = message.getSentDate();
+ assertNotNull(sentDate);
+ assertEquals(milliseconds, sentDate.getTime());
+ }
+
+ public void testSetSendDateFormatsHeaderCorrectlyWithCurrentTimeZone() throws Exception {
+ Message message = sampleMessage();
+ message.setSentDate(new Date(0), false);
+ assertEquals("Thu, 01 Jan 1970 09:00:00 +0900", message.getHeader("Date")[0]);
+ }
+
+ public void testSetSendDateFormatsHeaderCorrectlyWithoutTimeZone() throws Exception {
+ Message message = sampleMessage();
+ message.setSentDate(new Date(0), true);
+ assertEquals("Thu, 01 Jan 1970 00:00:00 +0000", message.getHeader("Date")[0]);
+ }
+
public void testMessage() throws MessagingException, IOException {
MimeMessage message;
ByteArrayOutputStream out;
@@ -374,7 +404,5 @@ public class MessageTest extends AndroidTestCase {
sb.append(Integer.toString(mMimeBoundary++));
return sb.toString();
}
-
}
-
}
diff --git a/tests/src/com/fsck/k9/mailstore/LocalMessageExtractorTest.java b/tests/src/com/fsck/k9/mailstore/LocalMessageExtractorTest.java
index 2fc007caf..a6b417fa5 100644
--- a/tests/src/com/fsck/k9/mailstore/LocalMessageExtractorTest.java
+++ b/tests/src/com/fsck/k9/mailstore/LocalMessageExtractorTest.java
@@ -120,7 +120,7 @@ public class LocalMessageExtractorTest extends AndroidTestCase {
// Create message/rfc822 body
MimeMessage innerMessage = new MimeMessage();
- innerMessage.addSentDate(new Date(112, 02, 17));
+ innerMessage.addSentDate(new Date(112, 02, 17), false);
innerMessage.setRecipients(RecipientType.TO, new Address[] { new Address("to@example.com") });
innerMessage.setSubject("Subject");
innerMessage.setFrom(new Address("from@example.com"));
From 245a6330ed5c093b529e33c066f3c529cc994cf9 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Tue, 16 Dec 2014 11:45:52 +0100
Subject: [PATCH 28/29] Move logic into MessageHelper and add tests
---
.../k9/controller/MessagingController.java | 5 +-
src/com/fsck/k9/helper/Contacts.java | 2 +-
src/com/fsck/k9/helper/MessageHelper.java | 89 ++++++++++++++++++-
src/com/fsck/k9/mail/Address.java | 84 -----------------
src/com/fsck/k9/view/MessageHeader.java | 6 +-
.../com/fsck/k9/helper/HtmlConverterTest.java | 2 -
.../com/fsck/k9/helper/MessageHelperTest.java | 63 +++++++++++++
7 files changed, 155 insertions(+), 96 deletions(-)
create mode 100644 tests/src/com/fsck/k9/helper/MessageHelperTest.java
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 103808d85..770742256 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -61,6 +61,7 @@ import com.fsck.k9.activity.setup.AccountSetupIncoming;
import com.fsck.k9.activity.setup.AccountSetupOutgoing;
import com.fsck.k9.cache.EmailProviderCache;
import com.fsck.k9.helper.Contacts;
+import com.fsck.k9.helper.MessageHelper;
import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
import com.fsck.k9.mail.Address;
@@ -4695,7 +4696,7 @@ public class MessagingController implements Runnable {
if (fromAddrs != null) {
isSelf = account.isAnIdentity(fromAddrs);
if (!isSelf && fromAddrs.length > 0) {
- return fromAddrs[0].toFriendly(contacts).toString();
+ return MessageHelper.toFriendly(fromAddrs[0], contacts).toString();
}
}
@@ -4705,7 +4706,7 @@ public class MessagingController implements Runnable {
if (rcpts != null && rcpts.length > 0) {
return context.getString(R.string.message_to_fmt,
- rcpts[0].toFriendly(contacts).toString());
+ MessageHelper.toFriendly(rcpts[0], contacts).toString());
}
return context.getString(R.string.general_no_sender);
diff --git a/src/com/fsck/k9/helper/Contacts.java b/src/com/fsck/k9/helper/Contacts.java
index f5d25a912..022139f89 100644
--- a/src/com/fsck/k9/helper/Contacts.java
+++ b/src/com/fsck/k9/helper/Contacts.java
@@ -18,7 +18,7 @@ import java.util.List;
/**
* Helper class to access the contacts stored on the device.
*/
-public class Contacts implements Address.Lookup {
+public class Contacts {
/**
* The order in which the search results are returned by
* {@link #searchContacts(CharSequence)}.
diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java
index 55caf8f66..ddc2f4a4d 100644
--- a/src/com/fsck/k9/helper/MessageHelper.java
+++ b/src/com/fsck/k9/helper/MessageHelper.java
@@ -1,7 +1,11 @@
package com.fsck.k9.helper;
import android.content.Context;
+import android.text.Spannable;
+import android.text.SpannableString;
import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
import android.util.Log;
import com.fsck.k9.Account;
@@ -16,6 +20,18 @@ import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mailstore.LocalMessage;
public class MessageHelper {
+ /**
+ * If the number of addresses exceeds this value the addresses aren't
+ * resolved to the names of Android contacts.
+ *
+ *
+ * TODO: This number was chosen arbitrarily and should be determined by
+ * performance tests.
+ *
+ *
+ * @see #toFriendly(Address[], com.fsck.k9.helper.Contacts)
+ */
+ private static final int TOO_MANY_ADDRESSES = 50;
private static MessageHelper sInstance;
@@ -55,11 +71,11 @@ public class MessageHelper {
Address[] addrs = message.getFrom();
if (addrs.length > 0 && account.isAnIdentity(addrs[0])) {
- CharSequence to = Address.toFriendly(message .getRecipients(RecipientType.TO), contactHelper);
+ CharSequence to = toFriendly(message.getRecipients(RecipientType.TO), contactHelper);
target.compareCounterparty = to.toString();
target.sender = new SpannableStringBuilder(mContext.getString(R.string.message_to_label)).append(to);
} else {
- target.sender = Address.toFriendly(addrs, contactHelper);
+ target.sender = toFriendly(addrs, contactHelper);
target.compareCounterparty = target.sender.toString();
}
@@ -83,11 +99,11 @@ public class MessageHelper {
CharSequence displayName;
if (fromAddrs.length > 0 && account.isAnIdentity(fromAddrs[0])) {
- CharSequence to = Address.toFriendly(toAddrs, contactHelper);
+ CharSequence to = toFriendly(toAddrs, contactHelper);
displayName = new SpannableStringBuilder(
mContext.getString(R.string.message_to_label)).append(to);
} else {
- displayName = Address.toFriendly(fromAddrs, contactHelper);
+ displayName = toFriendly(fromAddrs, contactHelper);
}
return displayName;
@@ -101,4 +117,69 @@ public class MessageHelper {
}
return false;
}
+
+ /**
+ * Returns the name of the contact this email address belongs to if
+ * the {@link Contacts contacts} parameter is not {@code null} and a
+ * contact is found. Otherwise the personal portion of the {@link Address}
+ * is returned. If that isn't available either, the email address is
+ * returned.
+ *
+ * @param address An {@link com.fsck.k9.mail.Address}
+ * @param contacts A {@link Contacts} instance or {@code null}.
+ * @return A "friendly" name for this {@link Address}.
+ */
+ public static CharSequence toFriendly(Address address, Contacts contacts) {
+ return toFriendly(address,contacts,
+ K9.showCorrespondentNames(),
+ K9.changeContactNameColor(),
+ K9.getContactNameColor());
+ }
+
+ public static CharSequence toFriendly(Address[] addresses, Contacts contacts) {
+ if (addresses == null) {
+ return null;
+ }
+
+ if (addresses.length >= TOO_MANY_ADDRESSES) {
+ // Don't look up contacts if the number of addresses is very high.
+ contacts = null;
+ }
+
+ SpannableStringBuilder sb = new SpannableStringBuilder();
+ for (int i = 0; i < addresses.length; i++) {
+ sb.append(toFriendly(addresses[i], contacts));
+ if (i < addresses.length - 1) {
+ sb.append(',');
+ }
+ }
+ return sb;
+ }
+
+ /* package, for testing */ static CharSequence toFriendly(Address address, Contacts contacts,
+ boolean showCorrespondentNames,
+ boolean changeContactNameColor,
+ int contactNameColor) {
+ if (!showCorrespondentNames) {
+ return address.getAddress();
+ } else if (contacts != null) {
+ final String name = contacts.getNameForAddress(address.getAddress());
+ // TODO: The results should probably be cached for performance reasons.
+ if (name != null) {
+ if (changeContactNameColor) {
+ final SpannableString coloredName = new SpannableString(name);
+ coloredName.setSpan(new ForegroundColorSpan(contactNameColor),
+ 0,
+ coloredName.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ );
+ return coloredName;
+ } else {
+ return name;
+ }
+ }
+ }
+
+ return (!TextUtils.isEmpty(address.getPersonal())) ? address.getPersonal() : address.getAddress();
+ }
}
diff --git a/src/com/fsck/k9/mail/Address.java b/src/com/fsck/k9/mail/Address.java
index 9702c1c8d..76a4ebf45 100644
--- a/src/com/fsck/k9/mail/Address.java
+++ b/src/com/fsck/k9/mail/Address.java
@@ -24,25 +24,8 @@ import com.fsck.k9.K9;
public class Address {
- public static interface Lookup {
- String getNameForAddress(String address);
- }
-
private static final Pattern ATOM = Pattern.compile("^(?:[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~]|\\s)+$");
- /**
- * If the number of addresses exceeds this value the addresses aren't
- * resolved to the names of Android contacts.
- *
- *
- * TODO: This number was chosen arbitrarily and should be determined by
- * performance tests.
- *
- *
- * @see Address#toFriendly(Address[], com.fsck.k9.mail.Address.Lookup)
- */
- private static final int TOO_MANY_ADDRESSES = 50;
-
/**
* Immutable empty {@link Address} array
*/
@@ -238,73 +221,6 @@ public class Address {
return sb.toString();
}
- /**
- * Returns either the personal portion of the Address or the address portion if the personal
- * is not available.
- * @return
- */
- public CharSequence toFriendly() {
- return toFriendly((Lookup)null);
- }
-
- /**
- * Returns the name of the contact this email address belongs to if
- * the {@link Contacts contacts} parameter is not {@code null} and a
- * contact is found. Otherwise the personal portion of the {@link Address}
- * is returned. If that isn't available either, the email address is
- * returned.
- *
- * @param contacts
- * A {@link Contacts} instance or {@code null}.
- * @return
- * A "friendly" name for this {@link Address}.
- */
- public CharSequence toFriendly(final Lookup contacts) {
- if (!K9.showCorrespondentNames()) {
- return mAddress;
-
- } else if (contacts != null) {
- final String name = contacts.getNameForAddress(mAddress);
-
- // TODO: The results should probably be cached for performance reasons.
-
- if (name != null) {
- if (K9.changeContactNameColor()) {
- final SpannableString coloredName = new SpannableString(name);
- coloredName.setSpan(new ForegroundColorSpan(K9.getContactNameColor()),
- 0,
- coloredName.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
- );
- return coloredName;
- } else {
- return name;
- }
- }
- }
-
- return (!TextUtils.isEmpty(mPersonal)) ? mPersonal : mAddress;
- }
-
- public static CharSequence toFriendly(Address[] addresses, Lookup contacts) {
- if (addresses == null) {
- return null;
- }
-
- if (addresses.length >= TOO_MANY_ADDRESSES) {
- // Don't look up contacts if the number of addresses is very high.
- contacts = null;
- }
-
- SpannableStringBuilder sb = new SpannableStringBuilder();
- for (int i = 0; i < addresses.length; i++) {
- sb.append(addresses[i].toFriendly(contacts));
- if (i < addresses.length - 1) {
- sb.append(',');
- }
- }
- return sb;
- }
/**
* Unpacks an address list previously packed with packAddressList()
diff --git a/src/com/fsck/k9/view/MessageHeader.java b/src/com/fsck/k9/view/MessageHeader.java
index 99d02ece4..67c5e130d 100644
--- a/src/com/fsck/k9/view/MessageHeader.java
+++ b/src/com/fsck/k9/view/MessageHeader.java
@@ -217,9 +217,9 @@ public class MessageHeader extends LinearLayout implements OnClickListener {
public void populate(final Message message, final Account account) throws MessagingException {
final Contacts contacts = K9.showContactName() ? mContacts : null;
- final CharSequence from = Address.toFriendly(message.getFrom(), contacts);
- final CharSequence to = Address.toFriendly(message.getRecipients(Message.RecipientType.TO), contacts);
- final CharSequence cc = Address.toFriendly(message.getRecipients(Message.RecipientType.CC), contacts);
+ final CharSequence from = MessageHelper.toFriendly(message.getFrom(), contacts);
+ final CharSequence to = MessageHelper.toFriendly(message.getRecipients(Message.RecipientType.TO), contacts);
+ final CharSequence cc = MessageHelper.toFriendly(message.getRecipients(Message.RecipientType.CC), contacts);
Address[] fromAddrs = message.getFrom();
Address[] toAddrs = message.getRecipients(Message.RecipientType.TO);
diff --git a/tests/src/com/fsck/k9/helper/HtmlConverterTest.java b/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
index 32aa241ed..c79958150 100644
--- a/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
+++ b/tests/src/com/fsck/k9/helper/HtmlConverterTest.java
@@ -1,7 +1,5 @@
package com.fsck.k9.helper;
-import com.fsck.k9.helper.HtmlConverter;
-
import junit.framework.TestCase;
import java.io.BufferedWriter;
diff --git a/tests/src/com/fsck/k9/helper/MessageHelperTest.java b/tests/src/com/fsck/k9/helper/MessageHelperTest.java
new file mode 100644
index 000000000..0d71784e3
--- /dev/null
+++ b/tests/src/com/fsck/k9/helper/MessageHelperTest.java
@@ -0,0 +1,63 @@
+package com.fsck.k9.helper;
+
+
+import android.graphics.Color;
+import android.test.AndroidTestCase;
+import android.text.SpannableString;
+
+import com.fsck.k9.mail.Address;
+
+public class MessageHelperTest extends AndroidTestCase {
+ private Contacts contacts;
+ private Contacts mockContacts;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ contacts = new Contacts(getContext());
+ mockContacts = new Contacts(getContext()) {
+ @Override public String getNameForAddress(String address) {
+ if ("test@testor.com".equals(address)) {
+ return "Tim Testor";
+ } else {
+ return null;
+ }
+ }
+ };
+ }
+
+ public void testToFriendlyShowsPersonalPartIfItExists() throws Exception {
+ Address address = new Address("test@testor.com", "Tim Testor");
+ assertEquals("Tim Testor", MessageHelper.toFriendly(address, contacts));
+ }
+
+ public void testToFriendlyShowsEmailPartIfNoPersonalPartExists() throws Exception {
+ Address address = new Address("test@testor.com");
+ assertEquals("test@testor.com", MessageHelper.toFriendly(address, contacts));
+ }
+
+ public void testToFriendlyArray() throws Exception {
+ Address address1 = new Address("test@testor.com", "Tim Testor");
+ Address address2 = new Address("foo@bar.com", "Foo Bar");
+ Address[] addresses = new Address[] { address1, address2 };
+ assertEquals("Tim Testor,Foo Bar", MessageHelper.toFriendly(addresses, contacts).toString());
+ }
+
+ public void testToFriendlyWithContactLookup() throws Exception {
+ Address address = new Address("test@testor.com");
+ assertEquals("Tim Testor", MessageHelper.toFriendly(address, mockContacts).toString());
+ }
+
+ public void testToFriendlyWithChangeContactColor() throws Exception {
+ Address address = new Address("test@testor.com");
+ CharSequence friendly = MessageHelper.toFriendly(address, mockContacts, true, true, Color.RED);
+ assertTrue(friendly instanceof SpannableString);
+ assertEquals("Tim Testor", friendly.toString());
+ }
+
+ public void testToFriendlyWithoutCorrespondentNames() throws Exception {
+ Address address = new Address("test@testor.com", "Tim Testor");
+ CharSequence friendly = MessageHelper.toFriendly(address, mockContacts, false, false, 0);
+ assertEquals("test@testor.com", friendly.toString());
+ }
+}
From 231684936bb6528ab1688fe6b9cc8b5387351960 Mon Sep 17 00:00:00 2001
From: Jan Berkel
Date: Tue, 16 Dec 2014 12:51:52 +0100
Subject: [PATCH 29/29] break/centralize dependencies to K9
---
src/com/fsck/k9/K9.java | 31 --
src/com/fsck/k9/mail/Address.java | 11 +-
src/com/fsck/k9/mail/Folder.java | 6 +-
src/com/fsck/k9/mail/K9MailLib.java | 44 +++
src/com/fsck/k9/mail/Message.java | 7 +-
.../fsck/k9/mail/internet/CharsetSupport.java | 4 +-
.../fsck/k9/mail/internet/DecoderUtil.java | 7 +-
.../k9/mail/internet/MessageExtractor.java | 6 +-
.../fsck/k9/mail/ssl/KeyChainKeyManager.java | 7 +-
src/com/fsck/k9/mail/ssl/LocalKeyStore.java | 8 +-
.../k9/mail/ssl/TrustedSocketFactory.java | 4 +-
.../k9/mail/store/ImapResponseParser.java | 2 +-
src/com/fsck/k9/mail/store/ImapStore.java | 373 +++++++++---------
src/com/fsck/k9/mail/store/ImapUtility.java | 10 +-
src/com/fsck/k9/mail/store/Pop3Store.java | 39 +-
src/com/fsck/k9/mail/store/WebDavStore.java | 81 ++--
.../fsck/k9/mail/transport/SmtpTransport.java | 25 +-
.../k9/mail/transport/WebDavTransport.java | 12 +-
18 files changed, 352 insertions(+), 325 deletions(-)
create mode 100644 src/com/fsck/k9/mail/K9MailLib.java
diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java
index b565ffc8c..cc359a6ac 100644
--- a/src/com/fsck/k9/K9.java
+++ b/src/com/fsck/k9/K9.java
@@ -136,37 +136,6 @@ public class K9 extends Application {
*/
public static boolean DEBUG = false;
- /**
- * Should K-9 log the conversation it has over the wire with
- * SMTP servers?
- */
-
- public static boolean DEBUG_PROTOCOL_SMTP = true;
-
- /**
- * Should K-9 log the conversation it has over the wire with
- * IMAP servers?
- */
-
- public static boolean DEBUG_PROTOCOL_IMAP = true;
-
-
- /**
- * Should K-9 log the conversation it has over the wire with
- * POP3 servers?
- */
-
- public static boolean DEBUG_PROTOCOL_POP3 = true;
-
- /**
- * Should K-9 log the conversation it has over the wire with
- * WebDAV servers?
- */
-
- public static boolean DEBUG_PROTOCOL_WEBDAV = true;
-
-
-
/**
* If this is enabled than logging that normally hides sensitive information
* like passwords will show that information.
diff --git a/src/com/fsck/k9/mail/Address.java b/src/com/fsck/k9/mail/Address.java
index 76a4ebf45..38a5a0f0b 100644
--- a/src/com/fsck/k9/mail/Address.java
+++ b/src/com/fsck/k9/mail/Address.java
@@ -11,17 +11,12 @@ import org.apache.james.mime4j.dom.address.Mailbox;
import org.apache.james.mime4j.dom.address.MailboxList;
import org.apache.james.mime4j.field.address.AddressBuilder;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
import android.text.TextUtils;
-import android.text.style.ForegroundColorSpan;
import android.text.util.Rfc822Token;
import android.text.util.Rfc822Tokenizer;
import android.util.Log;
-import com.fsck.k9.K9;
-
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
public class Address {
private static final Pattern ATOM = Pattern.compile("^(?:[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~]|\\s)+$");
@@ -150,12 +145,12 @@ public class Address {
Mailbox mailbox = (Mailbox)address;
addresses.add(new Address(mailbox.getLocalPart() + "@" + mailbox.getDomain(), mailbox.getName(), false));
} else {
- Log.e(K9.LOG_TAG, "Unknown address type from Mime4J: "
+ Log.e(LOG_TAG, "Unknown address type from Mime4J: "
+ address.getClass().toString());
}
}
} catch (MimeException pe) {
- Log.e(K9.LOG_TAG, "MimeException in Address.parse()", pe);
+ Log.e(LOG_TAG, "MimeException in Address.parse()", pe);
//but we do an silent failover : we just use the given string as name with empty address
addresses.add(new Address(null, addressList, false));
}
diff --git a/src/com/fsck/k9/mail/Folder.java b/src/com/fsck/k9/mail/Folder.java
index a11e7dd32..5502ef259 100644
--- a/src/com/fsck/k9/mail/Folder.java
+++ b/src/com/fsck/k9/mail/Folder.java
@@ -7,7 +7,7 @@ import java.util.Set;
import android.util.Log;
-import com.fsck.k9.K9;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
public abstract class Folder {
private String status = null;
@@ -146,8 +146,8 @@ public abstract class Folder {
// This is causing trouble. Disabled for now. See issue 1733
//throw new RuntimeException("fetchPart() not implemented.");
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "fetchPart() not implemented.");
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "fetchPart() not implemented.");
}
public abstract void delete(boolean recurse) throws MessagingException;
diff --git a/src/com/fsck/k9/mail/K9MailLib.java b/src/com/fsck/k9/mail/K9MailLib.java
new file mode 100644
index 000000000..490b5e67a
--- /dev/null
+++ b/src/com/fsck/k9/mail/K9MailLib.java
@@ -0,0 +1,44 @@
+package com.fsck.k9.mail;
+
+import com.fsck.k9.K9;
+
+public class K9MailLib {
+ private K9MailLib() {}
+
+ public static final String LOG_TAG = K9.LOG_TAG;
+
+ public static final int PUSH_WAKE_LOCK_TIMEOUT = K9.PUSH_WAKE_LOCK_TIMEOUT;
+ public static final String IDENTITY_HEADER = K9.IDENTITY_HEADER;
+
+ /**
+ * Should K-9 log the conversation it has over the wire with
+ * SMTP servers?
+ */
+ public static boolean DEBUG_PROTOCOL_SMTP = true;
+
+ /**
+ * Should K-9 log the conversation it has over the wire with
+ * IMAP servers?
+ */
+ public static boolean DEBUG_PROTOCOL_IMAP = true;
+
+ /**
+ * Should K-9 log the conversation it has over the wire with
+ * POP3 servers?
+ */
+ public static boolean DEBUG_PROTOCOL_POP3 = true;
+
+ /**
+ * Should K-9 log the conversation it has over the wire with
+ * WebDAV servers?
+ */
+ public static boolean DEBUG_PROTOCOL_WEBDAV = true;
+
+ public static boolean isDebug() {
+ return K9.DEBUG;
+ }
+
+ public static boolean isDebugSensitive() {
+ return K9.DEBUG_SENSITIVE;
+ }
+}
diff --git a/src/com/fsck/k9/mail/Message.java b/src/com/fsck/k9/mail/Message.java
index 7815d16c9..45c85450f 100644
--- a/src/com/fsck/k9/mail/Message.java
+++ b/src/com/fsck/k9/mail/Message.java
@@ -9,10 +9,11 @@ import java.util.Set;
import android.util.Log;
-import com.fsck.k9.K9;
import com.fsck.k9.mail.filter.CountingOutputStream;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
public abstract class Message implements Part, CompositeBody {
public enum RecipientType {
@@ -231,9 +232,9 @@ public abstract class Message implements Part, CompositeBody {
eolOut.flush();
return out.getCount();
} catch (IOException e) {
- Log.e(K9.LOG_TAG, "Failed to calculate a message size", e);
+ Log.e(LOG_TAG, "Failed to calculate a message size", e);
} catch (MessagingException e) {
- Log.e(K9.LOG_TAG, "Failed to calculate a message size", e);
+ Log.e(LOG_TAG, "Failed to calculate a message size", e);
}
return 0;
}
diff --git a/src/com/fsck/k9/mail/internet/CharsetSupport.java b/src/com/fsck/k9/mail/internet/CharsetSupport.java
index 5346566f3..ffd241031 100644
--- a/src/com/fsck/k9/mail/internet/CharsetSupport.java
+++ b/src/com/fsck/k9/mail/internet/CharsetSupport.java
@@ -2,7 +2,6 @@ package com.fsck.k9.mail.internet;
import android.util.Log;
-import com.fsck.k9.K9;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
@@ -15,6 +14,7 @@ import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.util.Locale;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
import static com.fsck.k9.mail.internet.JisSupport.SHIFT_JIS;
public class CharsetSupport {
@@ -111,7 +111,7 @@ public class CharsetSupport {
}
if (charset.matches(rule[0])) {
- Log.e(K9.LOG_TAG, "I don't know how to deal with the charset " + charset +
+ Log.e(LOG_TAG, "I don't know how to deal with the charset " + charset +
". Falling back to " + rule[1]);
charset = rule[1];
try {
diff --git a/src/com/fsck/k9/mail/internet/DecoderUtil.java b/src/com/fsck/k9/mail/internet/DecoderUtil.java
index 3e439ab99..d17c83bc7 100644
--- a/src/com/fsck/k9/mail/internet/DecoderUtil.java
+++ b/src/com/fsck/k9/mail/internet/DecoderUtil.java
@@ -2,7 +2,6 @@
package com.fsck.k9.mail.internet;
import android.util.Log;
-import com.fsck.k9.K9;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import java.io.ByteArrayInputStream;
@@ -13,6 +12,8 @@ import org.apache.james.mime4j.codec.Base64InputStream;
import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
import org.apache.james.mime4j.util.CharsetUtil;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
/**
* Static methods for decoding strings, byte arrays and encoded words.
@@ -168,7 +169,7 @@ class DecoderUtil {
}
if (encodedText.isEmpty()) {
- Log.w(K9.LOG_TAG, "Missing encoded text in encoded word: '" + body.substring(begin, end) + "'");
+ Log.w(LOG_TAG, "Missing encoded text in encoded word: '" + body.substring(begin, end) + "'");
return null;
}
@@ -177,7 +178,7 @@ class DecoderUtil {
} else if (encoding.equalsIgnoreCase("B")) {
return DecoderUtil.decodeB(encodedText, charset);
} else {
- Log.w(K9.LOG_TAG, "Warning: Unknown encoding in encoded word '" + body.substring(begin, end) + "'");
+ Log.w(LOG_TAG, "Warning: Unknown encoding in encoded word '" + body.substring(begin, end) + "'");
return null;
}
}
diff --git a/src/com/fsck/k9/mail/internet/MessageExtractor.java b/src/com/fsck/k9/mail/internet/MessageExtractor.java
index 1f35c0491..ba0bfa42f 100644
--- a/src/com/fsck/k9/mail/internet/MessageExtractor.java
+++ b/src/com/fsck/k9/mail/internet/MessageExtractor.java
@@ -2,7 +2,6 @@ package com.fsck.k9.mail.internet;
import android.util.Log;
-import com.fsck.k9.K9;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.BodyPart;
import com.fsck.k9.mail.Message;
@@ -19,6 +18,7 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
import static com.fsck.k9.mail.internet.CharsetSupport.fixupCharset;
import static com.fsck.k9.mail.internet.MimeUtility.getHeaderParameter;
import static com.fsck.k9.mail.internet.Viewable.Alternative;
@@ -110,13 +110,13 @@ public class MessageExtractor {
* If we are not able to process the body there's nothing we can do about it. Return
* null and let the upper layers handle the missing content.
*/
- Log.e(K9.LOG_TAG, "Unable to getTextFromPart " + oom.toString());
+ Log.e(LOG_TAG, "Unable to getTextFromPart " + oom.toString());
} catch (Exception e) {
/*
* If we are not able to process the body there's nothing we can do about it. Return
* null and let the upper layers handle the missing content.
*/
- Log.e(K9.LOG_TAG, "Unable to getTextFromPart", e);
+ Log.e(LOG_TAG, "Unable to getTextFromPart", e);
}
return null;
}
diff --git a/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java b/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java
index 52973e28b..273b7dd9a 100644
--- a/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java
+++ b/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java
@@ -20,11 +20,12 @@ import android.security.KeyChain;
import android.security.KeyChainException;
import android.util.Log;
-import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.MessagingException;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
/**
* For client certificate authentication! Provide private keys and certificates
* during the TLS handshake using the Android 4.0 KeyChain API.
@@ -207,10 +208,10 @@ class KeyChainKeyManager extends X509ExtendedKeyManager {
return mAlias;
}
}
- Log.w(K9.LOG_TAG, "Client certificate " + mAlias + " not issued by any of the requested issuers");
+ Log.w(LOG_TAG, "Client certificate " + mAlias + " not issued by any of the requested issuers");
return null;
}
- Log.w(K9.LOG_TAG, "Client certificate " + mAlias + " does not match any of the requested key types");
+ Log.w(LOG_TAG, "Client certificate " + mAlias + " does not match any of the requested key types");
return null;
}
}
diff --git a/src/com/fsck/k9/mail/ssl/LocalKeyStore.java b/src/com/fsck/k9/mail/ssl/LocalKeyStore.java
index 7133be7b0..cc0587c2c 100644
--- a/src/com/fsck/k9/mail/ssl/LocalKeyStore.java
+++ b/src/com/fsck/k9/mail/ssl/LocalKeyStore.java
@@ -15,7 +15,7 @@ import org.apache.commons.io.IOUtils;
import android.util.Log;
-import com.fsck.k9.K9;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
public class LocalKeyStore {
private static final int KEY_STORE_FILE_VERSION = 1;
@@ -50,7 +50,7 @@ public class LocalKeyStore {
* error, presuming setKeyStoreFile(File) is called next with a
* non-null File.
*/
- Log.w(K9.LOG_TAG, "Local key store has not been initialized");
+ Log.w(LOG_TAG, "Local key store has not been initialized");
}
}
@@ -92,7 +92,7 @@ public class LocalKeyStore {
mKeyStore = store;
mKeyStoreFile = file;
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Failed to initialize local key store", e);
+ Log.e(LOG_TAG, "Failed to initialize local key store", e);
// Use of the local key store is effectively disabled.
mKeyStore = null;
mKeyStoreFile = null;
@@ -169,7 +169,7 @@ public class LocalKeyStore {
} catch (KeyStoreException e) {
// Ignore: most likely there was no cert. found
} catch (CertificateException e) {
- Log.e(K9.LOG_TAG, "Error updating the local key store file", e);
+ Log.e(LOG_TAG, "Error updating the local key store file", e);
}
}
diff --git a/src/com/fsck/k9/mail/ssl/TrustedSocketFactory.java b/src/com/fsck/k9/mail/ssl/TrustedSocketFactory.java
index 9d68dd205..cf74bb899 100644
--- a/src/com/fsck/k9/mail/ssl/TrustedSocketFactory.java
+++ b/src/com/fsck/k9/mail/ssl/TrustedSocketFactory.java
@@ -19,6 +19,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
/**
* Filter and reorder list of cipher suites and TLS versions.
@@ -90,7 +92,7 @@ public class TrustedSocketFactory {
*/
supportedProtocols = sock.getSupportedProtocols();
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Error getting information about available SSL/TLS ciphers and " +
+ Log.e(LOG_TAG, "Error getting information about available SSL/TLS ciphers and " +
"protocols", e);
}
diff --git a/src/com/fsck/k9/mail/store/ImapResponseParser.java b/src/com/fsck/k9/mail/store/ImapResponseParser.java
index 541ff2376..b0e61fb70 100644
--- a/src/com/fsck/k9/mail/store/ImapResponseParser.java
+++ b/src/com/fsck/k9/mail/store/ImapResponseParser.java
@@ -293,7 +293,7 @@ class ImapResponseParser {
} catch (Exception e) {
// Catch everything else and save it for later.
mException = e;
- //Log.e(K9.LOG_TAG, "parseLiteral(): Exception in callback method", e);
+ //Log.e(LOG_TAG, "parseLiteral(): Exception in callback method", e);
}
// Check if only some of the literal data was read
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index c5eb8ead3..ae54c870b 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -68,6 +68,7 @@ import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
+import com.fsck.k9.mail.K9MailLib;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
@@ -94,6 +95,10 @@ import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZOutputStream;
import org.apache.commons.io.IOUtils;
+import static com.fsck.k9.mail.K9MailLib.DEBUG_PROTOCOL_IMAP;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+import static com.fsck.k9.mail.K9MailLib.PUSH_WAKE_LOCK_TIMEOUT;
+
/**
*
* TODO Need to start keeping track of UIDVALIDITY
@@ -539,7 +544,7 @@ public class ImapStore extends RemoteStore {
boolean includeFolder = true;
if (response.size() > 4 || !(response.getObject(3) instanceof String)) {
- Log.w(K9.LOG_TAG, "Skipping incorrectly parsed " + commandResponse +
+ Log.w(LOG_TAG, "Skipping incorrectly parsed " + commandResponse +
" reply: " + response);
continue;
}
@@ -548,7 +553,7 @@ public class ImapStore extends RemoteStore {
try {
decodedFolderName = decodeFolderName(response.getString(3));
} catch (CharacterCodingException e) {
- Log.w(K9.LOG_TAG, "Folder name not correctly encoded with the UTF-7 variant " +
+ Log.w(LOG_TAG, "Folder name not correctly encoded with the UTF-7 variant " +
"as defined by RFC 3501: " + response.getString(3), e);
//TODO: Use the raw name returned by the server for all commands that require
@@ -619,14 +624,14 @@ public class ImapStore extends RemoteStore {
String commandOptions = "";
if (connection.capabilities.contains("XLIST")) {
- if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration: Using XLIST.");
+ if (K9MailLib.isDebug()) Log.d(LOG_TAG, "Folder auto-configuration: Using XLIST.");
commandResponse = "XLIST";
} else if(connection.capabilities.contains("SPECIAL-USE")) {
- if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration: Using RFC6154/SPECIAL-USE.");
+ if (K9MailLib.isDebug()) Log.d(LOG_TAG, "Folder auto-configuration: Using RFC6154/SPECIAL-USE.");
commandResponse = "LIST";
commandOptions = " (SPECIAL-USE)";
} else {
- if (K9.DEBUG) Log.d(K9.LOG_TAG, "No detected folder auto-configuration methods.");
+ if (K9MailLib.isDebug()) Log.d(LOG_TAG, "No detected folder auto-configuration methods.");
return;
}
@@ -641,7 +646,7 @@ public class ImapStore extends RemoteStore {
try {
decodedFolderName = decodeFolderName(response.getString(3));
} catch (CharacterCodingException e) {
- Log.w(K9.LOG_TAG, "Folder name not correctly encoded with the UTF-7 variant " +
+ Log.w(LOG_TAG, "Folder name not correctly encoded with the UTF-7 variant " +
"as defined by RFC 3501: " + response.getString(3), e);
// We currently just skip folders with malformed names.
continue;
@@ -657,17 +662,17 @@ public class ImapStore extends RemoteStore {
String attribute = attributes.getString(i);
if (attribute.equals("\\Drafts")) {
mStoreConfig.setDraftsFolderName(decodedFolderName);
- if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration detected draft folder: " + decodedFolderName);
+ if (K9MailLib.isDebug()) Log.d(LOG_TAG, "Folder auto-configuration detected draft folder: " + decodedFolderName);
} else if (attribute.equals("\\Sent")) {
mStoreConfig.setSentFolderName(decodedFolderName);
- if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration detected sent folder: " + decodedFolderName);
+ if (K9MailLib.isDebug()) Log.d(LOG_TAG, "Folder auto-configuration detected sent folder: " + decodedFolderName);
} else if (attribute.equals("\\Spam") || attribute.equals("\\Junk")) {
//rfc6154 just mentions \Junk
mStoreConfig.setSpamFolderName(decodedFolderName);
- if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration detected spam folder: " + decodedFolderName);
+ if (K9MailLib.isDebug()) Log.d(LOG_TAG, "Folder auto-configuration detected spam folder: " + decodedFolderName);
} else if (attribute.equals("\\Trash")) {
mStoreConfig.setTrashFolderName(decodedFolderName);
- if (K9.DEBUG) Log.d(K9.LOG_TAG, "Folder auto-configuration detected trash folder: " + decodedFolderName);
+ if (K9MailLib.isDebug()) Log.d(LOG_TAG, "Folder auto-configuration detected trash folder: " + decodedFolderName);
}
}
}
@@ -909,7 +914,7 @@ public class ImapStore extends RemoteStore {
} catch (IOException ioe) {
throw ioExceptionHandler(mConnection, ioe);
} catch (MessagingException me) {
- Log.e(K9.LOG_TAG, "Unable to open connection for " + getLogId(), me);
+ Log.e(LOG_TAG, "Unable to open connection for " + getLogId(), me);
throw me;
}
}
@@ -963,7 +968,7 @@ public class ImapStore extends RemoteStore {
synchronized (this) {
// If we are mid-search and we get a close request, we gotta trash the connection.
if (mInSearch && mConnection != null) {
- Log.i(K9.LOG_TAG, "IMAP search was aborted, shutting down connection.");
+ Log.i(LOG_TAG, "IMAP search was aborted, shutting down connection.");
mConnection.close();
} else {
releaseConnection(mConnection);
@@ -1112,8 +1117,8 @@ public class ImapStore extends RemoteStore {
/*
* If the remote folder doesn't exist we try to create it.
*/
- if (K9.DEBUG) {
- Log.i(K9.LOG_TAG, "ImapFolder.copyMessages: attempting to create remote " +
+ if (K9MailLib.isDebug()) {
+ Log.i(LOG_TAG, "ImapFolder.copyMessages: attempting to create remote " +
"folder '" + remoteDestName + "' for " + getLogId());
}
@@ -1164,15 +1169,15 @@ public class ImapStore extends RemoteStore {
uidMap.put(srcUid, destUid);
}
} else {
- if (K9.DEBUG) {
- Log.v(K9.LOG_TAG, "Parse error: size of source UIDs " +
+ if (K9MailLib.isDebug()) {
+ Log.v(LOG_TAG, "Parse error: size of source UIDs " +
"list is not the same as size of destination " +
"UIDs list.");
}
}
} else {
- if (K9.DEBUG) {
- Log.v(K9.LOG_TAG, "Parsing of the sequence set failed.");
+ if (K9MailLib.isDebug()) {
+ Log.v(LOG_TAG, "Parsing of the sequence set failed.");
}
}
}
@@ -1209,14 +1214,14 @@ public class ImapStore extends RemoteStore {
/*
* If the remote trash folder doesn't exist we try to create it.
*/
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "IMAPMessage.delete: attempting to create remote '" + trashFolderName + "' folder for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "IMAPMessage.delete: attempting to create remote '" + trashFolderName + "' folder for " + getLogId());
remoteTrashFolder.create(FolderType.HOLDS_MESSAGES);
}
if (exists(remoteTrashName)) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "IMAPMessage.delete: copying remote " + messages.size() + " messages to '" + trashFolderName + "' for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "IMAPMessage.delete: copying remote " + messages.size() + " messages to '" + trashFolderName + "' for " + getLogId());
moveMessages(messages, remoteTrashFolder);
} else {
@@ -1276,7 +1281,7 @@ public class ImapStore extends RemoteStore {
return Long.parseLong(messages.get(0).getUid());
}
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Unable to find highest UID in folder " + getName(), e);
+ Log.e(LOG_TAG, "Unable to find highest UID in folder " + getName(), e);
}
return -1L;
@@ -1456,7 +1461,7 @@ public class ImapStore extends RemoteStore {
fetchFields.add("INTERNALDATE");
fetchFields.add("RFC822.SIZE");
fetchFields.add("BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc " +
- "reply-to message-id references in-reply-to " + K9.IDENTITY_HEADER + ")]");
+ "reply-to message-id references in-reply-to " + K9MailLib.IDENTITY_HEADER + ")]");
}
if (fp.contains(FetchProfile.Item.STRUCTURE)) {
fetchFields.add("BODYSTRUCTURE");
@@ -1501,18 +1506,18 @@ public class ImapStore extends RemoteStore {
if (uid != null) {
try {
msgSeqUidMap.put(msgSeq, uid);
- if (K9.DEBUG) {
- Log.v(K9.LOG_TAG, "Stored uid '" + uid + "' for msgSeq " + msgSeq + " into map " /*+ msgSeqUidMap.toString() */);
+ if (K9MailLib.isDebug()) {
+ Log.v(LOG_TAG, "Stored uid '" + uid + "' for msgSeq " + msgSeq + " into map " /*+ msgSeqUidMap.toString() */);
}
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Unable to store uid '" + uid + "' for msgSeq " + msgSeq);
+ Log.e(LOG_TAG, "Unable to store uid '" + uid + "' for msgSeq " + msgSeq);
}
}
Message message = messageMap.get(uid);
if (message == null) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Do not have message in messageMap for UID " + uid + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Do not have message in messageMap for UID " + uid + " for " + getLogId());
handleUntaggedResponse(response);
continue;
@@ -1591,8 +1596,8 @@ public class ImapStore extends RemoteStore {
String uid = fetchList.getKeyedString("UID");
if (!message.getUid().equals(uid)) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Did not ask for UID " + uid + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Did not ask for UID " + uid + " for " + getLogId());
handleUntaggedResponse(response);
continue;
@@ -1679,8 +1684,8 @@ public class ImapStore extends RemoteStore {
try {
parseBodyStructure(bs, message, "TEXT");
} catch (MessagingException e) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Error handling message for " + getLogId(), e);
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Error handling message for " + getLogId(), e);
message.setBody(null);
}
}
@@ -1728,8 +1733,8 @@ public class ImapStore extends RemoteStore {
String key = (String)keyObj;
if ("UIDNEXT".equalsIgnoreCase(key)) {
uidNext = bracketed.getLong(1);
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got UidNext = " + uidNext + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got UidNext = " + uidNext + " for " + getLogId());
}
}
}
@@ -1747,15 +1752,15 @@ public class ImapStore extends RemoteStore {
if (response.mTag == null && response.size() > 1) {
if (ImapResponseParser.equalsIgnoreCase(response.get(1), "EXISTS")) {
mMessageCount = response.getNumber(0);
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got untagged EXISTS with value " + mMessageCount + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got untagged EXISTS with value " + mMessageCount + " for " + getLogId());
}
handlePossibleUidNext(response);
if (ImapResponseParser.equalsIgnoreCase(response.get(1), "EXPUNGE") && mMessageCount > 0) {
mMessageCount--;
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got untagged EXPUNGE with mMessageCount " + mMessageCount + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got untagged EXPUNGE with mMessageCount " + mMessageCount + " for " + getLogId());
}
// if (response.size() > 1) {
// Object bracketedObj = response.get(1);
@@ -1777,7 +1782,7 @@ public class ImapStore extends RemoteStore {
// sb.append(' ');
// }
//
-// Log.w(K9.LOG_TAG, "ALERT: " + sb.toString() + " for " + getLogId());
+// Log.w(LOG_TAG, "ALERT: " + sb.toString() + " for " + getLogId());
// }
// }
// }
@@ -1786,7 +1791,7 @@ public class ImapStore extends RemoteStore {
// }
// }
}
- //Log.i(K9.LOG_TAG, "mMessageCount = " + mMessageCount + " for " + getLogId());
+ //Log.i(LOG_TAG, "mMessageCount = " + mMessageCount + " for " + getLogId());
}
private void parseBodyStructure(ImapList bs, Part part, String id)
@@ -2015,8 +2020,8 @@ public class ImapStore extends RemoteStore {
* not implement the APPENDUID response code.
*/
String newUid = getUidFromMessageId(message);
- if (K9.DEBUG) {
- Log.d(K9.LOG_TAG, "Got UID " + newUid + " for message for " + getLogId());
+ if (K9MailLib.isDebug()) {
+ Log.d(LOG_TAG, "Got UID " + newUid + " for message for " + getLogId());
}
if (!TextUtils.isEmpty(newUid)) {
@@ -2046,13 +2051,13 @@ public class ImapStore extends RemoteStore {
String[] messageIdHeader = message.getHeader("Message-ID");
if (messageIdHeader == null || messageIdHeader.length == 0) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Did not get a message-id in order to search for UID for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Did not get a message-id in order to search for UID for " + getLogId());
return null;
}
String messageId = messageIdHeader[0];
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Looking for UID for message with message-id " + messageId + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Looking for UID for message with message-id " + messageId + " for " + getLogId());
List responses =
executeSimpleCommand(
@@ -2131,7 +2136,7 @@ public class ImapStore extends RemoteStore {
return null;
}
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Exception while updated push state for " + getLogId(), e);
+ Log.e(LOG_TAG, "Exception while updated push state for " + getLogId(), e);
return null;
}
}
@@ -2163,7 +2168,7 @@ public class ImapStore extends RemoteStore {
}
private MessagingException ioExceptionHandler(ImapConnection connection, IOException ioe) {
- Log.e(K9.LOG_TAG, "IOException for " + getLogId(), ioe);
+ Log.e(LOG_TAG, "IOException for " + getLogId(), ioe);
if (connection != null) {
connection.close();
}
@@ -2346,14 +2351,14 @@ public class ImapStore extends RemoteStore {
if (capabilityList != null && !capabilityList.isEmpty() &&
ImapResponseParser.equalsIgnoreCase(capabilityList.get(0), CAPABILITY_CAPABILITY)) {
- if (K9.DEBUG) {
- Log.d(K9.LOG_TAG, "Saving " + capabilityList.size() + " capabilities for " + getLogId());
+ if (K9MailLib.isDebug()) {
+ Log.d(LOG_TAG, "Saving " + capabilityList.size() + " capabilities for " + getLogId());
}
for (Object capability : capabilityList) {
if (capability instanceof String) {
-// if (K9.DEBUG)
+// if (K9MailLib.isDebug())
// {
-// Log.v(K9.LOG_TAG, "Saving capability '" + capability + "' for " + getLogId());
+// Log.v(LOG_TAG, "Saving capability '" + capability + "' for " + getLogId());
// }
capabilities.add(((String)capability).toUpperCase(Locale.US));
}
@@ -2374,14 +2379,14 @@ public class ImapStore extends RemoteStore {
try {
Security.setProperty("networkaddress.cache.ttl", "0");
} catch (Exception e) {
- Log.w(K9.LOG_TAG, "Could not set DNS ttl to 0 for " + getLogId(), e);
+ Log.w(LOG_TAG, "Could not set DNS ttl to 0 for " + getLogId(), e);
}
try {
Security.setProperty("networkaddress.cache.negative.ttl", "0");
} catch (Exception e) {
- Log.w(K9.LOG_TAG, "Could not set DNS negative ttl to 0 for " + getLogId(), e);
+ Log.w(LOG_TAG, "Could not set DNS negative ttl to 0 for " + getLogId(), e);
}
try {
@@ -2391,8 +2396,8 @@ public class ImapStore extends RemoteStore {
InetAddress[] addresses = InetAddress.getAllByName(mSettings.getHost());
for (int i = 0; i < addresses.length; i++) {
try {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_IMAP) {
- Log.d(K9.LOG_TAG, "Connecting to " + mSettings.getHost() + " as " +
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_IMAP) {
+ Log.d(LOG_TAG, "Connecting to " + mSettings.getHost() + " as " +
addresses[i]);
}
@@ -2428,16 +2433,16 @@ public class ImapStore extends RemoteStore {
capabilities.clear();
ImapResponse nullResponse = mParser.readResponse();
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_IMAP)
- Log.v(K9.LOG_TAG, getLogId() + "<<<" + nullResponse);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_IMAP)
+ Log.v(LOG_TAG, getLogId() + "<<<" + nullResponse);
List nullResponses = new LinkedList();
nullResponses.add(nullResponse);
receiveCapabilities(nullResponses);
if (!hasCapability(CAPABILITY_CAPABILITY)) {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Did not get capabilities in banner, requesting CAPABILITY for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Did not get capabilities in banner, requesting CAPABILITY for " + getLogId());
List responses = receiveCapabilities(executeSimpleCommand(COMMAND_CAPABILITY));
if (responses.size() != 2) {
throw new MessagingException("Invalid CAPABILITY response received");
@@ -2459,8 +2464,8 @@ public class ImapStore extends RemoteStore {
mParser = new ImapResponseParser(mIn);
mOut = new BufferedOutputStream(mSocket.getOutputStream(), 1024);
// Per RFC 2595 (3.1): Once TLS has been started, reissue CAPABILITY command
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Updating capabilities after STARTTLS for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Updating capabilities after STARTTLS for " + getLogId());
capabilities.clear();
List responses = receiveCapabilities(executeSimpleCommand(COMMAND_CAPABILITY));
if (responses.size() != 2) {
@@ -2514,8 +2519,8 @@ public class ImapStore extends RemoteStore {
"Unhandled authentication method found in the server settings (bug).");
}
authSuccess = true;
- if (K9.DEBUG) {
- Log.d(K9.LOG_TAG, CAPABILITY_COMPRESS_DEFLATE + " = " + hasCapability(CAPABILITY_COMPRESS_DEFLATE));
+ if (K9MailLib.isDebug()) {
+ Log.d(LOG_TAG, CAPABILITY_COMPRESS_DEFLATE + " = " + hasCapability(CAPABILITY_COMPRESS_DEFLATE));
}
if (hasCapability(CAPABILITY_COMPRESS_DEFLATE)) {
ConnectivityManager connectivityManager = (ConnectivityManager)K9.app.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -2524,13 +2529,13 @@ public class ImapStore extends RemoteStore {
NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
if (netInfo != null) {
int type = netInfo.getType();
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "On network type " + type);
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "On network type " + type);
useCompression = mSettings.useCompression(type);
}
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "useCompression " + useCompression);
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "useCompression " + useCompression);
if (useCompression) {
try {
executeSimpleCommand(COMMAND_COMPRESS_DEFLATE);
@@ -2541,53 +2546,53 @@ public class ImapStore extends RemoteStore {
ZOutputStream zOutputStream = new ZOutputStream(mSocket.getOutputStream(), JZlib.Z_BEST_SPEED, true);
mOut = new BufferedOutputStream(zOutputStream, 1024);
zOutputStream.setFlushMode(JZlib.Z_PARTIAL_FLUSH);
- if (K9.DEBUG) {
- Log.i(K9.LOG_TAG, "Compression enabled for " + getLogId());
+ if (K9MailLib.isDebug()) {
+ Log.i(LOG_TAG, "Compression enabled for " + getLogId());
}
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Unable to negotiate compression", e);
+ Log.e(LOG_TAG, "Unable to negotiate compression", e);
}
}
}
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "NAMESPACE = " + hasCapability(CAPABILITY_NAMESPACE)
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "NAMESPACE = " + hasCapability(CAPABILITY_NAMESPACE)
+ ", mPathPrefix = " + mSettings.getPathPrefix());
if (mSettings.getPathPrefix() == null) {
if (hasCapability(CAPABILITY_NAMESPACE)) {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "mPathPrefix is unset and server has NAMESPACE capability");
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "mPathPrefix is unset and server has NAMESPACE capability");
List namespaceResponses =
executeSimpleCommand(COMMAND_NAMESPACE);
for (ImapResponse response : namespaceResponses) {
if (ImapResponseParser.equalsIgnoreCase(response.get(0), COMMAND_NAMESPACE)) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got NAMESPACE response " + response + " on " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got NAMESPACE response " + response + " on " + getLogId());
Object personalNamespaces = response.get(1);
if (personalNamespaces != null && personalNamespaces instanceof ImapList) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got personal namespaces: " + personalNamespaces);
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got personal namespaces: " + personalNamespaces);
ImapList bracketed = (ImapList)personalNamespaces;
Object firstNamespace = bracketed.get(0);
if (firstNamespace != null && firstNamespace instanceof ImapList) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got first personal namespaces: " + firstNamespace);
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got first personal namespaces: " + firstNamespace);
bracketed = (ImapList)firstNamespace;
mSettings.setPathPrefix(bracketed.getString(0));
mSettings.setPathDelimeter(bracketed.getString(1));
mSettings.setCombinedPrefix(null);
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got path '" + mSettings.getPathPrefix() + "' and separator '" + mSettings.getPathDelimeter() + "'");
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got path '" + mSettings.getPathPrefix() + "' and separator '" + mSettings.getPathDelimeter() + "'");
}
}
}
}
} else {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "mPathPrefix is unset but server does not have NAMESPACE capability");
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "mPathPrefix is unset but server does not have NAMESPACE capability");
mSettings.setPathPrefix("");
}
}
@@ -2599,12 +2604,12 @@ public class ImapStore extends RemoteStore {
if (ImapResponseParser.equalsIgnoreCase(response.get(0), "LIST")) {
mSettings.setPathDelimeter(response.getString(2));
mSettings.setCombinedPrefix(null);
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got path delimeter '" + mSettings.getPathDelimeter() + "' for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got path delimeter '" + mSettings.getPathDelimeter() + "' for " + getLogId());
}
}
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Unable to get path delimeter using LIST", e);
+ Log.e(LOG_TAG, "Unable to get path delimeter using LIST", e);
}
}
@@ -2621,14 +2626,14 @@ public class ImapStore extends RemoteStore {
String ceMess = ce.getMessage();
String[] tokens = ceMess.split("-");
if (tokens != null && tokens.length > 1 && tokens[1] != null) {
- Log.e(K9.LOG_TAG, "Stripping host/port from ConnectionException for " + getLogId(), ce);
+ Log.e(LOG_TAG, "Stripping host/port from ConnectionException for " + getLogId(), ce);
throw new ConnectException(tokens[1].trim());
} else {
throw ce;
}
} finally {
if (!authSuccess) {
- Log.e(K9.LOG_TAG, "Failed to login, closing connection for " + getLogId());
+ Log.e(LOG_TAG, "Failed to login, closing connection for " + getLogId());
close();
}
}
@@ -2721,7 +2726,7 @@ public class ImapStore extends RemoteStore {
throw new MessagingException(
"Command continuation aborted: " + response);
} else {
- Log.w(K9.LOG_TAG, "After sending tag " + tag
+ Log.w(LOG_TAG, "After sending tag " + tag
+ ", got tag response from previous command "
+ response + " for " + getLogId());
}
@@ -2737,11 +2742,11 @@ public class ImapStore extends RemoteStore {
ImapResponse response;
do {
response = mParser.readResponse();
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_IMAP)
- Log.v(K9.LOG_TAG, getLogId() + "<<<" + response);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_IMAP)
+ Log.v(LOG_TAG, getLogId() + "<<<" + response);
if (response.mTag != null && !response.mTag.equalsIgnoreCase(tag)) {
- Log.w(K9.LOG_TAG, "After sending tag " + tag + ", got tag response from previous command " + response + " for " + getLogId());
+ Log.w(LOG_TAG, "After sending tag " + tag + ", got tag response from previous command " + response + " for " + getLogId());
Iterator iter = responses.iterator();
while (iter.hasNext()) {
ImapResponse delResponse = iter.next();
@@ -2772,8 +2777,8 @@ public class ImapStore extends RemoteStore {
}
protected boolean isIdleCapable() {
- if (K9.DEBUG)
- Log.v(K9.LOG_TAG, "Connection " + getLogId() + " has " + capabilities.size() + " capabilities");
+ if (K9MailLib.isDebug())
+ Log.v(LOG_TAG, "Connection " + getLogId() + " has " + capabilities.size() + " capabilities");
return capabilities.contains(CAPABILITY_IDLE);
}
@@ -2809,8 +2814,8 @@ public class ImapStore extends RemoteStore {
public ImapResponse readResponse(ImapResponseParser.IImapResponseCallback callback) throws IOException {
try {
ImapResponse response = mParser.readResponse(callback);
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_IMAP)
- Log.v(K9.LOG_TAG, getLogId() + "<<<" + response);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_IMAP)
+ Log.v(LOG_TAG, getLogId() + "<<<" + response);
return response;
} catch (IOException ioe) {
@@ -2825,8 +2830,8 @@ public class ImapStore extends RemoteStore {
mOut.write('\n');
mOut.flush();
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_IMAP)
- Log.v(K9.LOG_TAG, getLogId() + ">>> " + continuation);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_IMAP)
+ Log.v(LOG_TAG, getLogId() + ">>> " + continuation);
}
@@ -2839,12 +2844,12 @@ public class ImapStore extends RemoteStore {
mOut.write(commandToSend.getBytes());
mOut.flush();
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_IMAP) {
- if (sensitive && !K9.DEBUG_SENSITIVE) {
- Log.v(K9.LOG_TAG, getLogId() + ">>> "
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_IMAP) {
+ if (sensitive && !K9MailLib.isDebugSensitive()) {
+ Log.v(LOG_TAG, getLogId() + ">>> "
+ "[Command Hidden, Enable Sensitive Debug Logging To Show]");
} else {
- Log.v(K9.LOG_TAG, getLogId() + ">>> " + commandToSend);
+ Log.v(LOG_TAG, getLogId() + ">>> " + commandToSend);
}
}
@@ -2874,17 +2879,17 @@ public class ImapStore extends RemoteStore {
public List executeSimpleCommand(String command, boolean sensitive, UntaggedHandler untaggedHandler)
throws IOException, ImapException, MessagingException {
String commandToLog = command;
- if (sensitive && !K9.DEBUG_SENSITIVE) {
+ if (sensitive && !K9MailLib.isDebugSensitive()) {
commandToLog = "*sensitive*";
}
- //if (K9.DEBUG)
- // Log.v(K9.LOG_TAG, "Sending IMAP command " + commandToLog + " on connection " + getLogId());
+ //if (K9MailLib.isDebug())
+ // Log.v(LOG_TAG, "Sending IMAP command " + commandToLog + " on connection " + getLogId());
String tag = sendCommand(command, sensitive);
- //if (K9.DEBUG)
- // Log.v(K9.LOG_TAG, "Sent IMAP command " + commandToLog + " with tag " + tag + " for " + getLogId());
+ //if (K9MailLib.isDebug())
+ // Log.v(LOG_TAG, "Sent IMAP command " + commandToLog + " with tag " + tag + " for " + getLogId());
return readStatusResponse(tag, commandToLog, untaggedHandler);
}
@@ -2954,7 +2959,7 @@ public class ImapStore extends RemoteStore {
}
public void refresh() throws IOException, MessagingException {
if (idling.get()) {
- wakeLock.acquire(K9.PUSH_WAKE_LOCK_TIMEOUT);
+ wakeLock.acquire(PUSH_WAKE_LOCK_TIMEOUT);
sendDone();
}
}
@@ -2982,9 +2987,9 @@ public class ImapStore extends RemoteStore {
Runnable runner = new Runnable() {
@Override
public void run() {
- wakeLock.acquire(K9.PUSH_WAKE_LOCK_TIMEOUT);
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Pusher starting for " + getLogId());
+ wakeLock.acquire(PUSH_WAKE_LOCK_TIMEOUT);
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Pusher starting for " + getLogId());
long lastUidNext = -1L;
while (!stop.get()) {
@@ -2994,10 +2999,10 @@ public class ImapStore extends RemoteStore {
String pushStateS = receiver.getPushState(getName());
ImapPushState pushState = ImapPushState.parse(pushStateS);
oldUidNext = pushState.uidNext;
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Got oldUidNext " + oldUidNext + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Got oldUidNext " + oldUidNext + " for " + getLogId());
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Unable to get oldUidNext for " + getLogId(), e);
+ Log.e(LOG_TAG, "Unable to get oldUidNext for " + getLogId(), e);
}
/*
@@ -3042,16 +3047,16 @@ public class ImapStore extends RemoteStore {
long newUidNext = uidNext;
if (newUidNext == -1) {
- if (K9.DEBUG) {
- Log.d(K9.LOG_TAG, "uidNext is -1, using search to find highest UID");
+ if (K9MailLib.isDebug()) {
+ Log.d(LOG_TAG, "uidNext is -1, using search to find highest UID");
}
long highestUid = getHighestUid();
if (highestUid != -1L) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "highest UID = " + highestUid);
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "highest UID = " + highestUid);
newUidNext = highestUid + 1;
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "highest UID = " + highestUid
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "highest UID = " + highestUid
+ ", set newUidNext to " + newUidNext);
}
}
@@ -3066,8 +3071,8 @@ public class ImapStore extends RemoteStore {
lastUidNext = newUidNext;
if (newUidNext > startUid) {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Needs sync from uid " + startUid + " to " + newUidNext + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Needs sync from uid " + startUid + " to " + newUidNext + " for " + getLogId());
List messages = new ArrayList();
for (long uid = startUid; uid < newUidNext; uid++) {
ImapMessage message = new ImapMessage("" + uid, ImapFolderPusher.this);
@@ -3080,15 +3085,15 @@ public class ImapStore extends RemoteStore {
} else {
List untaggedResponses = null;
while (!storedUntaggedResponses.isEmpty()) {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Processing " + storedUntaggedResponses.size() + " untagged responses from previous commands for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Processing " + storedUntaggedResponses.size() + " untagged responses from previous commands for " + getLogId());
untaggedResponses = new ArrayList(storedUntaggedResponses);
storedUntaggedResponses.clear();
processUntaggedResponses(untaggedResponses);
}
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "About to IDLE for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "About to IDLE for " + getLogId());
receiver.setPushActive(getName(), true);
idling.set(true);
@@ -3101,20 +3106,20 @@ public class ImapStore extends RemoteStore {
idleFailureCount.set(0);
}
} catch (Exception e) {
- wakeLock.acquire(K9.PUSH_WAKE_LOCK_TIMEOUT);
+ wakeLock.acquire(PUSH_WAKE_LOCK_TIMEOUT);
storedUntaggedResponses.clear();
idling.set(false);
receiver.setPushActive(getName(), false);
try {
close();
} catch (Exception me) {
- Log.e(K9.LOG_TAG, "Got exception while closing for exception for " + getLogId(), me);
+ Log.e(LOG_TAG, "Got exception while closing for exception for " + getLogId(), me);
}
if (stop.get()) {
- Log.i(K9.LOG_TAG, "Got exception while idling, but stop is set for " + getLogId());
+ Log.i(LOG_TAG, "Got exception while idling, but stop is set for " + getLogId());
} else {
receiver.pushError("Push error for " + getName(), e);
- Log.e(K9.LOG_TAG, "Got exception while idling for " + getLogId(), e);
+ Log.e(LOG_TAG, "Got exception while idling for " + getLogId(), e);
int delayTimeInt = delayTime.get();
receiver.sleep(wakeLock, delayTimeInt);
delayTimeInt *= 2;
@@ -3123,7 +3128,7 @@ public class ImapStore extends RemoteStore {
}
delayTime.set(delayTimeInt);
if (idleFailureCount.incrementAndGet() > IDLE_FAILURE_COUNT_LIMIT) {
- Log.e(K9.LOG_TAG, "Disabling pusher for " + getLogId() + " after " + idleFailureCount.get() + " consecutive errors");
+ Log.e(LOG_TAG, "Disabling pusher for " + getLogId() + " after " + idleFailureCount.get() + " consecutive errors");
receiver.pushError("Push disabled for " + getName() + " after " + idleFailureCount.get() + " consecutive errors", e);
stop.set(true);
}
@@ -3133,11 +3138,11 @@ public class ImapStore extends RemoteStore {
}
receiver.setPushActive(getName(), false);
try {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Pusher for " + getLogId() + " is exiting");
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Pusher for " + getLogId() + " is exiting");
close();
} catch (Exception me) {
- Log.e(K9.LOG_TAG, "Got exception while closing for " + getLogId(), me);
+ Log.e(LOG_TAG, "Got exception while closing for " + getLogId(), me);
} finally {
wakeLock.release();
}
@@ -3154,8 +3159,8 @@ public class ImapStore extends RemoteStore {
if (ImapResponseParser.equalsIgnoreCase(responseType, "FETCH")
|| ImapResponseParser.equalsIgnoreCase(responseType, "EXPUNGE")
|| ImapResponseParser.equalsIgnoreCase(responseType, "EXISTS")) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Storing response " + response + " for later processing");
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Storing response " + response + " for later processing");
storedUntaggedResponses.add(response);
}
@@ -3183,8 +3188,8 @@ public class ImapStore extends RemoteStore {
syncMessages(mMessageCount, true);
}
}
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "UIDs for messages needing flag sync are " + flagSyncMsgSeqs + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "UIDs for messages needing flag sync are " + flagSyncMsgSeqs + " for " + getLogId());
if (!flagSyncMsgSeqs.isEmpty()) {
syncMessages(flagSyncMsgSeqs);
@@ -3200,17 +3205,17 @@ public class ImapStore extends RemoteStore {
String pushStateS = receiver.getPushState(getName());
ImapPushState pushState = ImapPushState.parse(pushStateS);
oldUidNext = pushState.uidNext;
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Got oldUidNext " + oldUidNext + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Got oldUidNext " + oldUidNext + " for " + getLogId());
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Unable to get oldUidNext for " + getLogId(), e);
+ Log.e(LOG_TAG, "Unable to get oldUidNext for " + getLogId(), e);
}
List extends Message> messageList = getMessages(end, end, null, true, null);
if (messageList != null && messageList.size() > 0) {
long newUid = Long.parseLong(messageList.get(0).getUid());
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Got newUid " + newUid + " for message " + end + " on " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Got newUid " + newUid + " for message " + end + " on " + getLogId());
long startUid = oldUidNext;
if (startUid < newUid - 10) {
startUid = newUid - 10;
@@ -3220,8 +3225,8 @@ public class ImapStore extends RemoteStore {
}
if (newUid >= startUid) {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Needs sync from uid " + startUid + " to " + newUid + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Needs sync from uid " + startUid + " to " + newUid + " for " + getLogId());
List messages = new ArrayList();
for (long uid = startUid; uid <= newUid; uid++) {
ImapMessage message = new ImapMessage(Long.toString(uid), ImapFolderPusher.this);
@@ -3256,7 +3261,7 @@ public class ImapStore extends RemoteStore {
needsPoll.set(true);
msgSeqUidMap.clear();
String existingUid = existingMessage.getUid();
- Log.w(K9.LOG_TAG, "Message with UID " + existingUid + " still exists on server, not expunging");
+ Log.w(LOG_TAG, "Message with UID " + existingUid + " still exists on server, not expunging");
removeUids.remove(existingUid);
}
for (String uid : removeUids) {
@@ -3264,13 +3269,13 @@ public class ImapStore extends RemoteStore {
try {
message.setFlagInternal(Flag.DELETED, true);
} catch (MessagingException me) {
- Log.e(K9.LOG_TAG, "Unable to set DELETED flag on message " + message.getUid());
+ Log.e(LOG_TAG, "Unable to set DELETED flag on message " + message.getUid());
}
messages.add(message);
}
receiver.messagesRemoved(this, messages);
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Cannot remove EXPUNGEd messages", e);
+ Log.e(LOG_TAG, "Cannot remove EXPUNGEd messages", e);
}
}
@@ -3282,11 +3287,11 @@ public class ImapStore extends RemoteStore {
try {
Object responseType = response.get(1);
if (ImapResponseParser.equalsIgnoreCase(responseType, "FETCH")) {
- Log.i(K9.LOG_TAG, "Got FETCH " + response);
+ Log.i(LOG_TAG, "Got FETCH " + response);
long msgSeq = response.getLong(0);
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got untagged FETCH for msgseq " + msgSeq + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got untagged FETCH for msgseq " + msgSeq + " for " + getLogId());
if (!flagSyncMsgSeqs.contains(msgSeq)) {
flagSyncMsgSeqs.add(msgSeq);
@@ -3297,8 +3302,8 @@ public class ImapStore extends RemoteStore {
if (msgSeq <= oldMessageCount) {
messageCountDelta = -1;
}
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got untagged EXPUNGE for msgseq " + msgSeq + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got untagged EXPUNGE for msgseq " + msgSeq + " for " + getLogId());
List newSeqs = new ArrayList();
Iterator flagIter = flagSyncMsgSeqs.iterator();
@@ -3318,20 +3323,20 @@ public class ImapStore extends RemoteStore {
Collections.sort(msgSeqs); // Have to do comparisons in order because of msgSeq reductions
for (long msgSeqNum : msgSeqs) {
- if (K9.DEBUG) {
- Log.v(K9.LOG_TAG, "Comparing EXPUNGEd msgSeq " + msgSeq + " to " + msgSeqNum);
+ if (K9MailLib.isDebug()) {
+ Log.v(LOG_TAG, "Comparing EXPUNGEd msgSeq " + msgSeq + " to " + msgSeqNum);
}
if (msgSeqNum == msgSeq) {
String uid = msgSeqUidMap.get(msgSeqNum);
- if (K9.DEBUG) {
- Log.d(K9.LOG_TAG, "Scheduling removal of UID " + uid + " because msgSeq " + msgSeqNum + " was expunged");
+ if (K9MailLib.isDebug()) {
+ Log.d(LOG_TAG, "Scheduling removal of UID " + uid + " because msgSeq " + msgSeqNum + " was expunged");
}
removeMsgUids.add(uid);
msgSeqUidMap.remove(msgSeqNum);
} else if (msgSeqNum > msgSeq) {
String uid = msgSeqUidMap.get(msgSeqNum);
- if (K9.DEBUG) {
- Log.d(K9.LOG_TAG, "Reducing msgSeq for UID " + uid + " from " + msgSeqNum + " to " + (msgSeqNum - 1));
+ if (K9MailLib.isDebug()) {
+ Log.d(LOG_TAG, "Reducing msgSeq for UID " + uid + " from " + msgSeqNum + " to " + (msgSeqNum - 1));
}
msgSeqUidMap.remove(msgSeqNum);
msgSeqUidMap.put(msgSeqNum - 1, uid);
@@ -3339,7 +3344,7 @@ public class ImapStore extends RemoteStore {
}
}
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Could not handle untagged FETCH for " + getLogId(), e);
+ Log.e(LOG_TAG, "Could not handle untagged FETCH for " + getLogId(), e);
}
}
return messageCountDelta;
@@ -3370,27 +3375,27 @@ public class ImapStore extends RemoteStore {
}
ImapConnection conn = mConnection;
if (conn != null) {
- if (K9.DEBUG)
- Log.v(K9.LOG_TAG, "Closing mConnection to stop pushing for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.v(LOG_TAG, "Closing mConnection to stop pushing for " + getLogId());
conn.close();
} else {
- Log.w(K9.LOG_TAG, "Attempt to interrupt null mConnection to stop pushing on folderPusher for " + getLogId());
+ Log.w(LOG_TAG, "Attempt to interrupt null mConnection to stop pushing on folderPusher for " + getLogId());
}
}
@Override
public void handleAsyncUntaggedResponse(ImapResponse response) {
- if (K9.DEBUG)
- Log.v(K9.LOG_TAG, "Got async response: " + response);
+ if (K9MailLib.isDebug())
+ Log.v(LOG_TAG, "Got async response: " + response);
if (stop.get()) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got async untagged response: " + response + ", but stop is set for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got async untagged response: " + response + ", but stop is set for " + getLogId());
try {
sendDone();
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Exception while sending DONE for " + getLogId(), e);
+ Log.e(LOG_TAG, "Exception while sending DONE for " + getLogId(), e);
}
} else {
if (response.mTag == null) {
@@ -3400,22 +3405,22 @@ public class ImapStore extends RemoteStore {
if (ImapResponseParser.equalsIgnoreCase(responseType, "EXISTS") || ImapResponseParser.equalsIgnoreCase(responseType, "EXPUNGE") ||
ImapResponseParser.equalsIgnoreCase(responseType, "FETCH")) {
if (!started) {
- wakeLock.acquire(K9.PUSH_WAKE_LOCK_TIMEOUT);
+ wakeLock.acquire(PUSH_WAKE_LOCK_TIMEOUT);
started = true;
}
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Got useful async untagged response: " + response + " for " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Got useful async untagged response: " + response + " for " + getLogId());
try {
sendDone();
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Exception while sending DONE for " + getLogId(), e);
+ Log.e(LOG_TAG, "Exception while sending DONE for " + getLogId(), e);
}
}
} else if (response.mCommandContinuationRequested) {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, "Idling " + getLogId());
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, "Idling " + getLogId());
wakeLock.release();
}
@@ -3463,7 +3468,7 @@ public class ImapStore extends RemoteStore {
try {
folderPusher.refresh();
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Got exception while refreshing for " + folderPusher.getName(), e);
+ Log.e(LOG_TAG, "Got exception while refreshing for " + folderPusher.getName(), e);
}
}
}
@@ -3471,17 +3476,17 @@ public class ImapStore extends RemoteStore {
@Override
public void stop() {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Requested stop of IMAP pusher");
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Requested stop of IMAP pusher");
synchronized (folderPushers) {
for (ImapFolderPusher folderPusher : folderPushers.values()) {
try {
- if (K9.DEBUG)
- Log.i(K9.LOG_TAG, "Requesting stop of IMAP folderPusher " + folderPusher.getName());
+ if (K9MailLib.isDebug())
+ Log.i(LOG_TAG, "Requesting stop of IMAP folderPusher " + folderPusher.getName());
folderPusher.stop();
} catch (Exception e) {
- Log.e(K9.LOG_TAG, "Got exception while stopping " + folderPusher.getName(), e);
+ Log.e(LOG_TAG, "Got exception while stopping " + folderPusher.getName(), e);
}
}
folderPushers.clear();
@@ -3527,7 +3532,7 @@ public class ImapStore extends RemoteStore {
try {
newUidNext = Long.parseLong(value);
} catch (NumberFormatException e) {
- Log.e(K9.LOG_TAG, "Unable to part uidNext value " + value, e);
+ Log.e(LOG_TAG, "Unable to part uidNext value " + value, e);
}
}
diff --git a/src/com/fsck/k9/mail/store/ImapUtility.java b/src/com/fsck/k9/mail/store/ImapUtility.java
index 971f098cd..bd3b12a74 100644
--- a/src/com/fsck/k9/mail/store/ImapUtility.java
+++ b/src/com/fsck/k9/mail/store/ImapUtility.java
@@ -19,11 +19,11 @@ package com.fsck.k9.mail.store;
import android.util.Log;
-import com.fsck.k9.K9;
-
import java.util.ArrayList;
import java.util.List;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
/**
* Utility methods for use with IMAP.
*/
@@ -101,12 +101,12 @@ class ImapUtility {
}
}
} else {
- Log.d(K9.LOG_TAG, "Invalid range: " + range);
+ Log.d(LOG_TAG, "Invalid range: " + range);
}
}
}
} catch (NumberFormatException e) {
- Log.d(K9.LOG_TAG, "Invalid range value: " + range, e);
+ Log.d(LOG_TAG, "Invalid range value: " + range, e);
}
return list;
@@ -122,7 +122,7 @@ class ImapUtility {
// do nothing
}
- Log.d(K9.LOG_TAG, "Invalid UID value: " + number);
+ Log.d(LOG_TAG, "Invalid UID value: " + number);
return false;
}
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index b2d687fce..73366e4ae 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -31,6 +31,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import static com.fsck.k9.mail.K9MailLib.DEBUG_PROTOCOL_POP3;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
public class Pop3Store extends RemoteStore {
public static final String STORE_TYPE = "POP3";
@@ -631,7 +634,7 @@ public class Pop3Store extends RemoteStore {
// response = "+OK msgNum msgUid"
String[] uidParts = response.split(" +");
if (uidParts.length < 3 || !"+OK".equals(uidParts[0])) {
- Log.e(K9.LOG_TAG, "ERR response: " + response);
+ Log.e(LOG_TAG, "ERR response: " + response);
return;
}
String msgUid = uidParts[2];
@@ -689,8 +692,8 @@ public class Pop3Store extends RemoteStore {
Set unindexedUids = new HashSet();
for (String uid : uids) {
if (mUidToMsgMap.get(uid) == null) {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3) {
- Log.d(K9.LOG_TAG, "Need to index UID " + uid);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_POP3) {
+ Log.d(LOG_TAG, "Need to index UID " + uid);
}
unindexedUids.add(uid);
}
@@ -715,8 +718,8 @@ public class Pop3Store extends RemoteStore {
Integer msgNum = Integer.valueOf(uidParts[0]);
String msgUid = uidParts[1];
if (unindexedUids.contains(msgUid)) {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3) {
- Log.d(K9.LOG_TAG, "Got msgNum " + msgNum + " for UID " + msgUid);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_POP3) {
+ Log.d(LOG_TAG, "Got msgNum " + msgNum + " for UID " + msgUid);
}
Pop3Message message = mUidToMsgMap.get(msgUid);
@@ -730,8 +733,8 @@ public class Pop3Store extends RemoteStore {
}
private void indexMessage(int msgNum, Pop3Message message) {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3) {
- Log.d(K9.LOG_TAG, "Adding index for UID " + message.getUid() + " to msgNum " + msgNum);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_POP3) {
+ Log.d(LOG_TAG, "Adding index for UID " + message.getUid() + " to msgNum " + msgNum);
}
mMsgNumToMsgMap.put(msgNum, message);
mUidToMsgMap.put(message.getUid(), message);
@@ -902,8 +905,8 @@ public class Pop3Store extends RemoteStore {
// Try hard to use the TOP command if we're not asked to download the whole message.
if (lines != -1 && (!mTopNotSupported || mCapabilities.top)) {
try {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3 && !mCapabilities.top) {
- Log.d(K9.LOG_TAG, "This server doesn't support the CAPA command. " +
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_POP3 && !mCapabilities.top) {
+ Log.d(LOG_TAG, "This server doesn't support the CAPA command. " +
"Checking to see if the TOP command is supported nevertheless.");
}
@@ -917,8 +920,8 @@ public class Pop3Store extends RemoteStore {
// The TOP command should be supported but something went wrong.
throw e;
} else {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3) {
- Log.d(K9.LOG_TAG, "The server really doesn't support the TOP " +
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_POP3) {
+ Log.d(LOG_TAG, "The server really doesn't support the TOP " +
"command. Using RETR instead.");
}
@@ -1025,8 +1028,8 @@ public class Pop3Store extends RemoteStore {
}
} while ((d = mIn.read()) != -1);
String ret = sb.toString();
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3) {
- Log.d(K9.LOG_TAG, "<<< " + ret);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_POP3) {
+ Log.d(LOG_TAG, "<<< " + ret);
}
return ret;
}
@@ -1118,12 +1121,12 @@ public class Pop3Store extends RemoteStore {
open(Folder.OPEN_MODE_RW);
if (command != null) {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3) {
- if (sensitive && !K9.DEBUG_SENSITIVE) {
- Log.d(K9.LOG_TAG, ">>> "
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_POP3) {
+ if (sensitive && !K9MailLib.isDebugSensitive()) {
+ Log.d(LOG_TAG, ">>> "
+ "[Command Hidden, Enable Sensitive Debug Logging To Show]");
} else {
- Log.d(K9.LOG_TAG, ">>> " + command);
+ Log.d(LOG_TAG, ">>> " + command);
}
}
@@ -1195,7 +1198,7 @@ public class Pop3Store extends RemoteStore {
// }
// catch (MessagingException me)
// {
-// Log.w(K9.LOG_TAG, "Could not delete non-existent message", me);
+// Log.w(LOG_TAG, "Could not delete non-existent message", me);
// }
}
}
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index f1202ff45..9944c6a9e 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -2,8 +2,6 @@ package com.fsck.k9.mail.store;
import android.util.Log;
-import com.fsck.k9.K9;
-
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
@@ -47,6 +45,9 @@ import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.GZIPInputStream;
+import static com.fsck.k9.mail.K9MailLib.DEBUG_PROTOCOL_WEBDAV;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
/**
*
* Uses WebDAV formatted HTTP calls to an MS Exchange server to fetch email
@@ -719,7 +720,7 @@ public class WebDavStore extends RemoteStore {
doFBA(null);
}
} catch (IOException ioe) {
- Log.e(K9.LOG_TAG, "Error during authentication: " + ioe + "\nStack: " + processException(ioe));
+ Log.e(LOG_TAG, "Error during authentication: " + ioe + "\nStack: " + processException(ioe));
throw new MessagingException("Error during authentication", ioe);
}
@@ -789,7 +790,7 @@ public class WebDavStore extends RemoteStore {
} catch (SSLException e) {
throw new CertificateValidationException(e.getMessage(), e);
} catch (IOException ioe) {
- Log.e(K9.LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
+ Log.e(LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
throw new MessagingException("IOException", ioe);
}
@@ -891,7 +892,7 @@ public class WebDavStore extends RemoteStore {
response = httpClient.executeOverride(request, mContext);
authenticated = testAuthenticationResponse(response);
} catch (URISyntaxException e) {
- Log.e(K9.LOG_TAG, "URISyntaxException caught " + e + "\nTrace: " + processException(e));
+ Log.e(LOG_TAG, "URISyntaxException caught " + e + "\nTrace: " + processException(e));
throw new MessagingException("URISyntaxException caught", e);
}
} else {
@@ -985,7 +986,7 @@ public class WebDavStore extends RemoteStore {
}
}
} catch (URISyntaxException e) {
- Log.e(K9.LOG_TAG, "URISyntaxException caught " + e + "\nTrace: " + processException(e));
+ Log.e(LOG_TAG, "URISyntaxException caught " + e + "\nTrace: " + processException(e));
throw new MessagingException("URISyntaxException caught", e);
}
}
@@ -1022,10 +1023,10 @@ public class WebDavStore extends RemoteStore {
Scheme s = new Scheme("https", new WebDavSocketFactory(mHost, 443), 443);
reg.register(s);
} catch (NoSuchAlgorithmException nsa) {
- Log.e(K9.LOG_TAG, "NoSuchAlgorithmException in getHttpClient: " + nsa);
+ Log.e(LOG_TAG, "NoSuchAlgorithmException in getHttpClient: " + nsa);
throw new MessagingException("NoSuchAlgorithmException in getHttpClient: " + nsa);
} catch (KeyManagementException kme) {
- Log.e(K9.LOG_TAG, "KeyManagementException in getHttpClient: " + kme);
+ Log.e(LOG_TAG, "KeyManagementException in getHttpClient: " + kme);
throw new MessagingException("KeyManagementException in getHttpClient: " + kme);
}
}
@@ -1092,10 +1093,10 @@ public class WebDavStore extends RemoteStore {
istream = WebDavHttpClient.getUngzippedContent(entity);
}
} catch (UnsupportedEncodingException uee) {
- Log.e(K9.LOG_TAG, "UnsupportedEncodingException: " + uee + "\nTrace: " + processException(uee));
+ Log.e(LOG_TAG, "UnsupportedEncodingException: " + uee + "\nTrace: " + processException(uee));
throw new MessagingException("UnsupportedEncodingException", uee);
} catch (IOException ioe) {
- Log.e(K9.LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
+ Log.e(LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
throw new MessagingException("IOException", ioe);
}
@@ -1120,8 +1121,8 @@ public class WebDavStore extends RemoteStore {
boolean needsParsing)
throws MessagingException {
DataSet dataset = new DataSet();
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_WEBDAV) {
- Log.v(K9.LOG_TAG, "processRequest url = '" + url + "', method = '" + method + "', messageBody = '"
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_WEBDAV) {
+ Log.v(LOG_TAG, "processRequest url = '" + url + "', method = '" + method + "', messageBody = '"
+ messageBody + "'");
}
@@ -1153,10 +1154,10 @@ public class WebDavStore extends RemoteStore {
dataset = myHandler.getDataSet();
} catch (SAXException se) {
- Log.e(K9.LOG_TAG, "SAXException in processRequest() " + se + "\nTrace: " + processException(se));
+ Log.e(LOG_TAG, "SAXException in processRequest() " + se + "\nTrace: " + processException(se));
throw new MessagingException("SAXException in processRequest() ", se);
} catch (ParserConfigurationException pce) {
- Log.e(K9.LOG_TAG, "ParserConfigurationException in processRequest() " + pce + "\nTrace: "
+ Log.e(LOG_TAG, "ParserConfigurationException in processRequest() " + pce + "\nTrace: "
+ processException(pce));
throw new MessagingException("ParserConfigurationException in processRequest() ", pce);
}
@@ -1164,10 +1165,10 @@ public class WebDavStore extends RemoteStore {
istream.close();
}
} catch (UnsupportedEncodingException uee) {
- Log.e(K9.LOG_TAG, "UnsupportedEncodingException: " + uee + "\nTrace: " + processException(uee));
+ Log.e(LOG_TAG, "UnsupportedEncodingException: " + uee + "\nTrace: " + processException(uee));
throw new MessagingException("UnsupportedEncodingException in processRequest() ", uee);
} catch (IOException ioe) {
- Log.e(K9.LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
+ Log.e(LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
throw new MessagingException("IOException in processRequest() ", ioe);
}
@@ -1308,7 +1309,7 @@ public class WebDavStore extends RemoteStore {
headers.put("Brief", "t");
headers.put("If-Match", "*");
String action = (isMove ? "BMOVE" : "BCOPY");
- Log.i(K9.LOG_TAG, "Moving " + messages.size() + " messages to " + destFolder.mFolderUrl);
+ Log.i(LOG_TAG, "Moving " + messages.size() + " messages to " + destFolder.mFolderUrl);
processRequest(mFolderUrl, action, messageBody, headers, false);
}
@@ -1331,8 +1332,8 @@ public class WebDavStore extends RemoteStore {
if (dataset != null) {
messageCount = dataset.getMessageCount();
}
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_WEBDAV) {
- Log.v(K9.LOG_TAG, "Counted messages and webdav returned: "+messageCount);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_WEBDAV) {
+ Log.v(LOG_TAG, "Counted messages and webdav returned: "+messageCount);
}
return messageCount;
@@ -1559,7 +1560,7 @@ public class WebDavStore extends RemoteStore {
*/
if (wdMessage.getUrl().equals("")) {
wdMessage.setUrl(getMessageUrls(new String[] { wdMessage.getUid() }).get(wdMessage.getUid()));
- Log.i(K9.LOG_TAG, "Fetching messages with UID = '" + wdMessage.getUid() + "', URL = '"
+ Log.i(LOG_TAG, "Fetching messages with UID = '" + wdMessage.getUid() + "', URL = '"
+ wdMessage.getUrl() + "'");
if (wdMessage.getUrl().equals("")) {
throw new MessagingException("Unable to get URL for message");
@@ -1567,7 +1568,7 @@ public class WebDavStore extends RemoteStore {
}
try {
- Log.i(K9.LOG_TAG, "Fetching message with UID = '" + wdMessage.getUid() + "', URL = '"
+ Log.i(LOG_TAG, "Fetching message with UID = '" + wdMessage.getUid() + "', URL = '"
+ wdMessage.getUrl() + "'");
HttpGet httpget = new HttpGet(new URI(wdMessage.getUrl()));
HttpResponse response;
@@ -1623,13 +1624,13 @@ public class WebDavStore extends RemoteStore {
}
} catch (IllegalArgumentException iae) {
- Log.e(K9.LOG_TAG, "IllegalArgumentException caught " + iae + "\nTrace: " + processException(iae));
+ Log.e(LOG_TAG, "IllegalArgumentException caught " + iae + "\nTrace: " + processException(iae));
throw new MessagingException("IllegalArgumentException caught", iae);
} catch (URISyntaxException use) {
- Log.e(K9.LOG_TAG, "URISyntaxException caught " + use + "\nTrace: " + processException(use));
+ Log.e(LOG_TAG, "URISyntaxException caught " + use + "\nTrace: " + processException(use));
throw new MessagingException("URISyntaxException caught", use);
} catch (IOException ioe) {
- Log.e(K9.LOG_TAG, "Non-success response code loading message, response code was " + statusCode
+ Log.e(LOG_TAG, "Non-success response code loading message, response code was " + statusCode
+ "\nURL: " + wdMessage.getUrl() + "\nError: " + ioe.getMessage() + "\nTrace: "
+ processException(ioe));
throw new MessagingException("Failure code " + statusCode, ioe);
@@ -1700,7 +1701,7 @@ public class WebDavStore extends RemoteStore {
try {
wdMessage.setFlagInternal(Flag.SEEN, uidToReadStatus.get(wdMessage.getUid()));
} catch (NullPointerException e) {
- Log.v(K9.LOG_TAG,"Under some weird circumstances, setting the read status when syncing from webdav threw an NPE. Skipping.");
+ Log.v(LOG_TAG,"Under some weird circumstances, setting the read status when syncing from webdav threw an NPE. Skipping.");
}
if (listener != null) {
@@ -1769,7 +1770,7 @@ public class WebDavStore extends RemoteStore {
wdMessage.setNewHeaders(envelope);
wdMessage.setFlagInternal(Flag.SEEN, envelope.getReadStatus());
} else {
- Log.e(K9.LOG_TAG,"Asked to get metadata for a non-existent message: "+wdMessage.getUid());
+ Log.e(LOG_TAG,"Asked to get metadata for a non-existent message: "+wdMessage.getUid());
}
if (listener != null) {
@@ -1881,7 +1882,7 @@ public class WebDavStore extends RemoteStore {
}
messageURL += encodeUtf8(message.getUid() + ":" + System.currentTimeMillis() + ".eml");
- Log.i(K9.LOG_TAG, "Uploading message as " + messageURL);
+ Log.i(LOG_TAG, "Uploading message as " + messageURL);
httpmethod = new HttpGeneric(messageURL);
httpmethod.setMethod("PUT");
@@ -1920,7 +1921,7 @@ public class WebDavStore extends RemoteStore {
@Override
public String getUidFromMessageId(Message message) throws MessagingException {
- Log.e(K9.LOG_TAG,
+ Log.e(LOG_TAG,
"Unimplemented method getUidFromMessageId in WebDavStore.WebDavFolder could lead to duplicate messages "
+ " being uploaded to the Sent folder");
return null;
@@ -1928,7 +1929,7 @@ public class WebDavStore extends RemoteStore {
@Override
public void setFlags(final Set flags, boolean value) throws MessagingException {
- Log.e(K9.LOG_TAG,
+ Log.e(LOG_TAG,
"Unimplemented method setFlags(Set, boolean) breaks markAllMessagesAsRead and EmptyTrash");
// Try to make this efficient by not retrieving all of the messages
}
@@ -1970,7 +1971,7 @@ public class WebDavStore extends RemoteStore {
end = encodeUtf8(end);
end = end.replaceAll("\\+", "%20");
} catch (IllegalArgumentException iae) {
- Log.e(K9.LOG_TAG, "IllegalArgumentException caught in setUrl: " + iae + "\nTrace: "
+ Log.e(LOG_TAG, "IllegalArgumentException caught in setUrl: " + iae + "\nTrace: "
+ processException(iae));
}
@@ -2020,7 +2021,7 @@ public class WebDavStore extends RemoteStore {
@Override
public void delete(String trashFolderName) throws MessagingException {
WebDavFolder wdFolder = (WebDavFolder) getFolder();
- Log.i(K9.LOG_TAG, "Deleting message by moving to " + trashFolderName);
+ Log.i(LOG_TAG, "Deleting message by moving to " + trashFolderName);
wdFolder.moveMessages(Collections.singletonList(this), wdFolder.getStore().getFolder(trashFolderName));
}
@@ -2318,7 +2319,7 @@ public class WebDavStore extends RemoteStore {
Date parsedDate = dfInput.parse(date);
tempDate = dfOutput.format(parsedDate);
} catch (java.text.ParseException pe) {
- Log.e(K9.LOG_TAG, "Error parsing date: " + pe + "\nTrace: " + processException(pe));
+ Log.e(LOG_TAG, "Error parsing date: " + pe + "\nTrace: " + processException(pe));
}
envelope.addHeader(header, tempDate);
} else {
@@ -2357,8 +2358,8 @@ public class WebDavStore extends RemoteStore {
public HttpGeneric(final String uri) {
super();
- if (K9.DEBUG) {
- Log.v(K9.LOG_TAG, "Starting uri = '" + uri + "'");
+ if (K9MailLib.isDebug()) {
+ Log.v(LOG_TAG, "Starting uri = '" + uri + "'");
}
String[] urlParts = uri.split("/");
@@ -2376,7 +2377,7 @@ public class WebDavStore extends RemoteStore {
end = end.replaceAll("\\+", "%20");
}
} catch (IllegalArgumentException iae) {
- Log.e(K9.LOG_TAG, "IllegalArgumentException caught in HttpGeneric(String uri): " + iae + "\nTrace: "
+ Log.e(LOG_TAG, "IllegalArgumentException caught in HttpGeneric(String uri): " + iae + "\nTrace: "
+ processException(iae));
}
@@ -2387,13 +2388,13 @@ public class WebDavStore extends RemoteStore {
url = urlParts[i];
}
}
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_WEBDAV) {
- Log.v(K9.LOG_TAG, "url = '" + url + "' length = " + url.length()
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_WEBDAV) {
+ Log.v(LOG_TAG, "url = '" + url + "' length = " + url.length()
+ ", end = '" + end + "' length = " + end.length());
}
url = url + "/" + end;
- Log.i(K9.LOG_TAG, "url = " + url);
+ Log.i(LOG_TAG, "url = " + url);
setURI(URI.create(url));
}
@@ -2423,7 +2424,7 @@ public class WebDavStore extends RemoteStore {
* the License for the specific language governing permissions and limitations under the License.
*/
public static void modifyRequestToAcceptGzipResponse(HttpRequest request) {
- Log.i(K9.LOG_TAG, "Requesting gzipped data");
+ Log.i(LOG_TAG, "Requesting gzipped data");
request.addHeader("Accept-Encoding", "gzip");
}
@@ -2439,7 +2440,7 @@ public class WebDavStore extends RemoteStore {
if (contentEncoding == null)
return responseStream;
if (contentEncoding.contains("gzip")) {
- Log.i(K9.LOG_TAG, "Response is gzipped");
+ Log.i(LOG_TAG, "Response is gzipped");
responseStream = new GZIPInputStream(responseStream);
}
return responseStream;
diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java
index 29fae5f1c..485e45f02 100644
--- a/src/com/fsck/k9/mail/transport/SmtpTransport.java
+++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java
@@ -26,6 +26,9 @@ import java.net.*;
import java.security.GeneralSecurityException;
import java.util.*;
+import static com.fsck.k9.mail.K9MailLib.DEBUG_PROTOCOL_SMTP;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
public class SmtpTransport extends Transport {
public static final String TRANSPORT_TYPE = "SMTP";
@@ -303,8 +306,8 @@ public class SmtpTransport extends Transport {
try {
mLargestAcceptableMessage = Integer.parseInt(extensions.get("SIZE"));
} catch (Exception e) {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) {
- Log.d(K9.LOG_TAG, "Tried to parse " + extensions.get("SIZE") + " and get an int", e);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_SMTP) {
+ Log.d(LOG_TAG, "Tried to parse " + extensions.get("SIZE") + " and get an int", e);
}
}
}
@@ -436,14 +439,14 @@ public class SmtpTransport extends Transport {
extensions.put(pair[0].toUpperCase(Locale.US), pair.length == 1 ? "" : pair[1]);
}
} catch (NegativeSmtpReplyException e) {
- if (K9.DEBUG) {
- Log.v(K9.LOG_TAG, "Server doesn't support the EHLO command. Trying HELO...");
+ if (K9MailLib.isDebug()) {
+ Log.v(LOG_TAG, "Server doesn't support the EHLO command. Trying HELO...");
}
try {
executeSimpleCommand("HELO " + host);
} catch (NegativeSmtpReplyException e2) {
- Log.w(K9.LOG_TAG, "Server doesn't support the HELO command. Continuing anyway.");
+ Log.w(LOG_TAG, "Server doesn't support the HELO command. Continuing anyway.");
}
}
return extensions;
@@ -527,7 +530,7 @@ public class SmtpTransport extends Transport {
// "5xx text" -responses are permanent failures
String msg = e.getMessage();
if (msg != null && msg.startsWith("5")) {
- Log.w(K9.LOG_TAG, "handling 5xx SMTP error code as a permanent failure");
+ Log.w(LOG_TAG, "handling 5xx SMTP error code as a permanent failure");
possibleSend = false;
}
@@ -580,21 +583,21 @@ public class SmtpTransport extends Transport {
}
}
String ret = sb.toString();
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP)
- Log.d(K9.LOG_TAG, "SMTP <<< " + ret);
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_SMTP)
+ Log.d(LOG_TAG, "SMTP <<< " + ret);
return ret;
}
private void writeLine(String s, boolean sensitive) throws IOException {
- if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) {
+ if (K9MailLib.isDebug() && DEBUG_PROTOCOL_SMTP) {
final String commandToLog;
- if (sensitive && !K9.DEBUG_SENSITIVE) {
+ if (sensitive && !K9MailLib.isDebugSensitive()) {
commandToLog = "SMTP >>> *sensitive*";
} else {
commandToLog = "SMTP >>> " + s;
}
- Log.d(K9.LOG_TAG, commandToLog);
+ Log.d(LOG_TAG, commandToLog);
}
byte[] data = s.concat("\r\n").getBytes();
diff --git a/src/com/fsck/k9/mail/transport/WebDavTransport.java b/src/com/fsck/k9/mail/transport/WebDavTransport.java
index 839ec00d9..2693aa8c4 100644
--- a/src/com/fsck/k9/mail/transport/WebDavTransport.java
+++ b/src/com/fsck/k9/mail/transport/WebDavTransport.java
@@ -3,7 +3,7 @@ package com.fsck.k9.mail.transport;
import android.util.Log;
-import com.fsck.k9.K9;
+import com.fsck.k9.mail.K9MailLib;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.ServerSettings;
@@ -13,6 +13,8 @@ import com.fsck.k9.mail.store.WebDavStore;
import java.util.Collections;
+import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
+
public class WebDavTransport extends Transport {
public static final String TRANSPORT_TYPE = WebDavStore.STORE_TYPE;
@@ -46,14 +48,14 @@ public class WebDavTransport extends Transport {
public WebDavTransport(StoreConfig storeConfig) throws MessagingException {
store = new WebDavStore(storeConfig);
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, ">>> New WebDavTransport creation complete");
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, ">>> New WebDavTransport creation complete");
}
@Override
public void open() throws MessagingException {
- if (K9.DEBUG)
- Log.d(K9.LOG_TAG, ">>> open called on WebDavTransport ");
+ if (K9MailLib.isDebug())
+ Log.d(LOG_TAG, ">>> open called on WebDavTransport ");
store.getHttpClient();
}