1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-12 12:35:04 -05:00

Attempt to implement COPYUID, works for the most part except for updation of the LocalStore with freshly copied messages.

This commit is contained in:
Apoorv Khatreja 2011-06-24 02:54:12 +05:30
parent 970271dbf9
commit 0ba7f20622

View File

@ -29,6 +29,7 @@ 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;
@ -39,7 +40,9 @@ 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;
@ -813,8 +816,24 @@ public class ImapStore extends Store {
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.
uids[i] = messages[i].getUid(); uids[i] = messages[i].getUid();
} }
try { try {
@ -829,20 +848,104 @@ public class ImapStore extends Store {
iFolder.create(FolderType.HOLDS_MESSAGES); iFolder.create(FolderType.HOLDS_MESSAGES);
} }
if (exists(remoteDestName)) { mConnection.sendCommand(String.format("UID COPY %s %s",
executeSimpleCommand(String.format("UID COPY %s %s", Utility.combine(uids, ','),
Utility.combine(uids, ','), remoteDestName), false);
remoteDestName)); ImapResponse response;
} else { do {
throw new MessagingException("IMAPMessage.copyMessages: remote destination folder " + folder.getName() response = mConnection.readResponse();
+ " does not exist and could not be created for " + getLogId() handleUntaggedResponse(response);
, true); if (response.mCommandContinuationRequested) {
EOLConvertingOutputStream eolOut = new EOLConvertingOutputStream(mConnection.mOut);
eolOut.write('\r');
eolOut.write('\n');
eolOut.flush();
}
while (response.more());
} while (response.mTag == null);
/*
* If the server supports UIDPLUS, then along with the COPY response it will return an COPYUID response code.
* e.g. 24 OK [COPYUID 38505 304,319:320 3956:3958] Success
*
* COPYUID is followed by UIDVALIDITY, set of UIDs of copied messages from the source folder and set of corresponding UIDs assigned to them in the destination folder.
*
* We can use the new UIDs included in this response to update our records.
*/
Object responseList = response.get(1);
if (responseList instanceof ImapList) {
final ImapList copyList = (ImapList) responseList;
if ((copyList.size() >= 4) && copyList.getString(0).equals("COPYUID")) {
List<String> oldUids = parseSequenceSet(copyList.getString(2));
List<String> newUids = parseSequenceSet(copyList.getString(3));
if (oldUids.size() == newUids.size()) {
Iterator<Message> messageIterator = messageSet.iterator();
for (int i = 0; i < messages.length && messageIterator.hasNext(); i++) {
Message nextMessage = messageIterator.next();
if (oldUids.get(i).equals(nextMessage.getUid())) {
/*
* 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));
}
}
}
}
} }
} catch (IOException ioe) { } catch (IOException ioe) {
throw ioExceptionHandler(mConnection, ioe); throw ioExceptionHandler(mConnection, ioe);
} }
} }
private List<String> parseSequenceSet(String set) {
int index = 0;
List<String> sequenceList = new ArrayList<String>();
String element = "";
while (index < set.length()) {
if (set.charAt(index) == ':') {
String upperBound = "";
index++;
while (index < set.length()) {
if (!(set.charAt(index) == ',')) {
upperBound += set.charAt(index);
index++;
} else {
break;
}
}
int lower = Integer.parseInt(element);
int upper = Integer.parseInt(upperBound);
if (lower < upper) {
for (int i = lower; i <= upper; i++) {
sequenceList.add(String.valueOf(i));
}
} else {
for (int i = upper; i <= lower; i++) {
sequenceList.add(String.valueOf(i));
}
}
element = "";
} else if (set.charAt(index) == ',') {
sequenceList.add(element);
element = "";
} else {
element += set.charAt(index);
}
index++;
}
if (!element.equals("")) {
sequenceList.add(element);
}
return sequenceList;
}
@Override @Override
public void moveMessages(Message[] messages, Folder folder) throws MessagingException { public void moveMessages(Message[] messages, Folder folder) throws MessagingException {
if (messages.length == 0) if (messages.length == 0)
@ -2290,6 +2393,17 @@ public class ImapStore extends Store {
return executeSimpleCommand(command, sensitive, null); return executeSimpleCommand(command, sensitive, null);
} }
// public void logResponse (ImapList response) {
// for(int i=0;i<response.size();i++) {
// Object o = response.get(i);
// if(o instanceof String){
// Log.w(K9.LOG_TAG+" "+i, (String) o);
// } else if (o instanceof ImapList) {
// logResponse((ImapList)o);
// }
// }
// }
public List<ImapResponse> executeSimpleCommand(String command, boolean sensitive, UntaggedHandler untaggedHandler) public List<ImapResponse> executeSimpleCommand(String command, boolean sensitive, UntaggedHandler untaggedHandler)
throws IOException, ImapException, MessagingException { throws IOException, ImapException, MessagingException {
String commandToLog = command; String commandToLog = command;