ALF-9156 Convert the user event listing webscript, excluding repeating support (so far), to Java

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29040 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2011-07-14 14:28:31 +00:00
parent 113501c9a1
commit 70669e3136
5 changed files with 231 additions and 699 deletions

View File

@@ -1,691 +0,0 @@
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/lib/calendar.lib.js">
/**
* Limits the number of events that get returned.
* TODO: have this supported in the Lucene query syntax
*/
model.limit = args.limit;
var DAY_MS = 24*60*60*1000,
days =
{
SU: 0,
MO: 1,
TU: 2,
WE: 3,
TH: 4,
FR: 5,
SA: 6
},
username = person.properties["cm:userName"], // Get the username of the currently logged in person
range = {},
dateFilter = args.from,
siteId = url.templateArgs.site;
if (dateFilter)
{
range.fromdate = dateFilter;
}
model.events = getUserEvents(username, siteId, range);
/**
* Calculates duration based on specified start and end dates
*
* @method getDuration
* @param dtStartDate {Date} start date
* @param dtEndDate {Date} end date
* @return {String} Duration in ical format eg PT2H15M
*/
function getDuration(dtStartDate, dtEndDate)
{
var DAY = "D",
WEEK = "W",
HOUR = 'H',
SECOND = 'S',
MINUTE = 'Mn';
var dateDiff = {},
duration = 'P',
diff = new Date(),
timediff;
diff.setTime(Math.abs(dtStartDate.getTime() - dtEndDate.getTime()));
timediff = diff.getTime();
dateDiff[WEEK] = Math.floor(timediff / (1000 * 60 * 60 * 24 * 7));
timediff -= dateDiff[WEEK] * (1000 * 60 * 60 * 24 * 7);
dateDiff[DAY] = (Math.floor(timediff / (1000 * 60 * 60 * 24)));
timediff -= dateDiff[DAY] * (1000 * 60 * 60 * 24);
dateDiff[HOUR] = Math.floor(timediff / (1000 * 60 * 60));
timediff -= dateDiff[HOUR] * (1000 * 60 * 60);
dateDiff[MINUTE] = Math.floor(timediff / (1000 * 60));
timediff -= dateDiff[MINUTE] * (1000 * 60);
dateDiff[SECOND] = Math.floor(timediff / 1000);
timediff -= dateDiff[SECOND] * 1000;
if (dateDiff[WEEK] > 0)
{
duration += dateDiff[WEEK] + WEEK;
}
if (dateDiff[DAY] > 0)
{
duration += dateDiff[DAY] + DAY;
}
duration += 'T';
if (dateDiff[HOUR] > 0)
{
duration += dateDiff[HOUR] + HOUR;
}
if (dateDiff[MINUTE] > 0)
{
duration += dateDiff[MINUTE] + 'M';
}
if (dateDiff[SECOND] > 0)
{
duration += dateDiff[SECOND] + SECOND;
}
return duration;
}
/**
* Get events for the specified user
*
* @method getUserEvents
* @param user {String} Username
* @param siteId {String} SiteID (optional)
* @param range {Object} Open date range
* @return {Array} Array of event objects
*/
function getUserEvents(user, siteId, range)
{
if (!user)
{
return [];
}
var paths = [], site, siteTitles = {}, sites = [], results = [],
isSiteCalendarDashlet = (range.fromdate && range.fromdate.indexOf("-") != -1) ? true : false;
if (siteId == null)
{
sites = siteService.listUserSites(user);
}
else
{
site = siteService.getSite(siteId);
if (site != null)
{
sites.push(site);
}
}
for (var j = 0; j < sites.length; j++)
{
site = sites[j];
paths.push("PATH:\"/app:company_home/st:sites/cm:" + search.ISO9075Encode(sites[j].shortName) + "/cm:calendar/*\"");
siteTitles[site.shortName] = site.title;
}
if (paths.length > 0)
{
var luceneQuery = "+(" + paths.join(" OR ") + ") +TYPE:\"{http\://www.alfresco.org/model/calendar}calendarEvent\"";
if (range.fromdate)
{
luceneQuery += " +@ia\\:fromDate:[2008\\-1\\-1T00:00:00 TO 2099\\-1\\-1T00:00:00]";
}
results = search.luceneSearch(luceneQuery, "ia:fromDate", true);
}
// Repurpose results into custom array so as to add custom properties
var events = [];
for (var i = 0; i < results.length; i++)
{
var e = results[i];
if (!isSiteCalendarDashlet)
{
var d = new Date(),
fromDate = range.fromdate.split("/");
d.setMonth(fromDate[1] - 1);
d.setYear(fromDate[0]);
d.setDate(fromDate[2]);
var d1 = cloneDate(e.properties["ia:fromDate"]),
d2 = cloneDate(d);
d1.setHours(0, 0, 0, 0);
d2.setHours(0, 0, 0, 0);
if (d1 < d2 && e.properties["ia:recurrenceRule"] == null)
{
continue;
}
}
var eSite = e.parent.parent.name,
eStart = e.properties["ia:fromDate"],
eEnd = e.properties["ia:toDate"],
event =
{
isoutlook: (e.properties["ia:isOutlook"] != null && e.properties["ia:isOutlook"]),
name: e.name,
title: e.properties["ia:whatEvent"],
where: e.properties["ia:whereEvent"] == null ? "" : e.properties["ia:whereEvent"],
when: e.properties["ia:fromDate"],
description: e.properties["ia:descriptionEvent"],
start: eStart,
end: eEnd,
site: eSite,
siteTitle: siteTitles[eSite],
allday: (isAllDayEvent(e)) ? 'true' : 'false',
tags: e.tags.join(' '),
duration: getDuration(eStart, eEnd)
};
if (e.properties["ia:recurrenceRule"] != null)
{
event.recurrenceRule = e.properties["ia:recurrenceRule"];
if (e.properties["ia:recurrenceLastMeeting"] != null)
{
event.recurrenceLastMeeting = e.properties["ia:recurrenceLastMeeting"];
}
// Expects the date in the format yyyy-mm-dd
var startMonth = new Date(),
endMonth = new Date(),
eventStartDates = [],
fromDate;
if (isSiteCalendarDashlet)
{
fromDate = range.fromdate.split("-");
startMonth.setMonth(fromDate[1] - 1);
startMonth.setYear(fromDate[0]);
startMonth.setDate(fromDate[2] * 1 + 10);
startMonth.setDate(1);
endMonth.setTime(startMonth.getTime());
endMonth.setMonth(endMonth.getMonth() + 1);
eventStartDates = getNextEventStartDates(event, startMonth, endMonth, e, isSiteCalendarDashlet);
}
else
{
fromDate = range.fromdate.split("/");
startMonth.setMonth(fromDate[1] - 1);
startMonth.setYear(fromDate[0]);
startMonth.setDate(fromDate[2]);
eventStartDates = getNextEventStartDates(event, startMonth, endMonth, e, isSiteCalendarDashlet);
endMonth.setYear(2099);
endMonth.setMonth(0);
}
var recurEvent,
eventEnd;
for (var j = 0; j < eventStartDates.length; j++)
{
recurEvent =
{
name: event.name,
isoutlook: event.isoutlook,
title: event.title,
where: event.where,
site: event.site,
siteTitle: event.siteTitle,
allday: event.allday,
tags: event.tags,
duration: event.duration,
when: eventStartDates[j],
start: eventStartDates[j]
};
eventEnd = new Date();
eventEnd.setTime(recurEvent.start.getTime());
eventEnd.setTime(eventEnd.getTime() + (event.end.getTime() - event.start.getTime()));
recurEvent.end = eventEnd;
events.push(recurEvent);
if (!isSiteCalendarDashlet)
{
// TODO: Instead of this, add a bool flag to the event which Share can pick up on and annotate
recurEvent.title = event.title + " (Recurring)";
break;
}
}
}
else
{
events.push(event);
}
}
return events;
}
/**
* Clone provided date object
*
* @method cloneData
* @param date {Date} The date to be cloned
* @return {Date|null} A cloned date object or null
*/
function cloneDate(date)
{
var result = new Date();
result.setTime(date.getTime());
return result; // Date or null
}
/**
* Calculate if an event is an "all day" event
* NOTE: Another option would be to add an "all day" property to the
* existing calendar model.
*
* @method isAllDayEvent
* @param event {Node} The event node to evaluate
* @return {Boolean}
*/
function isAllDayEvent(event)
{
var startDate = event.properties["ia:fromDate"],
endDate = event.properties["ia:toDate"],
startTime = startDate.getHours() + ":" + startDate.getMinutes(),
endTime = endDate.getHours() + ":" + endDate.getMinutes();
if (logger.isLoggingEnabled())
{
logger.log("STARTTIME: " + startTime + " " + endTime + " " + (startTime == "0:0" && (startTime == endTime)));
}
return (startTime == "0:0" && (startTime == endTime));
}
/**
* Return next occurence of provided event after currentDate.
*
* @method getNextEventStartDates
* @param event {Object} Event object literal
* @param currentDate {Date} Current date
* @param endMonth {Date} Last month to evaluate
* @param event {Node} The event node to evaluate
* @param isSiteCalendarDashlet {Boolean} True when in Site Dahlet mode
*/
function getNextEventStartDates(event, currentDate, endMonth, eventNode, isSiteCalendarDashlet)
{
var rubeResult = [],
result = [],
recurrenceRule = event.recurrenceRule;
if (recurrenceRule)
{
var evStart = cloneDate(event.when);
// If event starts in future, then start search from its start date
if (evStart >= currentDate && !isSiteCalendarDashlet)
{
currentDate = evStart;
}
var parts = recurrenceRule.split(";"),
eventParam = {},
part;
for (var i = 0; i < parts.length; i++)
{
part = parts[i].split("=");
eventParam[part[0]] = part[1];
}
var endDate = new Date();
endDate.setTime(currentDate.getTime());
var needCycle = true;
while (needCycle)
{
// Get all events between currentDate and currentDate + event interval. There must be at least one event.
if (eventParam['FREQ'] == "WEEKLY")
{
if (isSiteCalendarDashlet)
{
endDate = endMonth;
}
else
{
endDate.setTime(endDate.getTime() + eventParam['INTERVAL'] * DAY_MS * 7);
}
rubeResult = this.resolveStartDateWeekly(event, eventParam, currentDate, endDate);
}
else if (eventParam['FREQ'] == "DAILY")
{
if (isSiteCalendarDashlet)
{
endDate = endMonth;
}
else
{
endDate.setTime(endDate.getTime() + eventParam['INTERVAL'] * DAY_MS);
}
rubeResult = this.resolveStartDaily(event, eventParam, currentDate, endDate);
}
else if (eventParam['FREQ'] == "MONTHLY")
{
if (isSiteCalendarDashlet)
{
endDate = endMonth;
}
else
{
endDate.setMonth(endDate.getMonth() + eventParam['INTERVAL'] * 1);
}
rubeResult = this.resolveStartMonthly(event, eventParam, currentDate, endDate, isSiteCalendarDashlet);
}
if (rubeResult.length > 0)
{
rubeResult.sort();
var ignoreEvents = {};
if (eventNode.children != null)
{
var childrenEvents = eventNode.children,
fullDate,
dateForCheck;
for (var j = 0; j < childrenEvents.length; j++)
{
fullDate = childrenEvents[j].properties["ia:date"];
ignoreEvents[fullDate.getFullYear() + " " + fullDate.getMonth() + " " + fullDate.getDate()] = 1;
}
for (var i = 0; i < rubeResult.length; i++)
{
dateForCheck = rubeResult[i];
if (!ignoreEvents[dateForCheck.getFullYear() + " " + dateForCheck.getMonth() + " " + dateForCheck.getDate()])
{
result.push(rubeResult[i]);
}
}
}
else
{
result = rubeResult;
}
if (result.length != 1)
{
needCycle = false;
}
else
{
currentDate = endDate;
}
}
else
{
needCycle = false;
}
}
}
else
{
var eventDate = cloneDate(event.when);
if ((eventDate.getTime() >= currentDate.getTime()) && (eventDate.getTime() < endMonth.getTime()))
{
result.push(eventDate.getDate());
}
}
return result;
}
/**
* Return all days between currentDate and endDate when weekly event occurs.
*
*
* @method resolveStartDatesWeekly
* @param ev {Object} object that represent weekly event
* @eventParam Map of event parameters taken from RRULE
* @param currentDate {Date} first day that event may occur.
* @param endDate {Date} last day that event may occur.
*
* @return {Array} Array that contains days beetwing currentDate and endDate on wich weekly event occurs
*/
function resolveStartDateWeekly (ev, eventParam, currentDate, endDate)
{
var result = [],
eventDays = eventParam['BYDAY'].split(","),
interval = eventParam['INTERVAL'],
lastEventDay = this.getLastEventDay(ev, currentDate, endDate);
if (lastEventDay == -1)
{
return result;
}
var eventStart = cloneDate(ev.when);
// Add as much full event cycles as need
if (eventStart.getTime() < currentDate.getTime())
{
var duration = Math.floor((currentDate.getTime() - eventStart.getTime()) / (interval * 7 * DAY_MS));
eventStart.setTime(eventStart.getTime() + duration * DAY_MS * interval * 7);
}
if (eventStart.getTime() > endDate.getTime())
{
return result;
}
var eventStartDay = eventStart.getDay();
eventStart.setTime(eventStart.getTime() - eventStartDay * DAY_MS);
var eventStartDays = [];
for (var i = 0; i < eventDays.length; i++)
{
eventStartDays.push(days[eventDays[i]]);
}
for (var i = 0; i < eventStartDays.length; i++)
{
var eventDate = new Date();
eventDate.setTime(eventStart.getTime() + eventStartDays[i] * DAY_MS);
while (eventDate.getTime() - lastEventDay.getTime() < DAY_MS)
{
if (eventDate.getTime() >= currentDate.getTime() && eventDate.getTime() >= cloneDate(ev.when).getTime())
{
var dateToAdd = new Date();
dateToAdd.setTime(eventDate.getTime());
result.push(dateToAdd);
}
eventDate.setTime(eventDate.getTime() + 7 * interval * DAY_MS);
}
}
return result;
}
/**
* Return all days between currentDate and endDate when daily event occurs.
*
* @method resolveStartDaily
* @param ev {Object} object that represent daily event
* @eventParam Map of event parameters taken from RRULE
* @param currentDate {Date} first day when event may occur.
* @param endDate {Date} last day when event may occur.
* @return {Array} Array that contains days beetwing currentDate and endDate on wich daily event occurs
*/
function resolveStartDaily (ev, eventParam, currentDate, endDate)
{
var result = [],
interval = eventParam['INTERVAL'],
lastEventDay = this.getLastEventDay(ev, currentDate, endDate);
if (lastEventDay == -1)
{
return result;
}
var eventStart = cloneDate(ev.when);
// Add as much full event cycles as need
if (eventStart.getTime() < currentDate.getTime())
{
var duration = Math.floor((currentDate.getTime() - eventStart.getTime())/(interval * DAY_MS));
eventStart.setTime(eventStart.getTime() + duration * DAY_MS * interval);
if (eventStart.getTime() < currentDate.getTime())
{
eventStart.setTime(eventStart.getTime() + interval * DAY_MS);
}
}
if (eventStart.getTime() > endDate.getTime())
{
return result;
}
var eventDate = eventStart,
dateToAdd;
while (eventDate.getTime() - lastEventDay.getTime() < DAY_MS)
{
dateToAdd = new Date();
dateToAdd.setTime(eventDate.getTime());
result.push(dateToAdd);
eventDate.setTime(eventDate.getTime() + interval * DAY_MS);
}
return result;
}
/**
* Return all days between currentDate and endDate when monthly event occurs.
*
* @method resolveStartMonthly
* @param ev {Object} object that represent monthly event
* @eventParam Map of event parameters taken from RRULE
* @param currentDate {Date} first day when event may occur
* @param endDate {Date} last day when event may occur
* @param isSiteCalendarDashlet {boolean} if current dashlet is SiteCalendar
* @return {Array} Array that contains days beetwing currentDate and endDate on wich monthly event occurs
*/
function resolveStartMonthly (ev, eventParam, currentDate, endDate, isSiteCalendarDashlet)
{
var result = [],
interval = eventParam['INTERVAL'],
eventStart = cloneDate(ev.when),
lastEventDay = this.getLastEventDay(ev, currentDate, endDate);
if (lastEventDay == -1)
{
return result;
}
var offset = ((currentDate.getFullYear() * 12 + currentDate.getMonth()) - (eventStart.getFullYear() * 12 + eventStart.getMonth())) % interval;
if (offset > 0)
{
if (isSiteCalendarDashlet)
{
return result();
}
currentDate.setMonth(currentDate.getMonth() + interval - offset);
}
var resultDate = currentDate;
resultDate.setDate(eventStart.getDate());
if (eventParam['BYDAY'])
{
var allowedDayNames = eventParam['BYDAY'].split(","),
allowedDays = new Object();
for (var i = 0; i < allowedDayNames.length; i++)
{
allowedDays[days[allowedDayNames[i]]] = 1;
}
var dayInWeek = eventParam['BYSETPOS'] * 1;
currentDate.setDate(1);
while (dayInWeek > 0)
{
if (allowedDays[currentDate.getDay()] == 1)
{
dayInWeek--;
}
if (dayInWeek > 0)
{
currentDate.setDate(currentDate.getDate() + 1);
}
}
if (dayInWeek == -1)
{
currentDate.setMonth(currentDate.getMonth() + 1);
currentDate.setTime(currentDate.getTime() - DAY_MS);
while (allowedDays[currentDate.getDay()] == undefined)
{
currentDate.setTime(currentDate.getTime() - DAY_MS);
}
}
resultDate = currentDate;
}
if (resultDate.getTime() - lastEventDay.getTime() < DAY_MS)
{
if (currentDate > resultDate && !isSiteCalendarDashlet)
{
resultDate.setMonth(resultDate.getMonth() + interval);
}
result.push(resultDate);
}
return result;
}
/**
* Return last day between currentDate and endDate when event may occur.
*
* @method getLastEventDay
* @param ev {Object} object that represent monthly event
* @param currentDate {Date} first day when event may occur.
* @param endDate {Date} last day when event may occur.
* @return {Date} last day in current month whe event may occur.
*/
function getLastEventDay (ev, currentDate, endDate)
{
var lastEventDay = new Date(endDate);
if ((ev.recurrenceLastMeeting) )
{
var lastAllowedDay = cloneDate(ev.recurrenceLastMeeting);
if (lastAllowedDay.getTime() < currentDate.getTime() || cloneDate(ev.when).getTime() > endDate.getTime())
{
return -1;
}
if ((lastAllowedDay.getTime() < endDate.getTime()))
{
lastEventDay = new Date(lastAllowedDay);
}
}
return lastEventDay;
}

View File

@@ -3,22 +3,32 @@
{ {
<#if events?exists> <#if events?exists>
"events": [ "events": [
<#list events?sort_by("when") as event> <#list events as event>
<#if event_index?string == limit?string><#break></#if> <#if event_index?string == limit?string><#break></#if>
{ {
"name": "${event.name}", "name": "${event.name}",
"title": "${event.title}", "title": "${event.title}",
"where": "${event.where}", "where": "${event.where}",
"when": "${xmldate(event.when)}",
"description": "${event.description}", "description": "${event.description}",
"url": "page/site/${event.site}/calendar?date=${event.when?string("yyyy-MM-dd")}", "url": "page/site/${event.siteName}/calendar?date=${event.start?string("yyyy-MM-dd")}",
"startAt": {
"iso8601": "${xmldate(event.start)}",
"legacyTime": "${event.start?string("HH:mm")}",
},
"endAt": {
"iso8601": "${xmldate(event.end)}",
"legacyTime": "${event.end?string("HH:mm")}",
},
"when": "${xmldate(event.start)}",
"endDate" : "${xmldate(event.end)}",
"start": "${event.start?string("HH:mm")}", "start": "${event.start?string("HH:mm")}",
"end": "${event.end?string("HH:mm")}", "end": "${event.end?string("HH:mm")}",
"endDate" : "${xmldate(event.end)}",
"site": "${event.site}", "site": "${event.site}",
"siteTitle": "${event.siteTitle}", "siteTitle": "${event.siteTitle}",
"allday": "${event.allday}", "allday": "${event.allday?string}",
"tags": "${event.tags}", "tags": [<#list event.tags as tag>"${tag}"<#if tag_has_next>,</#if></#list>],
"duration": "${event.duration}", "duration": "${event.duration}",
"isoutlook": "${event.isoutlook?string}" "isoutlook": "${event.isoutlook?string}"
}<#if event_has_next>,</#if> }<#if event_has_next>,</#if>

View File

@@ -1518,4 +1518,10 @@
parent="abstractCalendarWebScript"> parent="abstractCalendarWebScript">
</bean> </bean>
<!-- Lists the Calendar Events for a user -->
<bean id="webscript.org.alfresco.slingshot.calendar.userevents.get"
class="org.alfresco.repo.web.scripts.calendar.UserCalendarEntriesGet"
parent="abstractCalendarWebScript">
</bean>
</beans> </beans>

View File

@@ -40,7 +40,7 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
/** /**
* This class is the controller for the slingshot calendar eventList.get webscript. * This class is the controller for the slingshot calendar eventList.get webscript.
* *
* TODO Improve what we give to the FTL, and have the FTL include iso8601 dates too * TODO Improve what we give to the FTL
* *
* @author Nick Burch * @author Nick Burch
* @since 4.0 * @since 4.0

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.calendar;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.calendar.CalendarServiceImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.calendar.CalendarEntry;
import org.alfresco.service.cmr.calendar.CalendarEntryDTO;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.site.SiteInfo;
import org.json.JSONObject;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* This class is the controller for the slingshot calendar userevents.get webscript.
*
* @author Nick Burch
* @since 4.0
*/
public class UserCalendarEntriesGet extends AbstractCalendarWebScript
{
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req,
Status status, Cache cache)
{
Map<String, String> templateVars = req.getServiceMatch().getTemplateVars();
// Site is optional
SiteInfo site = null;
String siteName = templateVars.get("siteid");
if(siteName != null)
{
site = siteService.getSite(siteName);
}
return executeImpl(site, null, req, null, status, cache);
}
@Override
protected Map<String, Object> executeImpl(SiteInfo singleSite, String eventName,
WebScriptRequest req, JSONObject json, Status status, Cache cache) {
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); // Evil...
// Did they restrict by date?
Date fromDate = parseDate(req.getParameter("from"));
Date toDate = parseDate(req.getParameter("to"));
// One site, or all the user's ones?
List<SiteInfo> sites = new ArrayList<SiteInfo>();
if(singleSite != null)
{
// Just one
sites.add(singleSite);
}
else
{
// All their sites
sites = siteService.listSites(AuthenticationUtil.getRunAsUser());
}
// We need to know the Site Names, and the NodeRefs of the calendar containers
String[] siteShortNames = new String[sites.size()];
Map<NodeRef, SiteInfo> containerLookup = new HashMap<NodeRef, SiteInfo>();
for(int i=0; i<sites.size(); i++)
{
SiteInfo site = sites.get(i);
siteShortNames[i] = site.getShortName();
containerLookup.put(
siteService.getContainer(site.getShortName(), CalendarServiceImpl.CALENDAR_COMPONENT),
site
);
}
// Get the entries for the list
PagingRequest paging = buildPagingRequest(req);
PagingResults<CalendarEntry> entries =
calendarService.listCalendarEntries(siteShortNames, fromDate, toDate, paging);
List<Map<String, Object>> results = new ArrayList<Map<String,Object>>();
for(CalendarEntry entry : entries.getPage())
{
// Build the object
Map<String, Object> result = new HashMap<String, Object>();
result.put("name", entry.getSystemName());
result.put("title", entry.getTitle());
result.put("description", entry.getDescription());
result.put("where", entry.getLocation());
result.put("start", entry.getStart());
result.put("end", entry.getEnd());
result.put("duration", buildDuration(entry));
result.put("tags", entry.getTags());
result.put("isoutlook", entry.isOutlook());
result.put("allday", CalendarEntryDTO.isAllDay(entry));
// TODO Recurring
// Identify the site
SiteInfo site = containerLookup.get(entry.getContainerNodeRef());
result.put("site", site);
result.put("siteName", site.getShortName());
result.put("siteTitle", site.getTitle());
// Replace nulls with blank strings for the JSON
for(String key : result.keySet())
{
if(result.get(key) == null)
{
result.put(key, "");
}
}
results.add(result);
}
// All done
Map<String, Object> model = new HashMap<String, Object>();
model.put("events", results);
return model;
}
private static final long DURATION_SECOND = 1000;
private static final long DURATION_MINUTE = 60 * DURATION_SECOND;
private static final long DURATION_HOUR = 60 * DURATION_MINUTE;
private static final long DURATION_DAY = 24 * DURATION_HOUR;
private static final long DURATION_WEEK = 7 * DURATION_DAY;
/**
* Builds the duration in iCal format, eg PT2H15M
*/
private String buildDuration(CalendarEntry entry)
{
StringBuffer duration = new StringBuffer();
duration.append("P");
long timeDiff = entry.getEnd().getTime() - entry.getStart().getTime();
int weeks = (int)Math.floor(timeDiff / DURATION_WEEK);
if(weeks > 0)
{
duration.append(weeks);
duration.append("W");
timeDiff -= weeks * DURATION_WEEK;
}
int days = (int)Math.floor(timeDiff / DURATION_DAY);
if(days > 0)
{
duration.append(days);
duration.append("D");
timeDiff -= days * DURATION_DAY;
}
duration.append("T");
int hours = (int)Math.floor(timeDiff / DURATION_HOUR);
if(hours > 0)
{
duration.append(hours);
duration.append("H");
timeDiff -= hours * DURATION_HOUR;
}
int minutes = (int)Math.floor(timeDiff / DURATION_MINUTE);
if(minutes > 0)
{
duration.append(minutes);
duration.append("M");
timeDiff -= minutes * DURATION_MINUTE;
}
int seconds = (int)Math.floor(timeDiff / DURATION_SECOND);
if(seconds > 0)
{
duration.append(seconds);
timeDiff -= minutes * DURATION_MINUTE;
}
return duration.toString();
}
}