From bddfb2510949bb573d5837ff6fdf619b4f9bfedb Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 30 Nov 2011 18:23:17 +0000 Subject: [PATCH] Start on the refactoring changes for ALF-11687, to support the repeating=all flag on the dashlet event listing too git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@32421 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../AbstractCalendarListingWebScript.java | 178 ++++++++++++++++++ .../calendar/CalendarEntriesListGet.java | 1 + .../calendar/UserCalendarEntriesGet.java | 134 +------------ 3 files changed, 181 insertions(+), 132 deletions(-) create mode 100644 source/java/org/alfresco/repo/web/scripts/calendar/AbstractCalendarListingWebScript.java diff --git a/source/java/org/alfresco/repo/web/scripts/calendar/AbstractCalendarListingWebScript.java b/source/java/org/alfresco/repo/web/scripts/calendar/AbstractCalendarListingWebScript.java new file mode 100644 index 0000000000..24f089cc7d --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/calendar/AbstractCalendarListingWebScript.java @@ -0,0 +1,178 @@ +/* + * 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.util.ArrayList; +import java.util.Calendar; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.service.cmr.calendar.CalendarEntry; +import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper; + +/** + * This class provides functionality common across the webscripts + * which list events. + * + * @author Nick Burch + * @since 4.0 + */ +public abstract class AbstractCalendarListingWebScript extends AbstractCalendarWebScript +{ + protected static final String RESULT_NAME = "name"; + protected static final String RESULT_TITLE = "title"; + protected static final String RESULT_START = "start"; + protected static final String RESULT_END = "end"; + + /** + * Returns a Comparator for (re-)sorting events, typically used after + * expanding out recurring instances. + */ + protected static Comparator> getEventDetailsSorter() + { + return new Comparator>() + { + public int compare(Map resultA, + Map resultB) + { + Date startA = (Date)resultA.get(RESULT_START); + Date startB = (Date)resultB.get(RESULT_START); + + int cmp = startA.compareTo(startB); + if (cmp == 0) + { + Date endA = (Date)resultA.get(RESULT_END); + Date endB = (Date)resultB.get(RESULT_END); + cmp = endA.compareTo(endB); + if (cmp == 0) + { + String nameA = (String)resultA.get(RESULT_NAME); + String nameB = (String)resultB.get(RESULT_NAME); + return nameA.compareTo(nameB); + } + return cmp; + } + return cmp; + } + }; + } + + /** + * Do what's needed for recurring events. + * + * @return If dates have been tweaked, and a sort may be required + */ + protected boolean handleRecurring(CalendarEntry entry, Map entryResult, + List> allResults, Date from, Date until, boolean repeatingFirstOnly) + { + if (entry.getRecurrenceRule() == null) + { + // Nothing to do + return false; + } + + // If no date is given, start looking for occurrences from the event itself + if (from == null) + { + from = entry.getStart(); + } + + // Do we need to limit ourselves? + // Should we limit ourselves? + if (!repeatingFirstOnly) + { + if (until == null) + { + // If no end date was given, only allow repeating instances + // for next 60 days, to keep the list sane + // (It's normally only used for a month view anyway) + Calendar c = Calendar.getInstance(); + c.setTime(from); + c.add(Calendar.DATE, 60); + until = c.getTime(); + } + } + + // How long is it? + long duration = entry.getEnd().getTime() - entry.getStart().getTime(); + + // Get it's recurring instances + List dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter( + entry, from, until, repeatingFirstOnly); + if (dates == null) + { + dates = new ArrayList(); + } + + // Add on the original event time itself if needed + if (entry.getStart().getTime() >= from.getTime()) + { + if (dates.size() == 0 || dates.get(0).getTime() != entry.getStart().getTime()) + { + // Original event is after the start time, and not on the recurring list + dates.add(0, entry.getStart()); + } + } + + // If we got no dates, then no recurrences in the period so zap + if (dates.size() == 0) + { + allResults.remove(entryResult); + return false; // Remains sorted despite delete + } + + // 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 true; // Date has been changed + } + + // Otherwise generate one entry per extra date + for (int i=1; i newResult = new HashMap(entryResult); + + // Generate start and end based on this date + updateRepeatingStartEnd(dates.get(i), duration, newResult); + + // Save as a new event + allResults.add(newResult); + } + + // TODO Skip ignored instances + + // New dates have been added + return true; + } + + private void updateRepeatingStartEnd(Date newStart, long duration, Map result) + { + Date newEnd = new Date(newStart.getTime() + duration); + result.put(RESULT_START, newStart); + result.put(RESULT_END, newEnd); + } +} 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 ce78612562..6c1c2a1ee3 100644 --- a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntriesListGet.java +++ b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntriesListGet.java @@ -41,6 +41,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 + * TODO Switch to using {@link AbstractCalendarListingWebScript} * * @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 index 6a7892b09c..03d75f79ed 100644 --- a/source/java/org/alfresco/repo/web/scripts/calendar/UserCalendarEntriesGet.java +++ b/source/java/org/alfresco/repo/web/scripts/calendar/UserCalendarEntriesGet.java @@ -19,9 +19,7 @@ package org.alfresco.repo.web.scripts.calendar; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collections; -import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -34,7 +32,6 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.AccessDeniedException; 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.NodeRef; import org.alfresco.service.cmr.site.SiteInfo; import org.json.simple.JSONObject; @@ -48,13 +45,8 @@ import org.springframework.extensions.webscripts.WebScriptRequest; * @author Nick Burch * @since 4.0 */ -public class UserCalendarEntriesGet extends AbstractCalendarWebScript +public class UserCalendarEntriesGet extends AbstractCalendarListingWebScript { - 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 protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) @@ -206,31 +198,7 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript // If the recurring events meant dates changed, re-sort if (resortNeeded) { - Collections.sort(results, new Comparator>() - { - public int compare(Map resultA, - Map resultB) - { - Date startA = (Date)resultA.get(RESULT_START); - Date startB = (Date)resultB.get(RESULT_START); - - int cmp = startA.compareTo(startB); - if (cmp == 0) - { - Date endA = (Date)resultA.get(RESULT_END); - Date endB = (Date)resultB.get(RESULT_END); - cmp = endA.compareTo(endB); - if (cmp == 0) - { - String nameA = (String)resultA.get(RESULT_NAME); - String nameB = (String)resultB.get(RESULT_NAME); - return nameA.compareTo(nameB); - } - return cmp; - } - return cmp; - } - }); + Collections.sort(results, getEventDetailsSorter()); } // All done @@ -298,102 +266,4 @@ public class UserCalendarEntriesGet extends AbstractCalendarWebScript return duration.toString(); } - - /** - * Do what's needed for recurring events. - * - * @return If dates have been tweaked, and a sort may be required - */ - private boolean handleRecurring(CalendarEntry entry, Map entryResult, - List> allResults, Date from, Date until, boolean repeatingFirstOnly) - { - if (entry.getRecurrenceRule() == null) - { - // Nothing to do - return false; - } - - // If no date is given, start looking for occurrences from the event itself - if (from == null) - { - from = entry.getStart(); - } - - // Do we nee dto limit ourselves? - // Should we limit ourselves? - if (!repeatingFirstOnly) - { - if (until == null) - { - // If no end date was given, only allow repeating instances - // for next 60 days, to keep the list sane - // (It's normally only used for a month view anyway) - Calendar c = Calendar.getInstance(); - c.setTime(from); - c.add(Calendar.DATE, 60); - until = c.getTime(); - } - } - - // How long is it? - long duration = entry.getEnd().getTime() - entry.getStart().getTime(); - - // Get it's recurring instances - List dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter( - entry, from, until, repeatingFirstOnly); - if (dates == null) - { - dates = new ArrayList(); - } - - // Add on the original event time itself if needed - if (entry.getStart().getTime() >= from.getTime()) - { - if (dates.size() == 0 || dates.get(0).getTime() != entry.getStart().getTime()) - { - // Original event is after the start time, and not on the recurring list - dates.add(0, entry.getStart()); - } - } - - // If we got no dates, then no recurrences in the period so zap - if (dates.size() == 0) - { - allResults.remove(entryResult); - return false; // Remains sorted despite delete - } - - // 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 true; // Date has been changed - } - - // Otherwise generate one entry per extra date - for (int i=1; i newResult = new HashMap(entryResult); - - // Generate start and end based on this date - updateRepeatingStartEnd(dates.get(i), duration, newResult); - - // Save as a new event - allResults.add(newResult); - } - - // New dates have been added - return true; - } - - private void updateRepeatingStartEnd(Date newStart, long duration, Map result) - { - Date newEnd = new Date(newStart.getTime() + duration); - result.put(RESULT_START, newStart); - result.put(RESULT_END, newEnd); - } }