diff --git a/src/java/davmail/exchange/VCalendar.java b/src/java/davmail/exchange/VCalendar.java index 14bbc1ef..28cda255 100644 --- a/src/java/davmail/exchange/VCalendar.java +++ b/src/java/davmail/exchange/VCalendar.java @@ -52,8 +52,7 @@ public class VCalendar extends VObject { this.email = email; // set OWA timezone information if (this.vTimezone == null && vTimezone != null) { - this.vObjects.add(0, vTimezone); - this.vTimezone = vTimezone; + setTimezone(vTimezone); } } @@ -88,10 +87,24 @@ public class VCalendar extends VObject { type = "VCALENDAR"; } + /** + * Set timezone on vObject + * + * @param vTimezone timezone object + */ + public void setTimezone(VObject vTimezone) { + if (vObjects == null) { + addVObject(vTimezone); + } else { + vObjects.add(0, vTimezone); + } + this.vTimezone = vTimezone; + } + @Override public void addVObject(VObject vObject) { super.addVObject(vObject); - if (firstVevent == null && ("VEVENT".equals(vObject.type)|| "VTODO".equals(vObject.type))) { + if (firstVevent == null && ("VEVENT".equals(vObject.type) || "VTODO".equals(vObject.type))) { firstVevent = vObject; } if ("VTIMEZONE".equals(vObject.type)) { diff --git a/src/java/davmail/exchange/ews/AffectedTaskOccurrences.java b/src/java/davmail/exchange/ews/AffectedTaskOccurrences.java new file mode 100644 index 00000000..546d931a --- /dev/null +++ b/src/java/davmail/exchange/ews/AffectedTaskOccurrences.java @@ -0,0 +1,32 @@ +/* + * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway + * Copyright (C) 2011 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; + +/** + * Item delete option. + */ +@SuppressWarnings({"JavaDoc", "UnusedDeclaration"}) +public final class AffectedTaskOccurrences extends AttributeOption { + private AffectedTaskOccurrences(String value) { + super("AffectedTaskOccurrences", value); + } + + public static final AffectedTaskOccurrences AllOccurrences = new AffectedTaskOccurrences("AllOccurrences"); + public static final AffectedTaskOccurrences SpecifiedOccurrenceOnly = new AffectedTaskOccurrences("SpecifiedOccurrenceOnly"); +} diff --git a/src/java/davmail/exchange/ews/DeleteItemMethod.java b/src/java/davmail/exchange/ews/DeleteItemMethod.java index b351f6db..71bfe09b 100644 --- a/src/java/davmail/exchange/ews/DeleteItemMethod.java +++ b/src/java/davmail/exchange/ews/DeleteItemMethod.java @@ -33,6 +33,7 @@ public class DeleteItemMethod extends EWSMethod { super("Item", "DeleteItem"); addMethodOption(deleteType); addMethodOption(sendMeetingCancellations); + addMethodOption(AffectedTaskOccurrences.AllOccurrences); this.itemId = itemId; } diff --git a/src/java/davmail/exchange/ews/EwsExchangeSession.java b/src/java/davmail/exchange/ews/EwsExchangeSession.java index ff2707e0..a8dab47c 100644 --- a/src/java/davmail/exchange/ews/EwsExchangeSession.java +++ b/src/java/davmail/exchange/ews/EwsExchangeSession.java @@ -882,7 +882,12 @@ public class EwsExchangeSession extends ExchangeSession { */ @Override public ExchangeSession.Folder getFolder(String folderPath) throws IOException { - return internalGetFolder(folderPath); + Folder folder = internalGetFolder(folderPath); + if (isMainCalendar(folderPath)) { + Folder taskFolder = internalGetFolder(TASKS); + folder.ctag += taskFolder.ctag; + } + return folder; } /** @@ -1199,7 +1204,7 @@ public class EwsExchangeSession extends ExchangeSession { public ItemResult createOrUpdate() throws IOException { if (vCalendar.isTodo() && isMainCalendar(folderPath)) { // task item, move to tasks folder - folderPath = "tasks"; + folderPath = TASKS; } ItemResult itemResult = new ItemResult(); @@ -1248,6 +1253,7 @@ public class EwsExchangeSession extends ExchangeSession { } else { updates.add(Field.createFieldUpdate("status", vTodoToTaskStatusMap.get(vTodoStatus))); } + updates.add(Field.createFieldUpdate("duedate", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DUE")))); if (currentItemId != null) { // update createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly, @@ -1377,6 +1383,7 @@ public class EwsExchangeSession extends ExchangeSession { getItemMethod.addAdditionalProperty(Field.get("description")); getItemMethod.addAdditionalProperty(Field.get("percentcomplete")); getItemMethod.addAdditionalProperty(Field.get("status")); + getItemMethod.addAdditionalProperty(Field.get("duedate")); } else if (!"Message".equals(type)) { getItemMethod = new GetItemMethod(BaseShape.ID_ONLY, itemId, true); getItemMethod.addAdditionalProperty(Field.get("reminderset")); @@ -1393,9 +1400,11 @@ public class EwsExchangeSession extends ExchangeSession { executeMethod(getItemMethod); if ("Task".equals(type)) { + VObject vTimezone = getVTimezone(); VCalendar localVCalendar = new VCalendar(); VObject vTodo = new VObject(); vTodo.type = "VTODO"; + localVCalendar.setTimezone(vTimezone); vTodo.setPropertyValue("LAST-MODIFIED", convertDateFromExchange(getItemMethod.getResponseItem().get(Field.get("lastmodified").getResponseName()))); vTodo.setPropertyValue("CREATED", convertDateFromExchange(getItemMethod.getResponseItem().get(Field.get("created").getResponseName()))); String calendarUid = getItemMethod.getResponseItem().get(Field.get("calendaruid").getResponseName()); @@ -1408,6 +1417,9 @@ public class EwsExchangeSession extends ExchangeSession { vTodo.setPropertyValue("DESCRIPTION", getItemMethod.getResponseItem().get(Field.get("description").getResponseName())); vTodo.setPropertyValue("PERCENT-COMPLETE", getItemMethod.getResponseItem().get(Field.get("percentcomplete").getResponseName())); vTodo.setPropertyValue("STATUS", taskTovTodoStatusMap.get(getItemMethod.getResponseItem().get(Field.get("status").getResponseName()))); + VProperty vProperty = new VProperty("DUE", convertDateFromExchange(getItemMethod.getResponseItem().get(Field.get("duedate").getResponseName()))); + vProperty.setParam("TZID", vTimezone.getPropertyValue("TZID")); + vTodo.addProperty(vProperty); localVCalendar.addVObject(vTodo); content = localVCalendar.toString().getBytes("UTF-8"); } else { @@ -1577,7 +1589,7 @@ public class EwsExchangeSession extends ExchangeSession { EWSMethod.Item item = getEwsItem(folderPath, itemName); if (item == null && isMainCalendar(folderPath)) { // look for item in task folder - item = getEwsItem("tasks", itemName); + item = getEwsItem(TASKS, itemName); } if (item == null) { @@ -1643,6 +1655,10 @@ public class EwsExchangeSession extends ExchangeSession { @Override public void deleteItem(String folderPath, String itemName) throws IOException { EWSMethod.Item item = getEwsItem(folderPath, itemName); + if (item == null && isMainCalendar(folderPath)) { + // look for item in task folder + item = getEwsItem(TASKS, itemName); + } if (item != null) { DeleteItemMethod deleteItemMethod = new DeleteItemMethod(new ItemId(item), DeleteType.HardDelete, SendMeetingCancellations.SendToNone); executeMethod(deleteItemMethod); diff --git a/src/java/davmail/exchange/ews/Field.java b/src/java/davmail/exchange/ews/Field.java index 66c4c736..9c8bbfb6 100644 --- a/src/java/davmail/exchange/ews/Field.java +++ b/src/java/davmail/exchange/ews/Field.java @@ -209,7 +209,8 @@ public final class Field { // task FIELD_MAP.put("percentcomplete", new UnindexedFieldURI("task:PercentComplete")); - FIELD_MAP.put("status", new UnindexedFieldURI("task:Status")); + FIELD_MAP.put("status", new UnindexedFieldURI("task:Status")); + FIELD_MAP.put("duedate", new UnindexedFieldURI("task:DueDate")); // attachments FIELD_MAP.put("attachments", new UnindexedFieldURI("item:Attachments"));