Merge pull request #4478 from k9mail/bye_Folder

Get rid of base class Folder
This commit is contained in:
cketti 2020-01-28 17:16:40 +01:00 committed by GitHub
commit 5c3750ede3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 304 additions and 978 deletions

View file

@ -1,8 +1,8 @@
package com.fsck.k9.backend.imap
import com.fsck.k9.mail.Flag
import com.fsck.k9.mail.Folder
import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mail.store.imap.ImapFolder
import com.fsck.k9.mail.store.imap.ImapStore
internal class CommandDeleteAll(private val imapStore: ImapStore) {
@ -15,7 +15,7 @@ internal class CommandDeleteAll(private val imapStore: ImapStore) {
}
try {
remoteFolder.open(Folder.OPEN_MODE_RW)
remoteFolder.open(ImapFolder.OPEN_MODE_RW)
remoteFolder.setFlags(setOf(Flag.DELETED), true)
} finally {
remoteFolder.close()

View file

@ -3,8 +3,8 @@ package com.fsck.k9.backend.imap;
import java.util.List;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.imap.ImapFolder;
import com.fsck.k9.mail.store.imap.ImapStore;
import org.jetbrains.annotations.NotNull;
import timber.log.Timber;
@ -21,13 +21,13 @@ class CommandExpunge {
void expunge(@NotNull String folderServerId) throws MessagingException {
Timber.d("processPendingExpunge: folder = %s", folderServerId);
Folder remoteFolder = imapStore.getFolder(folderServerId);
ImapFolder remoteFolder = imapStore.getFolder(folderServerId);
try {
if (!remoteFolder.exists()) {
return;
}
remoteFolder.open(Folder.OPEN_MODE_RW);
if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
remoteFolder.open(ImapFolder.OPEN_MODE_RW);
if (remoteFolder.getMode() != ImapFolder.OPEN_MODE_RW) {
return;
}
remoteFolder.expunge();
@ -40,13 +40,13 @@ class CommandExpunge {
void expungeMessages(@NotNull String folderServerId, @NotNull List<String> messageServerIds)
throws MessagingException {
Folder remoteFolder = imapStore.getFolder(folderServerId);
ImapFolder remoteFolder = imapStore.getFolder(folderServerId);
try {
if (!remoteFolder.exists()) {
return;
}
remoteFolder.open(Folder.OPEN_MODE_RW);
if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
remoteFolder.open(ImapFolder.OPEN_MODE_RW);
if (remoteFolder.getMode() != ImapFolder.OPEN_MODE_RW) {
return;
}
remoteFolder.expungeUids(messageServerIds);

View file

@ -2,7 +2,6 @@ package com.fsck.k9.backend.imap
import com.fsck.k9.mail.BodyFactory
import com.fsck.k9.mail.FetchProfile
import com.fsck.k9.mail.Folder
import com.fsck.k9.mail.Message
import com.fsck.k9.mail.Part
import com.fsck.k9.mail.store.imap.ImapFolder
@ -14,7 +13,7 @@ internal class CommandFetchMessage(private val imapStore: ImapStore) {
fun fetchMessage(folderServerId: String, messageServerId: String, fetchProfile: FetchProfile): Message {
val folder = imapStore.getFolder(folderServerId)
try {
folder.open(Folder.OPEN_MODE_RO)
folder.open(ImapFolder.OPEN_MODE_RO)
val message = folder.getMessage(messageServerId)
@ -39,7 +38,7 @@ internal class CommandFetchMessage(private val imapStore: ImapStore) {
fun fetchPart(folderServerId: String, messageServerId: String, part: Part, bodyFactory: BodyFactory) {
val folder = imapStore.getFolder(folderServerId)
try {
folder.open(Folder.OPEN_MODE_RW)
folder.open(ImapFolder.OPEN_MODE_RW)
val message = folder.getMessage(messageServerId)
folder.fetchPart(message, part, null, bodyFactory)

View file

@ -1,6 +1,6 @@
package com.fsck.k9.backend.imap
import com.fsck.k9.mail.Folder
import com.fsck.k9.mail.store.imap.ImapFolder
import com.fsck.k9.mail.store.imap.ImapStore
internal class CommandFindByMessageId(private val imapStore: ImapStore) {
@ -8,7 +8,7 @@ internal class CommandFindByMessageId(private val imapStore: ImapStore) {
fun findByMessageId(folderServerId: String, messageId: String): String? {
val folder = imapStore.getFolder(folderServerId)
try {
folder.open(Folder.OPEN_MODE_RW)
folder.open(ImapFolder.OPEN_MODE_RW)
return folder.getUidFromMessageId(messageId)
} finally {
folder.close()

View file

@ -4,7 +4,6 @@ package com.fsck.k9.backend.imap;
import java.util.Collections;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.imap.ImapFolder;
import com.fsck.k9.mail.store.imap.ImapStore;
@ -26,8 +25,8 @@ class CommandMarkAllAsRead {
}
try {
remoteFolder.open(Folder.OPEN_MODE_RW);
if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
remoteFolder.open(ImapFolder.OPEN_MODE_RW);
if (remoteFolder.getMode() != ImapFolder.OPEN_MODE_RW) {
return;
}

View file

@ -7,7 +7,6 @@ import java.util.List;
import java.util.Map;
import com.fsck.k9.backend.api.BackendFolder;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.imap.ImapFolder;
@ -61,8 +60,8 @@ class CommandMoveOrCopyMessages {
" does not exist", true);
}
remoteSrcFolder.open(Folder.OPEN_MODE_RW);
if (remoteSrcFolder.getMode() != Folder.OPEN_MODE_RW) {
remoteSrcFolder.open(ImapFolder.OPEN_MODE_RW);
if (remoteSrcFolder.getMode() != ImapFolder.OPEN_MODE_RW) {
throw new MessagingException("processingPendingMoveOrCopy: could not open remoteSrcFolder " +
srcFolder + " read/write", true);
}

View file

@ -7,7 +7,6 @@ import java.util.List;
import com.fsck.k9.backend.api.BackendFolder;
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.imap.ImapFolder;
@ -27,13 +26,13 @@ class CommandSetFlag {
boolean newState) throws MessagingException {
ImapFolder remoteFolder = imapStore.getFolder(folderServerId);
if (!remoteFolder.exists() || !remoteFolder.isFlagSupported(flag)) {
if (!remoteFolder.exists()) {
return;
}
try {
remoteFolder.open(Folder.OPEN_MODE_RW);
if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
remoteFolder.open(ImapFolder.OPEN_MODE_RW);
if (remoteFolder.getMode() != ImapFolder.OPEN_MODE_RW) {
return;
}
List<Message> messages = new ArrayList<>();

View file

@ -1,7 +1,7 @@
package com.fsck.k9.backend.imap
import com.fsck.k9.mail.Folder
import com.fsck.k9.mail.Message
import com.fsck.k9.mail.store.imap.ImapFolder
import com.fsck.k9.mail.store.imap.ImapStore
internal class CommandUploadMessage(private val imapStore: ImapStore) {
@ -9,7 +9,7 @@ internal class CommandUploadMessage(private val imapStore: ImapStore) {
fun uploadMessage(folderServerId: String, message: Message): String? {
val folder = imapStore.getFolder(folderServerId)
try {
folder.open(Folder.OPEN_MODE_RW)
folder.open(ImapFolder.OPEN_MODE_RW)
val localUid = message.uid
val uidMap = folder.appendMessages(listOf(message))

View file

@ -24,7 +24,6 @@ import com.fsck.k9.mail.BodyFactory;
import com.fsck.k9.mail.DefaultBodyFactory;
import com.fsck.k9.mail.FetchProfile;
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.Part;
@ -102,7 +101,7 @@ class ImapSync {
Timber.d("SYNC: Expunging folder %s:%s", accountName, folder);
remoteFolder.expunge();
}
remoteFolder.open(Folder.OPEN_MODE_RO);
remoteFolder.open(ImapFolder.OPEN_MODE_RO);
listener.syncAuthenticationSuccess();
@ -250,7 +249,7 @@ class ImapSync {
BackendFolder backendFolder = backendStorage.getFolder(folderServerId);
ImapFolder remoteFolder = imapStore.getFolder(folderServerId);
try {
remoteFolder.open(Folder.OPEN_MODE_RO);
remoteFolder.open(ImapFolder.OPEN_MODE_RO);
ImapMessage remoteMessage = remoteFolder.getMessage(messageServerId);
downloadMessages(

View file

@ -14,7 +14,6 @@ import com.fsck.k9.backend.api.SyncConfig.ExpungePolicy;
import com.fsck.k9.backend.api.SyncListener;
import com.fsck.k9.mail.FetchProfile;
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.imap.ImapFolder;
@ -118,7 +117,7 @@ public class ImapSyncTest {
imapSync.sync(FOLDER_NAME, syncConfig, listener);
verify(remoteFolder).open(Folder.OPEN_MODE_RO);
verify(remoteFolder).open(ImapFolder.OPEN_MODE_RO);
}
@Test
@ -206,7 +205,6 @@ public class ImapSyncTest {
public void sync_shouldFetchUnsynchronizedMessagesListAndFlags() throws Exception {
messageCountInRemoteFolder(1);
hasUnsyncedRemoteMessage();
when(remoteFolder.supportsFetchingFlags()).thenReturn(true);
imapSync.sync(FOLDER_NAME, syncConfig, listener);
@ -222,7 +220,6 @@ public class ImapSyncTest {
ImapMessage smallMessage = buildSmallNewMessage();
messageCountInRemoteFolder(1);
hasUnsyncedRemoteMessage();
when(remoteFolder.supportsFetchingFlags()).thenReturn(false);
respondToFetchEnvelopesWithMessage(smallMessage);
imapSync.sync(FOLDER_NAME, syncConfig, listener);
@ -238,7 +235,6 @@ public class ImapSyncTest {
ImapMessage largeMessage = buildLargeNewMessage();
messageCountInRemoteFolder(1);
hasUnsyncedRemoteMessage();
when(remoteFolder.supportsFetchingFlags()).thenReturn(false);
respondToFetchEnvelopesWithMessage(largeMessage);
imapSync.sync(FOLDER_NAME, syncConfig, listener);

View file

@ -1,24 +0,0 @@
package com.fsck.k9.backend.pop3
import com.fsck.k9.mail.Flag
import com.fsck.k9.mail.Folder
import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mail.store.pop3.Pop3Store
internal class CommandDeleteAll(private val pop3Store: Pop3Store) {
@Throws(MessagingException::class)
fun deleteAll(folderServerId: String) {
val remoteFolder = pop3Store.getFolder(folderServerId)
if (!remoteFolder.exists()) {
return
}
try {
remoteFolder.open(Folder.OPEN_MODE_RW)
remoteFolder.setFlags(setOf(Flag.DELETED), true)
} finally {
remoteFolder.close()
}
}
}

View file

@ -1,7 +1,6 @@
package com.fsck.k9.backend.pop3
import com.fsck.k9.mail.FetchProfile
import com.fsck.k9.mail.Folder.OPEN_MODE_RW
import com.fsck.k9.mail.Message
import com.fsck.k9.mail.store.pop3.Pop3Store
@ -10,7 +9,7 @@ internal class CommandFetchMessage(private val pop3Store: Pop3Store) {
fun fetchMessage(folderServerId: String, messageServerId: String, fetchProfile: FetchProfile): Message {
val folder = pop3Store.getFolder(folderServerId)
try {
folder.open(OPEN_MODE_RW)
folder.open()
val message = folder.getMessage(messageServerId)
folder.fetch(listOf(message), fetchProfile, null)

View file

@ -7,7 +7,6 @@ import java.util.List;
import com.fsck.k9.backend.api.BackendFolder;
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.pop3.Pop3Folder;
@ -27,15 +26,12 @@ class CommandSetFlag {
boolean newState) throws MessagingException {
Pop3Folder remoteFolder = pop3Store.getFolder(folderServerId);
if (!remoteFolder.exists() || !remoteFolder.isFlagSupported(flag)) {
if (!remoteFolder.isFlagSupported(flag)) {
return;
}
try {
remoteFolder.open(Folder.OPEN_MODE_RW);
if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
return;
}
remoteFolder.open();
List<Message> messages = new ArrayList<>();
for (String uid : messageServerIds) {
if (!uid.startsWith(BackendFolder.LOCAL_UID_PREFIX)) {

View file

@ -23,7 +23,6 @@ class Pop3Backend(
private val pop3Sync: Pop3Sync = Pop3Sync(accountName, backendStorage, pop3Store)
private val commandRefreshFolderList = CommandRefreshFolderList(backendStorage)
private val commandSetFlag = CommandSetFlag(pop3Store)
private val commandDeleteAll = CommandDeleteAll(pop3Store)
private val commandFetchMessage = CommandFetchMessage(pop3Store)
override val supportsSeenFlag = false
@ -69,7 +68,7 @@ class Pop3Backend(
}
override fun deleteAllMessages(folderServerId: String) {
commandDeleteAll.deleteAll(folderServerId)
throw UnsupportedOperationException("not supported")
}
override fun moveMessages(

View file

@ -1,17 +1,6 @@
package com.fsck.k9.backend.pop3;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import com.fsck.k9.backend.api.BackendFolder;
import com.fsck.k9.backend.api.BackendFolder.MoreMessages;
import com.fsck.k9.backend.api.BackendStorage;
@ -19,17 +8,23 @@ import com.fsck.k9.backend.api.SyncConfig;
import com.fsck.k9.backend.api.SyncListener;
import com.fsck.k9.helper.ExceptionHelper;
import com.fsck.k9.mail.AuthenticationFailedException;
import com.fsck.k9.mail.BodyFactory;
import com.fsck.k9.mail.DefaultBodyFactory;
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.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MessageExtractor;
import com.fsck.k9.mail.store.pop3.Pop3Folder;
import com.fsck.k9.mail.store.pop3.Pop3Message;
import com.fsck.k9.mail.store.pop3.Pop3Store;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import timber.log.Timber;
@ -50,7 +45,7 @@ class Pop3Sync {
}
void synchronizeMailboxSynchronous(String folder, SyncConfig syncConfig, SyncListener listener) {
Folder remoteFolder = null;
Pop3Folder remoteFolder = null;
Timber.i("Synchronizing folder %s:%s", accountName, folder);
@ -97,7 +92,7 @@ class Pop3Sync {
*/
Timber.v("SYNC: About to open remote folder %s", folder);
remoteFolder.open(Folder.OPEN_MODE_RO);
remoteFolder.open();
listener.syncAuthenticationSuccess();
@ -112,8 +107,8 @@ class Pop3Sync {
visibleLimit = syncConfig.getDefaultVisibleLimit();
}
final List<Message> remoteMessages = new ArrayList<>();
Map<String, Message> remoteUidMap = new HashMap<>();
final List<Pop3Message> remoteMessages = new ArrayList<>();
Map<String, Pop3Message> remoteUidMap = new HashMap<>();
Timber.v("SYNC: Remote message count for folder %s is %d", folder, remoteMessageCount);
@ -137,12 +132,12 @@ class Pop3Sync {
listener.syncHeadersStarted(folder, folderName);
List<? extends Message> remoteMessageArray =
remoteFolder.getMessages(remoteStart, remoteMessageCount, earliestDate, null);
List<Pop3Message> remoteMessageArray =
remoteFolder.getMessages(remoteStart, remoteMessageCount, null);
int messageCount = remoteMessageArray.size();
for (Message thisMess : remoteMessageArray) {
for (Pop3Message thisMess : remoteMessageArray) {
headerProgress.incrementAndGet();
listener.syncHeadersProgress(folder, headerProgress.get(), messageCount);
@ -187,13 +182,13 @@ class Pop3Sync {
localUidMap = null;
if (moreMessages == MoreMessages.UNKNOWN) {
updateMoreMessages(remoteFolder, backendFolder, earliestDate, remoteStart);
updateMoreMessages(remoteFolder, backendFolder, remoteStart);
}
/*
* Now we download the actual content of messages.
*/
int newMessages = downloadMessages(syncConfig, remoteFolder, backendFolder, remoteMessages, false,
int newMessages = downloadMessages(syncConfig, remoteFolder, backendFolder, remoteMessages,
listener);
listener.folderStatusChanged(folder);
@ -241,21 +236,21 @@ class Pop3Sync {
}
}
private void updateMoreMessages(Folder remoteFolder, BackendFolder backendFolder, Date earliestDate,
int remoteStart) throws MessagingException, IOException {
private void updateMoreMessages(Pop3Folder remoteFolder, BackendFolder backendFolder,
int remoteStart) {
if (remoteStart == 1) {
backendFolder.setMoreMessages(MoreMessages.FALSE);
} else {
boolean moreMessagesAvailable = remoteFolder.areMoreMessagesAvailable(remoteStart, earliestDate);
boolean moreMessagesAvailable = remoteFolder.areMoreMessagesAvailable(remoteStart);
MoreMessages newMoreMessages = (moreMessagesAvailable) ? MoreMessages.TRUE : MoreMessages.FALSE;
backendFolder.setMoreMessages(newMoreMessages);
}
}
private int downloadMessages(final SyncConfig syncConfig, final Folder remoteFolder,
final BackendFolder backendFolder, List<Message> inputMessages, boolean flagSyncOnly,
private int downloadMessages(final SyncConfig syncConfig, final Pop3Folder remoteFolder,
final BackendFolder backendFolder, List<Pop3Message> inputMessages,
final SyncListener listener) throws MessagingException {
final Date earliestDate = syncConfig.getEarliestPollDate();
@ -266,15 +261,14 @@ class Pop3Sync {
}
final String folder = remoteFolder.getServerId();
List<Message> syncFlagMessages = new ArrayList<>();
List<Message> unsyncedMessages = new ArrayList<>();
List<Pop3Message> syncFlagMessages = new ArrayList<>();
List<Pop3Message> unsyncedMessages = new ArrayList<>();
final AtomicInteger newMessages = new AtomicInteger(0);
List<Message> messages = new ArrayList<>(inputMessages);
List<Pop3Message> messages = new ArrayList<>(inputMessages);
for (Message message : messages) {
evaluateMessageForDownload(message, folder, backendFolder, remoteFolder, unsyncedMessages,
syncFlagMessages, flagSyncOnly, listener);
for (Pop3Message message : messages) {
evaluateMessageForDownload(message, folder, backendFolder, unsyncedMessages, syncFlagMessages, listener);
}
final AtomicInteger progress = new AtomicInteger(0);
@ -284,8 +278,8 @@ class Pop3Sync {
Timber.d("SYNC: Have %d unsynced messages", unsyncedMessages.size());
messages.clear();
final List<Message> largeMessages = new ArrayList<>();
final List<Message> smallMessages = new ArrayList<>();
final List<Pop3Message> largeMessages = new ArrayList<>();
final List<Pop3Message> smallMessages = new ArrayList<>();
if (!unsyncedMessages.isEmpty()) {
int visibleLimit = backendFolder.getVisibleLimit();
int listSize = unsyncedMessages.size();
@ -295,9 +289,6 @@ class Pop3Sync {
}
FetchProfile fp = new FetchProfile();
if (remoteFolder.supportsFetchingFlags()) {
fp.add(FetchProfile.Item.FLAGS);
}
fp.add(FetchProfile.Item.ENVELOPE);
Timber.d("SYNC: About to fetch %d unsynced messages for folder %s", unsyncedMessages.size(), folder);
@ -332,13 +323,6 @@ class Pop3Sync {
downloadLargeMessages(syncConfig, remoteFolder, backendFolder, largeMessages, progress, newMessages, todo, fp, listener);
largeMessages.clear();
/*
* Refresh the flags for any messages in the local store that we didn't just
* download.
*/
refreshLocalMessageFlags(syncConfig, remoteFolder, backendFolder, syncFlagMessages, progress, todo, listener);
Timber.d("SYNC: Synced remote messages for folder %s, %d new messages", folder, newMessages.get());
// If the oldest message seen on this sync is newer than
@ -360,13 +344,11 @@ class Pop3Sync {
}
private void evaluateMessageForDownload(
final Message message,
final Pop3Message message,
final String folder,
final BackendFolder backendFolder,
final Folder remoteFolder,
final List<Message> unsyncedMessages,
final List<Message> syncFlagMessages,
boolean flagSyncOnly,
final List<Pop3Message> unsyncedMessages,
final List<Pop3Message> syncFlagMessages,
SyncListener listener) {
String messageServerId = message.getUid();
@ -380,25 +362,23 @@ class Pop3Sync {
boolean messagePresentLocally = backendFolder.isMessagePresent(messageServerId);
if (!messagePresentLocally) {
if (!flagSyncOnly) {
if (!message.isSet(Flag.X_DOWNLOADED_FULL) && !message.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
Timber.v("Message with uid %s has not yet been downloaded", messageServerId);
if (!message.isSet(Flag.X_DOWNLOADED_FULL) && !message.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
Timber.v("Message with uid %s has not yet been downloaded", messageServerId);
unsyncedMessages.add(message);
unsyncedMessages.add(message);
} else {
Timber.v("Message with uid %s is partially or fully downloaded", messageServerId);
// Store the updated message locally
boolean completeMessage = message.isSet(Flag.X_DOWNLOADED_FULL);
if (completeMessage) {
backendFolder.saveCompleteMessage(message);
} else {
Timber.v("Message with uid %s is partially or fully downloaded", messageServerId);
// Store the updated message locally
boolean completeMessage = message.isSet(Flag.X_DOWNLOADED_FULL);
if (completeMessage) {
backendFolder.saveCompleteMessage(message);
} else {
backendFolder.savePartialMessage(message);
}
boolean isOldMessage = isOldMessage(backendFolder, message);
listener.syncNewMessage(folder, messageServerId, isOldMessage);
backendFolder.savePartialMessage(message);
}
boolean isOldMessage = isOldMessage(backendFolder, message);
listener.syncNewMessage(folder, messageServerId, isOldMessage);
}
return;
}
@ -412,10 +392,6 @@ class Pop3Sync {
unsyncedMessages.add(message);
} else {
String newPushState = remoteFolder.getNewPushState(backendFolder.getPushState(), message);
if (newPushState != null) {
backendFolder.setPushState(newPushState);
}
syncFlagMessages.add(message);
}
} else {
@ -423,10 +399,10 @@ class Pop3Sync {
}
}
private <T extends Message> void fetchUnsyncedMessages(final SyncConfig syncConfig, final Folder<T> remoteFolder,
List<T> unsyncedMessages,
final List<Message> smallMessages,
final List<Message> largeMessages,
private void fetchUnsyncedMessages(final SyncConfig syncConfig, final Pop3Folder remoteFolder,
List<Pop3Message> unsyncedMessages,
final List<Pop3Message> smallMessages,
final List<Pop3Message> largeMessages,
final AtomicInteger progress,
final int todo,
FetchProfile fp,
@ -435,9 +411,9 @@ class Pop3Sync {
final Date earliestDate = syncConfig.getEarliestPollDate();
remoteFolder.fetch(unsyncedMessages, fp,
new MessageRetrievalListener<T>() {
new MessageRetrievalListener<Pop3Message>() {
@Override
public void messageFinished(T message, int number, int ofTotal) {
public void messageFinished(Pop3Message message, int number, int ofTotal) {
try {
if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) {
if (message.isSet(Flag.DELETED)) {
@ -478,10 +454,10 @@ class Pop3Sync {
});
}
private <T extends Message> void downloadSmallMessages(
final Folder<T> remoteFolder,
private void downloadSmallMessages(
final Pop3Folder remoteFolder,
final BackendFolder backendFolder,
List<T> smallMessages,
List<Pop3Message> smallMessages,
final AtomicInteger progress,
final AtomicInteger newMessages,
final int todo,
@ -492,9 +468,9 @@ class Pop3Sync {
Timber.d("SYNC: Fetching %d small messages for folder %s", smallMessages.size(), folder);
remoteFolder.fetch(smallMessages,
fp, new MessageRetrievalListener<T>() {
fp, new MessageRetrievalListener<Pop3Message>() {
@Override
public void messageFinished(final T message, int number, int ofTotal) {
public void messageFinished(final Pop3Message message, int number, int ofTotal) {
try {
// Store the updated message locally
@ -533,15 +509,15 @@ class Pop3Sync {
Timber.d("SYNC: Done fetching small messages for folder %s", folder);
}
private boolean isOldMessage(BackendFolder backendFolder, Message message) {
private boolean isOldMessage(BackendFolder backendFolder, Pop3Message message) {
return message.olderThan(backendFolder.getLatestOldMessageSeenTime());
}
private <T extends Message> void downloadLargeMessages(
private void downloadLargeMessages(
final SyncConfig syncConfig,
final Folder<T> remoteFolder,
final Pop3Folder remoteFolder,
final BackendFolder backendFolder,
List<T> largeMessages,
List<Pop3Message> largeMessages,
final AtomicInteger progress,
final AtomicInteger newMessages,
final int todo,
@ -552,13 +528,9 @@ class Pop3Sync {
Timber.d("SYNC: Fetching large messages for folder %s", folder);
remoteFolder.fetch(largeMessages, fp, null);
for (T message : largeMessages) {
for (Pop3Message message : largeMessages) {
if (message.getBody() == null) {
downloadSaneBody(syncConfig, remoteFolder, backendFolder, message);
} else {
downloadPartial(remoteFolder, backendFolder, message);
}
downloadSaneBody(syncConfig, remoteFolder, backendFolder, message);
String messageServerId = message.getUid();
Timber.v("About to notify listeners that we got a new large message %s:%s:%s",
@ -584,8 +556,8 @@ class Pop3Sync {
Timber.d("SYNC: Done fetching large messages for folder %s", folder);
}
private void downloadSaneBody(SyncConfig syncConfig, Folder remoteFolder, BackendFolder backendFolder,
Message message) throws MessagingException {
private void downloadSaneBody(SyncConfig syncConfig, Pop3Folder remoteFolder, BackendFolder backendFolder,
Pop3Message message) throws MessagingException {
/*
* The provider was unable to get the structure of the message, so
* we'll download a reasonable portion of the messge and mark it as
@ -627,92 +599,4 @@ class Pop3Sync {
backendFolder.savePartialMessage(message);
}
}
private void downloadPartial(Folder remoteFolder, BackendFolder backendFolder, Message message)
throws MessagingException {
/*
* We have a structure to deal with, from which
* we can pull down the parts we want to actually store.
* Build a list of parts we are interested in. Text parts will be downloaded
* right now, attachments will be left for later.
*/
Set<Part> viewables = MessageExtractor.collectTextParts(message);
/*
* Now download the parts we're interested in storing.
*/
BodyFactory bodyFactory = new DefaultBodyFactory();
for (Part part : viewables) {
remoteFolder.fetchPart(message, part, null, bodyFactory);
}
// Store the updated message locally
backendFolder.savePartialMessage(message);
}
private void refreshLocalMessageFlags(
final SyncConfig syncConfig,
final Folder remoteFolder,
final BackendFolder backendFolder,
List<Message> syncFlagMessages,
final AtomicInteger progress,
final int todo,
SyncListener listener
) throws MessagingException {
final String folder = remoteFolder.getServerId();
if (remoteFolder.supportsFetchingFlags()) {
Timber.d("SYNC: About to sync flags for %d remote messages for folder %s", syncFlagMessages.size(), folder);
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.FLAGS);
List<Message> undeletedMessages = new LinkedList<>();
for (Message message : syncFlagMessages) {
if (!message.isSet(Flag.DELETED)) {
undeletedMessages.add(message);
}
}
remoteFolder.fetch(undeletedMessages, fp, null);
for (Message remoteMessage : syncFlagMessages) {
boolean messageChanged = syncFlags(syncConfig, backendFolder, remoteMessage);
if (messageChanged) {
listener.syncFlagChanged(folder, remoteMessage.getUid());
}
progress.incrementAndGet();
listener.syncProgress(folder, progress.get(), todo);
}
}
}
private boolean syncFlags(SyncConfig syncConfig, BackendFolder backendFolder, Message remoteMessage) {
String messageServerId = remoteMessage.getUid();
if (!backendFolder.isMessagePresent(messageServerId)) {
return false;
}
Set<Flag> localMessageFlags = backendFolder.getMessageFlags(messageServerId);
if (localMessageFlags.contains(Flag.DELETED)) {
return false;
}
boolean messageChanged = false;
if (remoteMessage.isSet(Flag.DELETED)) {
if (syncConfig.getSyncRemoteDeletions()) {
backendFolder.setMessageFlag(messageServerId, Flag.DELETED, true);
messageChanged = true;
}
} else {
for (Flag flag : syncConfig.getSyncFlags()) {
if (remoteMessage.isSet(flag) != localMessageFlags.contains(flag)) {
backendFolder.setMessageFlag(messageServerId, flag, remoteMessage.isSet(flag));
messageChanged = true;
}
}
}
return messageChanged;
}
}

View file

@ -1,24 +0,0 @@
package com.fsck.k9.backend.webdav
import com.fsck.k9.mail.Flag
import com.fsck.k9.mail.Folder
import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mail.store.webdav.WebDavStore
internal class CommandDeleteAll(private val webDavStore: WebDavStore) {
@Throws(MessagingException::class)
fun deleteAll(folderServerId: String) {
val remoteFolder = webDavStore.getFolder(folderServerId)
if (!remoteFolder.exists()) {
return
}
try {
remoteFolder.open(Folder.OPEN_MODE_RW)
remoteFolder.setFlags(setOf(Flag.DELETED), true)
} finally {
remoteFolder.close()
}
}
}

View file

@ -1,39 +0,0 @@
package com.fsck.k9.backend.webdav;
import java.util.Collections;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.webdav.WebDavFolder;
import com.fsck.k9.mail.store.webdav.WebDavStore;
import org.jetbrains.annotations.NotNull;
class CommandMarkAllAsRead {
private final WebDavStore webDavStore;
CommandMarkAllAsRead(WebDavStore webDavStore) {
this.webDavStore = webDavStore;
}
void markAllAsRead(@NotNull String folderServerId) throws MessagingException {
WebDavFolder remoteFolder = webDavStore.getFolder(folderServerId);
if (!remoteFolder.exists()) {
return;
}
try {
remoteFolder.open(Folder.OPEN_MODE_RW);
if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
return;
}
remoteFolder.setFlags(Collections.singleton(Flag.SEEN), true);
} finally {
remoteFolder.close();
}
}
}

View file

@ -7,7 +7,6 @@ import java.util.List;
import java.util.Map;
import com.fsck.k9.backend.api.BackendFolder;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.webdav.WebDavFolder;
@ -56,16 +55,7 @@ class CommandMoveOrCopyMessages {
return null;
}
if (!remoteSrcFolder.exists()) {
throw new MessagingException("processingPendingMoveOrCopy: remoteFolder " + srcFolder +
" does not exist", true);
}
remoteSrcFolder.open(Folder.OPEN_MODE_RW);
if (remoteSrcFolder.getMode() != Folder.OPEN_MODE_RW) {
throw new MessagingException("processingPendingMoveOrCopy: could not open remoteSrcFolder " +
srcFolder + " read/write", true);
}
remoteSrcFolder.open();
Timber.d("processingPendingMoveOrCopy: source folder = %s, %d messages, " +
"destination folder = %s, isCopy = %s", srcFolder, messages.size(), destFolder, isCopy);

View file

@ -7,7 +7,6 @@ import java.util.List;
import com.fsck.k9.backend.api.BackendFolder;
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.webdav.WebDavFolder;
@ -27,15 +26,9 @@ class CommandSetFlag {
boolean newState) throws MessagingException {
WebDavFolder remoteFolder = webDavStore.getFolder(folderServerId);
if (!remoteFolder.exists() || !remoteFolder.isFlagSupported(flag)) {
return;
}
try {
remoteFolder.open(Folder.OPEN_MODE_RW);
if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
return;
}
remoteFolder.open();
List<Message> messages = new ArrayList<>();
for (String uid : messageServerIds) {
if (!uid.startsWith(BackendFolder.LOCAL_UID_PREFIX)) {

View file

@ -1,6 +1,5 @@
package com.fsck.k9.backend.webdav
import com.fsck.k9.mail.Folder
import com.fsck.k9.mail.Message
import com.fsck.k9.mail.store.webdav.WebDavStore
@ -9,7 +8,7 @@ internal class CommandUploadMessage(private val webDavStore: WebDavStore) {
fun uploadMessage(folderServerId: String, message: Message): String? {
val folder = webDavStore.getFolder(folderServerId)
try {
folder.open(Folder.OPEN_MODE_RW)
folder.open()
folder.appendMessages(listOf(message))

View file

@ -14,6 +14,7 @@ import com.fsck.k9.mail.PushReceiver
import com.fsck.k9.mail.Pusher
import com.fsck.k9.mail.store.webdav.WebDavStore
import com.fsck.k9.mail.transport.WebDavTransport
import timber.log.Timber
class WebDavBackend(
accountName: String,
@ -24,9 +25,7 @@ class WebDavBackend(
private val webDavSync: WebDavSync = WebDavSync(accountName, backendStorage, webDavStore)
private val commandGetFolders = CommandRefreshFolderList(backendStorage, webDavStore)
private val commandSetFlag = CommandSetFlag(webDavStore)
private val commandMarkAllAsRead = CommandMarkAllAsRead(webDavStore)
private val commandMoveOrCopyMessages = CommandMoveOrCopyMessages(webDavStore)
private val commandDeleteAll = CommandDeleteAll(webDavStore)
private val commandFetchMessage = CommandFetchMessage(webDavStore)
private val commandUploadMessage = CommandUploadMessage(webDavStore)
@ -58,7 +57,7 @@ class WebDavBackend(
}
override fun markAllAsRead(folderServerId: String) {
commandMarkAllAsRead.markAllAsRead(folderServerId)
Timber.e("Method not implemented; breaks 'mark all as read'")
}
override fun expunge(folderServerId: String) {
@ -74,7 +73,7 @@ class WebDavBackend(
}
override fun deleteAllMessages(folderServerId: String) {
commandDeleteAll.deleteAll(folderServerId)
Timber.e("Method not implemented; breaks 'empty trash'")
}
override fun moveMessages(

View file

@ -1,7 +1,21 @@
package com.fsck.k9.backend.webdav;
import java.io.IOException;
import com.fsck.k9.backend.api.BackendFolder;
import com.fsck.k9.backend.api.BackendFolder.MoreMessages;
import com.fsck.k9.backend.api.BackendStorage;
import com.fsck.k9.backend.api.SyncConfig;
import com.fsck.k9.backend.api.SyncListener;
import com.fsck.k9.helper.ExceptionHelper;
import com.fsck.k9.mail.AuthenticationFailedException;
import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.webdav.WebDavFolder;
import com.fsck.k9.mail.store.webdav.WebDavMessage;
import com.fsck.k9.mail.store.webdav.WebDavStore;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
@ -12,24 +26,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import com.fsck.k9.backend.api.BackendFolder;
import com.fsck.k9.backend.api.BackendFolder.MoreMessages;
import com.fsck.k9.backend.api.BackendStorage;
import com.fsck.k9.backend.api.SyncConfig;
import com.fsck.k9.backend.api.SyncListener;
import com.fsck.k9.helper.ExceptionHelper;
import com.fsck.k9.mail.AuthenticationFailedException;
import com.fsck.k9.mail.BodyFactory;
import com.fsck.k9.mail.DefaultBodyFactory;
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.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MessageExtractor;
import com.fsck.k9.mail.store.webdav.WebDavStore;
import timber.log.Timber;
@ -50,7 +46,7 @@ class WebDavSync {
}
void synchronizeMailboxSynchronous(String folder, SyncConfig syncConfig, SyncListener listener) {
Folder remoteFolder = null;
WebDavFolder remoteFolder = null;
Timber.i("Synchronizing folder %s:%s", accountName, folder);
@ -97,7 +93,7 @@ class WebDavSync {
*/
Timber.v("SYNC: About to open remote folder %s", folder);
remoteFolder.open(Folder.OPEN_MODE_RO);
remoteFolder.open();
listener.syncAuthenticationSuccess();
@ -112,8 +108,8 @@ class WebDavSync {
visibleLimit = syncConfig.getDefaultVisibleLimit();
}
final List<Message> remoteMessages = new ArrayList<>();
Map<String, Message> remoteUidMap = new HashMap<>();
final List<WebDavMessage> remoteMessages = new ArrayList<>();
Map<String, WebDavMessage> remoteUidMap = new HashMap<>();
Timber.v("SYNC: Remote message count for folder %s is %d", folder, remoteMessageCount);
@ -137,12 +133,12 @@ class WebDavSync {
listener.syncHeadersStarted(folder, folderName);
List<? extends Message> remoteMessageArray =
remoteFolder.getMessages(remoteStart, remoteMessageCount, earliestDate, null);
List<WebDavMessage> remoteMessageArray =
remoteFolder.getMessages(remoteStart, remoteMessageCount, null);
int messageCount = remoteMessageArray.size();
for (Message thisMess : remoteMessageArray) {
for (WebDavMessage thisMess : remoteMessageArray) {
headerProgress.incrementAndGet();
listener.syncHeadersProgress(folder, headerProgress.get(), messageCount);
@ -193,7 +189,7 @@ class WebDavSync {
/*
* Now we download the actual content of messages.
*/
int newMessages = downloadMessages(syncConfig, remoteFolder, backendFolder, remoteMessages, false,
int newMessages = downloadMessages(syncConfig, remoteFolder, backendFolder, remoteMessages,
listener);
listener.folderStatusChanged(folder);
@ -241,8 +237,8 @@ class WebDavSync {
}
}
private void updateMoreMessages(Folder remoteFolder, BackendFolder backendFolder, Date earliestDate,
int remoteStart) throws MessagingException, IOException {
private void updateMoreMessages(WebDavFolder remoteFolder, BackendFolder backendFolder, Date earliestDate,
int remoteStart) {
if (remoteStart == 1) {
backendFolder.setMoreMessages(MoreMessages.FALSE);
@ -254,8 +250,8 @@ class WebDavSync {
}
}
private int downloadMessages(final SyncConfig syncConfig, final Folder remoteFolder,
final BackendFolder backendFolder, List<Message> inputMessages, boolean flagSyncOnly,
private int downloadMessages(final SyncConfig syncConfig, final WebDavFolder remoteFolder,
final BackendFolder backendFolder, List<WebDavMessage> inputMessages,
final SyncListener listener) throws MessagingException {
final Date earliestDate = syncConfig.getEarliestPollDate();
@ -266,15 +262,14 @@ class WebDavSync {
}
final String folder = remoteFolder.getServerId();
List<Message> syncFlagMessages = new ArrayList<>();
List<Message> unsyncedMessages = new ArrayList<>();
List<WebDavMessage> syncFlagMessages = new ArrayList<>();
List<WebDavMessage> unsyncedMessages = new ArrayList<>();
final AtomicInteger newMessages = new AtomicInteger(0);
List<Message> messages = new ArrayList<>(inputMessages);
List<WebDavMessage> messages = new ArrayList<>(inputMessages);
for (Message message : messages) {
evaluateMessageForDownload(message, folder, backendFolder, remoteFolder, unsyncedMessages,
syncFlagMessages, flagSyncOnly, listener);
for (WebDavMessage message : messages) {
evaluateMessageForDownload(message, folder, backendFolder, unsyncedMessages, syncFlagMessages, listener);
}
final AtomicInteger progress = new AtomicInteger(0);
@ -284,8 +279,8 @@ class WebDavSync {
Timber.d("SYNC: Have %d unsynced messages", unsyncedMessages.size());
messages.clear();
final List<Message> largeMessages = new ArrayList<>();
final List<Message> smallMessages = new ArrayList<>();
final List<WebDavMessage> largeMessages = new ArrayList<>();
final List<WebDavMessage> smallMessages = new ArrayList<>();
if (!unsyncedMessages.isEmpty()) {
int visibleLimit = backendFolder.getVisibleLimit();
int listSize = unsyncedMessages.size();
@ -295,9 +290,7 @@ class WebDavSync {
}
FetchProfile fp = new FetchProfile();
if (remoteFolder.supportsFetchingFlags()) {
fp.add(FetchProfile.Item.FLAGS);
}
fp.add(FetchProfile.Item.FLAGS);
fp.add(FetchProfile.Item.ENVELOPE);
Timber.d("SYNC: About to fetch %d unsynced messages for folder %s", unsyncedMessages.size(), folder);
@ -360,13 +353,11 @@ class WebDavSync {
}
private void evaluateMessageForDownload(
final Message message,
final WebDavMessage message,
final String folder,
final BackendFolder backendFolder,
final Folder remoteFolder,
final List<Message> unsyncedMessages,
final List<Message> syncFlagMessages,
boolean flagSyncOnly,
final List<WebDavMessage> unsyncedMessages,
final List<WebDavMessage> syncFlagMessages,
SyncListener listener) {
String messageServerId = message.getUid();
@ -380,24 +371,22 @@ class WebDavSync {
boolean messagePresentLocally = backendFolder.isMessagePresent(messageServerId);
if (!messagePresentLocally) {
if (!flagSyncOnly) {
if (!message.isSet(Flag.X_DOWNLOADED_FULL) && !message.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
Timber.v("Message with uid %s has not yet been downloaded", messageServerId);
if (!message.isSet(Flag.X_DOWNLOADED_FULL) && !message.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
Timber.v("Message with uid %s has not yet been downloaded", messageServerId);
unsyncedMessages.add(message);
unsyncedMessages.add(message);
} else {
Timber.v("Message with uid %s is partially or fully downloaded", messageServerId);
// Store the updated message locally
boolean completeMessage = message.isSet(Flag.X_DOWNLOADED_FULL);
if (completeMessage) {
backendFolder.saveCompleteMessage(message);
} else {
Timber.v("Message with uid %s is partially or fully downloaded", messageServerId);
// Store the updated message locally
boolean completeMessage = message.isSet(Flag.X_DOWNLOADED_FULL);
if (completeMessage) {
backendFolder.saveCompleteMessage(message);
} else {
backendFolder.savePartialMessage(message);
}
listener.syncNewMessage(folder, messageServerId, false);
backendFolder.savePartialMessage(message);
}
listener.syncNewMessage(folder, messageServerId, false);
}
return;
}
@ -411,10 +400,6 @@ class WebDavSync {
unsyncedMessages.add(message);
} else {
String newPushState = remoteFolder.getNewPushState(backendFolder.getPushState(), message);
if (newPushState != null) {
backendFolder.setPushState(newPushState);
}
syncFlagMessages.add(message);
}
} else {
@ -422,10 +407,10 @@ class WebDavSync {
}
}
private <T extends Message> void fetchUnsyncedMessages(final SyncConfig syncConfig, final Folder<T> remoteFolder,
List<T> unsyncedMessages,
final List<Message> smallMessages,
final List<Message> largeMessages,
private void fetchUnsyncedMessages(final SyncConfig syncConfig, final WebDavFolder remoteFolder,
List<WebDavMessage> unsyncedMessages,
final List<WebDavMessage> smallMessages,
final List<WebDavMessage> largeMessages,
final AtomicInteger progress,
final int todo,
FetchProfile fp,
@ -434,9 +419,9 @@ class WebDavSync {
final Date earliestDate = syncConfig.getEarliestPollDate();
remoteFolder.fetch(unsyncedMessages, fp,
new MessageRetrievalListener<T>() {
new MessageRetrievalListener<WebDavMessage>() {
@Override
public void messageFinished(T message, int number, int ofTotal) {
public void messageFinished(WebDavMessage message, int number, int ofTotal) {
try {
if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) {
if (message.isSet(Flag.DELETED)) {
@ -477,10 +462,10 @@ class WebDavSync {
});
}
private <T extends Message> void downloadSmallMessages(
final Folder<T> remoteFolder,
private void downloadSmallMessages(
final WebDavFolder remoteFolder,
final BackendFolder backendFolder,
List<T> smallMessages,
List<WebDavMessage> smallMessages,
final AtomicInteger progress,
final AtomicInteger newMessages,
final int todo,
@ -491,9 +476,9 @@ class WebDavSync {
Timber.d("SYNC: Fetching %d small messages for folder %s", smallMessages.size(), folder);
remoteFolder.fetch(smallMessages,
fp, new MessageRetrievalListener<T>() {
fp, new MessageRetrievalListener<WebDavMessage>() {
@Override
public void messageFinished(final T message, int number, int ofTotal) {
public void messageFinished(final WebDavMessage message, int number, int ofTotal) {
try {
// Store the updated message locally
@ -531,11 +516,11 @@ class WebDavSync {
Timber.d("SYNC: Done fetching small messages for folder %s", folder);
}
private <T extends Message> void downloadLargeMessages(
private void downloadLargeMessages(
final SyncConfig syncConfig,
final Folder<T> remoteFolder,
final WebDavFolder remoteFolder,
final BackendFolder backendFolder,
List<T> largeMessages,
List<WebDavMessage> largeMessages,
final AtomicInteger progress,
final AtomicInteger newMessages,
final int todo,
@ -546,13 +531,8 @@ class WebDavSync {
Timber.d("SYNC: Fetching large messages for folder %s", folder);
remoteFolder.fetch(largeMessages, fp, null);
for (T message : largeMessages) {
if (message.getBody() == null) {
downloadSaneBody(syncConfig, remoteFolder, backendFolder, message);
} else {
downloadPartial(remoteFolder, backendFolder, message);
}
for (WebDavMessage message : largeMessages) {
downloadSaneBody(syncConfig, remoteFolder, backendFolder, message);
String messageServerId = message.getUid();
Timber.v("About to notify listeners that we got a new large message %s:%s:%s",
@ -577,8 +557,8 @@ class WebDavSync {
Timber.d("SYNC: Done fetching large messages for folder %s", folder);
}
private void downloadSaneBody(SyncConfig syncConfig, Folder remoteFolder, BackendFolder backendFolder,
Message message) throws MessagingException {
private void downloadSaneBody(SyncConfig syncConfig, WebDavFolder remoteFolder, BackendFolder backendFolder,
WebDavMessage message) throws MessagingException {
/*
* The provider was unable to get the structure of the message, so
* we'll download a reasonable portion of the messge and mark it as
@ -621,66 +601,41 @@ class WebDavSync {
}
}
private void downloadPartial(Folder remoteFolder, BackendFolder backendFolder, Message message)
throws MessagingException {
/*
* We have a structure to deal with, from which
* we can pull down the parts we want to actually store.
* Build a list of parts we are interested in. Text parts will be downloaded
* right now, attachments will be left for later.
*/
Set<Part> viewables = MessageExtractor.collectTextParts(message);
/*
* Now download the parts we're interested in storing.
*/
BodyFactory bodyFactory = new DefaultBodyFactory();
for (Part part : viewables) {
remoteFolder.fetchPart(message, part, null, bodyFactory);
}
// Store the updated message locally
backendFolder.savePartialMessage(message);
}
private void refreshLocalMessageFlags(
final SyncConfig syncConfig,
final Folder remoteFolder,
final WebDavFolder remoteFolder,
final BackendFolder backendFolder,
List<Message> syncFlagMessages,
List<WebDavMessage> syncFlagMessages,
final AtomicInteger progress,
final int todo,
SyncListener listener
) throws MessagingException {
final String folder = remoteFolder.getServerId();
if (remoteFolder.supportsFetchingFlags()) {
Timber.d("SYNC: About to sync flags for %d remote messages for folder %s", syncFlagMessages.size(), folder);
Timber.d("SYNC: About to sync flags for %d remote messages for folder %s", syncFlagMessages.size(), folder);
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.FLAGS);
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.FLAGS);
List<Message> undeletedMessages = new LinkedList<>();
for (Message message : syncFlagMessages) {
if (!message.isSet(Flag.DELETED)) {
undeletedMessages.add(message);
}
List<WebDavMessage> undeletedMessages = new LinkedList<>();
for (WebDavMessage message : syncFlagMessages) {
if (!message.isSet(Flag.DELETED)) {
undeletedMessages.add(message);
}
}
remoteFolder.fetch(undeletedMessages, fp, null);
for (Message remoteMessage : syncFlagMessages) {
boolean messageChanged = syncFlags(syncConfig, backendFolder, remoteMessage);
if (messageChanged) {
listener.syncFlagChanged(folder, remoteMessage.getUid());
}
progress.incrementAndGet();
listener.syncProgress(folder, progress.get(), todo);
remoteFolder.fetch(undeletedMessages, fp, null);
for (WebDavMessage remoteMessage : syncFlagMessages) {
boolean messageChanged = syncFlags(syncConfig, backendFolder, remoteMessage);
if (messageChanged) {
listener.syncFlagChanged(folder, remoteMessage.getUid());
}
progress.incrementAndGet();
listener.syncProgress(folder, progress.get(), todo);
}
}
private boolean syncFlags(SyncConfig syncConfig, BackendFolder backendFolder, Message remoteMessage) {
private boolean syncFlags(SyncConfig syncConfig, BackendFolder backendFolder, WebDavMessage remoteMessage) {
String messageServerId = remoteMessage.getUid();
if (!backendFolder.isMessagePresent(messageServerId)) {

View file

@ -1,173 +0,0 @@
package com.fsck.k9.mail;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import timber.log.Timber;
public abstract class Folder<T extends Message> {
private String status = null;
private FolderType type = FolderType.REGULAR;
public static final int OPEN_MODE_RW=0;
public static final int OPEN_MODE_RO=1;
/**
* Forces an open of the MailProvider. If the provider is already open this
* function returns without doing anything.
*
* @param mode READ_ONLY or READ_WRITE
*/
public abstract void open(int mode) throws MessagingException;
/**
* Forces a close of the MailProvider. Any further access will attempt to
* reopen the MailProvider.
*/
public abstract void close();
/**
* @return True if further commands are not expected to have to open the
* connection.
*/
public abstract boolean isOpen();
/**
* Get the mode the folder was opened with. This may be different than the mode the open
* was requested with.
* @return
*/
public abstract int getMode();
public abstract boolean create() throws MessagingException;
public abstract boolean exists() throws MessagingException;
/**
* @return A count of the messages in the selected folder.
*/
public abstract int getMessageCount() throws MessagingException;
public abstract int getUnreadMessageCount() throws MessagingException;
public abstract int getFlaggedMessageCount() 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.
* @param start UID sequence start
* @param end UID sequence end
* @param earliestDate Date to start on
* @param listener Listener to notify as we download messages.
* @return List of messages
* @throws MessagingException
*/
public abstract List<T> getMessages(int start, int end, Date earliestDate, MessageRetrievalListener<T> listener) throws MessagingException;
public abstract boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate)
throws IOException, MessagingException;
public abstract Map<String, String> appendMessages(List<? extends Message> messages) throws MessagingException;
public Map<String, String> copyMessages(List<? extends Message> msgs, Folder folder) throws MessagingException {
return null;
}
public Map<String, String> moveMessages(List<? extends Message> msgs, Folder folder) throws MessagingException {
return null;
}
public abstract void setFlags(List<? extends Message> messages, Set<Flag> flags, boolean value)
throws MessagingException;
public abstract void setFlags(Set<Flag> flags, boolean value) throws MessagingException;
public abstract String getUidFromMessageId(String messageId) throws MessagingException;
public void expunge() throws MessagingException
{}
public void expungeUids(List<String> uids) throws MessagingException {
}
/**
* Populate a list of messages based upon a FetchProfile. See {@link FetchProfile} for the things that can
* be fetched.
* @param messages Messages to populate
* @param fp Things to download
* @param listener Listener to notify as we fetch messages.
* @throws MessagingException
*/
public abstract void fetch(List<T> messages, FetchProfile fp,
MessageRetrievalListener<T> listener) throws MessagingException;
public void fetchPart(Message message, Part part, MessageRetrievalListener<Message> listener,
BodyFactory bodyFactory) throws MessagingException {
// This is causing trouble. Disabled for now. See issue 1733
//throw new RuntimeException("fetchPart() not implemented.");
Timber.d("fetchPart() not implemented.");
}
public abstract String getServerId();
public abstract String getName();
/**
* @param oldPushState
* @param message
* @return empty string to clear the pushState, null to leave the state as-is
*/
public String getNewPushState(String oldPushState, Message message) {
return null;
}
public boolean isFlagSupported(Flag flag) {
return true;
}
public boolean supportsFetchingFlags() {
return true;
}
@Override
public String toString() {
return getServerId();
}
public FolderClass getDisplayClass() {
return FolderClass.NO_CLASS;
}
public FolderClass getSyncClass() {
return getDisplayClass();
}
public FolderClass getPushClass() {
return getSyncClass();
}
public String getStatus() {
return status;
}
public void setStatus(String status) throws MessagingException {
this.status = status;
}
public List<T> search(String queryString, final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags)
throws MessagingException {
throw new MessagingException("K-9 does not support searches on this folder type");
}
public FolderType getType() {
return type;
}
public void setType(FolderType type) {
this.type = type;
}
}

View file

@ -23,7 +23,7 @@ import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.BodyFactory;
import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.FolderType;
import com.fsck.k9.mail.K9MailLib;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessageRetrievalListener;
@ -40,7 +40,10 @@ import timber.log.Timber;
import static com.fsck.k9.mail.store.imap.ImapUtility.getLastResponse;
public class ImapFolder extends Folder<ImapMessage> {
public class ImapFolder {
public static final int OPEN_MODE_RW = 0;
public static final int OPEN_MODE_RO = 1;
static final String INBOX = "INBOX";
private static final ThreadLocal<SimpleDateFormat> RFC3501_DATE = new ThreadLocal<SimpleDateFormat>() {
@Override
@ -55,10 +58,11 @@ public class ImapFolder extends Folder<ImapMessage> {
protected volatile int messageCount = -1;
protected volatile long uidNext = -1L;
protected volatile ImapConnection connection;
protected ImapStore store = null;
protected ImapStore store;
protected Map<Long, String> msgSeqUidMap = new ConcurrentHashMap<>();
private final FolderNameCodec folderNameCodec;
private final String name;
private FolderType type = FolderType.REGULAR;
private int mode;
private volatile boolean exists;
private boolean inSearch = false;
@ -76,6 +80,14 @@ public class ImapFolder extends Folder<ImapMessage> {
this.folderNameCodec = folderNameCodec;
}
public FolderType getType() {
return type;
}
public void setType(FolderType type) {
this.type = type;
}
private String getPrefixedName() throws MessagingException {
String prefixedName = "";
@ -111,7 +123,6 @@ public class ImapFolder extends Folder<ImapMessage> {
return handleUntaggedResponses(connection.executeSimpleCommand(command));
}
@Override
public void open(int mode) throws MessagingException {
internalOpen(mode);
@ -192,17 +203,14 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public boolean isOpen() {
return connection != null;
}
@Override
public int getMode() {
return mode;
}
@Override
public void close() {
messageCount = -1;
@ -223,12 +231,10 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public String getServerId() {
return name;
}
@Override
public String getName() {
return name;
}
@ -247,7 +253,6 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public boolean exists() throws MessagingException {
if (exists) {
return true;
@ -286,7 +291,6 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public boolean create() throws MessagingException {
/*
* This method needs to operate in the unselected mode as well as the selected mode
@ -335,17 +339,11 @@ public class ImapFolder extends Folder<ImapMessage> {
*
* @return The mapping of original message UIDs to the new server UIDs.
*/
@Override
public Map<String, String> copyMessages(List<? extends Message> messages, Folder folder) throws MessagingException {
if (!(folder instanceof ImapFolder)) {
throw new MessagingException("ImapFolder.copyMessages passed non-ImapFolder");
}
public Map<String, String> copyMessages(List<? extends Message> messages, ImapFolder folder) throws MessagingException {
if (messages.isEmpty()) {
return null;
}
ImapFolder imapFolder = (ImapFolder) folder;
checkOpen(); //only need READ access
Set<Long> uids = new HashSet<>(messages.size());
@ -353,7 +351,7 @@ public class ImapFolder extends Folder<ImapMessage> {
uids.add(Long.parseLong(messages.get(i).getUid()));
}
String encodedDestinationFolderName = folderNameCodec.encode(imapFolder.getPrefixedName());
String encodedDestinationFolderName = folderNameCodec.encode(folder.getPrefixedName());
String escapedDestinationFolderName = ImapUtility.encodeString(encodedDestinationFolderName);
//TODO: Just perform the operation and only check for existence of the folder if the operation fails.
@ -363,7 +361,7 @@ public class ImapFolder extends Folder<ImapMessage> {
escapedDestinationFolderName, getLogId());
}
throw new FolderNotFoundException(imapFolder.getServerId());
throw new FolderNotFoundException(folder.getServerId());
}
try {
@ -377,8 +375,7 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public Map<String, String> moveMessages(List<? extends Message> messages, Folder folder) throws MessagingException {
public Map<String, String> moveMessages(List<? extends Message> messages, ImapFolder folder) throws MessagingException {
if (messages.isEmpty()) {
return null;
}
@ -390,7 +387,6 @@ public class ImapFolder extends Folder<ImapMessage> {
return uidMapping;
}
@Override
public int getMessageCount() {
return messageCount;
}
@ -417,12 +413,10 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public int getUnreadMessageCount() throws MessagingException {
return getRemoteMessageCount("UNSEEN NOT DELETED");
}
@Override
public int getFlaggedMessageCount() throws MessagingException {
return getRemoteMessageCount("FLAGGED NOT DELETED");
}
@ -455,12 +449,10 @@ public class ImapFolder extends Folder<ImapMessage> {
return uids.get(0);
}
@Override
public ImapMessage getMessage(String uid) throws MessagingException {
public ImapMessage getMessage(String uid) {
return new ImapMessage(uid);
}
@Override
public List<ImapMessage> getMessages(int start, int end, Date earliestDate,
MessageRetrievalListener<ImapMessage> listener) throws MessagingException {
return getMessages(start, end, earliestDate, false, listener);
@ -497,7 +489,6 @@ public class ImapFolder extends Folder<ImapMessage> {
return " SINCE " + RFC3501_DATE.get().format(earliestDate);
}
@Override
public boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate) throws IOException,
MessagingException {
@ -569,8 +560,8 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
private List<ImapMessage> getMessages(SearchResponse searchResponse, MessageRetrievalListener<ImapMessage> listener)
throws MessagingException {
private List<ImapMessage> getMessages(SearchResponse searchResponse,
MessageRetrievalListener<ImapMessage> listener) {
List<ImapMessage> messages = new ArrayList<>();
List<Long> uids = searchResponse.getNumbers();
@ -598,7 +589,6 @@ public class ImapFolder extends Folder<ImapMessage> {
return messages;
}
@Override
public void fetch(List<ImapMessage> messages, FetchProfile fetchProfile,
MessageRetrievalListener<ImapMessage> listener) throws MessagingException {
if (messages == null || messages.isEmpty()) {
@ -728,7 +718,6 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public void fetchPart(Message message, Part part, MessageRetrievalListener<Message> listener,
BodyFactory bodyFactory) throws MessagingException {
checkOpen();
@ -1092,7 +1081,6 @@ public class ImapFolder extends Folder<ImapMessage> {
*
* @return The mapping of original message UIDs to the new server UIDs.
*/
@Override
public Map<String, String> appendMessages(List<? extends Message> messages) throws MessagingException {
open(OPEN_MODE_RW);
checkOpen();
@ -1182,7 +1170,6 @@ public class ImapFolder extends Folder<ImapMessage> {
return messageIdHeader.length == 0 ? null : messageIdHeader[0];
}
@Override
public String getUidFromMessageId(String messageId) throws MessagingException {
if (K9MailLib.isDebug()) {
Timber.d("Looking for UID for message with message-id %s for %s", messageId, getLogId());
@ -1206,7 +1193,6 @@ public class ImapFolder extends Folder<ImapMessage> {
return null;
}
@Override
public void expunge() throws MessagingException {
open(OPEN_MODE_RW);
checkOpen();
@ -1218,7 +1204,6 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public void expungeUids(List<String> uids) throws MessagingException {
if (uids == null || uids.isEmpty()) {
throw new IllegalArgumentException("expungeUids() must be called with a non-empty set of UIDs");
@ -1242,7 +1227,6 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public void setFlags(Set<Flag> flags, boolean value) throws MessagingException {
open(OPEN_MODE_RW);
checkOpen();
@ -1260,7 +1244,6 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public String getNewPushState(String oldSerializedPushState, Message message) {
try {
String uid = message.getUid();
@ -1282,7 +1265,6 @@ public class ImapFolder extends Folder<ImapMessage> {
}
}
@Override
public void setFlags(List<? extends Message> messages, final Set<Flag> flags, boolean value)
throws MessagingException {
open(OPEN_MODE_RW);
@ -1339,10 +1321,6 @@ public class ImapFolder extends Folder<ImapMessage> {
return getServerId().hashCode();
}
private ImapStore getStore() {
return store;
}
protected String getLogId() {
String id = store.getStoreConfig().toString() + ":" + getServerId() + "/" + Thread.currentThread().getName();
if (connection != null) {
@ -1360,7 +1338,6 @@ public class ImapFolder extends Folder<ImapMessage> {
* @return List of messages found
* @throws MessagingException On any error.
*/
@Override
public List<ImapMessage> search(final String queryString, final Set<Flag> requiredFlags,
final Set<Flag> forbiddenFlags) throws MessagingException {

View file

@ -1,8 +1,6 @@
package com.fsck.k9.mail.store.imap;
import com.fsck.k9.mail.Folder;
import static com.fsck.k9.mail.store.imap.ImapResponseParser.equalsIgnoreCase;
@ -51,6 +49,6 @@ class SelectOrExamineResponse {
throw new IllegalStateException("Called getOpenMode() despite hasOpenMode() returning false");
}
return readWriteMode ? Folder.OPEN_MODE_RW : Folder.OPEN_MODE_RO;
return readWriteMode ? ImapFolder.OPEN_MODE_RW : ImapFolder.OPEN_MODE_RO;
}
}

View file

@ -16,7 +16,6 @@ import com.fsck.k9.mail.DefaultBodyFactory;
import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.FetchProfile.Item;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.K9LibRobolectricTestRunner;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessageRetrievalListener;
@ -35,8 +34,8 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.RuntimeEnvironment;
import static com.fsck.k9.mail.Folder.OPEN_MODE_RO;
import static com.fsck.k9.mail.Folder.OPEN_MODE_RW;
import static com.fsck.k9.mail.store.imap.ImapFolder.OPEN_MODE_RO;
import static com.fsck.k9.mail.store.imap.ImapFolder.OPEN_MODE_RW;
import static com.fsck.k9.mail.store.imap.ImapResponseHelper.createImapResponse;
import static java.util.Arrays.asList;
import static java.util.Collections.singleton;
@ -284,20 +283,6 @@ public class ImapFolderTest {
assertFalse(success);
}
@Test
public void copyMessages_withoutDestinationFolderOfWrongType_shouldThrow() throws Exception {
ImapFolder sourceFolder = createFolder("Source");
Folder destinationFolder = mock(Folder.class);
List<ImapMessage> messages = singletonList(mock(ImapMessage.class));
try {
sourceFolder.copyMessages(messages, destinationFolder);
fail("Expected exception");
} catch (MessagingException e) {
assertEquals("ImapFolder.copyMessages passed non-ImapFolder", e.getMessage());
}
}
@Test
public void copyMessages_withEmptyMessageList_shouldReturnNull() throws Exception {
ImapFolder sourceFolder = createFolder("Source");

View file

@ -16,7 +16,6 @@ import android.net.ConnectivityManager;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.FolderType;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.oauth.OAuth2TokenProvider;
@ -57,7 +56,7 @@ public class ImapStoreTest {
@Test
public void getFolder_shouldReturnImapFolderInstance() throws Exception {
Folder result = imapStore.getFolder("INBOX");
ImapFolder result = imapStore.getFolder("INBOX");
assertEquals(ImapFolder.class, result.getClass());
}
@ -65,9 +64,9 @@ public class ImapStoreTest {
@Test
public void getFolder_calledTwice_shouldReturnFirstInstance() throws Exception {
String folderName = "Trash";
Folder imapFolder = imapStore.getFolder(folderName);
ImapFolder imapFolder = imapStore.getFolder(folderName);
Folder result = imapStore.getFolder(folderName);
ImapFolder result = imapStore.getFolder(folderName);
assertEquals(imapFolder, result);
}
@ -168,7 +167,7 @@ public class ImapStoreTest {
when(imapConnection.executeSimpleCommand("LIST \"\" \"*\"")).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
List<? extends Folder> result = imapStore.getPersonalNamespaces();
List<ImapFolder> result = imapStore.getPersonalNamespaces();
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderNames(result));
@ -196,7 +195,7 @@ public class ImapStoreTest {
when(imapConnection.executeSimpleCommand("LIST \"\" \"*\"")).thenReturn(imapResponses);
imapStore.enqueueImapConnection(imapConnection);
List<? extends Folder> result = imapStore.getPersonalNamespaces();
List<ImapFolder> result = imapStore.getPersonalNamespaces();
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderNames(result));
@ -383,9 +382,9 @@ public class ImapStoreTest {
return storeConfig;
}
private Set<String> extractFolderNames(List<? extends Folder> folders) {
private Set<String> extractFolderNames(List<ImapFolder> folders) {
Set<String> folderNames = new HashSet<>(folders.size());
for (Folder folder : folders) {
for (ImapFolder folder : folders) {
folderNames.add(folder.getServerId());
}

View file

@ -3,8 +3,8 @@ package com.fsck.k9.mail.store.imap;
import org.junit.Test;
import static com.fsck.k9.mail.Folder.OPEN_MODE_RO;
import static com.fsck.k9.mail.Folder.OPEN_MODE_RW;
import static com.fsck.k9.mail.store.imap.ImapFolder.OPEN_MODE_RO;
import static com.fsck.k9.mail.store.imap.ImapFolder.OPEN_MODE_RW;
import static com.fsck.k9.mail.store.imap.ImapResponseHelper.createImapResponse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

View file

@ -3,7 +3,6 @@ package com.fsck.k9.mail.store.pop3;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -15,7 +14,6 @@ import android.annotation.SuppressLint;
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;
@ -29,7 +27,7 @@ import static com.fsck.k9.mail.store.pop3.Pop3Commands.*;
/**
* POP3 only supports one folder, "Inbox". So the folder name is the ID here.
*/
public class Pop3Folder extends Folder<Pop3Message> {
public class Pop3Folder {
public static final String INBOX = "INBOX";
@ -48,8 +46,7 @@ public class Pop3Folder extends Folder<Pop3Message> {
this.name = name;
}
@Override
public synchronized void open(int mode) throws MessagingException {
public synchronized void open() throws MessagingException {
if (isOpen()) {
return;
}
@ -70,17 +67,10 @@ public class Pop3Folder extends Folder<Pop3Message> {
uidToMsgNumMap.clear();
}
@Override
public boolean isOpen() {
return connection != null && connection.isOpen();
}
@Override
public int getMode() {
return Folder.OPEN_MODE_RW;
}
@Override
public void close() {
try {
if (isOpen()) {
@ -99,42 +89,19 @@ public class Pop3Folder extends Folder<Pop3Message> {
}
}
@Override
public String getServerId() {
return name;
}
@Override
public String getName() {
return name;
}
@Override
public boolean create() throws MessagingException {
return false;
}
@Override
public boolean exists() throws MessagingException {
return INBOX.equals(name);
}
@Override
public int getMessageCount() {
return messageCount;
}
@Override
public int getUnreadMessageCount() throws MessagingException {
return -1;
}
@Override
public int getFlaggedMessageCount() throws MessagingException {
return -1;
}
@Override
public Pop3Message getMessage(String uid) throws MessagingException {
public Pop3Message getMessage(String uid) {
Pop3Message message = uidToMsgMap.get(uid);
if (message == null) {
message = new Pop3Message(uid);
@ -142,8 +109,7 @@ public class Pop3Folder extends Folder<Pop3Message> {
return message;
}
@Override
public List<Pop3Message> getMessages(int start, int end, Date earliestDate, MessageRetrievalListener<Pop3Message> listener)
public List<Pop3Message> getMessages(int start, int end, MessageRetrievalListener<Pop3Message> listener)
throws MessagingException {
if (start < 1 || end < 1 || end < start) {
throw new MessagingException(String.format(Locale.US, "Invalid message set %d %d",
@ -179,8 +145,7 @@ public class Pop3Folder extends Folder<Pop3Message> {
return messages;
}
@Override
public boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate) {
public boolean areMoreMessagesAvailable(int indexOfOldestMessage) {
return indexOfOldestMessage > 1;
}
@ -325,7 +290,6 @@ public class Pop3Folder extends Folder<Pop3Message> {
* @param messages Messages to populate
* @param fp The contents to populate
*/
@Override
public void fetch(List<Pop3Message> messages, FetchProfile fp,
MessageRetrievalListener<Pop3Message> listener)
throws MessagingException {
@ -517,22 +481,6 @@ public class Pop3Folder extends Folder<Pop3Message> {
}
}
@Override
public Map<String, String> appendMessages(List<? extends Message> messages) throws MessagingException {
return null;
}
@Override
public String getUidFromMessageId(String messageId) throws MessagingException {
return null;
}
@Override
public void setFlags(final Set<Flag> flags, boolean value) throws MessagingException {
throw new UnsupportedOperationException("POP3: No setFlags(Set<Flag>,boolean)");
}
@Override
public void setFlags(List<? extends Message> messages, final Set<Flag> flags, boolean value)
throws MessagingException {
if (!value || !flags.contains(Flag.DELETED)) {
@ -560,21 +508,15 @@ public class Pop3Folder extends Folder<Pop3Message> {
true
);
}
open(Folder.OPEN_MODE_RW);
open();
connection.executeSimpleCommand(String.format(DELE_COMMAND + " %s", msgNum));
}
}
@Override
public boolean isFlagSupported(Flag flag) {
return (flag == Flag.DELETED);
}
@Override
public boolean supportsFetchingFlags() {
return false;
}
@Override
public boolean equals(Object o) {
if (o instanceof Pop3Folder) {

View file

@ -8,7 +8,6 @@ import androidx.annotation.NonNull;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
@ -53,7 +52,7 @@ public class Pop3Store {
public void checkSettings() throws MessagingException {
Pop3Folder folder = new Pop3Folder(this, Pop3Folder.INBOX);
try {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
folder.requestUidl();
}
finally {

View file

@ -1,6 +1,16 @@
package com.fsck.k9.mail.store.pop3;
import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.FetchProfile.Item;
import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.BinaryTempFileBody;
import com.fsck.k9.mail.store.StoreConfig;
import org.junit.Before;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@ -8,27 +18,14 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.FetchProfile.Item;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.BinaryTempFileBody;
import com.fsck.k9.mail.store.StoreConfig;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@ -53,68 +50,18 @@ public class Pop3FolderTest {
BinaryTempFileBody.setTempDirectory(new File(System.getProperty("java.io.tmpdir")));
}
@Test
public void create_withHoldsFoldersArgument_shouldDoNothing() throws Exception {
Pop3Folder folder = new Pop3Folder(mockStore, "TestFolder");
boolean result = folder.create();
assertFalse(result);
verifyZeroInteractions(mockConnection);
}
@Test
public void create_withHoldsMessagesArgument_shouldDoNothing() throws Exception {
Pop3Folder folder = new Pop3Folder(mockStore, "TestFolder");
boolean result = folder.create();
assertFalse(result);
verifyZeroInteractions(mockConnection);
}
@Test
public void exists_withInbox_shouldReturnTrue() throws Exception {
boolean result = folder.exists();
assertTrue(result);
}
@Test
public void exists_withNonInboxFolder_shouldReturnFalse() throws Exception {
folder = new Pop3Folder(mockStore, "TestFolder");
boolean result = folder.exists();
assertFalse(result);
}
@Test
public void getUnreadMessageCount_shouldBeMinusOne() throws Exception {
int result = folder.getUnreadMessageCount();
assertEquals(-1, result);
}
@Test
public void getFlaggedMessageCount_shouldBeMinusOne() throws Exception {
int result = folder.getFlaggedMessageCount();
assertEquals(-1, result);
}
@Test(expected = MessagingException.class)
public void open_withoutInboxFolder_shouldThrow() throws Exception {
Pop3Folder folder = new Pop3Folder(mockStore, "TestFolder");
folder.open(Folder.OPEN_MODE_RW);
folder.open();
}
@Test
public void open_withoutInboxFolder_shouldNotTryAndCreateConnection() throws Exception {
Pop3Folder folder = new Pop3Folder(mockStore, "TestFolder");
try {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
} catch (Exception ignored) {}
verify(mockStore, never()).createConnection();
}
@ -124,13 +71,13 @@ public class Pop3FolderTest {
throws MessagingException {
when(mockStore.createConnection()).thenThrow(new MessagingException("Test"));
folder.open(Folder.OPEN_MODE_RW);
folder.open();
}
@Test
public void open_withInboxFolder_shouldSetMessageCountFromStatResponse()
throws MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
int messageCount = folder.getMessageCount();
@ -143,13 +90,13 @@ public class Pop3FolderTest {
when(mockConnection.executeSimpleCommand(Pop3Commands.STAT_COMMAND))
.thenThrow(new MessagingException("Test"));
folder.open(Folder.OPEN_MODE_RW);
folder.open();
}
@Test
public void open_createsAndOpensConnection()
throws MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
verify(mockStore, times(1)).createConnection();
verify(mockConnection).open();
@ -158,24 +105,14 @@ public class Pop3FolderTest {
@Test
public void open_whenAlreadyOpenWithValidConnection_doesNotCreateAnotherConnection()
throws MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
when(mockConnection.isOpen()).thenReturn(true);
folder.open(Folder.OPEN_MODE_RW);
folder.open();
verify(mockStore, times(1)).createConnection();
}
@Test
public void getMode_withFolderOpenedInRO_isRW() throws MessagingException {
folder.open(Folder.OPEN_MODE_RO);
int mode = folder.getMode();
assertEquals(Folder.OPEN_MODE_RW, mode);
}
@Test
public void close_onNonOpenedFolder_succeeds()
throws MessagingException {
@ -188,7 +125,7 @@ public class Pop3FolderTest {
public void close_onOpenedFolder_succeeds()
throws MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
folder.close();
}
@ -197,7 +134,7 @@ public class Pop3FolderTest {
public void close_onOpenedFolder_sendsQUIT()
throws MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
when(mockConnection.isOpen()).thenReturn(true);
folder.close();
@ -209,7 +146,7 @@ public class Pop3FolderTest {
public void close_withExceptionQuiting_ignoresException()
throws MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
when(mockConnection.isOpen()).thenReturn(true);
doThrow(new MessagingException("Test"))
.when(mockConnection)
@ -222,7 +159,7 @@ public class Pop3FolderTest {
public void close_onOpenedFolder_closesConnection()
throws MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
when(mockConnection.isOpen()).thenReturn(true);
folder.close();
@ -232,35 +169,35 @@ public class Pop3FolderTest {
@Test
public void getMessages_returnsListOfMessagesOnServer() throws IOException, MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
when(mockConnection.readLine()).thenReturn("1 abcd").thenReturn(".");
List<Pop3Message> result = folder.getMessages(1, 1, null, mockListener);
List<Pop3Message> result = folder.getMessages(1, 1, mockListener);
assertEquals(1, result.size());
}
@Test(expected = MessagingException.class)
public void getMessages_withInvalidSet_throwsException() throws IOException, MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
folder.getMessages(2, 1, null, mockListener);
folder.getMessages(2, 1, mockListener);
}
@Test(expected = MessagingException.class)
public void getMessages_withIOExceptionReadingLine_throwsException() throws IOException, MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
when(mockConnection.readLine()).thenThrow(new IOException("Test"));
folder.getMessages(1, 1, null, mockListener);
folder.getMessages(1, 1, mockListener);
}
@Test
public void getMessage_withPreviouslyFetchedMessage_returnsMessage()
throws IOException, MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
List<Pop3Message> messageList = setupMessageFromServer();
@ -272,7 +209,7 @@ public class Pop3FolderTest {
@Test
public void getMessage_withNoPreviouslyFetchedMessage_returnsNewMessage()
throws IOException, MessagingException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
Pop3Message message = folder.getMessage("abcd");
@ -282,7 +219,7 @@ public class Pop3FolderTest {
@Test
public void fetch_withEnvelopeProfile_setsSizeOfMessage() throws MessagingException, IOException {
folder.open(Folder.OPEN_MODE_RW);
folder.open();
List<Pop3Message> messageList = setupMessageFromServer();
FetchProfile fetchProfile = new FetchProfile();
fetchProfile.add(Item.ENVELOPE);
@ -304,7 +241,7 @@ public class Pop3FolderTest {
"Content-Transfer-Encoding: 7bit\r\n" +
"\r\n" +
"this is some test text.").getBytes());
folder.open(Folder.OPEN_MODE_RW);
folder.open();
List<Pop3Message> messageList = setupMessageFromServer();
FetchProfile fetchProfile = new FetchProfile();
fetchProfile.add(Item.BODY);
@ -321,6 +258,6 @@ public class Pop3FolderTest {
private List<Pop3Message> setupMessageFromServer() throws IOException, MessagingException {
when(mockConnection.readLine()).thenReturn("1 abcd").thenReturn(".");
return folder.getMessages(1, 1, null, mockListener);
return folder.getMessages(1, 1, mockListener);
}
}

View file

@ -10,7 +10,6 @@ import java.net.Socket;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.AuthenticationFailedException;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.filter.Base64;
@ -138,7 +137,7 @@ public class Pop3StoreTest {
when(mockSocket.getOutputStream()).thenReturn(byteArrayOutputStream);
Pop3Folder folder = store.getFolder(Pop3Folder.INBOX);
folder.open(Folder.OPEN_MODE_RW);
folder.open();
assertEquals(20, folder.getMessageCount());
assertEquals(AUTH + CAPA + AUTH_PLAIN_WITH_LOGIN + STAT, byteArrayOutputStream.toString("UTF-8"));
@ -153,7 +152,7 @@ public class Pop3StoreTest {
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(response.getBytes("UTF-8")));
Pop3Folder folder = store.getFolder(Pop3Folder.INBOX);
folder.open(Folder.OPEN_MODE_RW);
folder.open();
}
private ServerSettings createServerSettings() {

View file

@ -2,7 +2,7 @@ package com.fsck.k9.mail.store.webdav;
import com.fsck.k9.mail.FetchProfile;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.FolderType;
import com.fsck.k9.mail.K9MailLib;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessageRetrievalListener;
@ -39,8 +39,9 @@ import static com.fsck.k9.mail.helper.UrlEncodingHelper.encodeUtf8;
/**
* A WebDav Folder
*/
public class WebDavFolder extends Folder<WebDavMessage> {
public class WebDavFolder {
private String mName;
private FolderType type = FolderType.REGULAR;
private String mFolderUrl;
private boolean mIsOpen = false;
private int mMessageCount = 0;
@ -58,6 +59,14 @@ public class WebDavFolder extends Folder<WebDavMessage> {
buildFolderUrl();
}
public FolderType getType() {
return type;
}
public void setType(FolderType type) {
this.type = type;
}
private void buildFolderUrl() {
String encodedName;
String[] urlParts = this.mName.split("/");
@ -86,20 +95,19 @@ public class WebDavFolder extends Folder<WebDavMessage> {
}
}
@Override
public void open(int mode) throws MessagingException {
public void open() throws MessagingException {
store.getHttpClient();
this.mIsOpen = true;
}
@Override
public Map<String, String> copyMessages(List<? extends Message> messages, Folder folder) throws MessagingException {
public Map<String, String> copyMessages(List<? extends Message> messages, WebDavFolder folder)
throws MessagingException {
moveOrCopyMessages(messages, folder.getServerId(), false);
return null;
}
@Override
public Map<String, String> moveMessages(List<? extends Message> messages, Folder folder) throws MessagingException {
public Map<String, String> moveMessages(List<? extends Message> messages, WebDavFolder folder)
throws MessagingException {
moveOrCopyMessages(messages, folder.getServerId(), true);
return null;
}
@ -160,69 +168,41 @@ public class WebDavFolder extends Folder<WebDavMessage> {
return messageCount;
}
@Override
public int getMessageCount() throws MessagingException {
open(Folder.OPEN_MODE_RW);
open();
this.mMessageCount = getMessageCount(true);
return this.mMessageCount;
}
@Override
public int getUnreadMessageCount() throws MessagingException {
open(Folder.OPEN_MODE_RW);
open();
this.mUnreadMessageCount = getMessageCount(false);
return this.mUnreadMessageCount;
}
@Override
public int getFlaggedMessageCount() throws MessagingException {
return -1;
}
@Override
public boolean isOpen() {
return this.mIsOpen;
}
@Override
public int getMode() {
return Folder.OPEN_MODE_RW;
}
@Override
public String getServerId() {
return this.mName;
}
@Override
public String getName() {
return this.mName;
}
@Override
public boolean exists() {
return true;
}
@Override
public void close() {
this.mMessageCount = 0;
this.mUnreadMessageCount = 0;
this.mIsOpen = false;
}
@Override
public boolean create() throws MessagingException {
return true;
}
@Override
public WebDavMessage getMessage(String uid) throws MessagingException {
public WebDavMessage getMessage(String uid) {
return new WebDavMessage(uid, this);
}
@Override
public List<WebDavMessage> getMessages(int start, int end, Date earliestDate, MessageRetrievalListener<WebDavMessage> listener)
public List<WebDavMessage> getMessages(int start, int end, MessageRetrievalListener<WebDavMessage> listener)
throws MessagingException {
List<WebDavMessage> messages = new ArrayList<>();
String[] uids;
@ -270,7 +250,6 @@ public class WebDavFolder extends Folder<WebDavMessage> {
return messages;
}
@Override
public boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate) {
return indexOfOldestMessage > 1;
}
@ -288,7 +267,6 @@ public class WebDavFolder extends Folder<WebDavMessage> {
return dataset.getUidToUrl();
}
@Override
public void fetch(List<WebDavMessage> messages, FetchProfile fp, MessageRetrievalListener<WebDavMessage> listener)
throws MessagingException {
if (messages == null ||
@ -561,7 +539,6 @@ public class WebDavFolder extends Folder<WebDavMessage> {
}
}
@Override
public void setFlags(List<? extends Message> messages, final Set<Flag> flags, boolean value)
throws MessagingException {
String[] uids = new String[messages.size()];
@ -625,7 +602,6 @@ public class WebDavFolder extends Folder<WebDavMessage> {
return store.getUrl() + "Deleted%20Items/" + filename;
}
@Override
public Map<String, String> appendMessages(List<? extends Message> messages) throws MessagingException {
appendWebDavMessages(messages);
return null;
@ -651,7 +627,7 @@ public class WebDavFolder extends Folder<WebDavMessage> {
}
out = new ByteArrayOutputStream((int) size);
open(Folder.OPEN_MODE_RW);
open();
EOLConvertingOutputStream msgOut = new EOLConvertingOutputStream(
new BufferedOutputStream(out, 1024));
message.writeTo(msgOut);
@ -689,19 +665,6 @@ public class WebDavFolder extends Folder<WebDavMessage> {
return super.equals(o);
}
@Override
public String getUidFromMessageId(String messageId) throws MessagingException {
Timber.e("Unimplemented method getUidFromMessageId in WebDavStore.WebDavFolder could lead to duplicate messages "
+ " being uploaded to the Sent folder");
return null;
}
@Override
public void setFlags(final Set<Flag> flags, boolean value) throws MessagingException {
Timber.e("Unimplemented method setFlags(Set<Flag>, boolean) breaks markAllMessagesAsRead and EmptyTrash");
// Try to make this efficient by not retrieving all of the messages
}
public String getUrl() {
return mFolderUrl;
}

View file

@ -18,14 +18,12 @@ import java.util.Map;
import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.FolderType;
import com.fsck.k9.mail.K9MailLib;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.ssl.TrustManagerFactory;
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
import com.fsck.k9.mail.store.StoreConfig;
import com.fsck.k9.mail.store.webdav.WebDavHttpClient.WebDavHttpClientFactory;
import javax.net.ssl.SSLException;
@ -83,7 +81,7 @@ public class WebDavStore {
private short authenticationType = WebDavConstants.AUTH_TYPE_NONE;
private String cachedLoginUrl;
private Folder sendFolder = null;
private WebDavFolder sendFolder = null;
private Map<String, WebDavFolder> folderList = new HashMap<>();
public WebDavStore(TrustManagerFactory trustManagerFactory, WebDavStoreSettings serverSettings, StoreConfig storeConfig) {
@ -162,8 +160,8 @@ public class WebDavStore {
authenticate();
}
public List<? extends Folder> getPersonalNamespaces() throws MessagingException {
List<Folder> folderList = new LinkedList<>();
public List<WebDavFolder> getPersonalNamespaces() throws MessagingException {
List<WebDavFolder> folderList = new LinkedList<>();
/*
* We have to check authentication here so we have the proper URL stored
*/
@ -282,7 +280,7 @@ public class WebDavStore {
return folder;
}
private Folder getSendSpoolFolder() {
private WebDavFolder getSendSpoolFolder() {
if (sendFolder == null) {
sendFolder = getFolder(WebDavConstants.DAV_MAIL_SEND_FOLDER);
}
@ -939,7 +937,7 @@ public class WebDavStore {
public void sendMessages(List<? extends Message> messages) throws MessagingException {
WebDavFolder tmpFolder = getFolder(storeConfig.getDraftsFolder());
try {
tmpFolder.open(Folder.OPEN_MODE_RW);
tmpFolder.open();
List<? extends Message> retMessages = tmpFolder.appendWebDavMessages(messages);
tmpFolder.moveMessages(retMessages, getSendSpoolFolder());

View file

@ -7,7 +7,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -34,8 +33,6 @@ import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static com.fsck.k9.mail.Folder.OPEN_MODE_RO;
import static com.fsck.k9.mail.Folder.OPEN_MODE_RW;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -354,7 +351,7 @@ public class WebDavFolderTest {
@Test
public void open_should_open_folder() throws MessagingException {
folder.open(OPEN_MODE_RW);
folder.open();
assertTrue(folder.isOpen());
}
@ -364,18 +361,6 @@ public class WebDavFolderTest {
assertFalse(folder.isOpen());
}
@Test
public void mode_is_always_readwrite() throws Exception {
assertEquals(OPEN_MODE_RW, folder.getMode());
folder.open(OPEN_MODE_RO);
assertEquals(OPEN_MODE_RW, folder.getMode());
}
@Test
public void exists_is_always_true() throws Exception {
assertTrue(folder.exists());
}
@Test
public void can_fetch_message_count() throws Exception {
int messageCount = 23;
@ -420,7 +405,7 @@ public class WebDavFolderTest {
when(mockStore.processRequest(eq("https://localhost/webDavStoreUrl/testFolder"), eq("SEARCH"),
eq(messagesXml), Matchers.<Map<String, String>>any())).thenReturn(mockDataSet);
folder.getMessages(messageStart, messageEnd, new Date(), listener);
folder.getMessages(messageStart, messageEnd, listener);
verify(listener, times(5)).messageStarted(anyString(), anyInt(), eq(5));
verify(listener, times(5)).messageFinished(any(WebDavMessage.class), anyInt(), eq(5));
@ -438,7 +423,7 @@ public class WebDavFolderTest {
when(mockStore.processRequest(eq("https://localhost/webDavStoreUrl/testFolder"), eq("SEARCH"),
eq(messagesXml), Matchers.<Map<String, String>>any())).thenReturn(mockDataSet);
folder.getMessages(messageStart, messageEnd, new Date(), listener);
folder.getMessages(messageStart, messageEnd, listener);
verify(mockStore, times(2)).processRequest(anyString(), anyString(), anyString(),
headerCaptor.capture());
@ -464,7 +449,7 @@ public class WebDavFolderTest {
@Test(expected = MessagingException.class)
public void getMessages_should_throw_message_exception_if_requesting_messages_from_empty_folder()
throws MessagingException {
folder.getMessages(0, 10, new Date(), listener);
folder.getMessages(0, 10, listener);
}
private void setupMoveOrCopy() throws MessagingException {

View file

@ -11,7 +11,6 @@ import java.util.Map;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.FolderType;
import com.fsck.k9.mail.K9LibRobolectricTestRunner;
import com.fsck.k9.mail.MessagingException;
@ -197,7 +196,7 @@ public class WebDavStoreTest {
@Test
public void getFolder_shouldReturnWebDavFolderInstance() {
Folder result = webDavStore.getFolder("INBOX");
WebDavFolder result = webDavStore.getFolder("INBOX");
assertEquals(WebDavFolder.class, result.getClass());
}
@ -205,9 +204,9 @@ public class WebDavStoreTest {
@Test
public void getFolder_calledTwice_shouldReturnFirstInstance() {
String folderName = "Trash";
Folder webDavFolder = webDavStore.getFolder(folderName);
WebDavFolder webDavFolder = webDavStore.getFolder(folderName);
Folder result = webDavStore.getFolder(folderName);
WebDavFolder result = webDavStore.getFolder(folderName);
assertSame(webDavFolder, result);
}
@ -229,10 +228,10 @@ public class WebDavStoreTest {
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE, createOkPropfindResponse(),
createOkSearchResponse());
List<? extends Folder> folders = webDavStore.getPersonalNamespaces();
List<WebDavFolder> folders = webDavStore.getPersonalNamespaces();
Map<String, FolderType> folderNameToTypeMap = new HashMap<>();
for (Folder folder : folders) {
for (WebDavFolder folder : folders) {
folderNameToTypeMap.put(folder.getName(), folder.getType());
}
assertEquals(FolderType.INBOX, folderNameToTypeMap.get("Inbox"));
@ -257,7 +256,7 @@ public class WebDavStoreTest {
configureHttpResponses(UNAUTHORIZED_401_RESPONSE, OK_200_RESPONSE, createOkPropfindResponse(),
createOkSearchResponse());
List<? extends Folder> folders = webDavStore.getPersonalNamespaces();
List<WebDavFolder> folders = webDavStore.getPersonalNamespaces();
List<HttpGeneric> requests = requestCaptor.getAllValues();