From 52612dddb47e3027e465841eb5b9b2e7b73f921d Mon Sep 17 00:00:00 2001 From: mguessan Date: Thu, 22 Apr 2010 21:50:16 +0000 Subject: [PATCH] IMAP: poll folder every 30 seconds in IDLE mode, clear cached message git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1014 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- .../davmail/exchange/ExchangeSession.java | 26 +++++++++-- src/java/davmail/imap/ImapConnection.java | 43 +++++++++++-------- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 0d4104ac..30c478af 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -1457,10 +1457,22 @@ public class ExchangeSession { } /** - * Calendar folder flag. - * - * @return true if this is a calendar folder + * Get current folder messages imap uids + * @return imap uid list */ + public List getImapUidList() { + ArrayList imapUidList = new ArrayList(); + for (ExchangeSession.Message message : messages) { + imapUidList.add(message.getImapUid()); + } + return imapUidList; + } + + /** + * Calendar folder flag. + * + * @return true if this is a calendar folder + */ public boolean isCalendar() { return "urn:content-classes:calendarfolder".equals(contentClass); } @@ -1473,6 +1485,14 @@ public class ExchangeSession { public boolean isContact() { return "urn:content-classes:contactfolder".equals(contentClass); } + + /** + * drop cached message + */ + public void clearCache() { + messages.cachedMimeMessage = null; + messages.cachedMessageImapUid = 0; + } } /** diff --git a/src/java/davmail/imap/ImapConnection.java b/src/java/davmail/imap/ImapConnection.java index d7c05df7..cf3cc03c 100644 --- a/src/java/davmail/imap/ImapConnection.java +++ b/src/java/davmail/imap/ImapConnection.java @@ -40,6 +40,7 @@ import java.net.SocketTimeoutException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; +import java.util.logging.Logger; /** * Dav Gateway smtp connection implementation. @@ -418,13 +419,20 @@ public class ImapConnection extends AbstractConnection { sendClient(commandId + " OK APPEND completed"); } else if ("idle".equalsIgnoreCase(command)) { sendClient("+ idling "); + // clear cache before going to idle mode + currentFolder.clearCache(); + DavGatewayTray.resetIcon(); + int count = 0; while (!in.ready()) { - ExchangeSession.MessageList currentMessages = currentFolder.messages; - if (session.refreshFolder(currentFolder)) { - handleRefresh(currentFolder, currentMessages); + if (++count >= 30) { + count = 0; + List previousImapUidList = currentFolder.getImapUidList(); + if (session.refreshFolder(currentFolder)) { + handleRefresh(previousImapUidList, currentFolder.getImapUidList()); + } } - // sleep 10 seconds - Thread.sleep(10000); + // sleep 1 second + Thread.sleep(1000); } // read DONE line line = readClient(); @@ -436,9 +444,9 @@ public class ImapConnection extends AbstractConnection { } else if ("noop".equalsIgnoreCase(command) || "check".equalsIgnoreCase(command)) { if (currentFolder != null) { DavGatewayTray.debug(new BundleMessage("LOG_IMAP_COMMAND", command, currentFolder.folderName)); - ExchangeSession.MessageList currentMessages = currentFolder.messages; + List previousImapUidList = currentFolder.getImapUidList(); if (session.refreshFolder(currentFolder)) { - handleRefresh(currentFolder, currentMessages); + handleRefresh(previousImapUidList, currentFolder.getImapUidList()); } } sendClient(commandId + " OK " + command + " completed"); @@ -529,18 +537,17 @@ public class ImapConnection extends AbstractConnection { DavGatewayTray.resetIcon(); } - private void handleRefresh(ExchangeSession.Folder currentFolder, ExchangeSession.MessageList currentMessages) throws IOException { - // build new uid set - HashSet uidSet = new HashSet(); - for (ExchangeSession.Message message : currentFolder.messages) { - uidSet.add(message.getImapUid()); - } - // send expunge untagged response for removed IMAP message uids - // note: some STORE commands trigger a uid change in Exchange, - // thus those messages are expunged and reappear with a new uid + /** + * Send expunge untagged response for removed IMAP message uids. + * @param previousImapUidList uid list before refresh + * @param imapUidList uid list after refresh + * @throws IOException on error + */ + private void handleRefresh(List previousImapUidList, List imapUidList) throws IOException { + // int index = 1; - for (ExchangeSession.Message message : currentMessages) { - if (!uidSet.contains(message.getImapUid())) { + for (long previousImapUid : previousImapUidList) { + if (!imapUidList.contains(previousImapUid)) { sendClient("* " + index + " EXPUNGE"); } else { index++;