mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-14 11:42:23 -05:00
IMAP: brand new IMAP uid workaround and refresh folder on Expunge from Gellule
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@924 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
6ef09d6297
commit
9ebdf91c81
@ -1156,8 +1156,6 @@ public class ExchangeSession {
|
||||
currentFolder.noInferiors = newFolder.noInferiors;
|
||||
currentFolder.unreadCount = newFolder.unreadCount;
|
||||
currentFolder.contenttag = newFolder.contenttag;
|
||||
// keep previous messages for Thunderbird workaround
|
||||
currentFolder.previousMessages = currentFolder.messages;
|
||||
currentFolder.loadMessages();
|
||||
return true;
|
||||
} else {
|
||||
@ -1204,7 +1202,7 @@ public class ExchangeSession {
|
||||
}
|
||||
};
|
||||
int status = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, method);
|
||||
// ok or alredy exists
|
||||
// ok or already exists
|
||||
if (status != HttpStatus.SC_MULTI_STATUS && status != HttpStatus.SC_METHOD_NOT_ALLOWED) {
|
||||
throw DavGatewayHttpClientFacade.buildHttpException(method);
|
||||
}
|
||||
@ -1318,10 +1316,10 @@ public class ExchangeSession {
|
||||
*/
|
||||
public ExchangeSession.MessageList messages;
|
||||
/**
|
||||
* Previous folder message list before refresh.
|
||||
* PermanentURL to UID map.
|
||||
*/
|
||||
public ExchangeSession.MessageList previousMessages;
|
||||
|
||||
private final HashMap<String, Long> uidUrlHashMap = new HashMap<String, Long>();
|
||||
|
||||
/**
|
||||
* Get IMAP folder flags.
|
||||
*
|
||||
@ -1343,7 +1341,46 @@ public class ExchangeSession {
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public void loadMessages() throws IOException {
|
||||
messages = searchMessages(folderPath, "");
|
||||
messages = ExchangeSession.this.searchMessages(folderPath, "");
|
||||
fixUids(messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search messages in folder matching query.
|
||||
*
|
||||
* @param query search query
|
||||
* @return message list
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public MessageList searchMessages(String query) throws IOException {
|
||||
MessageList localMessages = ExchangeSession.this.searchMessages(folderName, query);
|
||||
fixUids(localMessages);
|
||||
return localMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore previous uids changed by a PROPPATCH (flag change).
|
||||
*
|
||||
* @param messages message list
|
||||
*/
|
||||
protected void fixUids(MessageList messages) {
|
||||
boolean sortNeeded = false;
|
||||
for (Message message : messages) {
|
||||
if (uidUrlHashMap.containsKey(message.getPermanentUrl())) {
|
||||
long previousUid = uidUrlHashMap.get(message.getPermanentUrl());
|
||||
if (message.getImapUid() != previousUid) {
|
||||
LOGGER.debug("Restoring IMAP uid " + message.getImapUid() + " -> " + previousUid + " for message " + message.getPermanentUrl() + " (" + message.messageUrl + ')');
|
||||
message.setImapUid(previousUid);
|
||||
sortNeeded = true;
|
||||
}
|
||||
} else {
|
||||
// add message to uid map
|
||||
uidUrlHashMap.put(message.getPermanentUrl(), message.getImapUid());
|
||||
}
|
||||
}
|
||||
if (sortNeeded) {
|
||||
Collections.sort(messages);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1446,6 +1483,14 @@ public class ExchangeSession {
|
||||
return imapUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set IMAP uid.
|
||||
* @param imapUid new uid
|
||||
*/
|
||||
public void setImapUid(long imapUid) {
|
||||
this.imapUid = imapUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange uid.
|
||||
*
|
||||
@ -1459,9 +1504,8 @@ public class ExchangeSession {
|
||||
* Return permanent message url.
|
||||
*
|
||||
* @return permanent message url
|
||||
* @throws URIException on error
|
||||
*/
|
||||
public String getPermanentUrl() throws URIException {
|
||||
public String getPermanentUrl() {
|
||||
return permanentUrl;
|
||||
}
|
||||
|
||||
@ -2222,10 +2266,10 @@ public class ExchangeSession {
|
||||
|| line.indexOf("RSVP=TRUE") >= 0
|
||||
|| line.indexOf("PARTSTAT=NEEDS-ACTION") >= 0
|
||||
// need to include other PARTSTATs participants for CANCEL notifications
|
||||
|| line.indexOf("PARTSTAT=ACCEPTED") >=0
|
||||
|| line.indexOf("PARTSTAT=DECLINED") >=0
|
||||
|| line.indexOf("PARTSTAT=TENTATIVE") >=0
|
||||
)) {
|
||||
|| line.indexOf("PARTSTAT=ACCEPTED") >= 0
|
||||
|| line.indexOf("PARTSTAT=DECLINED") >= 0
|
||||
|| line.indexOf("PARTSTAT=TENTATIVE") >= 0
|
||||
)) {
|
||||
if (line.indexOf("ROLE=OPT-PARTICIPANT") >= 0) {
|
||||
optionalAttendees.add(value);
|
||||
} else {
|
||||
|
@ -209,8 +209,15 @@ public class ImapConnection extends AbstractConnection {
|
||||
} else {
|
||||
sendClient(commandId + " BAD command unrecognized");
|
||||
}
|
||||
} else if ("close".equalsIgnoreCase(command) || "expunge".equalsIgnoreCase(command)) {
|
||||
expunge("close".equalsIgnoreCase(command));
|
||||
} else if ("expunge".equalsIgnoreCase(command)) {
|
||||
expunge(false);
|
||||
// need to refresh folder to avoid 404 errors
|
||||
session.refreshFolder(currentFolder);
|
||||
sendClient(commandId + " OK " + command + " completed");
|
||||
} else if ("close".equalsIgnoreCase(command)) {
|
||||
expunge(true);
|
||||
// deselect folder
|
||||
currentFolder = null;
|
||||
sendClient(commandId + " OK " + command + " completed");
|
||||
} else if ("create".equalsIgnoreCase(command)) {
|
||||
if (tokens.hasMoreTokens()) {
|
||||
@ -252,7 +259,7 @@ public class ImapConnection extends AbstractConnection {
|
||||
if (tokens.hasMoreTokens()) {
|
||||
parameters = tokens.nextToken();
|
||||
}
|
||||
UIDRangeIterator uidRangeIterator = getUIDRangeIterator(currentFolder, ranges);
|
||||
UIDRangeIterator uidRangeIterator = new UIDRangeIterator(currentFolder.messages, ranges);
|
||||
while (uidRangeIterator.hasNext()) {
|
||||
DavGatewayTray.switchIcon();
|
||||
ExchangeSession.Message message = uidRangeIterator.next();
|
||||
@ -275,13 +282,13 @@ public class ImapConnection extends AbstractConnection {
|
||||
sendClient(commandId + " OK SEARCH completed");
|
||||
|
||||
} else if ("store".equalsIgnoreCase(subcommand)) {
|
||||
UIDRangeIterator uidRangeIterator = getUIDRangeIterator(currentFolder, tokens.nextToken());
|
||||
UIDRangeIterator uidRangeIterator = new UIDRangeIterator(currentFolder.messages, tokens.nextToken());
|
||||
String action = tokens.nextToken();
|
||||
String flags = tokens.nextToken();
|
||||
handleStore(commandId, uidRangeIterator, action, flags);
|
||||
} else if ("copy".equalsIgnoreCase(subcommand)) {
|
||||
try {
|
||||
UIDRangeIterator uidRangeIterator = getUIDRangeIterator(currentFolder, tokens.nextToken());
|
||||
UIDRangeIterator uidRangeIterator = new UIDRangeIterator(currentFolder.messages, tokens.nextToken());
|
||||
String targetName = BASE64MailboxDecoder.decode(tokens.nextToken());
|
||||
while (uidRangeIterator.hasNext()) {
|
||||
DavGatewayTray.switchIcon();
|
||||
@ -648,7 +655,7 @@ public class ImapConnection extends AbstractConnection {
|
||||
if ("AND ()".equals(query)) {
|
||||
query = null;
|
||||
}
|
||||
ExchangeSession.MessageList localMessages = session.searchMessages(currentFolder.folderName, query);
|
||||
ExchangeSession.MessageList localMessages = currentFolder.searchMessages(query);
|
||||
int index = 1;
|
||||
for (ExchangeSession.Message message : localMessages) {
|
||||
if ((conditions.deleted == null || message.deleted == conditions.deleted)
|
||||
@ -1177,16 +1184,6 @@ public class ImapConnection extends AbstractConnection {
|
||||
return result;
|
||||
}
|
||||
|
||||
protected UIDRangeIterator getUIDRangeIterator(ExchangeSession.Folder folder, String ranges) {
|
||||
UIDRangeIterator uidRangeIterator = new UIDRangeIterator(folder.messages, ranges);
|
||||
if (!uidRangeIterator.hasNext() && folder.previousMessages != null) {
|
||||
// message not found in current list, try to get message
|
||||
// from previous list to handle recent uid change
|
||||
uidRangeIterator = new UIDRangeIterator(folder.previousMessages, ranges);
|
||||
}
|
||||
return uidRangeIterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to output only headers, also count full size
|
||||
*/
|
||||
|
@ -11,3 +11,5 @@ log4j.appender.ConsoleAppender=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.ConsoleAppender.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.ConsoleAppender.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c %x - %m%n
|
||||
|
||||
#log4j.logger.org.apache.commons.httpclient.util.IdleConnectionHandler=DEBUG
|
||||
#log4j.logger.org.apache.commons.httpclient.util.MultiThreadedHttpConnectionManager=DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user