Commit afa38da9 authored by Mickaël Guessant's avatar Mickaël Guessant

Caldav: EWS refactoring, implement timezone update, with failover for unknown values

git-svn-id: 3d1905a2-6b24-0410-a738-b14d5a86fcbd
parent d2757a52
......@@ -195,7 +195,7 @@ public class VCalendar extends VObject {
if (!fromServer) {
// iterate over vObjects
......@@ -312,7 +312,7 @@ public class VCalendar extends VObject {
private void fixTimezone() {
private void fixTimezoneToServer() {
if (vTimezone != null && vTimezone.vObjects != null && vTimezone.vObjects.size() > 2) {
VObject standard = null;
VObject daylight = null;
......@@ -349,6 +349,47 @@ public class VCalendar extends VObject {
// convert TZID to Exchange time zone id
ResourceBundle tzBundle = ResourceBundle.getBundle("exchtimezones");
ResourceBundle tzidsBundle = ResourceBundle.getBundle("timezoneids");
for (VObject vObject:vObjects) {
if (vObject.isVTimezone()) {
String tzid = vObject.getPropertyValue("TZID");
// check if tzid is avalid Exchange timezone id
if (!tzidsBundle.containsKey(tzid)) {
String exchangeTzid = null;
// try to convert standard timezone id to Exchange timezone id
if (tzBundle.containsKey(tzid)) {
exchangeTzid = tzBundle.getString(tzid);
} else {
// failover, map to a close timezone
for (VObject tzDefinition:vObject.vObjects) {
if ("STANDARD".equals(tzDefinition.type)) {
String tzOffset = tzDefinition.getPropertyValue("TZOFFSETTO");
exchangeTzid = ResourceBundle.getBundle("tzoffsettimezones").getString(tzOffset);
if (exchangeTzid != null) {
vObject.setPropertyValue("TZID", exchangeTzid);
// also replace TZID in properties
updateTzid(tzid, exchangeTzid);
protected void updateTzid(String tzid, String newTzid) {
for (VObject vObject:vObjects) {
if (vObject.isVEvent()) {
for (VProperty vProperty : {
if (tzid.equalsIgnoreCase(vProperty.getParamValue("TZID"))) {
vProperty.setParam("TZID", newTzid);
private void fixTzid(VProperty property) {
......@@ -92,6 +92,13 @@ public class VObject {
public VObject() {
public boolean isVTimezone() {
return "VTIMEZONE".equals(type);
public boolean isVEvent() {
return "VEVENT".equals(type);
protected void handleLine(String line, BufferedReader reader) throws IOException {
// skip empty lines
......@@ -1559,6 +1559,12 @@ public class EwsExchangeSession extends ExchangeSession {
// TODO: update all event fields and handle other occurrences
updates.add(Field.createFieldUpdate("dtstart", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTSTART"))));
updates.add(Field.createFieldUpdate("dtend", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DTEND"))));
if ("Exchange2007_SP1".equals(serverVersion)) {
updates.add(Field.createFieldUpdate("meetingtimezone", vCalendar.getVTimezone().getPropertyValue("TZID")));
} else {
updates.add(Field.createFieldUpdate("starttimezone", vCalendar.getFirstVevent().getProperty("DTSTART").getParamValue("TZID")));
updates.add(Field.createFieldUpdate("endtimezone", vCalendar.getFirstVevent().getProperty("DTEND").getParamValue("TZID")));
updates.add(Field.createFieldUpdate("isalldayevent", Boolean.toString(vCalendar.isCdoAllDay())));
......@@ -1736,6 +1742,10 @@ public class EwsExchangeSession extends ExchangeSession {
currentItemId, buildFieldUpdates(vCalendar));
// force context Timezone on Exchange 2010 and 2013
if (serverVersion != null && serverVersion.startsWith("Exchange201")) {
} else {
// create
......@@ -219,6 +219,7 @@ public final class Field {
FIELD_MAP.put("meetingtimezone", new UnindexedFieldURI("calendar:MeetingTimeZone"));
FIELD_MAP.put("starttimezone", new UnindexedFieldURI("calendar:StartTimeZone"));
FIELD_MAP.put("endtimezone", new UnindexedFieldURI("calendar:EndTimeZone"));
FIELD_MAP.put("busystatus", new UnindexedFieldURI("calendar:LegacyFreeBusyStatus"));
FIELD_MAP.put("requiredattendees", new UnindexedFieldURI("calendar:RequiredAttendees"));
......@@ -72,6 +72,10 @@ public class UnindexedFieldURI implements FieldURI {
buffer.append("<t:StartTimeZone Id=\"");
} else if ("EndTimeZone".equals(fieldName)) {
buffer.append("<t:EndTimeZone Id=\"");
} else {
# Timezone table to replace TZID with Exchange values
Africa/Algiers=W. Central Africa Standard Time
Africa/Cairo=Egypt Standard Time
Africa/Casablanca=Morocco Standard Time
Africa/Harare=South Africa Standard Time
Africa/Nairobi=E. Africa Standard Time
Africa/Windhoek=Namibia Standard Time
America/Anchorage=Alaskan Standard Time
America/Argentina/Buenos_Aires=Argentina Standard Time
America/Asuncion=Paraguay Standard Time
America/Caracas=Venezuela Standard Time
America/Cayenne=SA Eastern Standard Time
America/Chicago=Central America Standard Time
America/Chihuahua=Mountain Standard Time (Mexico)
America/Cuiaba=Central Brazilian Standard Time
America/Denver=Mountain Standard Time
America/El_Salvador=Bahia Standard Time
America/Godthab=Greenland Standard Time
America/Halifax=Atlantic Standard Time
America/Indiana/Knox=US Eastern Standard Time
America/Lima=SA Pacific Standard Time
America/Los_Angeles=Pacific Standard Time
America/Manaus=SA Western Standard Time
America/Mexico_City=Central Standard Time (Mexico)
America/Montevideo=Montevideo Standard Time
America/New_York=Eastern Standard Time
America/Phoenix=US Mountain Standard Time
America/Regina=Canada Central Standard Time
America/Santiago=Pacific SA Standard Time
America/Sao_Paulo=E. South America Standard Time
America/St_Johns=Newfoundland Standard Time
Asia/Amman=Jordan Standard Time
Asia/Baghdad=Arabic Standard Time
Asia/Baku=Azerbaijan Standard Time
Asia/Bangkok=SE Asia Standard Time
Asia/Beijing=China Standard Time
Asia/Damascus=Syria Standard Time
Asia/Dhaka=Bangladesh Standard Time
Asia/Dubai=Arabian Standard Time
Asia/Irkutsk=North Asia East Standard Time
Asia/Istanbul=Turkey Standard Time
Asia/Jerusalem=Israel Standard Time
Asia/Kabul=Afghanistan Standard Time
Asia/Kamchatka=Kamchatka Standard Time
Asia/Karachi=Pakistan Standard Time
Asia/Katmandu=Nepal Standard Time
Asia/Kolkata=India Standard Time
Asia/Krasnoyarsk=North Asia Standard Time
Asia/Kuala_Lumpur=Singapore Standard Time
Asia/Kuwait=Arab Standard Time
Asia/Magadan=Magadan Standard Time
Asia/Nicosia=E. Europe Standard Time
Asia/Novosibirsk=N. Central Asia Standard Time
Asia/Rangoon=Myanmar Standard Time
Asia/Seoul=Korea Standard Time
Asia/Taipei=Taipei Standard Time
Asia/Tashkent=West Asia Standard Time
Asia/Tbilisi=Georgian Standard Time
Asia/Tehran=Iran Standard Time
Asia/Tokyo=Tokyo Standard Time
Asia/Ulaanbaatar=Ulaanbaatar Standard Time
Asia/Vladivostok=Vladivostok Standard Time
Asia/Yakutsk=Yakutsk Standard Time
Asia/Yekaterinburg=Ekaterinburg Standard Time
Asia/Yerevan=Armenian Standard Time
Atlantic/Azores=Azores Standard Time
Atlantic/Cape_Verde=Cape Verde Standard Time
Atlantic/South_Georgia=Mid-Atlantic Standard Time
Australia/Adelaide=Cen. Australia Standard Time
Australia/Brisbane=E. Australia Standard Time
Australia/Darwin=AUS Central Standard Time
Australia/Hobart=Tasmania Standard Time
Australia/Melbourne=AUS Eastern Standard Time
Australia/Perth=W. Australia Standard Time
Europe/Athens=GTB Standard Time
Europe/Berlin=W. Europe Standard Time
Europe/Helsinki=FLE Standard Time
Europe/Kaliningrad=Kaliningrad Standard Time
Europe/London=GMT Standard Time
Europe/Moscow=Russian Standard Time
Europe/Paris=Romance Standard Time
Europe/Prague=Central Europe Standard Time
Europe/Sarajevo=Central European Standard Time
Greenwich=Greenwich Standard Time
Pacific/Auckland=New Zealand Standard Time
Pacific/Fiji=Fiji Standard Time
Pacific/Guam=West Pacific Standard Time
Pacific/Honolulu=Hawaiian Standard Time
Pacific/Kwajalein=Dateline Standard Time
Pacific/Noumea=Central Pacific Standard Time
Pacific/Samoa=Samoa Standard Time
Pacific/Tongatapu=Tonga Standard Time
......@@ -245,7 +245,7 @@ Pakistan\ Standard\ Time=Asia/Karachi
Central\ Brazilian\ Standard\ Time=America/Cuiaba
Mauritius\ Standard\ Time=Asia/Baku
Montevideo\ Standard\ Time=America/Montevideo
Kamchatka\ Standard\ Time=
Kamchatka\ Standard\ Time=Asia/Kamchatka
Paraguay\ Standard\ Time=America/Asuncion
UTC=Greenwich Standard Time
Ulaanbaatar\ Standard\ Time=Asia/Ulaanbaatar
# failover table to convert timezone offset to timezone id
-1200=Dateline Standard Time
-1100=Samoa Standard Time
-1000=Hawaiian Standard Time
-0900=Alaskan Standard Time
-0800=Pacific Standard Time
-0700=Mountain Standard Time
-0600=Central America Standard Time
-0500=Eastern Standard Time
-0400=Atlantic Standard Time
-0330=Newfoundland and Labrador Standard Time
-0300=E. South America Standard Time
-0200=Mid-Atlantic Standard Time
-0100=Azores Standard Time
+0000=GMT Standard Time
+0100=Central Europe Standard Time
+0200=E. Europe Standard Time
+0300=Russian Standard Time
+0330=Iran Standard Time
+0400=Arabian Standard Time
+0430=Transitional Islamic State of Afghanistan Standard Time
+0500=West Asia Standard Time
+0530=India Standard Time
+0545=Nepal Standard Time
+0600=Central Asia Standard Time
+0630=Myanmar Standard Time
+0700=S.E. Asia Standard Time
+0800=China Standard Time
+0900=Korea Standard Time
+0930=Cen. Australia Standard Time
+1000=E. Australia Standard Time
+1100=Central Pacific Standard Time
+1200=Fiji Islands Standard Time
+1300=Tonga Standard Time
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