mirror of
https://github.com/moparisthebest/davmail
synced 2025-01-05 18:58:02 -05:00
IMAP: implement MOVE RFC draft http://tools.ietf.org/id/draft-krecicki-imap-move-00.html
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1889 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
8bee35ad29
commit
5956574072
@ -413,7 +413,7 @@ public abstract class ExchangeSession {
|
||||
if (pinsafeUser == null) {
|
||||
pinsafeUser = userName;
|
||||
}
|
||||
GetMethod getMethod = new GetMethod("/PINsafeISAFilter.dll?username="+pinsafeUser);
|
||||
GetMethod getMethod = new GetMethod("/PINsafeISAFilter.dll?username=" + pinsafeUser);
|
||||
try {
|
||||
int status = httpClient.executeMethod(getMethod);
|
||||
if (status != HttpStatus.SC_OK) {
|
||||
@ -1257,7 +1257,7 @@ public abstract class ExchangeSession {
|
||||
* Send Mime message.
|
||||
*
|
||||
* @param mimeMessage MIME message
|
||||
* @throws IOException on error
|
||||
* @throws IOException on error
|
||||
* @throws MessagingException on error
|
||||
*/
|
||||
public abstract void sendMessage(MimeMessage mimeMessage) throws IOException, MessagingException;
|
||||
@ -1381,6 +1381,15 @@ public abstract class ExchangeSession {
|
||||
*/
|
||||
public abstract void copyMessage(Message message, String targetFolder) throws IOException;
|
||||
|
||||
/**
|
||||
* Move message to target folder
|
||||
*
|
||||
* @param message Exchange message
|
||||
* @param targetFolder target folder
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public abstract void moveMessage(Message message, String targetFolder) throws IOException;
|
||||
|
||||
/**
|
||||
* Move folder to target name.
|
||||
*
|
||||
@ -2382,57 +2391,60 @@ public abstract class ExchangeSession {
|
||||
// ICS description so that invites contain the description text
|
||||
String description = vCalendar.getFirstVeventPropertyValue("DESCRIPTION");
|
||||
|
||||
// handle notifications
|
||||
if ("urn:content-classes:calendarmessage".equals(contentClass)) {
|
||||
// need to parse attendees and organizer to build recipients
|
||||
VCalendar.Recipients recipients = vCalendar.getRecipients(true);
|
||||
String to;
|
||||
String cc;
|
||||
String notificationSubject;
|
||||
if (email.equalsIgnoreCase(recipients.organizer)) {
|
||||
// current user is organizer => notify all
|
||||
writer.writeHeader("To", recipients.attendees);
|
||||
writer.writeHeader("Cc", recipients.optionalAttendees);
|
||||
// do not send notification if no recipients found
|
||||
if (recipients.attendees == null && recipients.optionalAttendees == null) {
|
||||
return null;
|
||||
}
|
||||
to = recipients.attendees;
|
||||
cc = recipients.optionalAttendees;
|
||||
notificationSubject = subject;
|
||||
} else {
|
||||
String status = vCalendar.getAttendeeStatus();
|
||||
// notify only organizer
|
||||
String to = recipients.organizer;
|
||||
String cc = null;
|
||||
String notificationSubject = (status != null) ? (BundleMessage.format(status) + vEventSubject) : subject;
|
||||
to = recipients.organizer;
|
||||
cc = null;
|
||||
notificationSubject = (status != null) ? (BundleMessage.format(status) + vEventSubject) : subject;
|
||||
description = "";
|
||||
// Allow end user notification edit
|
||||
if (Settings.getBooleanProperty("davmail.caldavEditNotifications")) {
|
||||
// create notification edit dialog
|
||||
NotificationDialog notificationDialog = new NotificationDialog(recipients.organizer,
|
||||
null, notificationSubject);
|
||||
if (!notificationDialog.getSendNotification()) {
|
||||
LOGGER.debug("Notification canceled by user");
|
||||
return null;
|
||||
}
|
||||
// get description from dialog
|
||||
to = notificationDialog.getTo();
|
||||
cc = notificationDialog.getCc();
|
||||
notificationSubject = notificationDialog.getSubject();
|
||||
description = notificationDialog.getBody();
|
||||
}
|
||||
}
|
||||
|
||||
// do not send notification if no recipients found
|
||||
if (to == null || to.length() == 0) {
|
||||
// Allow end user notification edit
|
||||
if (Settings.getBooleanProperty("davmail.caldavEditNotifications")) {
|
||||
// create notification edit dialog
|
||||
NotificationDialog notificationDialog = new NotificationDialog(to,
|
||||
cc, notificationSubject, description);
|
||||
if (!notificationDialog.getSendNotification()) {
|
||||
LOGGER.debug("Notification canceled by user");
|
||||
return null;
|
||||
}
|
||||
|
||||
writer.writeHeader("To", to);
|
||||
writer.writeHeader("Cc", cc);
|
||||
writer.writeHeader("Subject", notificationSubject);
|
||||
|
||||
// get description from dialog
|
||||
to = notificationDialog.getTo();
|
||||
cc = notificationDialog.getCc();
|
||||
notificationSubject = notificationDialog.getSubject();
|
||||
description = notificationDialog.getBody();
|
||||
}
|
||||
|
||||
// do not send notification if no recipients found
|
||||
if ((to == null || to.length() == 0) && (cc == null || cc.length() == 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
writer.writeHeader("To", to);
|
||||
writer.writeHeader("Cc", cc);
|
||||
writer.writeHeader("Subject", notificationSubject);
|
||||
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
StringBuilder logBuffer = new StringBuilder("Sending notification ");
|
||||
if (recipients.attendees != null) {
|
||||
logBuffer.append("to: ").append(recipients.attendees);
|
||||
if (to != null) {
|
||||
logBuffer.append("to: ").append(to);
|
||||
}
|
||||
if (recipients.optionalAttendees != null) {
|
||||
logBuffer.append("cc: ").append(recipients.optionalAttendees);
|
||||
if (cc != null) {
|
||||
logBuffer.append("cc: ").append(cc);
|
||||
}
|
||||
LOGGER.debug(logBuffer.toString());
|
||||
}
|
||||
@ -2620,7 +2632,7 @@ public abstract class ExchangeSession {
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public List<Event> searchTasksOnly(String folderPath) throws IOException {
|
||||
return searchEvents(folderPath, and(isEqualTo("outlookmessageclass", "IPM.Task"),
|
||||
return searchEvents(folderPath, and(isEqualTo("outlookmessageclass", "IPM.Task"),
|
||||
or(isNull("datecompleted"), getPastDelayCondition("datecompleted"))));
|
||||
}
|
||||
|
||||
|
@ -2875,6 +2875,36 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void moveMessage(ExchangeSession.Message message, String targetFolder) throws IOException {
|
||||
try {
|
||||
moveMessage(message.permanentUrl, targetFolder);
|
||||
} catch (HttpNotFoundException e) {
|
||||
LOGGER.debug("404 not found at permanenturl: " + message.permanentUrl + ", retry with messageurl");
|
||||
moveMessage(message.messageUrl, targetFolder);
|
||||
}
|
||||
}
|
||||
|
||||
protected void moveMessage(String sourceUrl, String targetFolder) throws IOException {
|
||||
String targetPath = URIUtil.encodePath(getFolderPath(targetFolder)) + '/' + UUID.randomUUID().toString();
|
||||
MoveMethod method = new MoveMethod(URIUtil.encodePath(sourceUrl), targetPath, false);
|
||||
// allow rename if a message with the same name exists
|
||||
method.addRequestHeader("Allow-Rename", "t");
|
||||
try {
|
||||
int statusCode = httpClient.executeMethod(method);
|
||||
if (statusCode == HttpStatus.SC_PRECONDITION_FAILED) {
|
||||
throw new DavMailException("EXCEPTION_UNABLE_TO_MOVE_MESSAGE");
|
||||
} else if (statusCode != HttpStatus.SC_CREATED) {
|
||||
throw DavGatewayHttpClientFacade.buildHttpException(method);
|
||||
}
|
||||
} finally {
|
||||
method.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -1002,6 +1002,15 @@ public class EwsExchangeSession extends ExchangeSession {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void moveMessage(ExchangeSession.Message message, String targetFolder) throws IOException {
|
||||
MoveItemMethod moveItemMethod = new MoveItemMethod(((EwsExchangeSession.Message) message).itemId, getFolderId(targetFolder));
|
||||
executeMethod(moveItemMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -71,9 +71,9 @@ public class ImapConnection extends AbstractConnection {
|
||||
final String capabilities;
|
||||
int imapIdleDelay = Settings.getIntProperty("davmail.imapIdleDelay") * 60;
|
||||
if (imapIdleDelay > 0) {
|
||||
capabilities = "CAPABILITY IMAP4REV1 AUTH=LOGIN IDLE";
|
||||
capabilities = "CAPABILITY IMAP4REV1 AUTH=LOGIN IDLE MOVE";
|
||||
} else {
|
||||
capabilities = "CAPABILITY IMAP4REV1 AUTH=LOGIN";
|
||||
capabilities = "CAPABILITY IMAP4REV1 AUTH=LOGIN MOVE";
|
||||
}
|
||||
|
||||
String line;
|
||||
@ -327,16 +327,20 @@ public class ImapConnection extends AbstractConnection {
|
||||
String action = tokens.nextToken();
|
||||
String flags = tokens.nextToken();
|
||||
handleStore(commandId, uidRangeIterator, action, flags);
|
||||
} else if ("copy".equalsIgnoreCase(subcommand)) {
|
||||
} else if ("copy".equalsIgnoreCase(subcommand) || "move".equalsIgnoreCase(subcommand)) {
|
||||
try {
|
||||
UIDRangeIterator uidRangeIterator = new UIDRangeIterator(currentFolder.messages, tokens.nextToken());
|
||||
String targetName = BASE64MailboxDecoder.decode(tokens.nextToken());
|
||||
while (uidRangeIterator.hasNext()) {
|
||||
DavGatewayTray.switchIcon();
|
||||
ExchangeSession.Message message = uidRangeIterator.next();
|
||||
session.copyMessage(message, targetName);
|
||||
if ("copy".equalsIgnoreCase(subcommand)) {
|
||||
session.copyMessage(message, targetName);
|
||||
} else {
|
||||
session.moveMessage(message, targetName);
|
||||
}
|
||||
}
|
||||
sendClient(commandId + " OK copy completed");
|
||||
sendClient(commandId + " OK "+subcommand+" completed");
|
||||
} catch (HttpException e) {
|
||||
sendClient(commandId + " NO " + e.getMessage());
|
||||
}
|
||||
@ -394,16 +398,20 @@ public class ImapConnection extends AbstractConnection {
|
||||
String flags = tokens.nextToken();
|
||||
handleStore(commandId, rangeIterator, action, flags);
|
||||
|
||||
} else if ("copy".equalsIgnoreCase(command)) {
|
||||
} else if ("copy".equalsIgnoreCase(command) || "move".equalsIgnoreCase(command)) {
|
||||
try {
|
||||
RangeIterator rangeIterator = new RangeIterator(currentFolder.messages, tokens.nextToken());
|
||||
String targetName = BASE64MailboxDecoder.decode(tokens.nextToken());
|
||||
while (rangeIterator.hasNext()) {
|
||||
DavGatewayTray.switchIcon();
|
||||
ExchangeSession.Message message = rangeIterator.next();
|
||||
session.copyMessage(message, targetName);
|
||||
if ("copy".equalsIgnoreCase(command)) {
|
||||
session.copyMessage(message, targetName);
|
||||
} else {
|
||||
session.moveMessage(message, targetName);
|
||||
}
|
||||
}
|
||||
sendClient(commandId + " OK copy completed");
|
||||
sendClient(commandId + " OK "+command+" completed");
|
||||
} catch (HttpException e) {
|
||||
sendClient(commandId + " NO " + e.getMessage());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user