Java tutorial
/* * #%L * Alfresco Remote API * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * * 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/>. * #L% */ package org.alfresco.repo.web.scripts.calendar; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import java.util.TimeZone; import org.alfresco.repo.calendar.CalendarModel; import org.alfresco.service.cmr.calendar.CalendarEntry; import org.alfresco.service.cmr.calendar.CalendarEntryDTO; import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.site.SiteInfo; import org.alfresco.service.namespace.QName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.simple.JSONObject; import org.springframework.extensions.surf.util.I18NUtil; 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.get webscript. * * @author Nick Burch * @since 4.0 */ public class CalendarEntryGet extends AbstractCalendarWebScript { private static Log logger = LogFactory.getLog(CalendarEntryGet.class); private PermissionService permissionService; @Override protected Map<String, Object> executeImpl(SiteInfo site, String eventName, WebScriptRequest req, JSONObject json, Status status, Cache cache) { final ResourceBundle rb = getResources(); CalendarEntry entry = calendarService.getCalendarEntry(site.getShortName(), eventName); if (entry == null) { String message = rb.getString(MSG_EVENT_NOT_FOUND); return buildError(MessageFormat.format(message, eventName)); } Date date = parseDate(req.getParameter("date")); if (date != null) { // if some instances were updated SimpleDateFormat fdt = new SimpleDateFormat("yyyyMMdd"); Set<QName> childNodeTypeQNames = new HashSet<QName>(); childNodeTypeQNames.add(CalendarModel.TYPE_UPDATED_EVENT); List<ChildAssociationRef> updatedEventList = nodeService.getChildAssocs(entry.getNodeRef(), childNodeTypeQNames); for (ChildAssociationRef updatedEvent : updatedEventList) { NodeRef nodeRef = updatedEvent.getChildRef(); Date updatedDate = (Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_EVENT_DATE); if (fdt.format(updatedDate).equals(fdt.format(date))) { entry.setStart((Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_START)); entry.setEnd((Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_END)); entry.setTitle((String) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_WHAT)); entry.setLocation((String) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_WHERE)); break; } } } // Build the object Map<String, Object> result = new HashMap<String, Object>(); result.put("name", entry.getSystemName()); result.put("what", entry.getTitle()); result.put("description", entry.getDescription()); result.put("location", entry.getLocation()); boolean isAllDay = CalendarEntryDTO.isAllDay(entry); boolean removeTimezone = isAllDay && !entry.isOutlook(); result.put("from", removeTimeZoneIfRequired(entry.getStart(), isAllDay, removeTimezone)); result.put("to", removeTimeZoneIfRequired(entry.getEnd(), isAllDay, removeTimezone)); String legacyDateFormat = "M/d/yyyy"; String legacyTimeFormat = "HH:mm"; result.put("legacyDateFrom", removeTimeZoneIfRequired(entry.getStart(), isAllDay, removeTimezone, legacyDateFormat)); result.put("legacyTimeFrom", removeTimeZoneIfRequired(entry.getStart(), isAllDay, removeTimezone, legacyTimeFormat)); result.put("legacyDateTo", removeTimeZoneIfRequired(entry.getEnd(), isAllDay, removeTimezone, legacyDateFormat)); result.put("legacyTimeTo", removeTimeZoneIfRequired(entry.getEnd(), isAllDay, removeTimezone, legacyTimeFormat)); result.put("tags", entry.getTags()); result.put("isoutlook", entry.isOutlook()); result.put("outlookuid", entry.getOutlookUID()); result.put("allday", isAllDay); result.put("docfolder", entry.getSharePointDocFolder()); result.put("recurrence", buildRecurrenceString(entry)); // Replace nulls with blank strings for the JSON for (String key : result.keySet()) { if (result.get(key) == null) { result.put(key, ""); } } // Check the permissions the user has on the entry AccessStatus canEdit = permissionService.hasPermission(entry.getNodeRef(), PermissionService.WRITE); AccessStatus canDelete = permissionService.hasPermission(entry.getNodeRef(), PermissionService.DELETE); result.put("canEdit", (canEdit == AccessStatus.ALLOWED)); result.put("canDelete", (canDelete == AccessStatus.ALLOWED)); // All done Map<String, Object> model = new HashMap<String, Object>(); model.put("result", result); return model; } /** * This method replicates the pre-existing behaviour for recurring events. * Rather than try to render the text for them on the client, we instead * statically render the description text here on the server. * When we properly support recurring events in the client (and not just * for SharePoint ones), this can be replaced. */ protected String buildRecurrenceString(CalendarEntry event) { // If there's no recurrence rules, then there's nothing to do String recurrence = event.getRecurrenceRule(); if (recurrence == null || recurrence.trim().length() == 0) { return null; } // Get our days of the week, in the current locale, for each outlook two letter code Map<String, String> days = CalendarRecurrenceHelper.buildLocalRecurrenceDaysOfTheWeek(I18NUtil.getLocale()); // Get our weeks names, in the current locale Map<Integer, String> weeks = CalendarRecurrenceHelper.buildLocalRecurrenceWeekNames(I18NUtil.getLocale()); // Turn the string into a useful map Map<String, String> params = CalendarRecurrenceHelper.extractRecurrenceRule(event); // To hold our result StringBuffer text = new StringBuffer(); // Handle the different frequencies if (params.containsKey("FREQ")) { String freq = params.get("FREQ"); String interval = params.get("INTERVAL"); if (interval == null) { interval = "1"; } if ("WEEKLY".equals(freq)) { if ("1".equals(interval)) { text.append("Occurs each week on "); } else { text.append("Occurs every " + interval + " weeks on "); } for (String day : params.get("BYDAY").split(",")) { text.append(days.get(day)); text.append(", "); } } else if ("DAILY".equals(freq)) { if ("1".equals(interval)) { text.append("Occurs every day "); } else { text.append("Occurs every " + interval + " days "); } } else if ("MONTHLY".equals(freq)) { if (params.get("BYMONTHDAY") != null) { text.append("Occurs day " + params.get("BYMONTHDAY")); } else if (params.get("BYSETPOS") != null) { text.append("Occurs the "); text.append(weeks.get((Integer.parseInt(params.get("BYSETPOS")))) + " "); buildParams(params, text, days); } text.append(" of every " + interval + " month(s) "); } else if ("YEARLY".equals(freq)) { if (params.get("BYMONTHDAY") != null) { text.append("Occurs every " + params.get("BYMONTHDAY")); text.append("." + params.get("BYMONTH") + " "); } else { text.append("Occurs the "); text.append(weeks.get((Integer.parseInt(params.get("BYSETPOS")))) + " "); buildParams(params, text, days); text.append(" of " + params.get("BYMONTH") + " month "); } } else { logger.warn("Unsupported recurrence frequency " + freq); } } // And the rest DateFormat dFormat = SimpleDateFormat.getDateInstance(SimpleDateFormat.MEDIUM, I18NUtil.getLocale()); DateFormat tFormat = SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT, I18NUtil.getLocale()); text.append("effective " + dFormat.format(event.getStart())); if (params.containsKey("COUNT")) { // Nothing to do, is already handled in the recurrence date } if (event.getLastRecurrence() != null) { text.append(" until " + dFormat.format(event.getLastRecurrence())); } text.append(" from " + tFormat.format(event.getStart())); text.append(" to " + tFormat.format(event.getEnd())); // Add timezone in which recurrence rule was parsed TimeZone timeZone = TimeZone.getDefault(); boolean daylight = timeZone.inDaylightTime(new Date()); String tzDisplayName = timeZone.getDisplayName(daylight, TimeZone.SHORT); text.append(" (" + tzDisplayName + ")"); // All done return text.toString(); } private static StringBuffer buildParams(Map<String, String> params, StringBuffer text, Map<String, String> days) { int day = params.get("BYDAY").split(",").length; if (day == 7) { text.append(CalendarRecurrenceHelper.DAY); } if (day == 5) { text.append(CalendarRecurrenceHelper.WEEKDAYS); } if (day == 2) { text.append(CalendarRecurrenceHelper.WEEKENDS); } if (day != 7 && day != 5 && day != 2) { text.append(days.get(params.get("BYDAY"))); } return text; } public void setPermissionService(PermissionService permissionService) { this.permissionService = permissionService; } }