Rewrite IMAP expunge
This commit is contained in:
parent
f78ed69a88
commit
31b7cf8dae
7 changed files with 63 additions and 4 deletions
|
@ -116,6 +116,9 @@ public abstract class Folder<T extends Message> {
|
||||||
public void expunge() 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
|
* Populate a list of messages based upon a FetchProfile. See {@link FetchProfile} for the things that can
|
||||||
* be fetched.
|
* be fetched.
|
||||||
|
|
|
@ -14,4 +14,5 @@ class Capabilities {
|
||||||
public static final String COMPRESS_DEFLATE = "COMPRESS=DEFLATE";
|
public static final String COMPRESS_DEFLATE = "COMPRESS=DEFLATE";
|
||||||
public static final String STARTTLS = "STARTTLS";
|
public static final String STARTTLS = "STARTTLS";
|
||||||
public static final String SPECIAL_USE = "SPECIAL-USE";
|
public static final String SPECIAL_USE = "SPECIAL-USE";
|
||||||
|
public static final String UID_PLUS = "UIDPLUS";
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,4 +18,5 @@ class Commands {
|
||||||
public static final String UID_STORE = "UID STORE";
|
public static final String UID_STORE = "UID STORE";
|
||||||
public static final String UID_FETCH = "UID FETCH";
|
public static final String UID_FETCH = "UID FETCH";
|
||||||
public static final String UID_COPY = "UID COPY";
|
public static final String UID_COPY = "UID COPY";
|
||||||
|
public static final String UID_EXPUNGE = "UID EXPUNGE";
|
||||||
}
|
}
|
||||||
|
|
|
@ -710,6 +710,10 @@ class ImapConnection {
|
||||||
return capabilities.contains(Capabilities.IDLE);
|
return capabilities.contains(Capabilities.IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isUidPlusCapable() {
|
||||||
|
return capabilities.contains(Capabilities.UID_PLUS);
|
||||||
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
open = false;
|
open = false;
|
||||||
stacktraceForClose = new Exception();
|
stacktraceForClose = new Exception();
|
||||||
|
|
|
@ -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
|
@Override
|
||||||
public void setFlags(Set<Flag> flags, boolean value) throws MessagingException {
|
public void setFlags(Set<Flag> flags, boolean value) throws MessagingException {
|
||||||
open(OPEN_MODE_RW);
|
open(OPEN_MODE_RW);
|
||||||
|
|
|
@ -1005,6 +1005,28 @@ public class ImapFolderTest {
|
||||||
verify(imapConnection).executeSimpleCommand("EXPUNGE");
|
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
|
@Test
|
||||||
public void setFlags_shouldIssueUidStoreCommand() throws Exception {
|
public void setFlags_shouldIssueUidStoreCommand() throws Exception {
|
||||||
ImapFolder folder = createFolder("Folder");
|
ImapFolder folder = createFolder("Folder");
|
||||||
|
@ -1226,8 +1248,8 @@ public class ImapFolderTest {
|
||||||
|
|
||||||
for (int i = 0, end = commandPrefixes.size(); i < end; i++) {
|
for (int i = 0, end = commandPrefixes.size(); i < end; i++) {
|
||||||
String command = commandPrefixes.get(i) +
|
String command = commandPrefixes.get(i) +
|
||||||
" " + ImapUtility.join(",", commandUids.get(i)) + " " +
|
" " + ImapUtility.join(",", commandUids.get(i)) +
|
||||||
commandSuffixes.get(i);
|
((commandSuffixes.get(i).length() == 0) ? "" : " " + commandSuffixes.get(i));
|
||||||
if (command.equals(expectedCommand)) {
|
if (command.equals(expectedCommand)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1830,7 +1830,7 @@ public class MessagingController {
|
||||||
if (remoteDate != null) {
|
if (remoteDate != null) {
|
||||||
remoteMessage.setFlag(Flag.DELETED, true);
|
remoteMessage.setFlag(Flag.DELETED, true);
|
||||||
if (Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
|
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()) {
|
if (!isCopy && Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
|
||||||
Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account.getDescription(), srcFolder);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue