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.noInferiors = newFolder.noInferiors;
|
||||||
currentFolder.unreadCount = newFolder.unreadCount;
|
currentFolder.unreadCount = newFolder.unreadCount;
|
||||||
currentFolder.contenttag = newFolder.contenttag;
|
currentFolder.contenttag = newFolder.contenttag;
|
||||||
// keep previous messages for Thunderbird workaround
|
|
||||||
currentFolder.previousMessages = currentFolder.messages;
|
|
||||||
currentFolder.loadMessages();
|
currentFolder.loadMessages();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -1204,7 +1202,7 @@ public class ExchangeSession {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
int status = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, method);
|
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) {
|
if (status != HttpStatus.SC_MULTI_STATUS && status != HttpStatus.SC_METHOD_NOT_ALLOWED) {
|
||||||
throw DavGatewayHttpClientFacade.buildHttpException(method);
|
throw DavGatewayHttpClientFacade.buildHttpException(method);
|
||||||
}
|
}
|
||||||
@ -1318,9 +1316,9 @@ public class ExchangeSession {
|
|||||||
*/
|
*/
|
||||||
public ExchangeSession.MessageList messages;
|
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.
|
* Get IMAP folder flags.
|
||||||
@ -1343,7 +1341,46 @@ public class ExchangeSession {
|
|||||||
* @throws IOException on error
|
* @throws IOException on error
|
||||||
*/
|
*/
|
||||||
public void loadMessages() throws IOException {
|
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;
|
return imapUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set IMAP uid.
|
||||||
|
* @param imapUid new uid
|
||||||
|
*/
|
||||||
|
public void setImapUid(long imapUid) {
|
||||||
|
this.imapUid = imapUid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchange uid.
|
* Exchange uid.
|
||||||
*
|
*
|
||||||
@ -1459,9 +1504,8 @@ public class ExchangeSession {
|
|||||||
* Return permanent message url.
|
* Return permanent message url.
|
||||||
*
|
*
|
||||||
* @return permanent message url
|
* @return permanent message url
|
||||||
* @throws URIException on error
|
|
||||||
*/
|
*/
|
||||||
public String getPermanentUrl() throws URIException {
|
public String getPermanentUrl() {
|
||||||
return permanentUrl;
|
return permanentUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2222,9 +2266,9 @@ public class ExchangeSession {
|
|||||||
|| line.indexOf("RSVP=TRUE") >= 0
|
|| line.indexOf("RSVP=TRUE") >= 0
|
||||||
|| line.indexOf("PARTSTAT=NEEDS-ACTION") >= 0
|
|| line.indexOf("PARTSTAT=NEEDS-ACTION") >= 0
|
||||||
// need to include other PARTSTATs participants for CANCEL notifications
|
// need to include other PARTSTATs participants for CANCEL notifications
|
||||||
|| line.indexOf("PARTSTAT=ACCEPTED") >=0
|
|| line.indexOf("PARTSTAT=ACCEPTED") >= 0
|
||||||
|| line.indexOf("PARTSTAT=DECLINED") >=0
|
|| line.indexOf("PARTSTAT=DECLINED") >= 0
|
||||||
|| line.indexOf("PARTSTAT=TENTATIVE") >=0
|
|| line.indexOf("PARTSTAT=TENTATIVE") >= 0
|
||||||
)) {
|
)) {
|
||||||
if (line.indexOf("ROLE=OPT-PARTICIPANT") >= 0) {
|
if (line.indexOf("ROLE=OPT-PARTICIPANT") >= 0) {
|
||||||
optionalAttendees.add(value);
|
optionalAttendees.add(value);
|
||||||
|
@ -209,8 +209,15 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
} else {
|
} else {
|
||||||
sendClient(commandId + " BAD command unrecognized");
|
sendClient(commandId + " BAD command unrecognized");
|
||||||
}
|
}
|
||||||
} else if ("close".equalsIgnoreCase(command) || "expunge".equalsIgnoreCase(command)) {
|
} else if ("expunge".equalsIgnoreCase(command)) {
|
||||||
expunge("close".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");
|
sendClient(commandId + " OK " + command + " completed");
|
||||||
} else if ("create".equalsIgnoreCase(command)) {
|
} else if ("create".equalsIgnoreCase(command)) {
|
||||||
if (tokens.hasMoreTokens()) {
|
if (tokens.hasMoreTokens()) {
|
||||||
@ -252,7 +259,7 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
if (tokens.hasMoreTokens()) {
|
if (tokens.hasMoreTokens()) {
|
||||||
parameters = tokens.nextToken();
|
parameters = tokens.nextToken();
|
||||||
}
|
}
|
||||||
UIDRangeIterator uidRangeIterator = getUIDRangeIterator(currentFolder, ranges);
|
UIDRangeIterator uidRangeIterator = new UIDRangeIterator(currentFolder.messages, ranges);
|
||||||
while (uidRangeIterator.hasNext()) {
|
while (uidRangeIterator.hasNext()) {
|
||||||
DavGatewayTray.switchIcon();
|
DavGatewayTray.switchIcon();
|
||||||
ExchangeSession.Message message = uidRangeIterator.next();
|
ExchangeSession.Message message = uidRangeIterator.next();
|
||||||
@ -275,13 +282,13 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
sendClient(commandId + " OK SEARCH completed");
|
sendClient(commandId + " OK SEARCH completed");
|
||||||
|
|
||||||
} else if ("store".equalsIgnoreCase(subcommand)) {
|
} else if ("store".equalsIgnoreCase(subcommand)) {
|
||||||
UIDRangeIterator uidRangeIterator = getUIDRangeIterator(currentFolder, tokens.nextToken());
|
UIDRangeIterator uidRangeIterator = new UIDRangeIterator(currentFolder.messages, tokens.nextToken());
|
||||||
String action = tokens.nextToken();
|
String action = tokens.nextToken();
|
||||||
String flags = tokens.nextToken();
|
String flags = tokens.nextToken();
|
||||||
handleStore(commandId, uidRangeIterator, action, flags);
|
handleStore(commandId, uidRangeIterator, action, flags);
|
||||||
} else if ("copy".equalsIgnoreCase(subcommand)) {
|
} else if ("copy".equalsIgnoreCase(subcommand)) {
|
||||||
try {
|
try {
|
||||||
UIDRangeIterator uidRangeIterator = getUIDRangeIterator(currentFolder, tokens.nextToken());
|
UIDRangeIterator uidRangeIterator = new UIDRangeIterator(currentFolder.messages, tokens.nextToken());
|
||||||
String targetName = BASE64MailboxDecoder.decode(tokens.nextToken());
|
String targetName = BASE64MailboxDecoder.decode(tokens.nextToken());
|
||||||
while (uidRangeIterator.hasNext()) {
|
while (uidRangeIterator.hasNext()) {
|
||||||
DavGatewayTray.switchIcon();
|
DavGatewayTray.switchIcon();
|
||||||
@ -648,7 +655,7 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
if ("AND ()".equals(query)) {
|
if ("AND ()".equals(query)) {
|
||||||
query = null;
|
query = null;
|
||||||
}
|
}
|
||||||
ExchangeSession.MessageList localMessages = session.searchMessages(currentFolder.folderName, query);
|
ExchangeSession.MessageList localMessages = currentFolder.searchMessages(query);
|
||||||
int index = 1;
|
int index = 1;
|
||||||
for (ExchangeSession.Message message : localMessages) {
|
for (ExchangeSession.Message message : localMessages) {
|
||||||
if ((conditions.deleted == null || message.deleted == conditions.deleted)
|
if ((conditions.deleted == null || message.deleted == conditions.deleted)
|
||||||
@ -1177,16 +1184,6 @@ public class ImapConnection extends AbstractConnection {
|
|||||||
return result;
|
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
|
* 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=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.ConsoleAppender.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c %x - %m%n
|
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