EWS: move WebDav code to DavExchangeSession

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1084 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2010-06-09 09:13:13 +00:00
parent 51936619e3
commit 38f74f5c75
3 changed files with 296 additions and 215 deletions

View File

@ -291,21 +291,7 @@ public abstract class ExchangeSession {
* @throws NoRouteToHostException on error
* @throws UnknownHostException on error
*/
public boolean isExpired() throws NoRouteToHostException, UnknownHostException {
boolean isExpired = false;
try {
DavGatewayHttpClientFacade.executePropFindMethod(
httpClient, URIUtil.encodePath(inboxUrl), 0, DISPLAY_NAME);
} catch (UnknownHostException exc) {
throw exc;
} catch (NoRouteToHostException exc) {
throw exc;
} catch (IOException e) {
isExpired = true;
}
return isExpired;
}
public abstract boolean isExpired() throws NoRouteToHostException, UnknownHostException;
/**
* Test authentication mode : form based or basic.
@ -604,85 +590,7 @@ public abstract class ExchangeSession {
* @param messageBody mail body
* @throws IOException when unable to create message
*/
public void createMessage(String folderPath, String messageName, HashMap<String, String> properties, String messageBody) throws IOException {
String messageUrl = URIUtil.encodePathQuery(getFolderPath(folderPath) + '/' + messageName + ".EML");
PropPatchMethod patchMethod;
// create the message first as draft
if (properties.containsKey("draft")) {
patchMethod = new PropPatchMethod(messageUrl, buildProperties(properties));
try {
// update message with blind carbon copy and other flags
int statusCode = httpClient.executeMethod(patchMethod);
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
throw new DavMailException("EXCEPTION_UNABLE_TO_CREATE_MESSAGE", messageUrl, statusCode, ' ', patchMethod.getStatusLine());
}
} finally {
patchMethod.releaseConnection();
}
}
PutMethod putmethod = new PutMethod(messageUrl);
putmethod.setRequestHeader("Translate", "f");
try {
// use same encoding as client socket reader
putmethod.setRequestEntity(new ByteArrayRequestEntity(messageBody.getBytes()));
int code = httpClient.executeMethod(putmethod);
if (code != HttpStatus.SC_OK && code != HttpStatus.SC_CREATED) {
throw new DavMailException("EXCEPTION_UNABLE_TO_CREATE_MESSAGE", messageUrl, code, ' ', putmethod.getStatusLine());
}
} finally {
putmethod.releaseConnection();
}
// add bcc and other properties
if (!properties.isEmpty()) {
patchMethod = new PropPatchMethod(messageUrl, buildProperties(properties));
try {
// update message with blind carbon copy and other flags
int statusCode = httpClient.executeMethod(patchMethod);
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
throw new DavMailException("EXCEPTION_UNABLE_TO_PATCH_MESSAGE", messageUrl, statusCode, ' ', patchMethod.getStatusLine());
}
} finally {
patchMethod.releaseConnection();
}
}
}
protected List<DavProperty> buildProperties(Map<String, String> properties) {
ArrayList<DavProperty> list = new ArrayList<DavProperty>();
for (Map.Entry<String, String> entry : properties.entrySet()) {
if ("read".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("read", URN_SCHEMAS_HTTPMAIL), entry.getValue()));
} else if ("junk".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("x10830003", SCHEMAS_MAPI_PROPTAG), entry.getValue()));
} else if ("flagged".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("x10900003", SCHEMAS_MAPI_PROPTAG), entry.getValue()));
} else if ("answered".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("x10810003", SCHEMAS_MAPI_PROPTAG), entry.getValue()));
if ("102".equals(entry.getValue())) {
list.add(new DefaultDavProperty(DavPropertyName.create("x10800003", SCHEMAS_MAPI_PROPTAG), "261"));
}
} else if ("forwarded".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("x10810003", SCHEMAS_MAPI_PROPTAG), entry.getValue()));
if ("104".equals(entry.getValue())) {
list.add(new DefaultDavProperty(DavPropertyName.create("x10800003", SCHEMAS_MAPI_PROPTAG), "262"));
}
} else if ("bcc".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("bcc", Namespace.getNamespace("urn:schemas:mailheader:")), entry.getValue()));
} else if ("draft".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("x0E070003", SCHEMAS_MAPI_PROPTAG), entry.getValue()));
} else if ("deleted".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("_x0030_x8570", Namespace.getNamespace("http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/")), entry.getValue()));
} else if ("datereceived".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("datereceived", URN_SCHEMAS_HTTPMAIL), entry.getValue()));
}
}
return list;
}
public abstract void createMessage(String folderPath, String messageName, HashMap<String, String> properties, String messageBody) throws IOException;
/**
* Update given properties on message.
@ -691,23 +599,15 @@ public abstract class ExchangeSession {
* @param properties Webdav properties map
* @throws IOException on error
*/
public void updateMessage(Message message, Map<String, String> properties) throws IOException {
PropPatchMethod patchMethod = new PropPatchMethod(message.permanentUrl, buildProperties(properties)) {
@Override
protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
// ignore response body, sometimes invalid with exchange mapi properties
}
};
try {
int statusCode = httpClient.executeMethod(patchMethod);
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
throw new DavMailException("EXCEPTION_UNABLE_TO_UPDATE_MESSAGE");
}
public abstract void updateMessage(Message message, Map<String, String> properties) throws IOException;
} finally {
patchMethod.releaseConnection();
}
}
/**
* Send message to recipients, properties contains bcc recipients and other non MIME flags.
* @param properties additional message properties
* @param messageBody MIME message body
* @throws IOException on error
*/
public abstract void sendMessage(HashMap<String, String> properties, String messageBody) throws IOException;
protected static final List<String> POP_MESSAGE_ATTRIBUTES = new ArrayList<String>();
@ -742,6 +642,12 @@ public abstract class ExchangeSession {
IMAP_MESSAGE_ATTRIBUTES.add("date");
}
protected static final List<String> UID_MESSAGE_ATTRIBUTES = new ArrayList<String>();
static {
UID_MESSAGE_ATTRIBUTES.add("uid");
}
/**
* Get all folder messages.
*
@ -865,8 +771,7 @@ public abstract class ExchangeSession {
* @throws IOException on error
*/
public List<Folder> getSubFolders(String folderName, boolean recursive) throws IOException {
return getSubFolders(folderName,
or(equals("folderclass", "IPF.Note"), isNull("folderclass")),
return getSubFolders(folderName, or(equals("folderclass", "IPF.Note"), isNull("folderclass")),
recursive);
}
@ -902,32 +807,25 @@ public abstract class ExchangeSession {
public void purgeOldestTrashAndSentMessages() throws IOException {
int keepDelay = Settings.getIntProperty("davmail.keepDelay");
if (keepDelay != 0) {
purgeOldestFolderMessages(deleteditemsUrl, keepDelay);
purgeOldestFolderMessages(TRASH, keepDelay);
}
// this is a new feature, default is : do nothing
int sentKeepDelay = Settings.getIntProperty("davmail.sentKeepDelay");
if (sentKeepDelay != 0) {
purgeOldestFolderMessages(sentitemsUrl, sentKeepDelay);
purgeOldestFolderMessages(SENT, sentKeepDelay);
}
}
protected void purgeOldestFolderMessages(String folderUrl, int keepDelay) throws IOException {
protected void purgeOldestFolderMessages(String folderPath, int keepDelay) throws IOException {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, -keepDelay);
LOGGER.debug("Delete messages in " + folderUrl + " since " + cal.getTime());
LOGGER.debug("Delete messages in " + folderPath + " not modified since " + cal.getTime());
String searchRequest = "Select \"DAV:uid\"" +
" FROM Scope('SHALLOW TRAVERSAL OF \"" + folderUrl + "\"')\n" +
" WHERE \"DAV:isfolder\" = False\n" +
" AND \"DAV:getlastmodified\" < '" + formatSearchDate(cal.getTime()) + "'\n";
MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executeSearchMethod(
httpClient, URIUtil.encodePath(folderUrl), searchRequest);
MessageList messages = searchMessages(folderPath, UID_MESSAGE_ATTRIBUTES,
lt("lastmodified", formatSearchDate(cal.getTime())));
for (MultiStatusResponse response : responses) {
String messageUrl = URIUtil.decode(response.getHref());
LOGGER.debug("Delete " + messageUrl);
DavGatewayHttpClientFacade.executeDeleteMethod(httpClient, URIUtil.encodePath(messageUrl));
for (Message message : messages) {
message.delete();
}
}
@ -995,16 +893,7 @@ public abstract class ExchangeSession {
properties.put("bcc", bcc);
}
String messageName = UUID.randomUUID().toString();
createMessage("Drafts", messageName, properties, mailBuffer.toString());
String tempUrl = draftsUrl + '/' + messageName + ".EML";
MoveMethod method = new MoveMethod(URIUtil.encodePath(tempUrl), URIUtil.encodePath(sendmsgUrl), true);
int status = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, method);
if (status != HttpStatus.SC_OK) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
sendMessage(properties, mailBuffer.toString());
}
/**
@ -1101,23 +990,7 @@ public abstract class ExchangeSession {
* @param folderClass folder class
* @throws IOException on error
*/
public void createFolder(String folderName, String folderClass) throws IOException {
String folderPath = getFolderPath(folderName);
ArrayList<DavProperty> list = new ArrayList<DavProperty>();
list.add(new DefaultDavProperty(DavPropertyName.create("outlookfolderclass", Namespace.getNamespace("http://schemas.microsoft.com/exchange/")), folderClass));
// standard MkColMethod does not take properties, override PropPatchMethod instead
PropPatchMethod method = new PropPatchMethod(URIUtil.encodePath(folderPath), list) {
@Override
public String getName() {
return "MKCOL";
}
};
int status = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, method);
// ok or already exists
if (status != HttpStatus.SC_MULTI_STATUS && status != HttpStatus.SC_METHOD_NOT_ALLOWED) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
}
public abstract void createFolder(String folderName, String folderClass) throws IOException;
/**
* Delete Exchange folder.
@ -1125,9 +998,7 @@ public abstract class ExchangeSession {
* @param folderName logical folder name
* @throws IOException on error
*/
public void deleteFolder(String folderName) throws IOException {
DavGatewayHttpClientFacade.executeDeleteMethod(httpClient, URIUtil.encodePath(getFolderPath(folderName)));
}
public abstract void deleteFolder(String folderName) throws IOException;
/**
* Copy message to target folder
@ -1136,22 +1007,7 @@ public abstract class ExchangeSession {
* @param targetFolder target folder
* @throws IOException on error
*/
public void copyMessage(Message message, String targetFolder) throws IOException {
String targetPath = URIUtil.encodePath(getFolderPath(targetFolder)) + '/' + UUID.randomUUID().toString();
CopyMethod method = new CopyMethod(message.permanentUrl, 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_COPY_MESSAGE");
} else if (statusCode != HttpStatus.SC_CREATED) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
} finally {
method.releaseConnection();
}
}
public abstract void copyMessage(Message message, String targetFolder) throws IOException;
/**
* Move folder to target name.
@ -1160,39 +1016,9 @@ public abstract class ExchangeSession {
* @param targetName target folder name/path
* @throws IOException on error
*/
public void moveFolder(String folderName, String targetName) throws IOException {
String folderPath = getFolderPath(folderName);
String targetPath = getFolderPath(targetName);
MoveMethod method = new MoveMethod(URIUtil.encodePath(folderPath), URIUtil.encodePath(targetPath), false);
try {
int statusCode = httpClient.executeMethod(method);
if (statusCode == HttpStatus.SC_PRECONDITION_FAILED) {
throw new DavMailException("EXCEPTION_UNABLE_TO_MOVE_FOLDER");
} else if (statusCode != HttpStatus.SC_CREATED) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
} finally {
method.releaseConnection();
}
}
public abstract void moveFolder(String folderName, String targetName) throws IOException;
protected void moveToTrash(String encodedMessageUrl) throws IOException {
String destination = URIUtil.encodePath(deleteditemsUrl) + '/' + UUID.randomUUID().toString();
LOGGER.debug("Deleting : " + encodedMessageUrl + " to " + destination);
MoveMethod method = new MoveMethod(encodedMessageUrl, destination, false);
method.addRequestHeader("Allow-rename", "t");
int status = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, method);
// do not throw error if already deleted
if (status != HttpStatus.SC_CREATED && status != HttpStatus.SC_NOT_FOUND) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
if (method.getResponseHeader("Location") != null) {
destination = method.getResponseHeader("Location").getValue();
}
LOGGER.debug("Deleted to :" + destination);
}
protected abstract void moveToTrash(Message message) throws IOException;
/**
* Exchange folder with IMAP properties
@ -1688,6 +1514,7 @@ public abstract class ExchangeSession {
* @throws IOException on error
*/
public void delete() throws IOException {
LOGGER.debug("Delete " + permanentUrl + " (" + messageUrl + ")");
DavGatewayHttpClientFacade.executeDeleteMethod(httpClient, permanentUrl);
}
@ -1702,7 +1529,7 @@ public abstract class ExchangeSession {
properties.put("read", "1");
updateMessage(this, properties);
ExchangeSession.this.moveToTrash(permanentUrl);
ExchangeSession.this.moveToTrash(this);
}
/**

View File

@ -24,23 +24,24 @@ import davmail.exception.DavMailException;
import davmail.exchange.ExchangeSession;
import davmail.http.DavGatewayHttpClientFacade;
import davmail.ui.tray.DavGatewayTray;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
import org.apache.jackrabbit.webdav.client.methods.CopyMethod;
import org.apache.jackrabbit.webdav.client.methods.MoveMethod;
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
import org.apache.jackrabbit.webdav.property.DavProperty;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.apache.jackrabbit.webdav.property.DavPropertySet;
import org.apache.jackrabbit.webdav.client.methods.PropPatchMethod;
import org.apache.jackrabbit.webdav.property.*;
import org.apache.jackrabbit.webdav.xml.Namespace;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.NoRouteToHostException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.*;
/**
@ -196,6 +197,26 @@ public class DavExchangeSession extends ExchangeSession {
}
}
/**
* @inheritDoc
*/
@Override
public boolean isExpired() throws NoRouteToHostException, UnknownHostException {
boolean isExpired = false;
try {
DavGatewayHttpClientFacade.executePropFindMethod(
httpClient, URIUtil.encodePath(inboxUrl), 0, DISPLAY_NAME);
} catch (UnknownHostException exc) {
throw exc;
} catch (NoRouteToHostException exc) {
throw exc;
} catch (IOException e) {
isExpired = true;
}
return isExpired;
}
protected static class MultiCondition extends ExchangeSession.MultiCondition {
protected MultiCondition(Operator operator, Condition... condition) {
super(operator, condition);
@ -455,6 +476,55 @@ public class DavExchangeSession extends ExchangeSession {
return folders;
}
/**
* @inheritDoc
*/
public void createFolder(String folderName, String folderClass) throws IOException {
String folderPath = getFolderPath(folderName);
ArrayList<DavProperty> list = new ArrayList<DavProperty>();
list.add(Field.createDavProperty("folderclass", folderClass));
// standard MkColMethod does not take properties, override PropPatchMethod instead
PropPatchMethod method = new PropPatchMethod(URIUtil.encodePath(folderPath), list) {
@Override
public String getName() {
return "MKCOL";
}
};
int status = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, method);
// ok or already exists
if (status != HttpStatus.SC_MULTI_STATUS && status != HttpStatus.SC_METHOD_NOT_ALLOWED) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
}
/**
* @inheritDoc
*/
@Override
public void deleteFolder(String folderName) throws IOException {
DavGatewayHttpClientFacade.executeDeleteMethod(httpClient, URIUtil.encodePath(getFolderPath(folderName)));
}
/**
* @inheritDoc
*/
@Override
public void moveFolder(String folderName, String targetName) throws IOException {
String folderPath = getFolderPath(folderName);
String targetPath = getFolderPath(targetName);
MoveMethod method = new MoveMethod(URIUtil.encodePath(folderPath), URIUtil.encodePath(targetPath), false);
try {
int statusCode = httpClient.executeMethod(method);
if (statusCode == HttpStatus.SC_PRECONDITION_FAILED) {
throw new DavMailException("EXCEPTION_UNABLE_TO_MOVE_FOLDER");
} else if (statusCode != HttpStatus.SC_CREATED) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
} finally {
method.releaseConnection();
}
}
protected String getPropertyIfExists(DavPropertySet properties, String name) {
DavProperty property = properties.get(name, EMPTY);
if (property == null) {
@ -549,4 +619,174 @@ public class DavExchangeSession extends ExchangeSession {
Collections.sort(messages);
return messages;
}
protected List<DavProperty> buildProperties(Map<String, String> properties) {
ArrayList<DavProperty> list = new ArrayList<DavProperty>();
for (Map.Entry<String, String> entry : properties.entrySet()) {
if ("read".equals(entry.getKey())) {
list.add(Field.createDavProperty("read", entry.getValue()));
} else if ("junk".equals(entry.getKey())) {
list.add(Field.createDavProperty("junk", entry.getValue()));
} else if ("flagged".equals(entry.getKey())) {
list.add(Field.createDavProperty("flagStatus", entry.getValue()));
} else if ("answered".equals(entry.getKey())) {
list.add(Field.createDavProperty("lastVerbExecuted", entry.getValue()));
if ("102".equals(entry.getValue())) {
list.add(Field.createDavProperty("iconIndex", "261"));
}
} else if ("forwarded".equals(entry.getKey())) {
list.add(Field.createDavProperty("lastVerbExecuted", entry.getValue()));
if ("104".equals(entry.getValue())) {
list.add(Field.createDavProperty("iconIndex", "262"));
}
} else if ("bcc".equals(entry.getKey())) {
list.add(Field.createDavProperty("bcc", entry.getValue()));
} else if ("draft".equals(entry.getKey())) {
list.add(Field.createDavProperty("messageFlags", entry.getValue()));
} else if ("deleted".equals(entry.getKey())) {
// TODO: need to test this
list.add(Field.createDavProperty("writedeleted", entry.getValue()));
} else if ("datereceived".equals(entry.getKey())) {
list.add(new DefaultDavProperty(DavPropertyName.create("datereceived", URN_SCHEMAS_HTTPMAIL), entry.getValue()));
}
}
return list;
}
/**
* Create message in specified folder.
* Will overwrite an existing message with same subject in the same folder
*
* @param folderPath Exchange folder path
* @param messageName message name
* @param properties message properties (flags)
* @param messageBody mail body
* @throws IOException when unable to create message
*/
public void createMessage(String folderPath, String messageName, HashMap<String, String> properties, String messageBody) throws IOException {
String messageUrl = URIUtil.encodePathQuery(getFolderPath(folderPath) + '/' + messageName + ".EML");
PropPatchMethod patchMethod;
// create the message first as draft
if (properties.containsKey("draft")) {
patchMethod = new PropPatchMethod(messageUrl, buildProperties(properties));
try {
// update message with blind carbon copy and other flags
int statusCode = httpClient.executeMethod(patchMethod);
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
throw new DavMailException("EXCEPTION_UNABLE_TO_CREATE_MESSAGE", messageUrl, statusCode, ' ', patchMethod.getStatusLine());
}
} finally {
patchMethod.releaseConnection();
}
}
PutMethod putmethod = new PutMethod(messageUrl);
putmethod.setRequestHeader("Translate", "f");
try {
// use same encoding as client socket reader
putmethod.setRequestEntity(new ByteArrayRequestEntity(messageBody.getBytes()));
int code = httpClient.executeMethod(putmethod);
if (code != HttpStatus.SC_OK && code != HttpStatus.SC_CREATED) {
throw new DavMailException("EXCEPTION_UNABLE_TO_CREATE_MESSAGE", messageUrl, code, ' ', putmethod.getStatusLine());
}
} finally {
putmethod.releaseConnection();
}
// add bcc and other properties
if (!properties.isEmpty()) {
patchMethod = new PropPatchMethod(messageUrl, buildProperties(properties));
try {
// update message with blind carbon copy and other flags
int statusCode = httpClient.executeMethod(patchMethod);
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
throw new DavMailException("EXCEPTION_UNABLE_TO_PATCH_MESSAGE", messageUrl, statusCode, ' ', patchMethod.getStatusLine());
}
} finally {
patchMethod.releaseConnection();
}
}
}
/**
* @inheritDoc
*/
@Override
public void updateMessage(Message message, Map<String, String> properties) throws IOException {
PropPatchMethod patchMethod = new PropPatchMethod(message.permanentUrl, buildProperties(properties)) {
@Override
protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
// ignore response body, sometimes invalid with exchange mapi properties
}
};
try {
int statusCode = httpClient.executeMethod(patchMethod);
if (statusCode != HttpStatus.SC_MULTI_STATUS) {
throw new DavMailException("EXCEPTION_UNABLE_TO_UPDATE_MESSAGE");
}
} finally {
patchMethod.releaseConnection();
}
}
/**
* @inheritDoc
*/
@Override
public void sendMessage(HashMap<String, String> properties, String messageBody) throws IOException {
String messageName = UUID.randomUUID().toString();
createMessage("Drafts", messageName, properties, messageBody);
String tempUrl = draftsUrl + '/' + messageName + ".EML";
MoveMethod method = new MoveMethod(URIUtil.encodePath(tempUrl), URIUtil.encodePath(sendmsgUrl), true);
int status = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, method);
if (status != HttpStatus.SC_OK) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
}
/**
* @inheritDoc
*/
@Override
public void copyMessage(Message message, String targetFolder) throws IOException {
String targetPath = URIUtil.encodePath(getFolderPath(targetFolder)) + '/' + UUID.randomUUID().toString();
CopyMethod method = new CopyMethod(message.permanentUrl, 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_COPY_MESSAGE");
} else if (statusCode != HttpStatus.SC_CREATED) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
} finally {
method.releaseConnection();
}
}
@Override
protected void moveToTrash(Message message) throws IOException {
String destination = URIUtil.encodePath(deleteditemsUrl) + '/' + UUID.randomUUID().toString();
LOGGER.debug("Deleting : " + message.permanentUrl + " to " + destination);
MoveMethod method = new MoveMethod(message.permanentUrl, destination, false);
method.addRequestHeader("Allow-rename", "t");
int status = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, method);
// do not throw error if already deleted
if (status != HttpStatus.SC_CREATED && status != HttpStatus.SC_NOT_FOUND) {
throw DavGatewayHttpClientFacade.buildHttpException(method);
}
if (method.getResponseHeader("Location") != null) {
destination = method.getResponseHeader("Location").getValue();
}
LOGGER.debug("Deleted to :" + destination);
}
}

View File

@ -19,6 +19,7 @@
package davmail.exchange.dav;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
import org.apache.jackrabbit.webdav.xml.Namespace;
import java.util.HashMap;
@ -94,11 +95,14 @@ public class Field {
createField("flagStatus", 0x1090, PropertyType.Integer);//PR_FLAG_STATUS
createField("messageFlags", 0x0e07, PropertyType.Integer);//PR_MESSAGE_FLAGS
createField("lastVerbExecuted", 0x1081, PropertyType.Integer);//PR_LAST_VERB_EXECUTED
createField("iconIndex", 0x1080, PropertyType.Integer);//PR_ICON_INDEX
createField(URN_SCHEMAS_HTTPMAIL, "read");
//createField("read", 0x0e69, PropertyType.Boolean);//PR_READ
createField("deleted", DistinguishedPropertySetType.Common, 0x8570);
createField(URN_SCHEMAS_HTTPMAIL, "date"); //PR_CLIENT_SUBMIT_TIME, 0x0039
createField("writedeleted", DistinguishedPropertySetType.Common, 0x8570, PropertyType.Integer);
createField(URN_SCHEMAS_HTTPMAIL, "date");//PR_CLIENT_SUBMIT_TIME, 0x0039
//createField("date", 0x0e06, PropertyType.SystemTime);//PR_MESSAGE_DELIVERY_TIME
createField(URN_SCHEMAS_MAILHEADER, "bcc");//PS_INTERNET_HEADERS/bcc
// IMAP search
@ -129,6 +133,12 @@ public class Field {
fieldMap.put(field.alias, field);
}
protected static void createField(String alias, DistinguishedPropertySetType propertySetType, int propertyTag, PropertyType propertyType) {
String name = '{' + distinguishedPropertySetMap.get(propertySetType) + "}/_x" +propertyTypeMap.get(propertyType)+"_x"+Integer.toHexString(propertyTag);
Field field = new Field(alias, SCHEMAS_MAPI_ID, name);
fieldMap.put(field.alias, field);
}
protected static void createField(Namespace namespace, String name) {
Field field = new Field(namespace, name);
fieldMap.put(field.alias, field);
@ -185,4 +195,8 @@ public class Field {
String name = '{' + distinguishedPropertySetMap.get(DistinguishedPropertySetType.InternetHeaders) + "}/" + headerName;
return new Field(SCHEMAS_MAPI_STRING, name);
}
public static DefaultDavProperty createDavProperty(String alias, String value) {
return new DefaultDavProperty(Field.get(alias).davPropertyName, value);
}
}