From 70669e3136a18e5d3090ecde38331cca6e144729 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Thu, 14 Jul 2011 14:28:31 +0000 Subject: [PATCH] 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 --- .../slingshot/calendar/userevents.get.js | 691 ------------------ .../calendar/userevents.get.json.ftl | 24 +- .../web-scripts-application-context.xml | 6 + .../calendar/CalendarEntriesListGet.java | 2 +- .../calendar/UserCalendarEntriesGet.java | 207 ++++++ 5 files changed, 231 insertions(+), 699 deletions(-) delete mode 100644 config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/userevents.get.js create mode 100644 source/java/org/alfresco/repo/web/scripts/calendar/UserCalendarEntriesGet.java diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/userevents.get.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/userevents.get.js deleted file mode 100644 index 847488951c..0000000000 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/userevents.get.js +++ /dev/null @@ -1,691 +0,0 @@ - -/** - * 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; -} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/userevents.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/userevents.get.json.ftl index 183602603d..dc8da96d47 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/userevents.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/userevents.get.json.ftl @@ -3,22 +3,32 @@ { <#if events?exists> "events": [ -<#list events?sort_by("when") as event> +<#list events as event> <#if event_index?string == limit?string><#break> { "name": "${event.name}", "title": "${event.title}", "where": "${event.where}", - "when": "${xmldate(event.when)}", "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")}", "end": "${event.end?string("HH:mm")}", - "endDate" : "${xmldate(event.end)}", + "site": "${event.site}", "siteTitle": "${event.siteTitle}", - "allday": "${event.allday}", - "tags": "${event.tags}", + "allday": "${event.allday?string}", + "tags": [<#list event.tags as tag>"${tag}"<#if tag_has_next>,], "duration": "${event.duration}", "isoutlook": "${event.isoutlook?string}" }<#if event_has_next>, @@ -26,4 +36,4 @@ ] } - \ No newline at end of file + diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index dc174452e7..2bdd993c7d 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -1518,4 +1518,10 @@ parent="abstractCalendarWebScript"> + + + + diff --git a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntriesListGet.java b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntriesListGet.java index 9705cf4ff0..856d2a00e6 100644 --- a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntriesListGet.java +++ b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntriesListGet.java @@ -40,7 +40,7 @@ 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, and have the FTL include iso8601 dates too + * TODO Improve what we give to the FTL * * @author Nick Burch * @since 4.0 diff --git a/source/java/org/alfresco/repo/web/scripts/calendar/UserCalendarEntriesGet.java b/source/java/org/alfresco/repo/web/scripts/calendar/UserCalendarEntriesGet.java new file mode 100644 index 0000000000..70ab493284 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/calendar/UserCalendarEntriesGet.java @@ -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 . + */ +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 executeImpl(WebScriptRequest req, + Status status, Cache cache) + { + Map 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 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 sites = new ArrayList(); + 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 containerLookup = new HashMap(); + for(int i=0; i entries = + calendarService.listCalendarEntries(siteShortNames, fromDate, toDate, paging); + + List> results = new ArrayList>(); + for(CalendarEntry entry : entries.getPage()) + { + // Build the object + Map result = new HashMap(); + 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 model = new HashMap(); + 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(); + } +}