IMAP: Implement copy and delete actions on messages and folders

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@313 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2009-02-02 23:29:44 +00:00
parent 8ec93490fb
commit 61b3f9c7a5
2 changed files with 92 additions and 5 deletions

View File

@ -16,6 +16,7 @@ import org.apache.webdav.lib.WebdavResource;
import org.apache.webdav.lib.methods.MoveMethod;
import org.apache.webdav.lib.methods.PropPatchMethod;
import org.apache.webdav.lib.methods.SearchMethod;
import org.apache.webdav.lib.methods.CopyMethod;
import org.htmlcleaner.CommentToken;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
@ -545,7 +546,7 @@ public class ExchangeSession {
} else if ("message-id".equals(prop.getLocalName())) {
message.messageId = prop.getPropertyAsString();
if (message.messageId.startsWith("<") && message.messageId.endsWith(">")) {
message.messageId = message.messageId.substring(1, message.messageId.length()-1);
message.messageId = message.messageId.substring(1, message.messageId.length() - 1);
}
}
}
@ -849,6 +850,27 @@ public class ExchangeSession {
}
}
public void copyMessage(String messageUrl, String targetName) throws IOException {
String targetPath = getFolderPath(targetName) + messageUrl.substring(messageUrl.lastIndexOf('/'));
CopyMethod method = new CopyMethod(URIUtil.encodePath(messageUrl),
URIUtil.encodePath(targetPath));
method.setOverwrite(false);
method.addRequestHeader("Allow-Rename", "t");
try {
int statusCode = wdr.retrieveSessionInstance().executeMethod(method);
if (statusCode == HttpStatus.SC_PRECONDITION_FAILED) {
throw new HttpException("Unable to move message, target already exists");
} else if (statusCode != HttpStatus.SC_CREATED) {
HttpException ex = new HttpException();
ex.setReasonCode(method.getStatusCode());
ex.setReason(method.getStatusText());
throw ex;
}
} finally {
method.releaseConnection();
}
}
public void moveFolder(String folderName, String targetName) throws IOException {
String folderPath = getFolderPath(folderName);
String targetPath = getFolderPath(targetName);
@ -897,6 +919,7 @@ public class ExchangeSession {
public int size;
public String messageId;
public boolean read;
public boolean deleted;
public long getUidAsLong() {
byte[] decodedValue = Base64.decode(uid.getBytes());
@ -910,6 +933,17 @@ public class ExchangeSession {
return result;
}
public String getImapFlags() {
StringBuilder buffer = new StringBuilder();
if (read) {
buffer.append("\\Seen ");
}
if (deleted) {
buffer.append("\\Deleted");
}
return buffer.toString();
}
public void write(OutputStream os) throws IOException {
HttpMethod method = null;
BufferedReader reader = null;
@ -989,7 +1023,7 @@ public class ExchangeSession {
}
public int compareTo(Object message) {
return (int)(getUidAsLong()-((Message)message).getUidAsLong());
return (int) (getUidAsLong() - ((Message) message).getUidAsLong());
}
}
@ -1263,6 +1297,23 @@ public class ExchangeSession {
return status;
}
public void deleteFolder(String path) throws IOException {
wdr.deleteMethod(getFolderPath(path));
int status = wdr.getStatusCode();
if (status != HttpStatus.SC_OK) {
HttpException ex = new HttpException();
ex.setReasonCode(status);
ex.setReason(wdr.getStatusMessage());
throw ex;
}
}
public int deleteMessage(String path) throws IOException {
wdr.deleteMethod(path);
return wdr.getStatusCode();
}
public int deleteEvent(String path) throws IOException {
wdr.deleteMethod(calendarUrl + "/" + URIUtil.decode(path));
return wdr.getStatusCode();

View File

@ -142,6 +142,8 @@ public class ImapConnection extends AbstractConnection {
sendClient(commandId + " BAD missing folder argument");
}
} else if ("select".equalsIgnoreCase(command) || "examine".equalsIgnoreCase(command)) {
// first purge previous folder
expunge();
if (tokens.hasMoreTokens()) {
String folderName = BASE64MailboxDecoder.decode(tokens.nextToken());
currentFolder = session.getFolder(folderName);
@ -182,6 +184,14 @@ public class ImapConnection extends AbstractConnection {
} catch (HttpException e) {
sendClient(commandId + " NO " + e.getReason());
}
} else if ("delete".equalsIgnoreCase(command)) {
String folderName = BASE64MailboxDecoder.decode(tokens.nextToken());
try {
session.deleteFolder(folderName);
sendClient(commandId + " OK delete completed");
} catch (HttpException e) {
sendClient(commandId + " NO " + e.getReason());
}
} else if ("uid".equalsIgnoreCase(command)) {
if (tokens.hasMoreTokens()) {
String subcommand = tokens.nextToken();
@ -222,7 +232,7 @@ public class ImapConnection extends AbstractConnection {
int count = 0;
for (ExchangeSession.Message message : messages) {
count++;
sendClient("* " + count + " FETCH (UID " + message.getUidAsLong() + " FLAGS (" + (message.read ? "\\Seen" : "") + "))");
sendClient("* " + count + " FETCH (UID " + message.getUidAsLong() + " FLAGS (" + (message.getImapFlags()) + "))");
}
sendClient(commandId + " OK UID FETCH completed");
} else {
@ -255,7 +265,7 @@ public class ImapConnection extends AbstractConnection {
"] {" + baos.size() + "}");
os.write(baos.toByteArray());
os.flush();
sendClient(" FLAGS (" + (message.read ? "\\Seen" : "") + "))");
sendClient(" FLAGS (" + (message.getImapFlags()) + "))");
}
}
}
@ -307,6 +317,8 @@ public class ImapConnection extends AbstractConnection {
if ("\\Seen".equals(flag)) {
properties.put("read", "1");
message.read = true;
} else if ("\\Deleted".equals(flag)) {
message.deleted = true;
}
}
}
@ -315,10 +327,20 @@ public class ImapConnection extends AbstractConnection {
for (ExchangeSession.Message currentMessage : messages) {
index++;
if (currentMessage == message) {
sendClient("* " + index + " FETCH (UID " + message.getUidAsLong() + " FLAGS (" + (message.read ? "\\Seen" : "") + "))");
sendClient("* " + index + " FETCH (UID " + message.getUidAsLong() + " FLAGS (" + (message.getImapFlags()) + "))");
}
}
sendClient(commandId + " OK STORE completed");
} else if ("copy".equalsIgnoreCase(subcommand)) {
long uid = Long.parseLong(tokens.nextToken());
ExchangeSession.Message message = messages.getByUid(uid);
String targetName = BASE64MailboxDecoder.decode(tokens.nextToken());
try {
session.copyMessage(message.messageUrl, targetName);
sendClient(commandId + " OK rename completed");
} catch (HttpException e) {
sendClient(commandId + " NO " + e.getReason());
}
}
} else {
sendClient(commandId + " BAD command unrecognized");
@ -372,6 +394,7 @@ public class ImapConnection extends AbstractConnection {
sendClient(commandId + " OK APPEND completed");
} else if ("noop".equalsIgnoreCase(command) || "check".equalsIgnoreCase(command)) {
if (currentFolder != null) {
expunge();
currentFolder = session.getFolder(currentFolder.folderName);
messages = session.getAllMessages(currentFolder.folderUrl);
sendClient("* " + currentFolder.objectCount + " EXISTS");
@ -409,6 +432,19 @@ public class ImapConnection extends AbstractConnection {
DavGatewayTray.resetIcon();
}
protected void expunge() throws IOException {
if (messages != null) {
int index = 0;
for (ExchangeSession.Message message : messages) {
index++;
if (message.deleted) {
session.deleteMessage(message.messageUrl);
sendClient("* "+index+" EXPUNGE");
}
}
}
}
/**
* Decode IMAP credentials
*