Merge pull request #4478 from k9mail/bye_Folder
Get rid of base class Folder
This commit is contained in:
commit
5c3750ede3
36 changed files with 304 additions and 978 deletions
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<>();
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue