mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
ALF-9156 Finish recurring event support in the calendar listing webscript, and add in new unit tests to cover this case
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29235 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.alfresco.repo.web.scripts.calendar;
|
||||
|
||||
import org.alfresco.repo.calendar.CalendarHelpersTest;
|
||||
import org.alfresco.repo.calendar.CalendarServiceImplTest;
|
||||
import org.alfresco.service.cmr.calendar.CalendarService;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -34,6 +35,7 @@ import org.junit.runners.Suite;
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({
|
||||
CalendarServiceImplTest.class,
|
||||
CalendarHelpersTest.class,
|
||||
CalendarRestApiTest.class
|
||||
})
|
||||
public class AllCalendarTests
|
||||
|
@@ -211,7 +211,7 @@ public class CalendarRestApiTest extends BaseWebScriptTest
|
||||
int expectedStatus)
|
||||
throws Exception
|
||||
{
|
||||
String date = "2011/06/29";
|
||||
String date = "2011/06/29"; // A wednesday
|
||||
String start = "12:00";
|
||||
String end = "13:00";
|
||||
|
||||
@@ -252,7 +252,7 @@ public class CalendarRestApiTest extends BaseWebScriptTest
|
||||
private JSONObject updateEntry(String name, String what, String where, String description,
|
||||
boolean withRecurrence, int expectedStatus) throws Exception
|
||||
{
|
||||
String date = "2011/06/28";
|
||||
String date = "2011/06/28"; // A Tuesday
|
||||
String start = "11:30";
|
||||
String end = "13:30";
|
||||
|
||||
@@ -530,7 +530,13 @@ public class CalendarRestApiTest extends BaseWebScriptTest
|
||||
result = getEntries(null, null);
|
||||
assertEquals(1, result.length());
|
||||
|
||||
result = getEntries("admin", "2000/01/01"); // TODO From date shouldn't be needed...
|
||||
result = getEntries("admin", "2000/01/01"); // With a from date
|
||||
events = result.getJSONArray("events");
|
||||
assertEquals(2, events.length());
|
||||
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(0).getString("title"));
|
||||
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(1).getString("title"));
|
||||
|
||||
result = getEntries("admin", null); // Without a from date
|
||||
events = result.getJSONArray("events");
|
||||
assertEquals(2, events.length());
|
||||
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(0).getString("title"));
|
||||
@@ -588,4 +594,78 @@ public class CalendarRestApiTest extends BaseWebScriptTest
|
||||
assertEquals(0, events.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeating events support
|
||||
*/
|
||||
public void testRepeatingEventsInUserListing() throws Exception
|
||||
{
|
||||
JSONObject result;
|
||||
JSONArray events;
|
||||
|
||||
// Initially, there are no events
|
||||
result = getEntries(null, null);
|
||||
assertEquals(0, result.length());
|
||||
|
||||
result = getEntries("admin", null);
|
||||
events = result.getJSONArray("events");
|
||||
assertEquals(0, events.length());
|
||||
|
||||
// Add two events in the past, one of which repeats
|
||||
JSONObject entry1 = createEntry(EVENT_TITLE_ONE, "Somewhere", "Thing 1", Status.STATUS_OK);
|
||||
JSONObject entry2 = createEntry(EVENT_TITLE_TWO, "Somewhere", "Thing 2", Status.STATUS_OK);
|
||||
String entryName1 = getNameFromEntry(entry1);
|
||||
String entryName2 = getNameFromEntry(entry2);
|
||||
// Have it repeat on wednesdays and fridays every two weeks
|
||||
updateEntry(entryName2, EVENT_TITLE_TWO, "Somewhere", "Thing 2", true, Status.STATUS_OK);
|
||||
|
||||
|
||||
// Get all the entries, without repeats expanded
|
||||
result = getEntries("admin", "2011-06-27");
|
||||
events = result.getJSONArray("events");
|
||||
assertEquals(2, events.length());
|
||||
assertEquals(entryName2, events.getJSONObject(0).getString("name"));
|
||||
assertEquals(entryName1, events.getJSONObject(1).getString("name"));
|
||||
assertEquals(EVENT_TITLE_TWO + " (Repeating)", events.getJSONObject(0).getString("title"));
|
||||
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(1).getString("title"));
|
||||
|
||||
|
||||
// Get all the entries, with repeats expanded
|
||||
result = getEntries("admin", "2011/06/27");
|
||||
events = result.getJSONArray("events");
|
||||
assertEquals(7, Math.min(events.length(),7)); // At least
|
||||
assertEquals(entryName2, events.getJSONObject(0).getString("name"));
|
||||
assertEquals(entryName2, events.getJSONObject(1).getString("name")); // 11:30 ->
|
||||
assertEquals(entryName1, events.getJSONObject(2).getString("name")); // 12:00 ->
|
||||
assertEquals(entryName2, events.getJSONObject(3).getString("name"));
|
||||
assertEquals(entryName2, events.getJSONObject(4).getString("name"));
|
||||
assertEquals(entryName2, events.getJSONObject(5).getString("name"));
|
||||
assertEquals(entryName2, events.getJSONObject(6).getString("name"));
|
||||
assertEquals(entryName2, events.getJSONObject(7).getString("name"));
|
||||
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(0).getString("title"));
|
||||
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(1).getString("title"));
|
||||
assertEquals(EVENT_TITLE_ONE, events.getJSONObject(2).getString("title"));
|
||||
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(3).getString("title"));
|
||||
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(4).getString("title"));
|
||||
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(5).getString("title"));
|
||||
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(6).getString("title"));
|
||||
assertEquals(EVENT_TITLE_TWO, events.getJSONObject(7).getString("title"));
|
||||
|
||||
// Check the dates on these:
|
||||
// Repeating original
|
||||
assertEquals("2011-06-28T", events.getJSONObject(0).getJSONObject("startAt").getString("iso8601").substring(0,11));
|
||||
// 1st repeat Wednesday
|
||||
assertEquals("2011-06-29T", events.getJSONObject(1).getJSONObject("startAt").getString("iso8601").substring(0,11));
|
||||
// Non-repeating original
|
||||
assertEquals("2011-06-29T", events.getJSONObject(2).getJSONObject("startAt").getString("iso8601").substring(0,11));
|
||||
// 1st repeat Friday
|
||||
assertEquals("2011-07-01T", events.getJSONObject(3).getJSONObject("startAt").getString("iso8601").substring(0,11));
|
||||
// 2nd repeat Wednesday
|
||||
assertEquals("2011-07-13T", events.getJSONObject(4).getJSONObject("startAt").getString("iso8601").substring(0,11));
|
||||
// 2nd repeat Friday
|
||||
assertEquals("2011-07-15T", events.getJSONObject(5).getJSONObject("startAt").getString("iso8601").substring(0,11));
|
||||
// 3rd repeat Wednesday
|
||||
assertEquals("2011-07-27T", events.getJSONObject(6).getJSONObject("startAt").getString("iso8601").substring(0,11));
|
||||
// 3rd repeat Friday
|
||||
assertEquals("2011-07-29T", events.getJSONObject(7).getJSONObject("startAt").getString("iso8601").substring(0,11));
|
||||
}
|
||||
}
|
@@ -19,6 +19,9 @@
|
||||
package org.alfresco.repo.web.scripts.calendar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -77,9 +80,24 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||
|
||||
// What should we do about repeating events? First or all?
|
||||
boolean repeatingFirstOnly = true;
|
||||
String repeatingEvents = req.getParameter("repeating");
|
||||
if(repeatingEvents != null)
|
||||
{
|
||||
if("first".equals(repeatingEvents))
|
||||
{
|
||||
repeatingFirstOnly = true;
|
||||
}
|
||||
else if("all".equals(repeatingEvents))
|
||||
{
|
||||
repeatingFirstOnly = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to the icky old way of guessing it from
|
||||
// the format of the from date, which differs between uses!
|
||||
if(fromDate != null)
|
||||
{
|
||||
// TODO Find a better way to do this...
|
||||
String fromDateS = req.getParameter("from");
|
||||
if(fromDateS.indexOf('-') != -1)
|
||||
{
|
||||
@@ -92,6 +110,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||
repeatingFirstOnly = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// One site, or all the user's ones?
|
||||
List<SiteInfo> sites = new ArrayList<SiteInfo>();
|
||||
@@ -125,6 +144,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||
PagingResults<CalendarEntry> entries =
|
||||
calendarService.listCalendarEntries(siteShortNames, fromDate, toDate, paging);
|
||||
|
||||
boolean resortNeeded = false;
|
||||
List<Map<String, Object>> results = new ArrayList<Map<String,Object>>();
|
||||
for(CalendarEntry entry : entries.getPage())
|
||||
{
|
||||
@@ -160,7 +180,39 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||
results.add(result);
|
||||
|
||||
// Handle recurring as needed
|
||||
handleRecurring(entry, result, results, fromDate, repeatingFirstOnly);
|
||||
boolean orderChanged = handleRecurring(entry, result, results, fromDate, repeatingFirstOnly);
|
||||
if(orderChanged)
|
||||
{
|
||||
resortNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the recurring events meant dates changed, re-sort
|
||||
if(resortNeeded)
|
||||
{
|
||||
Collections.sort(results, new Comparator<Map<String, Object>>() {
|
||||
public int compare(Map<String, Object> resultA,
|
||||
Map<String, Object> resultB) {
|
||||
Date startA = (Date)resultA.get(RESULT_START);
|
||||
Date startB = (Date)resultB.get(RESULT_START);
|
||||
|
||||
int cmp = startA.compareTo(startB);
|
||||
if(cmp == 0)
|
||||
{
|
||||
Date endA = (Date)resultA.get(RESULT_END);
|
||||
Date endB = (Date)resultB.get(RESULT_END);
|
||||
cmp = endA.compareTo(endB);
|
||||
if(cmp == 0)
|
||||
{
|
||||
String nameA = (String)resultA.get(RESULT_NAME);
|
||||
String nameB = (String)resultB.get(RESULT_NAME);
|
||||
return nameA.compareTo(nameB);
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// All done
|
||||
@@ -230,23 +282,29 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||
}
|
||||
|
||||
/**
|
||||
* Do what's needed for recurring events
|
||||
* Do what's needed for recurring events.
|
||||
*
|
||||
* @return If dates have been tweaked, and a sort may be required
|
||||
*/
|
||||
private void handleRecurring(CalendarEntry entry, Map<String, Object> entryResult,
|
||||
private boolean handleRecurring(CalendarEntry entry, Map<String, Object> entryResult,
|
||||
List<Map<String, Object>> allResults, Date from, boolean repeatingFirstOnly)
|
||||
{
|
||||
if(entry.getRecurrenceRule() == null)
|
||||
{
|
||||
// Nothing to do
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Should we limit ourselves?
|
||||
Date until = null;
|
||||
if(!repeatingFirstOnly)
|
||||
{
|
||||
// Only repeating instances for the next 60 days
|
||||
until = new Date(from.getTime() + 24*60*60*1000);
|
||||
// Only repeating instances for the next 60 days, to keep the list sane
|
||||
// (It's normally only used for a month view anyway)
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(from);
|
||||
c.add(Calendar.DATE, 60);
|
||||
until = c.getTime();
|
||||
}
|
||||
|
||||
// How long is it?
|
||||
@@ -255,12 +313,26 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||
// Get it's recurring instances
|
||||
List<Date> dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter(
|
||||
entry, from, until, repeatingFirstOnly);
|
||||
if(dates == null)
|
||||
{
|
||||
dates = new ArrayList<Date>();
|
||||
}
|
||||
|
||||
// Add on the original event time itself if needed
|
||||
if(entry.getStart().getTime() >= from.getTime())
|
||||
{
|
||||
if(dates.size() == 0 || dates.get(0).getTime() != entry.getStart().getTime())
|
||||
{
|
||||
// Original event is after the start time, and not on the recurring list
|
||||
dates.add(0, entry.getStart());
|
||||
}
|
||||
}
|
||||
|
||||
// If we got no dates, then no recurrences in the period so zap
|
||||
if(dates == null || dates.size() == 0)
|
||||
if(dates.size() == 0)
|
||||
{
|
||||
allResults.remove(entryResult);
|
||||
return;
|
||||
return false; // Remains sorted despite delete
|
||||
}
|
||||
|
||||
// Always update the live entry
|
||||
@@ -270,7 +342,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||
if(repeatingFirstOnly)
|
||||
{
|
||||
entryResult.put(RESULT_TITLE, entry.getTitle() + " (Repeating)");
|
||||
return;
|
||||
return true; // Date has been changed
|
||||
}
|
||||
|
||||
// Otherwise generate one entry per extra date
|
||||
@@ -285,6 +357,9 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||
// Save as a new event
|
||||
allResults.add(newResult);
|
||||
}
|
||||
|
||||
// New dates have been added
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateRepeatingStartEnd(Date newStart, long duration, Map<String, Object> result)
|
||||
|
Reference in New Issue
Block a user