diff --git a/src/java/davmail/exchange/VCalendar.java b/src/java/davmail/exchange/VCalendar.java index 1060d602..63377ffa 100644 --- a/src/java/davmail/exchange/VCalendar.java +++ b/src/java/davmail/exchange/VCalendar.java @@ -111,6 +111,10 @@ public class VCalendar extends VObject { return "TRUE".equals(vObject.getPropertyValue("X-MICROSOFT-CDO-ALLDAYEVENT")); } + public boolean isCdoAllDay() { + return firstVevent != null && isCdoAllDay(firstVevent); + } + protected String getEmailValue(VProperty property) { if (property == null) { return null; @@ -452,6 +456,10 @@ public class VCalendar extends VObject { return getFirstVeventProperty("ATTENDEE") != null; } + public boolean isMeetingOrganizer() { + return email.equals(getEmailValue(getFirstVeventProperty("ORGANIZER"))); + } + public void setFirstVeventPropertyValue(String propertyName, String propertyValue) { firstVevent.setPropertyValue(propertyName, propertyValue); } diff --git a/src/java/davmail/exchange/ews/EwsExchangeSession.java b/src/java/davmail/exchange/ews/EwsExchangeSession.java index 5032cf84..21046f13 100644 --- a/src/java/davmail/exchange/ews/EwsExchangeSession.java +++ b/src/java/davmail/exchange/ews/EwsExchangeSession.java @@ -846,7 +846,7 @@ public class EwsExchangeSession extends ExchangeSession { Item item = getItem(sourceFolderPath.parentPath, sourceFolderPath.folderName); FolderPath targetFolderPath = new FolderPath(targetPath); FolderId toFolderId = getFolderId(targetFolderPath.parentPath); - MoveItemMethod moveItemMethod = new MoveItemMethod(((Event)item).itemId, toFolderId); + MoveItemMethod moveItemMethod = new MoveItemMethod(((Event) item).itemId, toFolderId); executeMethod(moveItemMethod); } @@ -1076,6 +1076,7 @@ public class EwsExchangeSession extends ExchangeSession { if (currentItemId != null) { /*Set updates = new HashSet(); + // TODO: update properties instead of brute force delete/add updates.add(new FieldUpdate(Field.get("mimeContent"), new String(Base64.encodeBase64(itemContent)))); // update createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly, @@ -1097,18 +1098,48 @@ public class EwsExchangeSession extends ExchangeSession { //updates.add(Field.createFieldUpdate("outlookmessageclass", "IPM.Appointment")); // force urlcompname updates.add(Field.createFieldUpdate("urlcompname", convertItemNameToEML(itemName))); - // does not work - if (vCalendar.isMeeting()) { + if (vCalendar.isMeeting() && vCalendar.isMeetingOrganizer()) { updates.add(Field.createFieldUpdate("apptstateflags", "1")); } else { updates.add(Field.createFieldUpdate("apptstateflags", "0")); } + /* + // patch allday date values + if (vCalendar.isCdoAllDay()) { + if ("Exchange2010".equals(serverVersion)) { + updates.add(Field.createFieldUpdate("starttimezone", vCalendar.getVTimezone().getPropertyValue("TZID"))); + } else { + updates.add(Field.createFieldUpdate("meetingtimezone", vCalendar.getVTimezone().getPropertyValue("TZID"))); + } + updates.add(Field.createFieldUpdate("dtstart", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTSTART")))); + updates.add(Field.createFieldUpdate("dtend", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTEND")))); + } + */ + newItem.setFieldUpdates(updates); createOrUpdateItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, SendMeetingInvitations.SendToNone, getFolderId(folderPath), newItem); //} executeMethod(createOrUpdateItemMethod); + // patch allday date values + if (vCalendar.isCdoAllDay()) { + updates = new ArrayList(); + if ("Exchange2010".equals(serverVersion)) { + updates.add(Field.createFieldUpdate("starttimezone", vCalendar.getVTimezone().getPropertyValue("TZID"))); + } else { + updates.add(Field.createFieldUpdate("meetingtimezone", vCalendar.getVTimezone().getPropertyValue("TZID"))); + } + updates.add(Field.createFieldUpdate("dtstart", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTSTART")))); + updates.add(Field.createFieldUpdate("dtend", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTEND")))); + createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly, + ConflictResolution.AutoResolve, + SendMeetingInvitationsOrCancellations.SendToNone, + new ItemId(createOrUpdateItemMethod.getResponseItem()), updates); + executeMethod(createOrUpdateItemMethod); + } + + itemResult.status = createOrUpdateItemMethod.getStatusCode(); if (itemResult.status == HttpURLConnection.HTTP_OK) { //noinspection VariableNotUsedInsideIf @@ -1142,16 +1173,16 @@ public class EwsExchangeSession extends ExchangeSession { getItemMethod.addAdditionalProperty(Field.get("calendaruid")); executeMethod(getItemMethod); content = getItemMethod.getMimeContent(); - VCalendar vCalendar = new VCalendar(content, email, getVTimezone()); + VCalendar localVCalendar = new VCalendar(content, email, getVTimezone()); // remove additional reminder if (!"true".equals(getItemMethod.getResponseItem().get(Field.get("reminderset").getResponseName()))) { - vCalendar.removeVAlarm(); + localVCalendar.removeVAlarm(); } String calendaruid = getItemMethod.getResponseItem().get(Field.get("calendaruid").getResponseName()); - if (calendaruid != null) { - vCalendar.setFirstVeventPropertyValue("UID", calendaruid); + if (calendaruid != null) { + localVCalendar.setFirstVeventPropertyValue("UID", calendaruid); } - content = vCalendar.toString().getBytes("UTF-8"); + content = localVCalendar.toString().getBytes("UTF-8"); } catch (IOException e) { throw buildHttpException(e); @@ -1612,6 +1643,22 @@ public class EwsExchangeSession extends ExchangeSession { return zuluDateValue; } + protected String convertCalendarDateToExchange(String vcalendarDateValue) throws DavMailException { + String zuluDateValue = null; + if (vcalendarDateValue != null) { + try { + SimpleDateFormat dateParser = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH); + dateParser.setTimeZone(GMT_TIMEZONE); + SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); + dateFormatter.setTimeZone(GMT_TIMEZONE); + zuluDateValue = dateFormatter.format(dateParser.parse(vcalendarDateValue)); + } catch (ParseException e) { + throw new DavMailException("EXCEPTION_INVALID_DATE", vcalendarDateValue); + } + } + return zuluDateValue; + } + /** * Format date to exchange search format. * diff --git a/src/java/davmail/exchange/ews/Field.java b/src/java/davmail/exchange/ews/Field.java index eece5a72..b263e06d 100644 --- a/src/java/davmail/exchange/ews/Field.java +++ b/src/java/davmail/exchange/ews/Field.java @@ -48,8 +48,10 @@ public class Field { 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("dtstart", new ExtendedFieldURI(0x10C3, ExtendedFieldURI.PropertyType.SystemTime)); - FIELD_MAP.put("dtend", new ExtendedFieldURI(0x10C4, ExtendedFieldURI.PropertyType.SystemTime)); + //FIELD_MAP.put("dtstart", new ExtendedFieldURI(0x10C3, ExtendedFieldURI.PropertyType.SystemTime)); + //FIELD_MAP.put("dtend", new ExtendedFieldURI(0x10C4, ExtendedFieldURI.PropertyType.SystemTime)); + FIELD_MAP.put("dtstart", new UnindexedFieldURI("calendar:Start")); + FIELD_MAP.put("dtend", new UnindexedFieldURI("calendar:End")); FIELD_MAP.put("mimeContent", new UnindexedFieldURI("item:MimeContent")); @@ -182,6 +184,9 @@ public class Field { FIELD_MAP.put("apptstateflags", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.Appointment, 0x8217, ExtendedFieldURI.PropertyType.Integer)); // PidLidAppointmentStateFlags 1: Meeting, 2: Received, 4: Cancelled FIELD_MAP.put("calendaruid", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.PublicStrings, "urn:schemas:calendar:uid", ExtendedFieldURI.PropertyType.String)); + FIELD_MAP.put("meetingtimezone", new UnindexedFieldURI("calendar:MeetingTimeZone")); + FIELD_MAP.put("starttimezone", new UnindexedFieldURI("calendar:StartTimeZone")); + // attachments FIELD_MAP.put("attachments", new UnindexedFieldURI("item:Attachments")); } diff --git a/src/java/davmail/exchange/ews/UnindexedFieldURI.java b/src/java/davmail/exchange/ews/UnindexedFieldURI.java index 22062c8f..75d22431 100644 --- a/src/java/davmail/exchange/ews/UnindexedFieldURI.java +++ b/src/java/davmail/exchange/ews/UnindexedFieldURI.java @@ -49,6 +49,8 @@ public class UnindexedFieldURI implements FieldURI { public void appendValue(StringBuilder buffer, String itemType, String value) { if (fieldURI.startsWith("message") && itemType != null) { itemType = "Message"; + } else if (fieldURI.startsWith("calendar") && itemType != null) { + itemType = "CalendarItem"; } if (itemType != null) { appendTo(buffer); @@ -56,13 +58,23 @@ public class UnindexedFieldURI implements FieldURI { buffer.append(itemType); buffer.append('>'); } - buffer.append("'); - buffer.append(StringUtil.xmlEncode(value)); - buffer.append("'); + if ("MeetingTimeZone".equals(fieldName)) { + buffer.append(""); + } else if ("StartTimeZone".equals(fieldName)) { + buffer.append(""); + } else { + buffer.append("'); + buffer.append(StringUtil.xmlEncode(value)); + buffer.append("'); + } if (itemType != null) { buffer.append("