ALF-11687 Update the site Calendar listing to optionally expand out repeating events for the period, and add tests for this

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@32515 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2011-12-05 05:04:25 +00:00
parent 9f9a44dd56
commit d33252bf60
5 changed files with 166 additions and 25 deletions

View File

@@ -5,8 +5,9 @@
<#elseif events?exists && events?size &gt; 0>
<#assign prev = "">
<#list events as item>
<#-- Note - use item not event start for repeating events expansion -->
<#assign date = item.start?string("M/d/yyyy")>
<#assign event = item.event>
<#assign date = event.start?string("M/d/yyyy")>
<#if date != prev>
<#assign counter = 0>
<#if item_index &gt; 0>],</#if>
@@ -14,17 +15,17 @@
</#if>
<#if counter &gt; 0>,</#if>
{
"name": "${event.title}",
"name": "${item.title}",
"uri": "calendar/event/${siteId}/${event.systemName}",
"startAt": {
"iso8601": "${xmldate(event.start)}",
"legacyDate": "${event.start?string("M/d/yyyy")}",
"legacyTime": "${event.start?string("HH:mm")}"
"iso8601": "${xmldate(item.start)}",
"legacyDate": "${item.start?string("M/d/yyyy")}",
"legacyTime": "${item.start?string("HH:mm")}"
},
"endAt": {
"iso8601": "${xmldate(event.end)}",
"legacyDate": "${event.end?string("M/d/yyyy")}",
"legacyTime": "${event.end?string("HH:mm")}"
"iso8601": "${xmldate(item.end)}",
"legacyDate": "${item.end?string("M/d/yyyy")}",
"legacyTime": "${item.end?string("HH:mm")}"
},
"tags": [<#list item.tags as tag>"${tag}"<#if tag_has_next>,</#if></#list>],

View File

@@ -38,6 +38,7 @@ import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper;
*/
public abstract class AbstractCalendarListingWebScript extends AbstractCalendarWebScript
{
protected static final String RESULT_EVENT = "event";
protected static final String RESULT_NAME = "name";
protected static final String RESULT_TITLE = "title";
protected static final String RESULT_START = "start";

View File

@@ -20,6 +20,7 @@ package org.alfresco.repo.web.scripts.calendar;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -40,31 +41,55 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* This class is the controller for the slingshot calendar eventList.get webscript.
*
* TODO Improve what we give to the FTL
* TODO Switch to using {@link AbstractCalendarListingWebScript}
*
* @author Nick Burch
* @since 4.0
*/
public class CalendarEntriesListGet extends AbstractCalendarWebScript
public class CalendarEntriesListGet extends AbstractCalendarListingWebScript
{
@Override
protected Map<String, Object> executeImpl(SiteInfo site, String eventName,
WebScriptRequest req, JSONObject json, Status status, Cache cache)
{
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); // Evil...
// Evil format needed for compatibility with old API...
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
// Decide on date ranges and repeating rules
Date fromDate = parseDate(req.getParameter("from"));
Date toDate = parseDate(req.getParameter("to"));
boolean resortNeeded = false;
boolean repeatingFirstOnly = true;
String repeatingEvents = req.getParameter("repeating");
if (repeatingEvents != null)
{
if ("first".equals(repeatingEvents))
{
repeatingFirstOnly = true;
}
else if ("all".equals(repeatingEvents))
{
repeatingFirstOnly = false;
resortNeeded = true;
}
}
// Get the entries for the list
PagingRequest paging = buildPagingRequest(req);
PagingResults<CalendarEntry> entries =
calendarService.listCalendarEntries(site.getShortName(), paging);
PagingResults<CalendarEntry> entries = calendarService.listCalendarEntries(
new String[] {site.getShortName()}, fromDate, toDate, paging);
// For each one in our page, grab details of any ignored instances
List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
for (CalendarEntry entry : entries.getPage())
{
Map<String, Object> result = new HashMap<String, Object>();
result.put("event", entry);
result.put(RESULT_EVENT, entry);
result.put(RESULT_NAME, entry.getSystemName());
result.put(RESULT_TITLE, entry.getTitle());
result.put(RESULT_START, entry.getStart());
result.put(RESULT_END, entry.getEnd());
result.put("fromDate", entry.getStart());
result.put("tags", entry.getTags());
@@ -86,9 +111,23 @@ public class CalendarEntriesListGet extends AbstractCalendarWebScript
result.put("ignoreEvents", ignoreEvents);
result.put("ignoreEventDates", ignoreEventDates);
// For repeating events, push forward if needed
boolean orderChanged = handleRecurring(entry, result, results, fromDate, toDate, repeatingFirstOnly);
if (orderChanged)
{
resortNeeded = true;
}
// All done with this one
results.add(result);
}
// If they asked for repeating events to be expanded, then do so
if (resortNeeded)
{
Collections.sort(results, getEventDetailsSorter());
}
// All done
Map<String, Object> model = new HashMap<String, Object>();
model.put("events", results);

View File

@@ -18,7 +18,10 @@
*/
package org.alfresco.repo.web.scripts.calendar;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.calendar.CalendarServiceImpl;
@@ -195,7 +198,7 @@ public class CalendarRestApiTest extends BaseWebScriptTest
}
if (from != null)
{
if (url.indexOf('/') > 0)
if (url.indexOf('?') > 0)
{
url += "&";
}
@@ -265,10 +268,8 @@ public class CalendarRestApiTest extends BaseWebScriptTest
json.put("page", "calendar");
// Copy in the date properties
Iterator<String> datesIT = datesJSON.keys();
while(datesIT.hasNext())
for (String key : getKeys(datesJSON, false))
{
String key = datesIT.next();
json.put(key, datesJSON.get(key));
}
@@ -368,6 +369,25 @@ public class CalendarRestApiTest extends BaseWebScriptTest
return response.getContentAsString();
}
/**
* Returns the Keys of a JSON Object, optionally sorted
*/
private String[] getKeys(JSONObject json, boolean sorted)
{
@SuppressWarnings("unchecked")
Iterator<String> ki = json.keys();
List<String> keys = new ArrayList<String>(json.length());
while (ki.hasNext())
{
keys.add(ki.next());
}
if(sorted) { Collections.sort(keys); }
return keys.toArray(new String[keys.size()]);
}
// Tests
@@ -985,9 +1005,10 @@ public class CalendarRestApiTest extends BaseWebScriptTest
}
/**
* Repeating events support
* Repeating events support, across both the site
* specific and user wide listings.
*/
public void testRepeatingEventsInUserListing() throws Exception
public void testRepeatingEventsInListings() throws Exception
{
JSONObject result;
JSONArray events;
@@ -1010,7 +1031,10 @@ public class CalendarRestApiTest extends BaseWebScriptTest
// Get all the entries, without repeats expanded
result = getEntries("admin", "2011-06-27");
// ---------------------------------------------
// For the user
result = getEntries("admin", "2011-06-27&repeating=first");
events = result.getJSONArray("events");
assertEquals(2, events.length());
assertEquals(entryName2, events.getJSONObject(0).getString("name"));
@@ -1019,7 +1043,25 @@ public class CalendarRestApiTest extends BaseWebScriptTest
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(1).getString("title"));
// For the site (JSON format is different)
result = getEntries(null, "2011-06-27&repeating=first");
assertEquals(2, result.length());
assertEquals("6/28/2011", getKeys(result, true)[0]);
assertEquals("6/29/2011", getKeys(result, true)[1]);
events = result.getJSONArray("6/28/2011");
assertEquals(1, events.length());
assertEquals(EVENT_TITLE_TWO + " (Repeating)", events.getJSONObject(0).getString("name"));
events = result.getJSONArray("6/29/2011");
assertEquals(1, events.length());
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(0).getString("name"));
// Get all the entries, with repeats expanded
// ------------------------------------------
// For the user
result = getEntries("admin", "2011/06/27");
events = result.getJSONArray("events");
assertEquals(7, Math.min(events.length(),7)); // At least
@@ -1059,6 +1101,42 @@ public class CalendarRestApiTest extends BaseWebScriptTest
assertEquals("2011-07-29T", events.getJSONObject(7).getJSONObject("startAt").getString("iso8601").substring(0,11));
// For the site
result = getEntries(null, "2011-06-28&repeating=all");
assertEquals(7, Math.min(result.length(),7)); // At least
// Repeating original
assertEquals("6/28/2011", getKeys(result, true)[0]);
assertEquals(1, result.getJSONArray("6/28/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("6/28/2011").getJSONObject(0).get("name"));
// 1st repeat Wednesday, then Non-repeating original
assertEquals("6/29/2011", getKeys(result, true)[1]);
assertEquals(2, result.getJSONArray("6/29/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("6/29/2011").getJSONObject(0).get("name"));
assertEquals(EVENT_TITLE_ONE, result.getJSONArray("6/29/2011").getJSONObject(1).get("name"));
// 1st repeat Friday
assertEquals("7/1/2011", getKeys(result, true)[2]);
assertEquals(1, result.getJSONArray("7/1/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("7/1/2011").getJSONObject(0).get("name"));
// 2nd repeat Wednesday
assertEquals("7/13/2011", getKeys(result, true)[3]);
assertEquals(1, result.getJSONArray("7/13/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("7/13/2011").getJSONObject(0).get("name"));
// 2nd repeat Friday
assertEquals("7/15/2011", getKeys(result, true)[4]);
assertEquals(1, result.getJSONArray("7/15/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("7/15/2011").getJSONObject(0).get("name"));
// 3rd repeat Wednesday
assertEquals("7/27/2011", getKeys(result, true)[5]);
assertEquals(1, result.getJSONArray("7/27/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("7/27/2011").getJSONObject(0).get("name"));
// 3rd repeat Friday
assertEquals("7/29/2011", getKeys(result, true)[6]);
assertEquals(1, result.getJSONArray("7/29/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("7/29/2011").getJSONObject(0).get("name"));
// Ask for events from a date in the future
// We shouldn't get either of the original events, but we
// should get the repeating instances of the 2nd one
@@ -1080,5 +1158,26 @@ public class CalendarRestApiTest extends BaseWebScriptTest
assertEquals("2011-09-07T", events.getJSONObject(2).getJSONObject("startAt").getString("iso8601").substring(0,11));
// Friday, final repeating instance date
assertEquals("2011-09-09T", events.getJSONObject(3).getJSONObject("startAt").getString("iso8601").substring(0,11));
// Check by site, should see the same
result = getEntries(null, "2011-08-20&repeating=all");
assertEquals(4, result.length());
assertEquals("8/24/2011", getKeys(result, true)[0]);
assertEquals(1, result.getJSONArray("8/24/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("8/24/2011").getJSONObject(0).get("name"));
assertEquals("8/26/2011", getKeys(result, true)[1]);
assertEquals(1, result.getJSONArray("8/26/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("8/26/2011").getJSONObject(0).get("name"));
assertEquals("9/7/2011", getKeys(result, true)[2]);
assertEquals(1, result.getJSONArray("9/7/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("9/7/2011").getJSONObject(0).get("name"));
assertEquals("9/9/2011", getKeys(result, true)[3]);
assertEquals(1, result.getJSONArray("9/9/2011").length());
assertEquals(EVENT_TITLE_TWO, result.getJSONArray("9/9/2011").getJSONObject(0).get("name"));
}
}

View File

@@ -158,6 +158,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarListingWebScript
{
// Build the object
Map<String, Object> result = new HashMap<String, Object>();
result.put(RESULT_EVENT, entry);
result.put(RESULT_NAME, entry.getSystemName());
result.put(RESULT_TITLE, entry.getTitle());
result.put("description", entry.getDescription());