mirror of
https://github.com/moparisthebest/davmail
synced 2025-01-07 11:48:02 -05:00
EWS: implement calendar event create or update, processed field, subfolder path handling
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1164 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
f96c8989dd
commit
a0339007c4
@ -647,7 +647,11 @@ public abstract class ExchangeSession {
|
|||||||
protected MultiCondition(Operator operator, Condition... conditions) {
|
protected MultiCondition(Operator operator, Condition... conditions) {
|
||||||
this.operator = operator;
|
this.operator = operator;
|
||||||
this.conditions = new ArrayList<Condition>();
|
this.conditions = new ArrayList<Condition>();
|
||||||
this.conditions.addAll(Arrays.asList(conditions));
|
for (Condition condition:conditions) {
|
||||||
|
if (condition != null) {
|
||||||
|
this.conditions.add(condition);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2475,7 +2479,7 @@ public abstract class ExchangeSession {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ItemResult createOrUpdate(byte[] content) throws IOException;
|
protected abstract ItemResult createOrUpdate(byte[] mimeContent) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,7 +749,7 @@ public class DavExchangeSession extends ExchangeSession {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected ItemResult createOrUpdate(byte[] messageContent) throws IOException {
|
protected ItemResult createOrUpdate(byte[] mimeContent) throws IOException {
|
||||||
PutMethod putmethod = new PutMethod(URIUtil.encodePath(getHref()));
|
PutMethod putmethod = new PutMethod(URIUtil.encodePath(getHref()));
|
||||||
putmethod.setRequestHeader("Translate", "f");
|
putmethod.setRequestHeader("Translate", "f");
|
||||||
putmethod.setRequestHeader("Overwrite", "f");
|
putmethod.setRequestHeader("Overwrite", "f");
|
||||||
@ -760,7 +760,7 @@ public class DavExchangeSession extends ExchangeSession {
|
|||||||
putmethod.setRequestHeader("If-None-Match", noneMatch);
|
putmethod.setRequestHeader("If-None-Match", noneMatch);
|
||||||
}
|
}
|
||||||
putmethod.setRequestHeader("Content-Type", "message/rfc822");
|
putmethod.setRequestHeader("Content-Type", "message/rfc822");
|
||||||
putmethod.setRequestEntity(new ByteArrayRequestEntity(messageContent, "message/rfc822"));
|
putmethod.setRequestEntity(new ByteArrayRequestEntity(mimeContent, "message/rfc822"));
|
||||||
int status;
|
int status;
|
||||||
try {
|
try {
|
||||||
status = httpClient.executeMethod(putmethod);
|
status = httpClient.executeMethod(putmethod);
|
||||||
@ -793,7 +793,7 @@ public class DavExchangeSession extends ExchangeSession {
|
|||||||
// Set contentclass to make ActiveSync happy
|
// Set contentclass to make ActiveSync happy
|
||||||
propertyList.add(Field.createDavProperty("contentclass", contentClass));
|
propertyList.add(Field.createDavProperty("contentclass", contentClass));
|
||||||
// ... but also set PR_INTERNET_CONTENT to preserve custom properties
|
// ... but also set PR_INTERNET_CONTENT to preserve custom properties
|
||||||
propertyList.add(Field.createDavProperty("internetContent", new String(Base64.encodeBase64(messageContent))));
|
propertyList.add(Field.createDavProperty("internetContent", new String(Base64.encodeBase64(mimeContent))));
|
||||||
PropPatchMethod propPatchMethod = new PropPatchMethod(URIUtil.encodePath(getHref()), propertyList);
|
PropPatchMethod propPatchMethod = new PropPatchMethod(URIUtil.encodePath(getHref()), propertyList);
|
||||||
int patchStatus = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, propPatchMethod);
|
int patchStatus = DavGatewayHttpClientFacade.executeHttpMethod(httpClient, propPatchMethod);
|
||||||
if (patchStatus != HttpStatus.SC_MULTI_STATUS) {
|
if (patchStatus != HttpStatus.SC_MULTI_STATUS) {
|
||||||
|
@ -492,12 +492,12 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Condition isTrue(String attributeName) {
|
public Condition isTrue(String attributeName) {
|
||||||
return new AttributeCondition(attributeName, Operator.IsEqualTo, "True");
|
return new AttributeCondition(attributeName, Operator.IsEqualTo, "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Condition isFalse(String attributeName) {
|
public Condition isFalse(String attributeName) {
|
||||||
return new AttributeCondition(attributeName, Operator.IsEqualTo, "False");
|
return new AttributeCondition(attributeName, Operator.IsEqualTo, "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final HashSet<FieldURI> FOLDER_PROPERTIES = new HashSet<FieldURI>();
|
protected static final HashSet<FieldURI> FOLDER_PROPERTIES = new HashSet<FieldURI>();
|
||||||
@ -529,8 +529,15 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<ExchangeSession.Folder> getSubFolders(String folderPath, Condition condition, boolean recursive) throws IOException {
|
public List<ExchangeSession.Folder> getSubFolders(String folderPath, Condition condition, boolean recursive) throws IOException {
|
||||||
|
String baseFolderPath = folderPath;
|
||||||
|
if (baseFolderPath.startsWith("/users/")) {
|
||||||
|
int index = baseFolderPath.indexOf('/', "/users/".length());
|
||||||
|
if (index >= 0) {
|
||||||
|
baseFolderPath = baseFolderPath.substring(index+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
List<ExchangeSession.Folder> folders = new ArrayList<ExchangeSession.Folder>();
|
List<ExchangeSession.Folder> folders = new ArrayList<ExchangeSession.Folder>();
|
||||||
appendSubFolders(folders, folderPath, getFolderId(folderPath), condition, recursive);
|
appendSubFolders(folders, baseFolderPath, getFolderId(folderPath), condition, recursive);
|
||||||
return folders;
|
return folders;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,7 +767,6 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
itemResult.etag = getItemMethod.getResponseItem().get(Field.get("etag").getResponseName());
|
itemResult.etag = getItemMethod.getResponseItem().get(Field.get("etag").getResponseName());
|
||||||
|
|
||||||
return itemResult;
|
return itemResult;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,6 +780,7 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
permanentUrl = response.get(Field.get("permanenturl").getResponseName());
|
permanentUrl = response.get(Field.get("permanenturl").getResponseName());
|
||||||
etag = response.get(Field.get("etag").getResponseName());
|
etag = response.get(Field.get("etag").getResponseName());
|
||||||
displayName = response.get(Field.get("displayname").getResponseName());
|
displayName = response.get(Field.get("displayname").getResponseName());
|
||||||
|
itemName = response.get(Field.get("urlcompname").getResponseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -785,29 +792,70 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemResult createOrUpdate(byte[] content) throws IOException {
|
protected ItemResult createOrUpdate(byte[] mimeContent) throws IOException {
|
||||||
EWSMethod.Item item = new EWSMethod.Item();
|
ItemResult itemResult = new ItemResult();
|
||||||
item.type = "Message";
|
EWSMethod createOrUpdateItemMethod;
|
||||||
item.mimeContent = Base64.encodeBase64(content);
|
|
||||||
// TODO: handle etag and noneMatch
|
|
||||||
CreateItemMethod createItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, getFolderId(folderPath), item);
|
|
||||||
executeMethod(createItemMethod);
|
|
||||||
|
|
||||||
// TODO: detect create/update
|
// first try to load existing event
|
||||||
int status = createItemMethod.getStatusCode();
|
String urlcompname = convertItemNameToEML(itemName);
|
||||||
if (status == HttpURLConnection.HTTP_OK) {
|
String currentEtag = null;
|
||||||
|
ItemId currentItemId = null;
|
||||||
|
List<EWSMethod.Item> responses = searchItems(folderPath, EVENT_REQUEST_PROPERTIES, EwsExchangeSession.this.equals("urlcompname", urlcompname), FolderQueryTraversal.SHALLOW);
|
||||||
|
if (!responses.isEmpty()) {
|
||||||
|
EWSMethod.Item response = responses.get(0);
|
||||||
|
currentItemId = new ItemId(response);
|
||||||
|
currentEtag = response.get(Field.get("etag").getResponseName());
|
||||||
|
}
|
||||||
|
if ("*".equals(noneMatch)) {
|
||||||
|
// create requested
|
||||||
|
if (currentItemId != null) {
|
||||||
|
itemResult.status = HttpStatus.SC_PRECONDITION_FAILED;
|
||||||
|
return itemResult;
|
||||||
|
}
|
||||||
|
} else if (etag != null) {
|
||||||
|
// update requested
|
||||||
|
if (currentItemId == null || !etag.equals(currentEtag)) {
|
||||||
|
itemResult.status = HttpStatus.SC_PRECONDITION_FAILED;
|
||||||
|
return itemResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentItemId != null) {
|
||||||
|
Set<FieldUpdate> updates = new HashSet<FieldUpdate>();
|
||||||
|
updates.add(new FieldUpdate(Field.get("mimeContent"), String.valueOf(Base64.encodeBase64(mimeContent))));
|
||||||
|
// update
|
||||||
|
createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly,
|
||||||
|
ConflictResolution.AlwaysOverwrite,
|
||||||
|
CalendarItemCreateOrDeleteOperation.SendToNone,
|
||||||
|
currentItemId, updates);
|
||||||
|
} else {
|
||||||
|
// create
|
||||||
|
EWSMethod.Item newItem = new EWSMethod.Item();
|
||||||
|
newItem.type = "Message";
|
||||||
|
newItem.mimeContent = Base64.encodeBase64(mimeContent);
|
||||||
|
createOrUpdateItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, getFolderId(folderPath), newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
executeMethod(createOrUpdateItemMethod);
|
||||||
|
|
||||||
|
itemResult.status = createOrUpdateItemMethod.getStatusCode();
|
||||||
|
if (itemResult.status == HttpURLConnection.HTTP_OK) {
|
||||||
|
//noinspection VariableNotUsedInsideIf
|
||||||
if (etag != null) {
|
if (etag != null) {
|
||||||
|
itemResult.status = HttpStatus.SC_CREATED;
|
||||||
LOGGER.debug("Updated event " + getHref());
|
LOGGER.debug("Updated event " + getHref());
|
||||||
} else {
|
} else {
|
||||||
LOGGER.warn("Overwritten event " + getHref());
|
LOGGER.warn("Overwritten event " + getHref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemResult itemResult = new ItemResult();
|
|
||||||
itemResult.status = status;
|
ItemId newItemId = new ItemId(createOrUpdateItemMethod.getResponseItem());
|
||||||
// TODO: get etag
|
GetItemMethod getItemMethod = new GetItemMethod(BaseShape.ID_ONLY, newItemId, false);
|
||||||
// itemResult.etag = ???
|
executeMethod(getItemMethod);
|
||||||
|
itemResult.etag = getItemMethod.getResponseItem().get(Field.get("etag").getResponseName());
|
||||||
|
|
||||||
return itemResult;
|
return itemResult;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -37,6 +37,8 @@ public class Field {
|
|||||||
FIELD_MAP.put("permanenturl", new ExtendedFieldURI(0x670E, ExtendedFieldURI.PropertyType.String)); //PR_FLAT_URL_NAME
|
FIELD_MAP.put("permanenturl", new ExtendedFieldURI(0x670E, ExtendedFieldURI.PropertyType.String)); //PR_FLAT_URL_NAME
|
||||||
FIELD_MAP.put("instancetype", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.PublicStrings, "urn:schemas:calendar:instancetype"));
|
FIELD_MAP.put("instancetype", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.PublicStrings, "urn:schemas:calendar:instancetype"));
|
||||||
|
|
||||||
|
FIELD_MAP.put("mimeContent", new UnindexedFieldURI("item:MimeContent"));
|
||||||
|
|
||||||
// use PR_RECORD_KEY as unique key
|
// use PR_RECORD_KEY as unique key
|
||||||
FIELD_MAP.put("uid", new ExtendedFieldURI(0x0FF9, ExtendedFieldURI.PropertyType.Binary));
|
FIELD_MAP.put("uid", new ExtendedFieldURI(0x0FF9, ExtendedFieldURI.PropertyType.Binary));
|
||||||
FIELD_MAP.put("messageFlags", new ExtendedFieldURI(0x0e07, ExtendedFieldURI.PropertyType.Integer));//PR_MESSAGE_FLAGS
|
FIELD_MAP.put("messageFlags", new ExtendedFieldURI(0x0e07, ExtendedFieldURI.PropertyType.Integer));//PR_MESSAGE_FLAGS
|
||||||
@ -131,7 +133,9 @@ public class Field {
|
|||||||
FIELD_MAP.put("sensitivity", new ExtendedFieldURI(0x0036, ExtendedFieldURI.PropertyType.Long));
|
FIELD_MAP.put("sensitivity", new ExtendedFieldURI(0x0036, ExtendedFieldURI.PropertyType.Long));
|
||||||
|
|
||||||
FIELD_MAP.put("haspicture", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.Address, 0x8015, ExtendedFieldURI.PropertyType.Boolean));
|
FIELD_MAP.put("haspicture", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.Address, 0x8015, ExtendedFieldURI.PropertyType.Boolean));
|
||||||
|
|
||||||
|
// calendar
|
||||||
|
FIELD_MAP.put("processed", new ExtendedFieldURI(0x65e8, ExtendedFieldURI.PropertyType.Boolean));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user