mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
AFL-9156 Start on the logic to find future instances of a recurring event for the event listing webscript
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29150 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -19,14 +19,13 @@
|
|||||||
package org.alfresco.repo.web.scripts.calendar;
|
package org.alfresco.repo.web.scripts.calendar;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.DateFormatSymbols;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.calendar.CalendarEntry;
|
import org.alfresco.service.cmr.calendar.CalendarEntry;
|
||||||
import org.alfresco.service.cmr.calendar.CalendarEntryDTO;
|
import org.alfresco.service.cmr.calendar.CalendarEntryDTO;
|
||||||
|
import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper;
|
||||||
import org.alfresco.service.cmr.site.SiteInfo;
|
import org.alfresco.service.cmr.site.SiteInfo;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
@@ -104,34 +103,12 @@ public class CalendarEntryGet extends AbstractCalendarWebScript
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get our days of the week, in the current locale
|
// Get our days of the week, in the current locale, for each outlook two letter code
|
||||||
DateFormatSymbols dates = new DateFormatSymbols(I18NUtil.getLocale());
|
Map<String,String> days =
|
||||||
String[] weekdays = dates.getWeekdays();
|
CalendarRecurrenceHelper.buildLocalRecurrenceDaysOfTheWeek(I18NUtil.getLocale());
|
||||||
|
|
||||||
// And map them based on the outlook two letter codes
|
|
||||||
Map<String,String> days = new HashMap<String, String>();
|
|
||||||
days.put("SU", weekdays[Calendar.SUNDAY]);
|
|
||||||
days.put("MO", weekdays[Calendar.MONDAY]);
|
|
||||||
days.put("TU", weekdays[Calendar.TUESDAY]);
|
|
||||||
days.put("WE", weekdays[Calendar.WEDNESDAY]);
|
|
||||||
days.put("Th", weekdays[Calendar.THURSDAY]);
|
|
||||||
days.put("FR", weekdays[Calendar.FRIDAY]);
|
|
||||||
days.put("SA", weekdays[Calendar.SATURDAY]);
|
|
||||||
|
|
||||||
// Turn the string into a useful map
|
// Turn the string into a useful map
|
||||||
Map<String,String> params = new HashMap<String, String>();
|
Map<String,String> params = CalendarRecurrenceHelper.extractRecurrenceRule(event);
|
||||||
for(String rule : recurrence.split(";"))
|
|
||||||
{
|
|
||||||
String[] parts = rule.split("=");
|
|
||||||
if(parts.length != 2)
|
|
||||||
{
|
|
||||||
logger.warn("Invalid rule '" + rule + "' in recurrence: " + recurrence);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
params.put(parts[0], parts[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// To hold our result
|
// To hold our result
|
||||||
StringBuffer text = new StringBuffer();
|
StringBuffer text = new StringBuffer();
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.web.scripts.calendar;
|
package org.alfresco.repo.web.scripts.calendar;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -31,6 +30,7 @@ import org.alfresco.repo.calendar.CalendarServiceImpl;
|
|||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.service.cmr.calendar.CalendarEntry;
|
import org.alfresco.service.cmr.calendar.CalendarEntry;
|
||||||
import org.alfresco.service.cmr.calendar.CalendarEntryDTO;
|
import org.alfresco.service.cmr.calendar.CalendarEntryDTO;
|
||||||
|
import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.site.SiteInfo;
|
import org.alfresco.service.cmr.site.SiteInfo;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@@ -46,6 +46,11 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
|
|||||||
*/
|
*/
|
||||||
public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
||||||
{
|
{
|
||||||
|
private static final String RESULT_NAME = "name";
|
||||||
|
private static final String RESULT_TITLE = "title";
|
||||||
|
private static final String RESULT_START = "start";
|
||||||
|
private static final String RESULT_END = "end";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req,
|
protected Map<String, Object> executeImpl(WebScriptRequest req,
|
||||||
Status status, Cache cache)
|
Status status, Cache cache)
|
||||||
@@ -66,12 +71,28 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
|||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(SiteInfo singleSite, String eventName,
|
protected Map<String, Object> executeImpl(SiteInfo singleSite, String eventName,
|
||||||
WebScriptRequest req, JSONObject json, Status status, Cache cache) {
|
WebScriptRequest req, JSONObject json, Status status, Cache cache) {
|
||||||
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); // Evil...
|
|
||||||
|
|
||||||
// Did they restrict by date?
|
// Did they restrict by date?
|
||||||
Date fromDate = parseDate(req.getParameter("from"));
|
Date fromDate = parseDate(req.getParameter("from"));
|
||||||
Date toDate = parseDate(req.getParameter("to"));
|
Date toDate = parseDate(req.getParameter("to"));
|
||||||
|
|
||||||
|
// What should we do about repeating events? First or all?
|
||||||
|
boolean repeatingFirstOnly = true;
|
||||||
|
if(fromDate != null)
|
||||||
|
{
|
||||||
|
// TODO Find a better way to do this...
|
||||||
|
String fromDateS = req.getParameter("from");
|
||||||
|
if(fromDateS.indexOf('-') != -1)
|
||||||
|
{
|
||||||
|
// Apparently this is the site calendar dashlet...
|
||||||
|
repeatingFirstOnly = true;
|
||||||
|
}
|
||||||
|
if(fromDateS.indexOf('/') != -1)
|
||||||
|
{
|
||||||
|
// This is something else, wants all events in range
|
||||||
|
repeatingFirstOnly = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// One site, or all the user's ones?
|
// One site, or all the user's ones?
|
||||||
List<SiteInfo> sites = new ArrayList<SiteInfo>();
|
List<SiteInfo> sites = new ArrayList<SiteInfo>();
|
||||||
if(singleSite != null)
|
if(singleSite != null)
|
||||||
@@ -96,7 +117,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
|||||||
siteService.getContainer(site.getShortName(), CalendarServiceImpl.CALENDAR_COMPONENT),
|
siteService.getContainer(site.getShortName(), CalendarServiceImpl.CALENDAR_COMPONENT),
|
||||||
site
|
site
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get the entries for the list
|
// Get the entries for the list
|
||||||
@@ -109,19 +130,17 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
|||||||
{
|
{
|
||||||
// Build the object
|
// Build the object
|
||||||
Map<String, Object> result = new HashMap<String, Object>();
|
Map<String, Object> result = new HashMap<String, Object>();
|
||||||
result.put("name", entry.getSystemName());
|
result.put(RESULT_NAME, entry.getSystemName());
|
||||||
result.put("title", entry.getTitle());
|
result.put(RESULT_TITLE, entry.getTitle());
|
||||||
result.put("description", entry.getDescription());
|
result.put("description", entry.getDescription());
|
||||||
result.put("where", entry.getLocation());
|
result.put("where", entry.getLocation());
|
||||||
result.put("start", entry.getStart());
|
result.put(RESULT_START, entry.getStart());
|
||||||
result.put("end", entry.getEnd());
|
result.put(RESULT_END, entry.getEnd());
|
||||||
result.put("duration", buildDuration(entry));
|
result.put("duration", buildDuration(entry));
|
||||||
result.put("tags", entry.getTags());
|
result.put("tags", entry.getTags());
|
||||||
result.put("isoutlook", entry.isOutlook());
|
result.put("isoutlook", entry.isOutlook());
|
||||||
result.put("allday", CalendarEntryDTO.isAllDay(entry));
|
result.put("allday", CalendarEntryDTO.isAllDay(entry));
|
||||||
|
|
||||||
// TODO Recurring
|
|
||||||
|
|
||||||
// Identify the site
|
// Identify the site
|
||||||
SiteInfo site = containerLookup.get(entry.getContainerNodeRef());
|
SiteInfo site = containerLookup.get(entry.getContainerNodeRef());
|
||||||
result.put("site", site);
|
result.put("site", site);
|
||||||
@@ -136,7 +155,12 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
|||||||
result.put(key, "");
|
result.put(key, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save this one
|
||||||
results.add(result);
|
results.add(result);
|
||||||
|
|
||||||
|
// Handle recurring as needed
|
||||||
|
handleRecurring(entry, result, results, fromDate, repeatingFirstOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
// All done
|
// All done
|
||||||
@@ -204,4 +228,69 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript
|
|||||||
|
|
||||||
return duration.toString();
|
return duration.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do what's needed for recurring events
|
||||||
|
*/
|
||||||
|
private void handleRecurring(CalendarEntry entry, Map<String, Object> entryResult,
|
||||||
|
List<Map<String, Object>> allResults, Date from, boolean repeatingFirstOnly)
|
||||||
|
{
|
||||||
|
if(entry.getRecurrenceRule() == null)
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// How long is it?
|
||||||
|
long duration = entry.getEnd().getTime() - entry.getStart().getTime();
|
||||||
|
|
||||||
|
// Get it's recurring instances
|
||||||
|
List<Date> dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter(
|
||||||
|
entry, from, until, repeatingFirstOnly);
|
||||||
|
|
||||||
|
// If we got no dates, then no recurrences in the period so zap
|
||||||
|
if(dates == null || dates.size() == 0)
|
||||||
|
{
|
||||||
|
allResults.remove(entryResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always update the live entry
|
||||||
|
updateRepeatingStartEnd(dates.get(0), duration, entryResult);
|
||||||
|
|
||||||
|
// If first result only, alter title and finish
|
||||||
|
if(repeatingFirstOnly)
|
||||||
|
{
|
||||||
|
entryResult.put(RESULT_TITLE, entry.getTitle() + " (Repeating)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise generate one entry per extra date
|
||||||
|
for(int i=1; i<dates.size(); i++)
|
||||||
|
{
|
||||||
|
// Clone the properties
|
||||||
|
Map<String, Object> newResult = new HashMap<String, Object>(entryResult);
|
||||||
|
|
||||||
|
// Generate start and end based on this date
|
||||||
|
updateRepeatingStartEnd(dates.get(i), duration, newResult);
|
||||||
|
|
||||||
|
// Save as a new event
|
||||||
|
allResults.add(newResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRepeatingStartEnd(Date newStart, long duration, Map<String, Object> result)
|
||||||
|
{
|
||||||
|
Date newEnd = new Date(newStart.getTime() + duration);
|
||||||
|
result.put(RESULT_START, newStart);
|
||||||
|
result.put(RESULT_END, newEnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user