Move code to search/fetch messages to Backend implementations
This commit is contained in:
parent
d7558a1313
commit
80c76e6fb9
16 changed files with 232 additions and 62 deletions
|
@ -1,8 +1,10 @@
|
|||
package com.fsck.k9.backend.api
|
||||
|
||||
|
||||
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.MessagingException
|
||||
|
||||
|
||||
|
@ -44,4 +46,15 @@ interface Backend {
|
|||
targetFolderServerId: String,
|
||||
messageServerIds: List<String>
|
||||
): Map<String, String>?
|
||||
|
||||
@Throws(MessagingException::class)
|
||||
fun search(
|
||||
folderServerId: String,
|
||||
query: String?,
|
||||
requiredFlags: Set<Flag>?,
|
||||
forbiddenFlags: Set<Flag>?
|
||||
): List<String>
|
||||
|
||||
@Throws(MessagingException::class)
|
||||
fun fetchMessage(folderServerId: String, messageServerId: String, fetchProfile: FetchProfile): Message
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package com.fsck.k9.backend.imap
|
||||
|
||||
|
||||
import com.fsck.k9.mail.FetchProfile
|
||||
import com.fsck.k9.mail.Message
|
||||
import com.fsck.k9.mail.store.imap.ImapFolder
|
||||
import com.fsck.k9.mail.store.imap.ImapMessage
|
||||
import com.fsck.k9.mail.store.imap.ImapStore
|
||||
|
||||
|
||||
internal class CommandFetchMessage(private val imapStore: ImapStore) {
|
||||
|
||||
fun fetchMessage(folderServerId: String, messageServerId: String, fetchProfile: FetchProfile): Message {
|
||||
val folder = imapStore.getFolder(folderServerId)
|
||||
try {
|
||||
val message = folder.getMessage(messageServerId)
|
||||
|
||||
//fun fact: ImapFolder.fetch can't handle getting STRUCTURE at same time as headers
|
||||
if (fetchProfile.contains(FetchProfile.Item.STRUCTURE) &&
|
||||
fetchProfile.contains(FetchProfile.Item.ENVELOPE)) {
|
||||
val headerFetchProfile = fetchProfile.without(FetchProfile.Item.STRUCTURE)
|
||||
val structureFetchProfile = FetchProfile().apply { add(FetchProfile.Item.STRUCTURE) }
|
||||
|
||||
fetchMessage(folder, message, headerFetchProfile)
|
||||
fetchMessage(folder, message, structureFetchProfile)
|
||||
} else {
|
||||
fetchMessage(folder, message, fetchProfile)
|
||||
}
|
||||
|
||||
return message
|
||||
} finally {
|
||||
folder.close()
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchMessage(remoteFolder: ImapFolder, message: ImapMessage, fetchProfile: FetchProfile) {
|
||||
remoteFolder.fetch(listOf(message), fetchProfile, null)
|
||||
}
|
||||
|
||||
private fun FetchProfile.without(item: FetchProfile.Item) = FetchProfile().apply {
|
||||
this@without.forEach {
|
||||
if (it != item) add(it)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.fsck.k9.backend.imap
|
||||
|
||||
|
||||
import com.fsck.k9.mail.Flag
|
||||
import com.fsck.k9.mail.store.imap.ImapStore
|
||||
|
||||
|
||||
internal class CommandSearch(private val imapStore: ImapStore) {
|
||||
|
||||
fun search(
|
||||
folderServerId: String,
|
||||
query: String?,
|
||||
requiredFlags: Set<Flag>?,
|
||||
forbiddenFlags: Set<Flag>?
|
||||
): List<String> {
|
||||
val folder = imapStore.getFolder(folderServerId)
|
||||
try {
|
||||
return folder.search(query, requiredFlags, forbiddenFlags)
|
||||
.sortedWith(UidReverseComparator())
|
||||
.map { it.uid }
|
||||
} finally {
|
||||
folder.close()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,14 +3,17 @@ package com.fsck.k9.backend.imap;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.fsck.k9.backend.api.Backend;
|
||||
import com.fsck.k9.backend.api.BackendStorage;
|
||||
import com.fsck.k9.backend.api.FolderInfo;
|
||||
import com.fsck.k9.backend.api.SyncConfig;
|
||||
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.Message;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.store.imap.ImapStore;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -25,6 +28,8 @@ public class ImapBackend implements Backend {
|
|||
private final CommandExpunge commandExpunge;
|
||||
private final CommandMoveOrCopyMessages commandMoveOrCopyMessages;
|
||||
private final CommandDeleteAll commandDeleteAll;
|
||||
private final CommandSearch commandSearch;
|
||||
private final CommandFetchMessage commandFetchMessage;
|
||||
|
||||
|
||||
public ImapBackend(String accountName, BackendStorage backendStorage, ImapStore imapStore) {
|
||||
|
@ -35,6 +40,8 @@ public class ImapBackend implements Backend {
|
|||
commandMoveOrCopyMessages = new CommandMoveOrCopyMessages(imapStore);
|
||||
commandGetFolders = new CommandGetFolders(imapStore);
|
||||
commandDeleteAll = new CommandDeleteAll(imapStore);
|
||||
commandSearch = new CommandSearch(imapStore);
|
||||
commandFetchMessage = new CommandFetchMessage(imapStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,4 +106,19 @@ public class ImapBackend implements Backend {
|
|||
@NotNull List<String> messageServerIds) throws MessagingException {
|
||||
return commandMoveOrCopyMessages.copyMessages(sourceFolderServerId, targetFolderServerId, messageServerIds);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> search(@NotNull String folderServerId, @Nullable String query,
|
||||
@Nullable Set<? extends Flag> requiredFlags, @Nullable Set<? extends Flag> forbiddenFlags)
|
||||
throws MessagingException {
|
||||
return commandSearch.search(folderServerId, query, requiredFlags, forbiddenFlags);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Message fetchMessage(@NotNull String folderServerId, @NotNull String messageServerId,
|
||||
@NotNull FetchProfile fetchProfile) throws MessagingException {
|
||||
return commandFetchMessage.fetchMessage(folderServerId, messageServerId, fetchProfile);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package com.fsck.k9.backend.pop3
|
||||
|
||||
|
||||
import com.fsck.k9.mail.FetchProfile
|
||||
import com.fsck.k9.mail.Message
|
||||
import com.fsck.k9.mail.store.pop3.Pop3Store
|
||||
|
||||
|
||||
internal class CommandFetchMessage(private val pop3Store: Pop3Store) {
|
||||
|
||||
fun fetchMessage(folderServerId: String, messageServerId: String, fetchProfile: FetchProfile): Message {
|
||||
val folder = pop3Store.getFolder(folderServerId)
|
||||
try {
|
||||
val message = folder.getMessage(messageServerId)
|
||||
|
||||
folder.fetch(listOf(message), fetchProfile, null)
|
||||
|
||||
return message
|
||||
} finally {
|
||||
folder.close()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,8 +5,10 @@ import com.fsck.k9.backend.api.BackendStorage
|
|||
import com.fsck.k9.backend.api.FolderInfo
|
||||
import com.fsck.k9.backend.api.SyncConfig
|
||||
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.Message
|
||||
import com.fsck.k9.mail.store.pop3.Pop3Store
|
||||
|
||||
class Pop3Backend(accountName: String, backendStorage: BackendStorage, pop3Store: Pop3Store) : Backend {
|
||||
|
@ -14,6 +16,7 @@ class Pop3Backend(accountName: String, backendStorage: BackendStorage, pop3Store
|
|||
private val commandGetFolders = CommandGetFolders()
|
||||
private val commandSetFlag = CommandSetFlag(pop3Store)
|
||||
private val commandDeleteAll = CommandDeleteAll(pop3Store)
|
||||
private val commandFetchMessage = CommandFetchMessage(pop3Store)
|
||||
|
||||
override val supportsSeenFlag: Boolean = false
|
||||
override val supportsExpunge: Boolean = false
|
||||
|
@ -61,4 +64,17 @@ class Pop3Backend(accountName: String, backendStorage: BackendStorage, pop3Store
|
|||
): Map<String, String>? {
|
||||
throw UnsupportedOperationException("not supported")
|
||||
}
|
||||
|
||||
override fun search(
|
||||
folderServerId: String,
|
||||
query: String?,
|
||||
requiredFlags: Set<Flag>?,
|
||||
forbiddenFlags: Set<Flag>?
|
||||
): List<String> {
|
||||
throw UnsupportedOperationException("not supported")
|
||||
}
|
||||
|
||||
override fun fetchMessage(folderServerId: String, messageServerId: String, fetchProfile: FetchProfile): Message {
|
||||
return commandFetchMessage.fetchMessage(folderServerId, messageServerId, fetchProfile)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package com.fsck.k9.backend.webdav
|
||||
|
||||
|
||||
import com.fsck.k9.mail.FetchProfile
|
||||
import com.fsck.k9.mail.Message
|
||||
import com.fsck.k9.mail.store.webdav.WebDavStore
|
||||
|
||||
|
||||
internal class CommandFetchMessage(private val webDavStore: WebDavStore) {
|
||||
|
||||
fun fetchMessage(folderServerId: String, messageServerId: String, fetchProfile: FetchProfile): Message {
|
||||
val folder = webDavStore.getFolder(folderServerId)
|
||||
try {
|
||||
val message = folder.getMessage(messageServerId)
|
||||
|
||||
folder.fetch(listOf(message), fetchProfile, null)
|
||||
|
||||
return message
|
||||
} finally {
|
||||
folder.close()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,8 +5,10 @@ import com.fsck.k9.backend.api.BackendStorage
|
|||
import com.fsck.k9.backend.api.FolderInfo
|
||||
import com.fsck.k9.backend.api.SyncConfig
|
||||
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.Message
|
||||
import com.fsck.k9.mail.MessagingException
|
||||
import com.fsck.k9.mail.store.webdav.WebDavStore
|
||||
|
||||
|
@ -17,6 +19,7 @@ class WebDavBackend(accountName: String, backendStorage: BackendStorage, webDavS
|
|||
private val commandMarkAllAsRead = CommandMarkAllAsRead(webDavStore)
|
||||
private val commandMoveOrCopyMessages = CommandMoveOrCopyMessages(webDavStore)
|
||||
private val commandDeleteAll = CommandDeleteAll(webDavStore)
|
||||
private val commandFetchMessage = CommandFetchMessage(webDavStore)
|
||||
|
||||
override val supportsSeenFlag: Boolean = true
|
||||
override val supportsExpunge: Boolean = true
|
||||
|
@ -66,4 +69,17 @@ class WebDavBackend(accountName: String, backendStorage: BackendStorage, webDavS
|
|||
): Map<String, String>? {
|
||||
return commandMoveOrCopyMessages.copyMessages(sourceFolderServerId, targetFolderServerId, messageServerIds)
|
||||
}
|
||||
|
||||
override fun search(
|
||||
folderServerId: String,
|
||||
query: String?,
|
||||
requiredFlags: Set<Flag>?,
|
||||
forbiddenFlags: Set<Flag>?
|
||||
): List<String> {
|
||||
throw UnsupportedOperationException("not supported")
|
||||
}
|
||||
|
||||
override fun fetchMessage(folderServerId: String, messageServerId: String, fetchProfile: FetchProfile): Message {
|
||||
return commandFetchMessage.fetchMessage(folderServerId, messageServerId, fetchProfile)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -590,45 +590,36 @@ public class MessagingController {
|
|||
listener.remoteSearchStarted(folderServerId);
|
||||
}
|
||||
|
||||
List<Message> extraResults = new ArrayList<>();
|
||||
List<String> extraResults = new ArrayList<>();
|
||||
try {
|
||||
RemoteStore remoteStore = acct.getRemoteStore();
|
||||
LocalStore localStore = acct.getLocalStore();
|
||||
|
||||
if (remoteStore == null || localStore == null) {
|
||||
throw new MessagingException("Could not get store");
|
||||
}
|
||||
|
||||
Folder remoteFolder = remoteStore.getFolder(folderServerId);
|
||||
LocalFolder localFolder = localStore.getFolder(folderServerId);
|
||||
if (remoteFolder == null || localFolder == null) {
|
||||
if (localFolder == null) {
|
||||
throw new MessagingException("Folder not found");
|
||||
}
|
||||
|
||||
List<Message> messages = remoteFolder.search(query, requiredFlags, forbiddenFlags);
|
||||
Backend backend = getBackend(acct);
|
||||
|
||||
Timber.i("Remote search got %d results", messages.size());
|
||||
List<String> messageServerIds = backend.search(folderServerId, query, requiredFlags, forbiddenFlags);
|
||||
|
||||
Timber.i("Remote search got %d results", messageServerIds.size());
|
||||
|
||||
// There's no need to fetch messages already completely downloaded
|
||||
List<Message> remoteMessages = localFolder.extractNewMessages(messages);
|
||||
messages.clear();
|
||||
messageServerIds = localFolder.extractNewMessages(messageServerIds);
|
||||
|
||||
if (listener != null) {
|
||||
listener.remoteSearchServerQueryComplete(folderServerId, remoteMessages.size(),
|
||||
listener.remoteSearchServerQueryComplete(folderServerId, messageServerIds.size(),
|
||||
acct.getRemoteSearchNumResults());
|
||||
}
|
||||
|
||||
Collections.sort(remoteMessages, new UidReverseComparator());
|
||||
|
||||
int resultLimit = acct.getRemoteSearchNumResults();
|
||||
if (resultLimit > 0 && remoteMessages.size() > resultLimit) {
|
||||
extraResults = remoteMessages.subList(resultLimit, remoteMessages.size());
|
||||
remoteMessages = remoteMessages.subList(0, resultLimit);
|
||||
if (resultLimit > 0 && messageServerIds.size() > resultLimit) {
|
||||
extraResults = messageServerIds.subList(resultLimit, messageServerIds.size());
|
||||
messageServerIds = messageServerIds.subList(0, resultLimit);
|
||||
}
|
||||
|
||||
loadSearchResultsSynchronous(remoteMessages, localFolder, remoteFolder, listener);
|
||||
|
||||
|
||||
loadSearchResultsSynchronous(acct, messageServerIds, localFolder);
|
||||
} catch (Exception e) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
Timber.i(e, "Caught exception on aborted remote search; safe to ignore.");
|
||||
|
@ -647,8 +638,8 @@ public class MessagingController {
|
|||
|
||||
}
|
||||
|
||||
public void loadSearchResults(final Account account, final String folderServerId, final List<Message> messages,
|
||||
final MessagingListener listener) {
|
||||
public void loadSearchResults(final Account account, final String folderServerId,
|
||||
final List<String> messageServerIds, final MessagingListener listener) {
|
||||
threadPool.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -656,20 +647,18 @@ public class MessagingController {
|
|||
listener.enableProgressIndicator(true);
|
||||
}
|
||||
try {
|
||||
RemoteStore remoteStore = account.getRemoteStore();
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
|
||||
if (remoteStore == null || localStore == null) {
|
||||
if (localStore == null) {
|
||||
throw new MessagingException("Could not get store");
|
||||
}
|
||||
|
||||
Folder remoteFolder = remoteStore.getFolder(folderServerId);
|
||||
LocalFolder localFolder = localStore.getFolder(folderServerId);
|
||||
if (remoteFolder == null || localFolder == null) {
|
||||
if (localFolder == null) {
|
||||
throw new MessagingException("Folder not found");
|
||||
}
|
||||
|
||||
loadSearchResultsSynchronous(messages, localFolder, remoteFolder, listener);
|
||||
loadSearchResultsSynchronous(account, messageServerIds, localFolder);
|
||||
} catch (MessagingException e) {
|
||||
Timber.e(e, "Exception in loadSearchResults");
|
||||
} finally {
|
||||
|
@ -681,25 +670,23 @@ public class MessagingController {
|
|||
});
|
||||
}
|
||||
|
||||
private void loadSearchResultsSynchronous(List<Message> messages, LocalFolder localFolder, Folder remoteFolder,
|
||||
MessagingListener listener) throws MessagingException {
|
||||
final FetchProfile header = new FetchProfile();
|
||||
header.add(FetchProfile.Item.FLAGS);
|
||||
header.add(FetchProfile.Item.ENVELOPE);
|
||||
final FetchProfile structure = new FetchProfile();
|
||||
structure.add(FetchProfile.Item.STRUCTURE);
|
||||
private void loadSearchResultsSynchronous(Account account, List<String> messageServerIds, LocalFolder localFolder)
|
||||
throws MessagingException {
|
||||
|
||||
int i = 0;
|
||||
for (Message message : messages) {
|
||||
i++;
|
||||
LocalMessage localMsg = localFolder.getMessage(message.getUid());
|
||||
FetchProfile fetchProfile = new FetchProfile();
|
||||
fetchProfile.add(FetchProfile.Item.FLAGS);
|
||||
fetchProfile.add(FetchProfile.Item.ENVELOPE);
|
||||
fetchProfile.add(FetchProfile.Item.STRUCTURE);
|
||||
|
||||
if (localMsg == null) {
|
||||
remoteFolder.fetch(Collections.singletonList(message), header, null);
|
||||
//fun fact: ImapFolder.fetch can't handle getting STRUCTURE at same time as headers
|
||||
remoteFolder.fetch(Collections.singletonList(message), structure, null);
|
||||
Backend backend = getBackend(account);
|
||||
String folderServerId = localFolder.getServerId();
|
||||
|
||||
for (String messageServerId : messageServerIds) {
|
||||
LocalMessage localMessage = localFolder.getMessage(messageServerId);
|
||||
|
||||
if (localMessage == null) {
|
||||
Message message = backend.fetchMessage(folderServerId, messageServerId, fetchProfile);
|
||||
localFolder.appendMessages(Collections.singletonList(message));
|
||||
localMsg = localFolder.getMessage(message.getUid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public interface MessagingListener {
|
|||
|
||||
void remoteSearchStarted(String folder);
|
||||
void remoteSearchServerQueryComplete(String folderServerId, int numResults, int maxResults);
|
||||
void remoteSearchFinished(String folderServerId, int numResults, int maxResults, List<Message> extraResults);
|
||||
void remoteSearchFinished(String folderServerId, int numResults, int maxResults, List<String> extraResults);
|
||||
void remoteSearchFailed(String folderServerId, String err);
|
||||
|
||||
void enableProgressIndicator(boolean enable);
|
||||
|
|
|
@ -171,7 +171,7 @@ public abstract class SimpleMessagingListener implements MessagingListener {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void remoteSearchFinished(String folderServerId, int numResults, int maxResults, List<Message> extraResults) {
|
||||
public void remoteSearchFinished(String folderServerId, int numResults, int maxResults, List<String> extraResults) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -183,7 +183,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
|
||||
private boolean remoteSearchPerformed = false;
|
||||
private Future<?> remoteSearchFuture = null;
|
||||
private List<Message> extraSearchResults;
|
||||
private List<String> extraSearchResults;
|
||||
|
||||
private String title;
|
||||
private LocalSearch search = null;
|
||||
|
@ -360,7 +360,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
int numResults = extraSearchResults.size();
|
||||
int limit = account.getRemoteSearchNumResults();
|
||||
|
||||
List<Message> toProcess = extraSearchResults;
|
||||
List<String> toProcess = extraSearchResults;
|
||||
|
||||
if (limit > 0 && numResults > limit) {
|
||||
toProcess = toProcess.subList(0, limit);
|
||||
|
@ -1318,7 +1318,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
}
|
||||
|
||||
@Override
|
||||
public void remoteSearchFinished(String folderServerId, int numResults, int maxResults, List<Message> extraResults) {
|
||||
public void remoteSearchFinished(String folderServerId, int numResults, int maxResults, List<String> extraResults) {
|
||||
handler.progress(false);
|
||||
handler.remoteSearchFinished();
|
||||
extraSearchResults = extraResults;
|
||||
|
|
|
@ -2252,32 +2252,32 @@ public class LocalFolder extends Folder<LocalMessage> {
|
|||
return new ThreadInfo(threadId, msgId, messageId, rootId, parentId);
|
||||
}
|
||||
|
||||
public List<Message> extractNewMessages(final List<Message> messages)
|
||||
public List<String> extractNewMessages(final List<String> messageServerIds)
|
||||
throws MessagingException {
|
||||
|
||||
try {
|
||||
return this.localStore.getDatabase().execute(false, new DbCallback<List<Message>>() {
|
||||
return this.localStore.getDatabase().execute(false, new DbCallback<List<String>>() {
|
||||
@Override
|
||||
public List<Message> doDbWork(final SQLiteDatabase db) throws WrappedException {
|
||||
public List<String> doDbWork(final SQLiteDatabase db) throws WrappedException {
|
||||
try {
|
||||
open(OPEN_MODE_RW);
|
||||
} catch (MessagingException e) {
|
||||
throw new WrappedException(e);
|
||||
}
|
||||
|
||||
List<Message> result = new ArrayList<>();
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
List<String> selectionArgs = new ArrayList<>();
|
||||
Set<String> existingMessages = new HashSet<>();
|
||||
int start = 0;
|
||||
|
||||
while (start < messages.size()) {
|
||||
while (start < messageServerIds.size()) {
|
||||
StringBuilder selection = new StringBuilder();
|
||||
|
||||
selection.append("folder_id = ? AND UID IN (");
|
||||
selectionArgs.add(Long.toString(databaseId));
|
||||
|
||||
int count = Math.min(messages.size() - start, LocalStore.UID_CHECK_BATCH_SIZE);
|
||||
int count = Math.min(messageServerIds.size() - start, LocalStore.UID_CHECK_BATCH_SIZE);
|
||||
|
||||
for (int i = start, end = start + count; i < end; i++) {
|
||||
if (i > start) {
|
||||
|
@ -2286,7 +2286,7 @@ public class LocalFolder extends Folder<LocalMessage> {
|
|||
selection.append("?");
|
||||
}
|
||||
|
||||
selectionArgs.add(messages.get(i).getUid());
|
||||
selectionArgs.add(messageServerIds.get(i));
|
||||
}
|
||||
|
||||
selection.append(")");
|
||||
|
@ -2305,9 +2305,9 @@ public class LocalFolder extends Folder<LocalMessage> {
|
|||
}
|
||||
|
||||
for (int i = start, end = start + count; i < end; i++) {
|
||||
Message message = messages.get(i);
|
||||
if (!existingMessages.contains(message.getUid())) {
|
||||
result.add(message);
|
||||
String messageServerId = messageServerIds.get(i);
|
||||
if (!existingMessages.contains(messageServerId)) {
|
||||
result.add(messageServerId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import com.fsck.k9.mail.MessagingException;
|
|||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
|
||||
|
||||
class ImapMessage extends MimeMessage {
|
||||
public class ImapMessage extends MimeMessage {
|
||||
ImapMessage(String uid, Folder folder) {
|
||||
this.mUid = uid;
|
||||
this.mFolder = folder;
|
||||
|
|
|
@ -8,7 +8,7 @@ import com.fsck.k9.mail.MessagingException;
|
|||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
|
||||
|
||||
class Pop3Message extends MimeMessage {
|
||||
public class Pop3Message extends MimeMessage {
|
||||
Pop3Message(String uid, Pop3Folder folder) {
|
||||
mUid = uid;
|
||||
mFolder = folder;
|
||||
|
|
|
@ -16,7 +16,7 @@ import static com.fsck.k9.mail.helper.UrlEncodingHelper.encodeUtf8;
|
|||
/**
|
||||
* A WebDav Message
|
||||
*/
|
||||
class WebDavMessage extends MimeMessage {
|
||||
public class WebDavMessage extends MimeMessage {
|
||||
private String mUrl = "";
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue