mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-28 04:02:19 -05:00
COPYUID implementation now in place and working, restructured appendMessages, copyMessages and moveMessages globally to return a Map of srcUids -> destUids rather than returning nothing. This is now used to bring local and remote UIDs upto speed without the need for additional requests.
This commit is contained in:
parent
0ba7f20622
commit
bc9b7030d7
@ -2088,9 +2088,32 @@ public class MessagingController implements Runnable {
|
|||||||
command.arguments[0] = srcFolder;
|
command.arguments[0] = srcFolder;
|
||||||
command.arguments[1] = destFolder;
|
command.arguments[1] = destFolder;
|
||||||
command.arguments[2] = Boolean.toString(isCopy);
|
command.arguments[2] = Boolean.toString(isCopy);
|
||||||
System.arraycopy(uids, 0, command.arguments, 3, uids.length);
|
command.arguments[3] = Boolean.toString(false);
|
||||||
|
System.arraycopy(uids, 0, command.arguments, 4, uids.length);
|
||||||
queuePendingCommand(account, command);
|
queuePendingCommand(account, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void queueMoveOrCopy(Account account, String srcFolder, String destFolder, boolean isCopy, String uids[], Map<String, String> uidMap) {
|
||||||
|
if (uidMap == null || uidMap.isEmpty()) {
|
||||||
|
queueMoveOrCopy(account, srcFolder, destFolder, isCopy, uids);
|
||||||
|
} else {
|
||||||
|
if (account.getErrorFolderName().equals(srcFolder)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PendingCommand command = new PendingCommand();
|
||||||
|
command.command = PENDING_COMMAND_MOVE_OR_COPY_BULK;
|
||||||
|
|
||||||
|
int length = 4 + uidMap.keySet().size() + uidMap.values().size();
|
||||||
|
command.arguments = new String[length];
|
||||||
|
command.arguments[0] = srcFolder;
|
||||||
|
command.arguments[1] = destFolder;
|
||||||
|
command.arguments[2] = Boolean.toString(isCopy);
|
||||||
|
command.arguments[3] = Boolean.toString(true);
|
||||||
|
System.arraycopy(uidMap.keySet().toArray(), 0, command.arguments, 4, uidMap.keySet().size());
|
||||||
|
System.arraycopy(uidMap.values().toArray(), 0, command.arguments, 4 + uidMap.keySet().size(), uidMap.values().size());
|
||||||
|
queuePendingCommand(account, command);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Process a pending trash message command.
|
* Process a pending trash message command.
|
||||||
*
|
*
|
||||||
@ -2102,6 +2125,7 @@ public class MessagingController implements Runnable {
|
|||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
Folder remoteSrcFolder = null;
|
Folder remoteSrcFolder = null;
|
||||||
Folder remoteDestFolder = null;
|
Folder remoteDestFolder = null;
|
||||||
|
Folder localDestFolder = null;
|
||||||
try {
|
try {
|
||||||
String srcFolder = command.arguments[0];
|
String srcFolder = command.arguments[0];
|
||||||
if (account.getErrorFolderName().equals(srcFolder)) {
|
if (account.getErrorFolderName().equals(srcFolder)) {
|
||||||
@ -2109,17 +2133,45 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
String destFolder = command.arguments[1];
|
String destFolder = command.arguments[1];
|
||||||
String isCopyS = command.arguments[2];
|
String isCopyS = command.arguments[2];
|
||||||
|
String hasNewUidsS = command.arguments[3];
|
||||||
|
|
||||||
|
boolean hasNewUids = false;
|
||||||
|
if (hasNewUidsS != null) {
|
||||||
|
hasNewUids = Boolean.parseBoolean(hasNewUidsS);
|
||||||
|
}
|
||||||
|
|
||||||
Store remoteStore = account.getRemoteStore();
|
Store remoteStore = account.getRemoteStore();
|
||||||
remoteSrcFolder = remoteStore.getFolder(srcFolder);
|
remoteSrcFolder = remoteStore.getFolder(srcFolder);
|
||||||
|
|
||||||
|
Store localStore = account.getLocalStore();
|
||||||
|
localDestFolder = localStore.getFolder(destFolder);
|
||||||
List<Message> messages = new ArrayList<Message>();
|
List<Message> messages = new ArrayList<Message>();
|
||||||
for (int i = 3; i < command.arguments.length; i++) {
|
|
||||||
|
/*
|
||||||
|
* We split up the localUidMap into two parts while sending the command, here we assemble it back.
|
||||||
|
*/
|
||||||
|
Map<String, String> localUidMap = new HashMap<String, String>();
|
||||||
|
if (hasNewUids) {
|
||||||
|
int offset = (command.arguments.length - 4) / 2;
|
||||||
|
|
||||||
|
for (int i = 4; i < 4 + offset; i++) {
|
||||||
|
localUidMap.put(command.arguments[i], command.arguments[i + offset]);
|
||||||
|
|
||||||
String uid = command.arguments[i];
|
String uid = command.arguments[i];
|
||||||
if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||||
messages.add(remoteSrcFolder.getMessage(uid));
|
messages.add(remoteSrcFolder.getMessage(uid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (int i = 4; i < command.arguments.length; i++) {
|
||||||
|
String uid = command.arguments[i];
|
||||||
|
if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||||
|
messages.add(remoteSrcFolder.getMessage(uid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean isCopy = false;
|
boolean isCopy = false;
|
||||||
if (isCopyS != null) {
|
if (isCopyS != null) {
|
||||||
isCopy = Boolean.parseBoolean(isCopyS);
|
isCopy = Boolean.parseBoolean(isCopyS);
|
||||||
@ -2137,6 +2189,8 @@ public class MessagingController implements Runnable {
|
|||||||
Log.d(K9.LOG_TAG, "processingPendingMoveOrCopy: source folder = " + srcFolder
|
Log.d(K9.LOG_TAG, "processingPendingMoveOrCopy: source folder = " + srcFolder
|
||||||
+ ", " + messages.size() + " messages, destination folder = " + destFolder + ", isCopy = " + isCopy);
|
+ ", " + messages.size() + " messages, destination folder = " + destFolder + ", isCopy = " + isCopy);
|
||||||
|
|
||||||
|
Map <String, String> remoteUidMap = new HashMap<String, String>();
|
||||||
|
|
||||||
if (!isCopy && destFolder.equals(account.getTrashFolderName())) {
|
if (!isCopy && destFolder.equals(account.getTrashFolderName())) {
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "processingPendingMoveOrCopy doing special case for deleting message");
|
Log.d(K9.LOG_TAG, "processingPendingMoveOrCopy doing special case for deleting message");
|
||||||
@ -2150,9 +2204,9 @@ public class MessagingController implements Runnable {
|
|||||||
remoteDestFolder = remoteStore.getFolder(destFolder);
|
remoteDestFolder = remoteStore.getFolder(destFolder);
|
||||||
|
|
||||||
if (isCopy) {
|
if (isCopy) {
|
||||||
remoteSrcFolder.copyMessages(messages.toArray(EMPTY_MESSAGE_ARRAY), remoteDestFolder);
|
remoteUidMap = remoteSrcFolder.copyMessages(messages.toArray(EMPTY_MESSAGE_ARRAY), remoteDestFolder);
|
||||||
} else {
|
} else {
|
||||||
remoteSrcFolder.moveMessages(messages.toArray(EMPTY_MESSAGE_ARRAY), remoteDestFolder);
|
remoteUidMap = remoteSrcFolder.moveMessages(messages.toArray(EMPTY_MESSAGE_ARRAY), remoteDestFolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isCopy && Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy())) {
|
if (!isCopy && Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy())) {
|
||||||
@ -2161,12 +2215,27 @@ public class MessagingController implements Runnable {
|
|||||||
|
|
||||||
remoteSrcFolder.expunge();
|
remoteSrcFolder.expunge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This next part is used to bring the local UIDs of the local destination folder
|
||||||
|
* upto speed with the remote UIDs of remote destionation folder.
|
||||||
|
*/
|
||||||
|
if (!localUidMap.isEmpty() && !remoteUidMap.isEmpty()) {
|
||||||
|
Set<String> remoteSrcUids = remoteUidMap.keySet();
|
||||||
|
Iterator<String> remoteSrcUidsIterator = remoteSrcUids.iterator();
|
||||||
|
|
||||||
|
while (remoteSrcUidsIterator.hasNext()) {
|
||||||
|
String remoteSrcUid = remoteSrcUidsIterator.next();
|
||||||
|
String localDestUid = localUidMap.get(remoteSrcUid);
|
||||||
|
|
||||||
|
Message localDestMessage = localDestFolder.getMessage(localDestUid);
|
||||||
|
localDestMessage.setUid(remoteUidMap.get(remoteSrcUid));
|
||||||
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
closeFolder(remoteSrcFolder);
|
closeFolder(remoteSrcFolder);
|
||||||
closeFolder(remoteDestFolder);
|
closeFolder(remoteDestFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queueSetFlag(final Account account, final String folderName, final String newState, final String flag, final String[] uids) {
|
private void queueSetFlag(final Account account, final String folderName, final String newState, final String flag, final String[] uids) {
|
||||||
@ -3248,6 +3317,7 @@ public class MessagingController implements Runnable {
|
|||||||
private void moveOrCopyMessageSynchronous(final Account account, final String srcFolder, final Message[] inMessages,
|
private void moveOrCopyMessageSynchronous(final Account account, final String srcFolder, final Message[] inMessages,
|
||||||
final String destFolder, final boolean isCopy, MessagingListener listener) {
|
final String destFolder, final boolean isCopy, MessagingListener listener) {
|
||||||
try {
|
try {
|
||||||
|
Map<String, String> uidMap = new HashMap<String, String>();
|
||||||
Store localStore = account.getLocalStore();
|
Store localStore = account.getLocalStore();
|
||||||
Store remoteStore = account.getRemoteStore();
|
Store remoteStore = account.getRemoteStore();
|
||||||
if (!isCopy && (!remoteStore.isMoveCapable() || !localStore.isMoveCapable())) {
|
if (!isCopy && (!remoteStore.isMoveCapable() || !localStore.isMoveCapable())) {
|
||||||
@ -3285,9 +3355,9 @@ public class MessagingController implements Runnable {
|
|||||||
fp.add(FetchProfile.Item.ENVELOPE);
|
fp.add(FetchProfile.Item.ENVELOPE);
|
||||||
fp.add(FetchProfile.Item.BODY);
|
fp.add(FetchProfile.Item.BODY);
|
||||||
localSrcFolder.fetch(messages, fp, null);
|
localSrcFolder.fetch(messages, fp, null);
|
||||||
localSrcFolder.copyMessages(messages, localDestFolder);
|
uidMap = localSrcFolder.copyMessages(messages, localDestFolder);
|
||||||
} else {
|
} else {
|
||||||
localSrcFolder.moveMessages(messages, localDestFolder);
|
uidMap = localSrcFolder.moveMessages(messages, localDestFolder);
|
||||||
for (String origUid : origUidMap.keySet()) {
|
for (String origUid : origUidMap.keySet()) {
|
||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
l.messageUidChanged(account, srcFolder, origUid, origUidMap.get(origUid).getUid());
|
l.messageUidChanged(account, srcFolder, origUid, origUidMap.get(origUid).getUid());
|
||||||
@ -3296,7 +3366,7 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queueMoveOrCopy(account, srcFolder, destFolder, isCopy, origUidMap.keySet().toArray(EMPTY_STRING_ARRAY));
|
queueMoveOrCopy(account, srcFolder, destFolder, isCopy, origUidMap.keySet().toArray(EMPTY_STRING_ARRAY), uidMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
processPendingCommands(account);
|
processPendingCommands(account);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.fsck.k9.mail;
|
package com.fsck.k9.mail;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
@ -102,11 +103,15 @@ public abstract class Folder {
|
|||||||
public abstract Message[] getMessages(String[] uids, MessageRetrievalListener listener)
|
public abstract Message[] getMessages(String[] uids, MessageRetrievalListener listener)
|
||||||
throws MessagingException;
|
throws MessagingException;
|
||||||
|
|
||||||
public abstract void appendMessages(Message[] messages) throws MessagingException;
|
public abstract Map<String, String> appendMessages(Message[] messages) throws MessagingException;
|
||||||
|
|
||||||
public void copyMessages(Message[] msgs, Folder folder) throws MessagingException {}
|
public Map<String, String> copyMessages(Message[] msgs, Folder folder) throws MessagingException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void moveMessages(Message[] msgs, Folder folder) throws MessagingException {}
|
public Map<String, String> moveMessages(Message[] msgs, Folder folder) throws MessagingException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void delete(Message[] msgs, String trashFolderName) throws MessagingException {
|
public void delete(Message[] msgs, String trashFolderName) throws MessagingException {
|
||||||
for (Message message : msgs) {
|
for (Message message : msgs) {
|
||||||
|
@ -29,7 +29,6 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -40,9 +39,7 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -806,32 +803,19 @@ public class ImapStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void copyMessages(Message[] messages, Folder folder) throws MessagingException {
|
public Map<String, String> copyMessages(Message[] messages, Folder folder) throws MessagingException {
|
||||||
if (!(folder instanceof ImapFolder)) {
|
if (!(folder instanceof ImapFolder)) {
|
||||||
throw new MessagingException("ImapFolder.copyMessages passed non-ImapFolder");
|
throw new MessagingException("ImapFolder.copyMessages passed non-ImapFolder");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messages.length == 0)
|
if (messages.length == 0)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
ImapFolder iFolder = (ImapFolder)folder;
|
ImapFolder iFolder = (ImapFolder)folder;
|
||||||
checkOpen();
|
checkOpen();
|
||||||
|
|
||||||
SortedSet<Message> messageSet = new TreeSet<Message>(new Comparator<Message>() {
|
|
||||||
public int compare(Message m1, Message m2) {
|
|
||||||
int uid1 = Integer.parseInt(m1.getUid()), uid2 = Integer.parseInt(m2.getUid());
|
|
||||||
if (uid1 < uid2) {
|
|
||||||
return -1;
|
|
||||||
} else if (uid1 == uid2) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
String[] uids = new String[messages.length];
|
String[] uids = new String[messages.length];
|
||||||
for (int i = 0, count = messages.length; i < count; i++) {
|
for (int i = 0, count = messages.length; i < count; i++) {
|
||||||
messageSet.add(messages[i]);
|
|
||||||
|
|
||||||
// Not bothering to sort the UIDs in ascending order while sending the command for convenience, and because it does not make a difference.
|
// Not bothering to sort the UIDs in ascending order while sending the command for convenience, and because it does not make a difference.
|
||||||
uids[i] = messages[i].getUid();
|
uids[i] = messages[i].getUid();
|
||||||
@ -875,31 +859,36 @@ public class ImapStore extends Store {
|
|||||||
|
|
||||||
Object responseList = response.get(1);
|
Object responseList = response.get(1);
|
||||||
|
|
||||||
|
Map<String, String> uidMap = null;
|
||||||
|
|
||||||
if (responseList instanceof ImapList) {
|
if (responseList instanceof ImapList) {
|
||||||
final ImapList copyList = (ImapList) responseList;
|
final ImapList copyList = (ImapList) responseList;
|
||||||
if ((copyList.size() >= 4) && copyList.getString(0).equals("COPYUID")) {
|
if ((copyList.size() >= 4) && copyList.getString(0).equals("COPYUID")) {
|
||||||
List<String> oldUids = parseSequenceSet(copyList.getString(2));
|
List<String> srcUids = parseSequenceSet(copyList.getString(2));
|
||||||
List<String> newUids = parseSequenceSet(copyList.getString(3));
|
List<String> destUids = parseSequenceSet(copyList.getString(3));
|
||||||
if (oldUids.size() == newUids.size()) {
|
if (srcUids.size() == destUids.size()) {
|
||||||
Iterator<Message> messageIterator = messageSet.iterator();
|
Iterator<String> srcUidsIterator = srcUids.iterator();
|
||||||
for (int i = 0; i < messages.length && messageIterator.hasNext(); i++) {
|
Iterator<String> destUidsIterator = destUids.iterator();
|
||||||
Message nextMessage = messageIterator.next();
|
uidMap = new HashMap<String, String>();
|
||||||
if (oldUids.get(i).equals(nextMessage.getUid())) {
|
while (srcUidsIterator.hasNext() && destUidsIterator.hasNext()) {
|
||||||
/*
|
uidMap.put(srcUidsIterator.next(), destUidsIterator.next());
|
||||||
* Here, we need to *create* new messages in the localstore, same as the older messages, the only changes are that old UIDs need to be swapped with new UIDs,
|
|
||||||
* and old folder swapped with new folder.
|
|
||||||
*/
|
|
||||||
// nextMessage.setUid(newUids.get(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return uidMap;
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw ioExceptionHandler(mConnection, ioe);
|
throw ioExceptionHandler(mConnection, ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to parse sequence sets or UID sets appearing is responses such as COPYUID.
|
||||||
|
* e.g. [COPYUID 38505 304,319:320 3956:3958]
|
||||||
|
*
|
||||||
|
* @param set
|
||||||
|
* @return List<String> sequenceSet
|
||||||
|
*/
|
||||||
private List<String> parseSequenceSet(String set) {
|
private List<String> parseSequenceSet(String set) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
List<String> sequenceList = new ArrayList<String>();
|
List<String> sequenceList = new ArrayList<String>();
|
||||||
@ -947,11 +936,12 @@ public class ImapStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveMessages(Message[] messages, Folder folder) throws MessagingException {
|
public Map<String, String> moveMessages(Message[] messages, Folder folder) throws MessagingException {
|
||||||
if (messages.length == 0)
|
if (messages.length == 0)
|
||||||
return;
|
return null;
|
||||||
copyMessages(messages, folder);
|
Map<String, String> uidMap = copyMessages(messages, folder);
|
||||||
setFlags(messages, new Flag[] { Flag.DELETED }, true);
|
setFlags(messages, new Flag[] { Flag.DELETED }, true);
|
||||||
|
return uidMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1698,9 +1688,10 @@ public class ImapStore extends Store {
|
|||||||
* new server UID.
|
* new server UID.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void appendMessages(Message[] messages) throws MessagingException {
|
public Map<String, String> appendMessages(Message[] messages) throws MessagingException {
|
||||||
checkOpen();
|
checkOpen();
|
||||||
try {
|
try {
|
||||||
|
Map<String, String> uidMap = null;
|
||||||
for (Message message : messages) {
|
for (Message message : messages) {
|
||||||
mConnection.sendCommand(
|
mConnection.sendCommand(
|
||||||
String.format("APPEND %s (%s) {%d}",
|
String.format("APPEND %s (%s) {%d}",
|
||||||
@ -1734,9 +1725,18 @@ public class ImapStore extends Store {
|
|||||||
if (responseList instanceof ImapList) {
|
if (responseList instanceof ImapList) {
|
||||||
final ImapList appendList = (ImapList) responseList;
|
final ImapList appendList = (ImapList) responseList;
|
||||||
if ((appendList.size() >= 3) && appendList.getString(0).equals("APPENDUID")) {
|
if ((appendList.size() >= 3) && appendList.getString(0).equals("APPENDUID")) {
|
||||||
String serverUid = appendList.getString(2);
|
String newUid = appendList.getString(2);
|
||||||
if (!TextUtils.isEmpty(serverUid)) {
|
|
||||||
message.setUid(serverUid);
|
/*
|
||||||
|
* We need uidMap to be null initially to maintain consistency with the behavior of other similar methods (copyMessages, moveMessages) which
|
||||||
|
* return null if new UIDs are not available. Therefore, we initialize uidMap over here.
|
||||||
|
*/
|
||||||
|
if (uidMap == null) {
|
||||||
|
uidMap = new HashMap<String, String>();
|
||||||
|
}
|
||||||
|
uidMap.put(message.getUid(), newUid);
|
||||||
|
if (!TextUtils.isEmpty(newUid)) {
|
||||||
|
message.setUid(newUid);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1751,11 +1751,14 @@ public class ImapStore extends Store {
|
|||||||
Log.d(K9.LOG_TAG, "Got UID " + newUid + " for message for " + getLogId());
|
Log.d(K9.LOG_TAG, "Got UID " + newUid + " for message for " + getLogId());
|
||||||
|
|
||||||
if (newUid != null) {
|
if (newUid != null) {
|
||||||
|
if (uidMap == null) {
|
||||||
|
uidMap = new HashMap<String, String>();
|
||||||
|
}
|
||||||
|
uidMap.put(message.getUid(), newUid);
|
||||||
message.setUid(newUid);
|
message.setUid(newUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return uidMap;
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw ioExceptionHandler(mConnection, ioe);
|
throw ioExceptionHandler(mConnection, ioe);
|
||||||
}
|
}
|
||||||
|
@ -1885,21 +1885,23 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void copyMessages(Message[] msgs, Folder folder) throws MessagingException {
|
public Map<String, String> copyMessages(Message[] msgs, Folder folder) throws MessagingException {
|
||||||
if (!(folder instanceof LocalFolder)) {
|
if (!(folder instanceof LocalFolder)) {
|
||||||
throw new MessagingException("copyMessages called with incorrect Folder");
|
throw new MessagingException("copyMessages called with incorrect Folder");
|
||||||
}
|
}
|
||||||
((LocalFolder) folder).appendMessages(msgs, true);
|
return ((LocalFolder) folder).appendMessages(msgs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveMessages(final Message[] msgs, final Folder destFolder) throws MessagingException {
|
public Map<String, String> moveMessages(final Message[] msgs, final Folder destFolder) throws MessagingException {
|
||||||
if (!(destFolder instanceof LocalFolder)) {
|
if (!(destFolder instanceof LocalFolder)) {
|
||||||
throw new MessagingException("moveMessages called with non-LocalFolder");
|
throw new MessagingException("moveMessages called with non-LocalFolder");
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalFolder lDestFolder = (LocalFolder)destFolder;
|
final LocalFolder lDestFolder = (LocalFolder)destFolder;
|
||||||
|
|
||||||
|
final Map<String, String> uidMap = new HashMap<String, String>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
database.execute(false, new DbCallback<Void>() {
|
database.execute(false, new DbCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
@ -1936,7 +1938,7 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
LocalMessage placeHolder = new LocalMessage(oldUID, LocalFolder.this);
|
LocalMessage placeHolder = new LocalMessage(oldUID, LocalFolder.this);
|
||||||
placeHolder.setFlagInternal(Flag.DELETED, true);
|
placeHolder.setFlagInternal(Flag.DELETED, true);
|
||||||
placeHolder.setFlagInternal(Flag.SEEN, true);
|
placeHolder.setFlagInternal(Flag.SEEN, true);
|
||||||
appendMessages(new Message[] { placeHolder });
|
uidMap.putAll(appendMessages(new Message[] { placeHolder }));
|
||||||
}
|
}
|
||||||
} catch (MessagingException e) {
|
} catch (MessagingException e) {
|
||||||
throw new WrappedException(e);
|
throw new WrappedException(e);
|
||||||
@ -1944,6 +1946,7 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return uidMap;
|
||||||
} catch (WrappedException e) {
|
} catch (WrappedException e) {
|
||||||
throw(MessagingException) e.getCause();
|
throw(MessagingException) e.getCause();
|
||||||
}
|
}
|
||||||
@ -1989,8 +1992,8 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
* message, retrieve the appropriate local message instance first (if it already exists).
|
* message, retrieve the appropriate local message instance first (if it already exists).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void appendMessages(Message[] messages) throws MessagingException {
|
public Map<String, String> appendMessages(Message[] messages) throws MessagingException {
|
||||||
appendMessages(messages, false);
|
return appendMessages(messages, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroyMessages(final Message[] messages) throws MessagingException {
|
public void destroyMessages(final Message[] messages) throws MessagingException {
|
||||||
@ -2026,10 +2029,12 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
* message, retrieve the appropriate local message instance first (if it already exists).
|
* message, retrieve the appropriate local message instance first (if it already exists).
|
||||||
* @param messages
|
* @param messages
|
||||||
* @param copy
|
* @param copy
|
||||||
|
* @return Map<String, String> uidMap of srcUids -> destUids
|
||||||
*/
|
*/
|
||||||
private void appendMessages(final Message[] messages, final boolean copy) throws MessagingException {
|
private Map<String, String> appendMessages(final Message[] messages, final boolean copy) throws MessagingException {
|
||||||
open(OpenMode.READ_WRITE);
|
open(OpenMode.READ_WRITE);
|
||||||
try {
|
try {
|
||||||
|
final Map<String, String> uidMap = new HashMap<String, String>();
|
||||||
database.execute(true, new DbCallback<Void>() {
|
database.execute(true, new DbCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
|
public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
|
||||||
@ -2040,11 +2045,15 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String uid = message.getUid();
|
String uid = message.getUid();
|
||||||
if (uid == null || copy) {
|
if (uid == null && !copy) {
|
||||||
uid = K9.LOCAL_UID_PREFIX + UUID.randomUUID().toString();
|
uid = K9.LOCAL_UID_PREFIX + UUID.randomUUID().toString();
|
||||||
if (!copy) {
|
|
||||||
message.setUid(uid);
|
message.setUid(uid);
|
||||||
|
} else if (copy) {
|
||||||
|
String temp = K9.LOCAL_UID_PREFIX + UUID.randomUUID().toString();
|
||||||
|
if (uid != null) {
|
||||||
|
uidMap.put(uid, temp);
|
||||||
}
|
}
|
||||||
|
uid = temp;
|
||||||
} else {
|
} else {
|
||||||
Message oldMessage = getMessage(uid);
|
Message oldMessage = getMessage(uid);
|
||||||
if (oldMessage != null && !oldMessage.isSet(Flag.SEEN)) {
|
if (oldMessage != null && !oldMessage.isSet(Flag.SEEN)) {
|
||||||
@ -2150,6 +2159,7 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return uidMap;
|
||||||
} catch (WrappedException e) {
|
} catch (WrappedException e) {
|
||||||
throw(MessagingException) e.getCause();
|
throw(MessagingException) e.getCause();
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Pop3Store extends Store {
|
public class Pop3Store extends Store {
|
||||||
public static final int CONNECTION_SECURITY_NONE = 0;
|
public static final int CONNECTION_SECURITY_NONE = 0;
|
||||||
@ -736,7 +737,8 @@ public class Pop3Store extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendMessages(Message[] messages) throws MessagingException {
|
public Map<String, String> appendMessages(Message[] messages) throws MessagingException {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,6 +51,7 @@ import java.util.HashMap;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@ -1161,13 +1162,15 @@ public class WebDavStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void copyMessages(Message[] messages, Folder folder) throws MessagingException {
|
public Map<String, String> copyMessages(Message[] messages, Folder folder) throws MessagingException {
|
||||||
moveOrCopyMessages(messages, folder.getName(), false);
|
moveOrCopyMessages(messages, folder.getName(), false);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveMessages(Message[] messages, Folder folder) throws MessagingException {
|
public Map<String, String> moveMessages(Message[] messages, Folder folder) throws MessagingException {
|
||||||
moveOrCopyMessages(messages, folder.getName(), true);
|
moveOrCopyMessages(messages, folder.getName(), true);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1728,8 +1731,9 @@ public class WebDavStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendMessages(Message[] messages) throws MessagingException {
|
public Map<String, String> appendMessages(Message[] messages) throws MessagingException {
|
||||||
appendWebDavMessages(messages);
|
appendWebDavMessages(messages);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Message[] appendWebDavMessages(Message[] messages) throws MessagingException {
|
public Message[] appendWebDavMessages(Message[] messages) throws MessagingException {
|
||||||
|
Loading…
Reference in New Issue
Block a user