IMAP: implement IDLE extension (RFC2177)

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1010 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2010-04-22 09:41:41 +00:00
parent d53078d254
commit 9e478908e7
1 changed files with 41 additions and 20 deletions

View File

@ -65,7 +65,7 @@ public class ImapConnection extends AbstractConnection {
IMAPTokenizer tokens; IMAPTokenizer tokens;
try { try {
ExchangeSessionFactory.checkConfig(); ExchangeSessionFactory.checkConfig();
sendClient("* OK [CAPABILITY IMAP4REV1 AUTH=LOGIN] IMAP4rev1 DavMail server ready"); sendClient("* OK [CAPABILITY IMAP4REV1 AUTH=LOGIN IDLE] IMAP4rev1 DavMail server ready");
for (; ;) { for (; ;) {
line = readClient(); line = readClient();
// unable to read line, connection closed ? // unable to read line, connection closed ?
@ -84,7 +84,7 @@ public class ImapConnection extends AbstractConnection {
break; break;
} }
if ("capability".equalsIgnoreCase(command)) { if ("capability".equalsIgnoreCase(command)) {
sendClient("* CAPABILITY IMAP4REV1 AUTH=LOGIN"); sendClient("* CAPABILITY IMAP4REV1 AUTH=LOGIN IDLE");
sendClient(commandId + " OK CAPABILITY completed"); sendClient(commandId + " OK CAPABILITY completed");
} else if ("login".equalsIgnoreCase(command)) { } else if ("login".equalsIgnoreCase(command)) {
parseCredentials(tokens); parseCredentials(tokens);
@ -416,29 +416,29 @@ public class ImapConnection extends AbstractConnection {
String messageName = UUID.randomUUID().toString(); String messageName = UUID.randomUUID().toString();
session.createMessage(folderName, messageName, properties, new String(buffer)); session.createMessage(folderName, messageName, properties, new String(buffer));
sendClient(commandId + " OK APPEND completed"); sendClient(commandId + " OK APPEND completed");
} else if ("idle".equalsIgnoreCase(command)) {
sendClient("+ idling ");
while (!in.ready()) {
ExchangeSession.MessageList currentMessages = currentFolder.messages;
if (session.refreshFolder(currentFolder)) {
handleRefresh(currentFolder, currentMessages);
}
// sleep 10 seconds
Thread.sleep(10000);
}
// read DONE line
line = readClient();
if ("DONE".equals(line)) {
sendClient(commandId + " OK " + command + " terminated");
} else {
sendClient(commandId + " BAD command unrecognized");
}
} else if ("noop".equalsIgnoreCase(command) || "check".equalsIgnoreCase(command)) { } else if ("noop".equalsIgnoreCase(command) || "check".equalsIgnoreCase(command)) {
if (currentFolder != null) { if (currentFolder != null) {
DavGatewayTray.debug(new BundleMessage("LOG_IMAP_COMMAND", command, currentFolder.folderName)); DavGatewayTray.debug(new BundleMessage("LOG_IMAP_COMMAND", command, currentFolder.folderName));
ExchangeSession.MessageList currentMessages = currentFolder.messages; ExchangeSession.MessageList currentMessages = currentFolder.messages;
if (session.refreshFolder(currentFolder)) { if (session.refreshFolder(currentFolder)) {
// build new uid set handleRefresh(currentFolder, currentMessages);
HashSet<Long> uidSet = new HashSet<Long>();
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
int index = 1;
for (ExchangeSession.Message message : currentMessages) {
if (!uidSet.contains(message.getImapUid())) {
sendClient("* " + index + " EXPUNGE");
} else {
index++;
}
}
sendClient("* " + currentFolder.count() + " EXISTS");
sendClient("* " + currentFolder.count() + " RECENT");
} }
} }
sendClient(commandId + " OK " + command + " completed"); sendClient(commandId + " OK " + command + " completed");
@ -529,6 +529,27 @@ public class ImapConnection extends AbstractConnection {
DavGatewayTray.resetIcon(); DavGatewayTray.resetIcon();
} }
private void handleRefresh(ExchangeSession.Folder currentFolder, ExchangeSession.MessageList currentMessages) throws IOException {
// build new uid set
HashSet<Long> uidSet = new HashSet<Long>();
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
int index = 1;
for (ExchangeSession.Message message : currentMessages) {
if (!uidSet.contains(message.getImapUid())) {
sendClient("* " + index + " EXPUNGE");
} else {
index++;
}
}
sendClient("* " + currentFolder.count() + " EXISTS");
sendClient("* " + currentFolder.count() + " RECENT");
}
private void handleFetch(ExchangeSession.Message message, int currentIndex, String parameters) throws IOException, MessagingException { private void handleFetch(ExchangeSession.Message message, int currentIndex, String parameters) throws IOException, MessagingException {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
buffer.append("* ").append(currentIndex).append(" FETCH (UID ").append(message.getImapUid()); buffer.append("* ").append(currentIndex).append(" FETCH (UID ").append(message.getImapUid());