Rewrite IMAP expunge

This commit is contained in:
Hari 2017-11-11 02:31:13 +05:30
parent f78ed69a88
commit 31b7cf8dae
7 changed files with 63 additions and 4 deletions

View file

@ -116,6 +116,9 @@ public abstract class Folder<T extends Message> {
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.

View file

@ -14,4 +14,5 @@ class Capabilities {
public static final String COMPRESS_DEFLATE = "COMPRESS=DEFLATE";
public static final String STARTTLS = "STARTTLS";
public static final String SPECIAL_USE = "SPECIAL-USE";
public static final String UID_PLUS = "UIDPLUS";
}

View file

@ -18,4 +18,5 @@ class Commands {
public static final String UID_STORE = "UID STORE";
public static final String UID_FETCH = "UID FETCH";
public static final String UID_COPY = "UID COPY";
public static final String UID_EXPUNGE = "UID EXPUNGE";
}

View file

@ -710,6 +710,10 @@ class ImapConnection {
return capabilities.contains(Capabilities.IDLE);
}
boolean isUidPlusCapable() {
return capabilities.contains(Capabilities.UID_PLUS);
}
public void close() {
open = false;
stacktraceForClose = new Exception();

View file

@ -1259,6 +1259,30 @@ 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");
}
open(OPEN_MODE_RW);
checkOpen();
try {
if (connection.isUidPlusCapable()) {
Set<Long> longUids = new HashSet<>(uids.size());
for (String uid : uids) {
longUids.add(Long.parseLong(uid));
}
connection.executeCommandWithIdSet(Commands.UID_EXPUNGE, "", longUids);
} else {
executeSimpleCommand("EXPUNGE");
}
} catch (IOException ioe) {
throw ioExceptionHandler(connection, ioe);
}
}
@Override
public void setFlags(Set<Flag> flags, boolean value) throws MessagingException {
open(OPEN_MODE_RW);

View file

@ -1005,6 +1005,28 @@ public class ImapFolderTest {
verify(imapConnection).executeSimpleCommand("EXPUNGE");
}
@Test
public void expungeUids_withUidPlus_shouldIssueUidExpungeCommand() throws Exception {
ImapFolder folder = createFolder("Folder");
prepareImapFolderForOpen(OPEN_MODE_RW);
when(imapConnection.isUidPlusCapable()).thenReturn(true);
folder.expungeUids(singletonList("1"));
assertCommandWithIdsIssued("UID EXPUNGE 1");
}
@Test
public void expungeUids_withoutUidPlus_shouldIssueExpungeCommand() throws Exception {
ImapFolder folder = createFolder("Folder");
prepareImapFolderForOpen(OPEN_MODE_RW);
when(imapConnection.isUidPlusCapable()).thenReturn(false);
folder.expungeUids(singletonList("1"));
verify(imapConnection).executeSimpleCommand("EXPUNGE");
}
@Test
public void setFlags_shouldIssueUidStoreCommand() throws Exception {
ImapFolder folder = createFolder("Folder");
@ -1226,8 +1248,8 @@ public class ImapFolderTest {
for (int i = 0, end = commandPrefixes.size(); i < end; i++) {
String command = commandPrefixes.get(i) +
" " + ImapUtility.join(",", commandUids.get(i)) + " " +
commandSuffixes.get(i);
" " + ImapUtility.join(",", commandUids.get(i)) +
((commandSuffixes.get(i).length() == 0) ? "" : " " + commandSuffixes.get(i));
if (command.equals(expectedCommand)) {
return;
}

View file

@ -1830,7 +1830,7 @@ public class MessagingController {
if (remoteDate != null) {
remoteMessage.setFlag(Flag.DELETED, true);
if (Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
remoteFolder.expunge();
remoteFolder.expungeUids(Collections.singletonList(remoteMessage.getUid()));
}
}
}
@ -1914,7 +1914,11 @@ public class MessagingController {
}
if (!isCopy && Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account.getDescription(), srcFolder);
remoteSrcFolder.expunge();
List<String> movedUids = new ArrayList<>(messages.size());
for (Message message : messages) {
movedUids.add(message.getUid());
}
remoteSrcFolder.expungeUids(movedUids);
}
/*