Commit 179b6341 authored by Mickaël Guessant's avatar Mickaël Guessant

Caldav: EWS refactoring, implement excluded dates (deleted occurrences)

git-svn-id: https://svn.code.sf.net/p/davmail/code/trunk@2520 3d1905a2-6b24-0410-a738-b14d5a86fcbd
parent f64b886d
......@@ -744,6 +744,7 @@ public abstract class EWSMethod extends PostMethod {
if (!"ErrorAccessDenied".equals(errorDetail)
&& !"ErrorMailRecipientNotFound".equals(errorDetail)
&& !"ErrorItemNotFound".equals(errorDetail)
&& !"ErrorCalendarOccurrenceIsDeletedFromRecurrence".equals(errorDetail)
) {
try {
throw new EWSException(errorDetail + ' ' + ((errorDescription != null) ? errorDescription : "") + "\n request: " + new String(generateSoapEnvelope(), "UTF-8"));
......
......@@ -1561,6 +1561,59 @@ public class EwsExchangeSession extends ExchangeSession {
super(folderPath, itemName, contentClass, itemBody, etag, noneMatch);
}
/**
* Handle excluded dates (deleted occurrences).
*
* @param currentItemId current item id to iterate over occurrences
* @param vCalendar vCalendar object
* @throws DavMailException on error
*/
protected void handleExcludedDates(ItemId currentItemId, VCalendar vCalendar) throws DavMailException {
List<VProperty> excludedDates = vCalendar.getFirstVeventProperties("EXDATE");
if (excludedDates != null) {
for (VProperty property:excludedDates) {
List<String> values = property.getValues();
for (String value: values) {
String convertedValue = convertCalendarDateToExchange(value)+"Z";
LOGGER.debug("Looking for occurrence " + convertedValue);
int instanceIndex = 0;
// let's try to find occurence
while (true) {
instanceIndex++;
try {
GetItemMethod getItemMethod = new GetItemMethod(BaseShape.ID_ONLY,
new OccurrenceItemId(currentItemId.id, instanceIndex)
, false);
getItemMethod.addAdditionalProperty(Field.get("originalstart"));
executeMethod(getItemMethod);
if (getItemMethod.getResponseItem() != null) {
String itemOriginalStart = getItemMethod.getResponseItem().get(Field.get("originalstart").getResponseName());
if (convertedValue.equals(itemOriginalStart)) {
// found item, delete it
DeleteItemMethod deleteItemMethod = new DeleteItemMethod(new ItemId(getItemMethod.getResponseItem()),
DeleteType.HardDelete, SendMeetingCancellations.SendToAllAndSaveCopy);
executeMethod(deleteItemMethod);
break;
} else if (convertedValue.compareTo(itemOriginalStart) < 0) {
// current item is after searched item => probably already deleted
break;
}
}
} catch (IOException e) {
LOGGER.warn("Error looking for occurrence " + convertedValue+": "+e.getMessage());
// after end of recurrence
break;
}
}
}
}
}
}
protected List<FieldUpdate> buildFieldUpdates(VCalendar vCalendar) throws DavMailException {
List<FieldUpdate> updates = new ArrayList<FieldUpdate>();
......@@ -1601,6 +1654,7 @@ public class EwsExchangeSession extends ExchangeSession {
updates.add(Field.createFieldUpdate("busystatus", status));
updates.add(Field.createFieldUpdate("description", vCalendar.getFirstVeventPropertyValue("DESCRIPTION")));
updates.add(Field.createFieldUpdate("subject", vCalendar.getFirstVeventPropertyValue("SUMMARY")));
updates.add(Field.createFieldUpdate("location", vCalendar.getFirstVeventPropertyValue("LOCATION")));
// Collect categories on multiple lines
List<VProperty> categories = vCalendar.getFirstVevent().getProperties("CATEGORIES");
......@@ -1642,13 +1696,13 @@ public class EwsExchangeSession extends ExchangeSession {
}
AttendeeFieldUpdate requiredAttendees = new AttendeeFieldUpdate(Field.get("requiredattendees"));
AttendeeFieldUpdate optionalAttendees = new AttendeeFieldUpdate(Field.get("optionalattendees"));
MultiValuedFieldUpdate requiredAttendees = new MultiValuedFieldUpdate(Field.get("requiredattendees"));
MultiValuedFieldUpdate optionalAttendees = new MultiValuedFieldUpdate(Field.get("optionalattendees"));
updates.add(requiredAttendees);
updates.add(optionalAttendees);
List<VProperty> attendees = vCalendar.getFirstVevent().getProperties("ATTENDEE");
List<VProperty> attendees = vCalendar.getFirstVeventProperties("ATTENDEE");
if (attendees != null) {
for (VProperty property:attendees) {
String attendeeEmail = vCalendar.getEmailValue(property);
......@@ -1774,7 +1828,7 @@ public class EwsExchangeSession extends ExchangeSession {
SendMeetingInvitations.SendToAllAndSaveCopy,
getFolderId(SENT),
item
);
);
} else {
if (Settings.getBooleanProperty("davmail.caldavRealUpdate", false)) {
createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly,
......@@ -1933,6 +1987,12 @@ public class EwsExchangeSession extends ExchangeSession {
updates);
executeMethod(createOrUpdateItemMethod);
}
// handle deleted occurrences
if (currentItemId != null && !isMeetingResponse &&
Settings.getBooleanProperty("davmail.caldavRealUpdate", false)) {
handleExcludedDates(currentItemId, vCalendar);
}
}
ItemId newItemId = new ItemId(createOrUpdateItemMethod.getResponseItem());
......
......@@ -56,6 +56,8 @@ public final class Field {
FIELD_MAP.put("dtstart", new UnindexedFieldURI("calendar:Start"));
FIELD_MAP.put("dtend", new UnindexedFieldURI("calendar:End"));
FIELD_MAP.put("originalstart", new UnindexedFieldURI("calendar:OriginalStart"));
FIELD_MAP.put("mimeContent", new UnindexedFieldURI("item:MimeContent"));
// use PR_RECORD_KEY as unique key
......@@ -227,6 +229,7 @@ public final class Field {
FIELD_MAP.put("requiredattendees", new UnindexedFieldURI("calendar:RequiredAttendees"));
FIELD_MAP.put("optionalattendees", new UnindexedFieldURI("calendar:OptionalAttendees"));
FIELD_MAP.put("modifiedoccurrences", new UnindexedFieldURI("calendar:ModifiedOccurrences"));
FIELD_MAP.put("deletedoccurrences", new UnindexedFieldURI("calendar:DeletedOccurrences"));
FIELD_MAP.put("recurrence", new UnindexedFieldURI("calendar:Recurrence"));
......
......@@ -26,7 +26,7 @@ import java.util.ArrayList;
/**
* Specific field update class to handle multiple attendee values
*/
public class AttendeeFieldUpdate extends FieldUpdate {
public class MultiValuedFieldUpdate extends FieldUpdate {
ArrayList<String> values = new ArrayList<String>();
/**
......@@ -34,7 +34,7 @@ public class AttendeeFieldUpdate extends FieldUpdate {
*
* @param fieldURI target field
*/
public AttendeeFieldUpdate(FieldURI fieldURI) {
public MultiValuedFieldUpdate(FieldURI fieldURI) {
this.fieldURI = fieldURI;
}
......
/*
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
* Copyright (C) 2010 Mickael Guessant
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package davmail.exchange.ews;
import java.io.IOException;
import java.io.Writer;
public class OccurrenceItemId extends ItemId {
protected final int instanceIndex;
/**
* Build Item id object from item id and change key.
*
* @param recurringMasterId recurring master id
* @param instanceIndex occurrence index
*/
public OccurrenceItemId(String recurringMasterId, int instanceIndex) {
super("OccurrenceItemId", recurringMasterId);
this.instanceIndex = instanceIndex;
}
/**
* Build Item id object from item id and change key.
*
* @param recurringMasterId recurring master id
* @param changeKey change key
* @param instanceIndex occurrence index
*/
public OccurrenceItemId(String recurringMasterId, String changeKey, int instanceIndex) {
super("OccurrenceItemId", recurringMasterId, changeKey);
this.instanceIndex = instanceIndex;
}
/**
* Write item id as XML.
*
* @param writer request writer
* @throws IOException on error
*/
public void write(Writer writer) throws IOException {
writer.write("<t:");
writer.write(name);
writer.write(" RecurringMasterId=\"");
writer.write(id);
if (changeKey != null) {
writer.write("\" ChangeKey=\"");
writer.write(changeKey);
}
writer.write("\" InstanceIndex=\"");
writer.write(String.valueOf(instanceIndex));
writer.write("\"/>");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment