mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
ALF-10204 Support for specifying the timezone (rather than just offset) for calendar entries when creating/editing, with tests, and use this to improve all day event storage/detection
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30436 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -26,6 +26,7 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.alfresco.query.PagingRequest;
|
import org.alfresco.query.PagingRequest;
|
||||||
import org.alfresco.repo.calendar.CalendarModel;
|
import org.alfresco.repo.calendar.CalendarModel;
|
||||||
@@ -151,16 +152,48 @@ public abstract class AbstractCalendarWebScript extends DeclarativeWebScript
|
|||||||
protected boolean extractDates(CalendarEntry entry, JSONObject json) throws JSONException
|
protected boolean extractDates(CalendarEntry entry, JSONObject json) throws JSONException
|
||||||
{
|
{
|
||||||
boolean isAllDay = false;
|
boolean isAllDay = false;
|
||||||
|
if (json.containsKey("allday"))
|
||||||
|
{
|
||||||
|
isAllDay = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (json.containsKey("startAt") && json.containsKey("endAt"))
|
if (json.containsKey("startAt") && json.containsKey("endAt"))
|
||||||
{
|
{
|
||||||
// New style ISO8601 dates
|
// New style ISO8601 based dates and times
|
||||||
entry.setStart(parseDate((String)json.get("startAt")));
|
String startAt = ((String)json.get("startAt"));
|
||||||
entry.setEnd(parseDate((String)json.get("endAt")));
|
String endAt = ((String)json.get("endAt"));
|
||||||
|
|
||||||
|
// Is this an all day event?
|
||||||
if (json.containsKey("allday"))
|
if (json.containsKey("allday"))
|
||||||
{
|
{
|
||||||
// TODO Handle All Day events properly, including timezones
|
// Store it as UTC midnight to midnight
|
||||||
isAllDay = true;
|
// Reset the time part to ensure that
|
||||||
|
String utcMidnight = "T00:00:00Z";
|
||||||
|
startAt = startAt.substring(0, 10) + utcMidnight;
|
||||||
|
endAt = endAt.substring(0, 10) + utcMidnight;
|
||||||
|
entry.setStart(ISO8601DateFormat.parse(startAt));
|
||||||
|
entry.setEnd(ISO8601DateFormat.parse(endAt));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Regular event start and end rules
|
||||||
|
|
||||||
|
// Do we have explicit timezone information?
|
||||||
|
if (json.containsKey("timeZone"))
|
||||||
|
{
|
||||||
|
// Get the specified timezone
|
||||||
|
TimeZone tz = TimeZone.getTimeZone((String)json.get("timeZone"));
|
||||||
|
|
||||||
|
// Grab the dates and times in the specified timezone
|
||||||
|
entry.setStart(ISO8601DateFormat.parse(startAt, tz));
|
||||||
|
entry.setEnd(ISO8601DateFormat.parse(endAt, tz));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Offset info is either in the date, or we just have to guess
|
||||||
|
entry.setStart(parseDate(startAt));
|
||||||
|
entry.setEnd(parseDate(endAt));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (json.containsKey("allday"))
|
else if (json.containsKey("allday"))
|
||||||
@@ -168,7 +201,6 @@ public abstract class AbstractCalendarWebScript extends DeclarativeWebScript
|
|||||||
// Old style all-day event
|
// Old style all-day event
|
||||||
entry.setStart(parseDate(getOrNull(json, "from")));
|
entry.setStart(parseDate(getOrNull(json, "from")));
|
||||||
entry.setEnd(parseDate(getOrNull(json, "to")));
|
entry.setEnd(parseDate(getOrNull(json, "to")));
|
||||||
isAllDay = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.web.scripts.calendar;
|
package org.alfresco.repo.web.scripts.calendar;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
@@ -211,25 +213,47 @@ public class CalendarRestApiTest extends BaseWebScriptTest
|
|||||||
private JSONObject createEntry(String name, String where, String description,
|
private JSONObject createEntry(String name, String where, String description,
|
||||||
int expectedStatus) throws Exception
|
int expectedStatus) throws Exception
|
||||||
{
|
{
|
||||||
String date = "2011/06/29"; // A wednesday
|
String date = "2011-06-29"; // A wednesday
|
||||||
String start = "12:00";
|
String start = "12:00";
|
||||||
String end = "13:00";
|
String end = "13:00";
|
||||||
|
|
||||||
|
// Old style is:
|
||||||
|
// "from": "2011/06/29",
|
||||||
|
// "to": "2011/06/29",
|
||||||
|
// "start": "12:00",
|
||||||
|
// "end": "13:00",
|
||||||
|
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("startAt", date + "T" + start + ":00+01:00");
|
||||||
|
json.put("endAt", date + "T" + end + ":00+01:00");
|
||||||
|
|
||||||
|
return createEntry(name, where, description, json, expectedStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an event, with the date properties manually set
|
||||||
|
*/
|
||||||
|
private JSONObject createEntry(String name, String where, String description,
|
||||||
|
JSONObject datesJSON, int expectedStatus) throws Exception
|
||||||
|
{
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
|
||||||
json.put("site", SITE_SHORT_NAME_CALENDAR);
|
json.put("site", SITE_SHORT_NAME_CALENDAR);
|
||||||
json.put("what", name);
|
json.put("what", name);
|
||||||
json.put("where", where);
|
json.put("where", where);
|
||||||
json.put("desc", description);
|
json.put("desc", description);
|
||||||
json.put("from", date);
|
|
||||||
json.put("to", date);
|
|
||||||
// json.put("fromdate", "Wednesday, 29 June 2011"); // Not needed
|
|
||||||
// json.put("todate", "Wednesday, 29 June 2011"); // Not needed
|
|
||||||
json.put("start", start);
|
|
||||||
json.put("end", end);
|
|
||||||
json.put("tags", "");
|
json.put("tags", "");
|
||||||
json.put("docfolder", "");
|
json.put("docfolder", "");
|
||||||
json.put("page", "calendar");
|
json.put("page", "calendar");
|
||||||
|
|
||||||
|
// Copy in the date properties
|
||||||
|
Iterator<String> datesIT = datesJSON.keys();
|
||||||
|
while(datesIT.hasNext())
|
||||||
|
{
|
||||||
|
String key = datesIT.next();
|
||||||
|
json.put(key, datesJSON.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
Response response = sendRequest(new PostRequest(URL_EVENT_CREATE, json.toString(), "application/json"), expectedStatus);
|
Response response = sendRequest(new PostRequest(URL_EVENT_CREATE, json.toString(), "application/json"), expectedStatus);
|
||||||
if (expectedStatus == Status.STATUS_OK)
|
if (expectedStatus == Status.STATUS_OK)
|
||||||
{
|
{
|
||||||
@@ -369,10 +393,10 @@ public class CalendarRestApiTest extends BaseWebScriptTest
|
|||||||
assertEquals("false", entry.getString("allday"));
|
assertEquals("false", entry.getString("allday"));
|
||||||
|
|
||||||
// Check the new style dates too
|
// Check the new style dates too
|
||||||
// assertEquals("2011-06-29T12:00:00Z", entry.getJSONObject("startAt").get("iso8601")); // TODO Needs TZ going in
|
assertEquals("2011-06-29T12:00:00.000+01:00", entry.getJSONObject("startAt").get("iso8601"));
|
||||||
assertEquals("6/29/2011", entry.getJSONObject("startAt").get("legacyDate"));
|
assertEquals("6/29/2011", entry.getJSONObject("startAt").get("legacyDate"));
|
||||||
assertEquals("12:00", entry.getJSONObject("startAt").get("legacyTime"));
|
assertEquals("12:00", entry.getJSONObject("startAt").get("legacyTime"));
|
||||||
// assertEquals("2011-06-29T13:00:00Z", entry.getJSONObject("endAt").get("iso8601")); // TODO Needs TZ going in
|
assertEquals("2011-06-29T13:00:00.000+01:00", entry.getJSONObject("endAt").get("iso8601"));
|
||||||
assertEquals("6/29/2011", entry.getJSONObject("endAt").get("legacyDate"));
|
assertEquals("6/29/2011", entry.getJSONObject("endAt").get("legacyDate"));
|
||||||
assertEquals("13:00", entry.getJSONObject("endAt").get("legacyTime"));
|
assertEquals("13:00", entry.getJSONObject("endAt").get("legacyTime"));
|
||||||
|
|
||||||
@@ -384,9 +408,9 @@ public class CalendarRestApiTest extends BaseWebScriptTest
|
|||||||
assertEquals("More Where", entry.getString("location"));
|
assertEquals("More Where", entry.getString("location"));
|
||||||
assertEquals("More Thing", entry.getString("description"));
|
assertEquals("More Thing", entry.getString("description"));
|
||||||
|
|
||||||
// No from/to/start/end, does dtstart and dtend instead
|
// Now uses new style dates
|
||||||
assertEquals("2011-06-28T11:30", entry.getString("dtstart"));
|
assertEquals("2011-06-28T11:30", entry.getJSONObject("startAt").getString("legacyDateTime"));
|
||||||
assertEquals("2011-06-28T13:30", entry.getString("dtend"));
|
assertEquals("2011-06-28T13:30", entry.getJSONObject("endAt").getString("legacyDateTime"));
|
||||||
assertEquals("false", entry.getString("allday"));
|
assertEquals("false", entry.getString("allday"));
|
||||||
// No isoutlook on create/edit
|
// No isoutlook on create/edit
|
||||||
|
|
||||||
@@ -451,6 +475,123 @@ public class CalendarRestApiTest extends BaseWebScriptTest
|
|||||||
assertEquals(true, entry.has("error"));
|
assertEquals(true, entry.has("error"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that we can work with old style two part date times,
|
||||||
|
* ISO8601 datetimes with offsets, and ISO8601 datetimes with an
|
||||||
|
* explicit timezone.
|
||||||
|
*/
|
||||||
|
public void testDifferentDateStyles() throws Exception
|
||||||
|
{
|
||||||
|
JSONObject json;
|
||||||
|
JSONObject entry;
|
||||||
|
|
||||||
|
// From+Start, To+End with slashes
|
||||||
|
json = new JSONObject();
|
||||||
|
json.put("from", "2011/06/21");
|
||||||
|
json.put("to", "2011/06/21");
|
||||||
|
json.put("start", "11:00");
|
||||||
|
json.put("end", "12:00");
|
||||||
|
entry = createEntry(EVENT_TITLE_ONE, "Where", "Thing", json, Status.STATUS_OK);
|
||||||
|
|
||||||
|
assertEquals("2011-06-21", entry.getString("from"));
|
||||||
|
assertEquals("2011-06-21", entry.getString("to"));
|
||||||
|
assertEquals("11:00", entry.getString("start"));
|
||||||
|
assertEquals("12:00", entry.getString("end"));
|
||||||
|
assertEquals("false", entry.getString("allday"));
|
||||||
|
// Can't check iso8601 form as we don't know the TZ
|
||||||
|
|
||||||
|
|
||||||
|
// From+Start, To+End with dashes
|
||||||
|
json = new JSONObject();
|
||||||
|
json.put("from", "2011-06-22");
|
||||||
|
json.put("to", "2011-06-22");
|
||||||
|
json.put("start", "10:00");
|
||||||
|
json.put("end", "12:00");
|
||||||
|
entry = createEntry(EVENT_TITLE_ONE, "Where", "Thing", json, Status.STATUS_OK);
|
||||||
|
|
||||||
|
assertEquals("2011-06-22", entry.getString("from"));
|
||||||
|
assertEquals("2011-06-22", entry.getString("to"));
|
||||||
|
assertEquals("10:00", entry.getString("start"));
|
||||||
|
assertEquals("12:00", entry.getString("end"));
|
||||||
|
assertEquals("false", entry.getString("allday"));
|
||||||
|
// Can't check iso8601 form as we don't know the TZ
|
||||||
|
|
||||||
|
|
||||||
|
// ISO8601 with offset
|
||||||
|
json = new JSONObject();
|
||||||
|
json.put("startAt", "2011-06-21T11:30:05+01:00");
|
||||||
|
json.put("endAt", "2011-06-21T12:45:25+01:00");
|
||||||
|
entry = createEntry(EVENT_TITLE_ONE, "Where", "Thing", json, Status.STATUS_OK);
|
||||||
|
|
||||||
|
// Check old style dates and times
|
||||||
|
assertEquals("2011-06-21", entry.getString("from"));
|
||||||
|
assertEquals("2011-06-21", entry.getString("to"));
|
||||||
|
assertEquals("11:30", entry.getString("start"));
|
||||||
|
assertEquals("12:45", entry.getString("end"));
|
||||||
|
assertEquals("false", entry.getString("allday"));
|
||||||
|
|
||||||
|
// Check new style dates and times
|
||||||
|
assertEquals("2011-06-21T11:30:05.000+01:00", entry.getJSONObject("startAt").getString("iso8601"));
|
||||||
|
assertEquals("2011-06-21T12:45:25.000+01:00", entry.getJSONObject("endAt").getString("iso8601"));
|
||||||
|
|
||||||
|
|
||||||
|
// ISO8601 with timezone
|
||||||
|
json = new JSONObject();
|
||||||
|
json.put("startAt", "2011-06-22T11:30:05");
|
||||||
|
json.put("endAt", "2011-06-22T12:45:25");
|
||||||
|
json.put("timeZone", "Europe/London");
|
||||||
|
entry = createEntry(EVENT_TITLE_ONE, "Where", "Thing", json, Status.STATUS_OK);
|
||||||
|
|
||||||
|
// Check old style dates and times
|
||||||
|
assertEquals("2011-06-22", entry.getString("from"));
|
||||||
|
assertEquals("2011-06-22", entry.getString("to"));
|
||||||
|
assertEquals("11:30", entry.getString("start"));
|
||||||
|
assertEquals("12:45", entry.getString("end"));
|
||||||
|
assertEquals("false", entry.getString("allday"));
|
||||||
|
|
||||||
|
// Check new style dates and times
|
||||||
|
assertEquals("2011-06-22T11:30:05.000+01:00", entry.getJSONObject("startAt").getString("iso8601"));
|
||||||
|
assertEquals("2011-06-22T12:45:25.000+01:00", entry.getJSONObject("endAt").getString("iso8601"));
|
||||||
|
|
||||||
|
|
||||||
|
// All-day old-style
|
||||||
|
json = new JSONObject();
|
||||||
|
json.put("from", "2011/06/21");
|
||||||
|
json.put("to", "2011/06/21");
|
||||||
|
json.put("allday", Boolean.TRUE);
|
||||||
|
entry = createEntry(EVENT_TITLE_ONE, "Where", "Thing", json, Status.STATUS_OK);
|
||||||
|
|
||||||
|
assertEquals("2011-06-21", entry.getString("from"));
|
||||||
|
assertEquals("2011-06-21", entry.getString("to"));
|
||||||
|
assertEquals("00:00", entry.getString("start"));
|
||||||
|
assertEquals("00:00", entry.getString("end"));
|
||||||
|
assertEquals("true", entry.getString("allday"));
|
||||||
|
|
||||||
|
|
||||||
|
// All-day ISO8601 with offset
|
||||||
|
json = new JSONObject();
|
||||||
|
json.put("startAt", "2011-06-21T00:00:00+01:00");
|
||||||
|
json.put("endAt", "2011-06-21T00:00:00+01:00");
|
||||||
|
json.put("allday", Boolean.TRUE);
|
||||||
|
|
||||||
|
assertEquals("2011-06-21", entry.getString("from"));
|
||||||
|
assertEquals("2011-06-21", entry.getString("to"));
|
||||||
|
assertEquals("true", entry.getString("allday"));
|
||||||
|
|
||||||
|
|
||||||
|
// All-day ISO8601 with timezone
|
||||||
|
json = new JSONObject();
|
||||||
|
json.put("startAt", "2011-06-22T00:00:00");
|
||||||
|
json.put("endAt", "2011-06-22T00:00:00");
|
||||||
|
json.put("timeZone", "Europe/London");
|
||||||
|
json.put("allday", Boolean.TRUE);
|
||||||
|
entry = createEntry(EVENT_TITLE_ONE, "Where", "Thing", json, Status.STATUS_OK);
|
||||||
|
|
||||||
|
assertEquals("2011-06-22", entry.getString("from"));
|
||||||
|
assertEquals("2011-06-22", entry.getString("to"));
|
||||||
|
assertEquals("true", entry.getString("allday"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listing
|
* Listing
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user