From 9bdeee79863623bbfba4f565adb14d48ee0adaaf Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Thu, 7 Jul 2011 20:57:31 +0000 Subject: [PATCH] ALF-9156 Convert the last of the Calendar CRUD webscripts to Java (except for recurring parts) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28866 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../slingshot/calendar/event.post.html.ftl | 4 +- .../slingshot/calendar/event.put.json.ftl | 22 +- .../slingshot/calendar/event.put.json.js | 198 ----------------- .../web-scripts-application-context.xml | 6 + .../calendar/AbstractCalendarWebScript.java | 48 +++- .../scripts/calendar/CalendarEntryDelete.java | 2 +- .../scripts/calendar/CalendarEntryPost.java | 34 +-- .../scripts/calendar/CalendarEntryPut.java | 207 ++++++++++++++++++ .../scripts/calendar/CalendarRestApiTest.java | 2 +- 9 files changed, 284 insertions(+), 239 deletions(-) delete mode 100644 config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.put.json.js create mode 100644 source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryPut.java diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.post.html.ftl b/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.post.html.ftl index 89b34e47c2..5f49110aa9 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.post.html.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.post.html.ftl @@ -11,12 +11,12 @@ "where": "${result.where?html}", "startAt": { "iso8601": "${xmldate(result.from)}", - "legacyDate": "${result.from?string("M/d/yyyy")}", + "legacyDate": "${result.from?string("yyyy-MM-dd")}", "legacyTime": "${result.from?string("HH:mm")}", }, "endAt": { "iso8601": "${xmldate(result.to)}", - "legacyDate": "${result.to?string("M/d/yyyy")}", + "legacyDate": "${result.to?string("yyyy-MM-dd")}", "legacyTime": "${result.to?string("HH:mm")}", }, "allday": "${result.allday?string}", diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.put.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.put.json.ftl index cb022bf6fc..1a4806da1c 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.put.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.put.json.ftl @@ -7,8 +7,24 @@ "summary" : "${result.summary?js_string}", "location" : "${result.location?js_string}", "description" : "${result.description?js_string}", - "dtstart" : "${result.dtstart}", - "dtend" : "${result.dtend}", + + "startAt": { + "iso8601": "${xmldate(result.dtstart)}", + "legacyDateTime": "${result.dtstart?string("yyyy-MM-dd")}T${result.dtstart?string("HH:mm")}", + "legacyDate": "${result.dtstart?string("yyyy-MM-dd")}", + "legacyTime": "${result.dtstart?string("HH:mm")}", + }, + "endAt": { + "iso8601": "${xmldate(result.dtend)}", + "legacyDateTime": "${result.dtend?string("yyyy-MM-dd")}T${result.dtend?string("HH:mm")}", + "legacyDate": "${result.dtend?string("yyyy-MM-dd")}", + "legacyTime": "${result.dtend?string("HH:mm")}", + }, + + <#-- These are the old ones we'll get rid of soon --> + "dtstart" : "${result.dtstart?string("yyyy-MM-dd")}T${result.dtstart?string("HH:mm")}", + "dtend" : "${result.dtend?string("yyyy-MM-dd")}T${result.dtend?string("HH:mm")}", + "uri" : "${result.uri}", "allday" : "${result.allday?string}", "tags" : "${result.tags}", @@ -17,4 +33,4 @@ } - \ No newline at end of file + diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.put.json.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.put.json.js deleted file mode 100644 index 618079f4d8..0000000000 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/calendar/event.put.json.js +++ /dev/null @@ -1,198 +0,0 @@ - -/** - * Update event properties - * @method PUT - * @param uri {string} /calendar/event/{siteid}/{eventname} - */ -function getTemplateParams() -{ - // Grab the URI parameters - var siteid = "" + url.templateArgs.siteid; - var eventname = "" + url.templateArgs.eventname; - var date = args["date"]; - - - if (siteid === null || siteid.length === 0) - { - return null; - } - - if (eventname === null || eventname.length === 0) - { - return null; - } - - return { - "siteid": siteid, - "eventname": eventname, - "date": date - }; -} - -function main() -{ - var params = getTemplateParams(); - if (params === null) - { - return { - "error": "Invalid parameters" - }; - } - - // Get the site - var site = siteService.getSite(params.siteid); - if (site === null) - { - return { - "error": "Could find not specified site" - }; - } - - var eventsFolder = getCalendarContainer(site); - if (eventsFolder === null) - { - return { - "error": "Could not find specified calendar" - }; - } - - var editedEvent = eventsFolder.childByNamePath(params.eventname); - var event = editedEvent; - - if (event === null) - { - return { - "error": "Could not find specified event to update" - }; - } - - if (editedEvent.properties["ia:recurrenceRule"] != null) - { - var prop = new Array(); - var fromParts = params.date.split("-"); - prop["ia:date"] = new Date(fromParts[0],fromParts[1] - 1,fromParts[2]); - editedEvent.createNode(null, "ia:ignoreEvent", prop, "ia:ignoreEventList"); - - var timestamp = new Date().getTime(); - var random = Math.round(Math.random() * 10000); - - event = eventsFolder.createNode(timestamp + "-" + random + ".ics", "ia:calendarEvent"); - event.properties["ia:isOutlook"] = true; - } - - if (json.get("docfolder")=='*NOT_CHANGE*') - { - if (editedEvent.properties["ia:docFolder"] != "") - event.properties["ia:docFolder"] = editedEvent.properties["ia:docFolder"]; - } - else - { - if (json.get("docfolder") != "") - event.properties["ia:docFolder"] = json.get("docfolder"); - } - - var props = [ - "what", - "desc", - "where" - ]; - - var propsmap = - { - "what" : "ia:whatEvent", - "desc" : "ia:descriptionEvent", - "where" : "ia:whereEvent" - }; - - for (var i=0; i < props.length; i++) - { - var prop = props[i], value; - if (!json.isNull(prop)) - { - value = json.get(prop); - event.properties[ propsmap[prop] ] = value; - } - } - - if (!json.isNull("tags")) - { - var tags = String(json.get("tags")); // space delimited string - if (tags !== "") - { - var tagsArray = tags.split(" "); - event.tags = tagsArray; - } - else - { - event.tags = []; // reset - } - } - - try - { - // Handle date formatting as a separate case - var from = json.get("from"); - var to = json.get("to"); - - if (json.isNull("allday")) - { - from += " " + json.get("start"); - to += " " + json.get("end"); - allday = '' - } - from = new Date(from); - to = new Date(to); - event.properties["ia:fromDate"] = from; - event.properties["ia:toDate"] = to; - - - var pad = function (value, length) - { - value = String(value); - length = parseInt(length) || 2; - while (value.length < length) - { - value = "0" + value; - } - return value; - }; - - var fromIsoDate = from.getFullYear() + "-" + pad(from.getMonth() + 1) + "-" + pad(from.getDate()); - var toIsoDate = to.getFullYear() + "-" + pad(to.getMonth() + 1) + "-" + pad(to.getDate()); - - var data = - { - title: json.get("what"), - page: json.get("page") + "?date=" + fromIsoDate - } - activities.postActivity("org.alfresco.calendar.event-updated", params.siteid, "calendar", jsonUtils.toJSONString(data)); - } - catch(e) - { - if (logger.isLoggingEnabled()) - { - logger.log(e); - } - } - // Saved data - // {"site":"testSite","page":"calendar","from":"Tuesday, 4 November 2008","to":"Tuesday, 4 November 2008" - // ,"what":"big lunchie","where":"somewhere","desc":"","fromdate":"Tuesday, 4 November 2008","start":"12 - // :00","todate":"Tuesday, 4 November 2008","end":"13:00","tags":""} - event.save(); - var savedData = - { - summary: json.get('what'), - location: json.get('where'), - description: json.get('desc'), - dtstart: fromIsoDate+ 'T' + json.get('start'), - dtend: toIsoDate + 'T' + json.get('end'), - allday: (json.isNull("allday")) ? "" : (json.get('allday') == 'on') ? true : "", - uri: "calendar/event/" + params.siteid + "/" + event.name + "?date=" + params.date, - tags: tags, - docfolder: event.properties["ia:docFolder"] == null ? "" : event.properties["ia:docFolder"] - } - - return savedData; -} - -model.result = main(); diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index c9a3759587..27e0625f1a 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -1466,6 +1466,12 @@ parent="abstractCalendarWebScript"> + + + + props = new HashMap(); - Date date = extractDate(req.getParameter("date")); + Date date = parseDate(req.getParameter("date")); props.put(CalendarModel.PROP_IGNORE_EVENT_DATE, date); // Create a child node of the event diff --git a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryPost.java b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryPost.java index c20cbc52a9..a716a22774 100644 --- a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryPost.java +++ b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryPost.java @@ -61,30 +61,7 @@ public class CalendarEntryPost extends AbstractCalendarWebScript entry.setSharePointDocFolder(getOrNull(json, "docfolder")); // Handle the dates - if(json.has("startAt") && json.has("endAt")) - { - // New style ISO8601 dates - entry.setStart(extractDate(json.getString("startAt"))); - entry.setEnd(extractDate(json.getString("endAt"))); - if(json.has("allday")) - { - // TODO Handle All Day events properly, including timezones - isAllDay = true; - } - } - else if(json.has("allday")) - { - // Old style all-day event - entry.setStart(extractDate(getOrNull(json, "from"))); - entry.setEnd(extractDate(getOrNull(json, "to"))); - isAllDay = true; - } - else - { - // Old style regular event - entry.setStart(extractDate(json.getString("from") + " " + json.getString("start"))); - entry.setEnd(extractDate(json.getString("to") + " " + json.getString("end"))); - } + isAllDay = extractDates(entry, json); // Handle tags if(json.has("tags")) @@ -162,13 +139,4 @@ public class CalendarEntryPost extends AbstractCalendarWebScript model.put("result", result); return model; } - - private String getOrNull(JSONObject json, String key) throws JSONException - { - if(json.has(key)) - { - return json.getString(key); - } - return null; - } } diff --git a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryPut.java b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryPut.java new file mode 100644 index 0000000000..044bb773a5 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryPut.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.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + +import org.alfresco.service.cmr.calendar.CalendarEntry; +import org.alfresco.service.cmr.site.SiteInfo; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONException; +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 event.put webscript. + * + * @author Nick Burch + * @since 4.0 + */ +public class CalendarEntryPut extends AbstractCalendarWebScript +{ + private static Log logger = LogFactory.getLog(CalendarEntryPut.class); + + @Override + protected Map executeImpl(SiteInfo site, String eventName, + WebScriptRequest req, JSONObject json, Status status, Cache cache) { + CalendarEntry entry = calendarService.getCalendarEntry( + site.getShortName(), eventName + ); + + if(entry == null) + { + return buildError("Could not find event: " + eventName); + } + + // TODO Handle All Day events properly, including timezones + boolean isAllDay = false; + + try + { + // Doc folder is a bit special + String docFolder = json.getString("docfolder"); + + if(entry.getRecurrenceRule() != null) + { + // TODO Handle editing recurring rules + // Needs stuff with ignored events +/* + var prop = new Array(); + var fromParts = params.date.split("-"); + prop["ia:date"] = new Date(fromParts[0],fromParts[1] - 1,fromParts[2]); + editedEvent.createNode(null, "ia:ignoreEvent", prop, "ia:ignoreEventList"); + + var timestamp = new Date().getTime(); + var random = Math.round(Math.random() * 10000); + + event = eventsFolder.createNode(timestamp + "-" + random + ".ics", "ia:calendarEvent"); + event.properties["ia:isOutlook"] = true; + + */ + + // TODO Special doc folder stuff + if("*NOT_CHANGE*".equals(docFolder)) + { + // TODO + } + } + + // Doc folder is a bit special + if("*NOT_CHANGE*".equals(docFolder)) + { + // Nothing to change + } + else + { + entry.setSharePointDocFolder(docFolder); + } + + + // Grab the properties + entry.setTitle(getOrNull(json, "what")); + entry.setDescription(getOrNull(json, "desc")); + entry.setLocation(getOrNull(json, "where")); + + // Handle the dates + isAllDay = extractDates(entry, json); + + // Handle tags + if(json.has("tags")) + { + entry.getTags().clear(); + + StringTokenizer st = new StringTokenizer(json.getString("tags"), " "); + while(st.hasMoreTokens()) + { + entry.getTags().add(st.nextToken()); + } + } + } + catch(JSONException je) + { + return buildError("Invalid JSON: " + je.getMessage()); + } + + if(entry == null) + { + return buildError("Could not find event: " + eventName); + } + + + // Have it edited + entry = calendarService.updateCalendarEntry(entry); + + + // Generate the activity feed for this + SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); + String dateOpt = "?date=" + fmt.format(entry.getStart()); + try + { + JSONObject activity = new JSONObject(); + activity.put("title", entry.getTitle()); + activity.put("page", req.getParameter("page") + dateOpt); + + activityService.postActivity( + "org.alfresco.calendar.event-updated", + site.getShortName(), + CALENDAR_SERVICE_ACTIVITY_APP_NAME, + activity.toString() + ); + } + catch(Exception e) + { + // Warn, but carry on + logger.warn("Error adding event deletion to activities feed", e); + } + + + // Build the return object + Map result = new HashMap(); + result.put("summary", entry.getTitle()); + result.put("description", entry.getDescription()); + result.put("location", entry.getLocation()); + result.put("dtstart", entry.getStart()); + result.put("dtend", entry.getEnd()); + result.put("uri", "calendar/event/" + site.getShortName() + "/" + + entry.getSystemName() + dateOpt); + + result.put("tags", generateTagString(entry)); + result.put("allday", isAllDay); + result.put("docfolder", entry.getSharePointDocFolder()); + + // Replace nulls with blank strings for the JSON + for(String key : result.keySet()) + { + if(result.get(key) == null) + { + result.put(key, ""); + } + } + + // All done + Map model = new HashMap(); + model.put("result", result); + return model; + } + + /** + * We use lists for tags internally, and the other webscripts + * return arrays too. This one is different, and it needs to + * a single space separated string. This does the conversion + */ + protected String generateTagString(CalendarEntry entry) + { + StringBuffer sb = new StringBuffer(); + if(entry.getTags() != null) + { + for(String tag : entry.getTags()) + { + if(sb.length() > 0) sb.append(' '); + sb.append(tag); + } + } + return sb.toString(); + } +} diff --git a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarRestApiTest.java index 12a0c27681..a980995dd5 100644 --- a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarRestApiTest.java +++ b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarRestApiTest.java @@ -379,7 +379,7 @@ public class CalendarRestApiTest extends BaseWebScriptTest // No from/to/start/end, does dtstart and dtend instead assertEquals("2011-06-28T11:30", entry.getString("dtstart")); assertEquals("2011-06-28T13:30", entry.getString("dtend")); - assertEquals("", entry.getString("allday")); + assertEquals("false", entry.getString("allday")); // No isoutlook on create/edit