diff --git a/source/java/org/alfresco/repo/calendar/CalendarHelpersTest.java b/source/java/org/alfresco/repo/calendar/CalendarHelpersTest.java new file mode 100644 index 0000000000..28488ddc45 --- /dev/null +++ b/source/java/org/alfresco/repo/calendar/CalendarHelpersTest.java @@ -0,0 +1,234 @@ +/* + * 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.calendar; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.query.PagingRequest; +import org.alfresco.query.PagingResults; +import org.alfresco.repo.policy.BehaviourFilter; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.site.SiteModel; +import org.alfresco.repo.transaction.RetryingTransactionHelper; +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.calendar.CalendarService; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.MutableAuthenticationService; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.cmr.site.SiteInfo; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.cmr.site.SiteVisibility; +import org.alfresco.service.cmr.tagging.TaggingService; +import org.alfresco.util.ApplicationContextHelper; +import org.alfresco.util.PropertyMap; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.context.ApplicationContext; + +/** + * Test cases for the helpers relating to the {@link CalendarService}, + * but which don't need a full repo + * + * @author Nick Burch + * @since 4.0 + */ +public class CalendarHelpersTest +{ + private static SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); + + @Test public void allDayDetection() + { + Calendar c20110719_0000 = Calendar.getInstance(); + Calendar c20110719_1000 = Calendar.getInstance(); + Calendar c20110720_0000 = Calendar.getInstance(); + Calendar c20110721_0000 = Calendar.getInstance(); + c20110719_0000.set(2011, 07, 19, 0, 0, 0); + c20110719_1000.set(2011, 07, 19, 1, 0, 0); + c20110720_0000.set(2011, 07, 20, 0, 0, 0); + c20110721_0000.set(2011, 07, 21, 0, 0, 0); + + CalendarEntryDTO entry = new CalendarEntryDTO(); + + // Start and end at the same midnight + entry.setStart(c20110719_0000.getTime()); + entry.setEnd( c20110719_0000.getTime()); + assertTrue(CalendarEntryDTO.isAllDay(entry)); + + // Start and end at the next midnight + entry.setStart(c20110719_0000.getTime()); + entry.setEnd( c20110720_0000.getTime()); + assertTrue(CalendarEntryDTO.isAllDay(entry)); + + // Start and end at the midnight after + entry.setStart(c20110719_0000.getTime()); + entry.setEnd( c20110721_0000.getTime()); + assertTrue(CalendarEntryDTO.isAllDay(entry)); + + // One is midnight, one not + entry.setStart(c20110719_0000.getTime()); + entry.setEnd( c20110719_1000.getTime()); + assertFalse(CalendarEntryDTO.isAllDay(entry)); + + entry.setStart(c20110719_1000.getTime()); + entry.setEnd( c20110720_0000.getTime()); + assertFalse(CalendarEntryDTO.isAllDay(entry)); + + // Neither midnight + entry.setStart(c20110719_1000.getTime()); + entry.setEnd( c20110719_1000.getTime()); + assertFalse(CalendarEntryDTO.isAllDay(entry)); + } + + @Test public void dailyRecurrenceDates() + { + List dates = new ArrayList(); + + Calendar currentDate = Calendar.getInstance(); + + + // Dates in the past, get nothing + dates.clear(); + currentDate.set(2011,7-1,19,10,30); + RecurrenceHelper.buildDailyRecurrences( + currentDate, dates, null, + date(2011,7,10), date(2011,7,15), + true, 1 + ); + assertEquals(0, dates.size()); + + dates.clear(); + currentDate.set(2011,7-1,19,10,30); + RecurrenceHelper.buildDailyRecurrences( + currentDate, dates, null, + date(2011,7,10), date(2011,7,15), + false, 1 + ); + assertEquals(0, dates.size()); + + + // From today + dates.clear(); + currentDate.set(2011,7-1,19,10,30); + RecurrenceHelper.buildDailyRecurrences( + currentDate, dates, null, + date(2011,7,19), date(2011,7,25), + true, 1 + ); + assertEquals(1, dates.size()); + assertEquals("2011-07-19", dateFmt.format(dates.get(0))); + + dates.clear(); + currentDate.set(2011,7-1,19,10,30); + RecurrenceHelper.buildDailyRecurrences( + currentDate, dates, null, + date(2011,7,19), date(2011,7,25), + false, 1 + ); + assertEquals(6, dates.size()); + assertEquals("2011-07-19", dateFmt.format(dates.get(0))); + assertEquals("2011-07-24", dateFmt.format(dates.get(5))); + + + // Dates in the future, goes from then + dates.clear(); + currentDate.set(2011,7-1,19,10,30); + RecurrenceHelper.buildDailyRecurrences( + currentDate, dates, null, + date(2011,7,20), date(2011,7,30), + true, 1 + ); + assertEquals(1, dates.size()); + assertEquals("2011-07-20", dateFmt.format(dates.get(0))); + + dates.clear(); + currentDate.set(2011,7-1,19,10,30); + RecurrenceHelper.buildDailyRecurrences( + currentDate, dates, null, + date(2011,7,20), date(2011,7,30), + false, 1 + ); + assertEquals(10, dates.size()); + assertEquals("2011-07-20", dateFmt.format(dates.get(0))); + assertEquals("2011-07-29", dateFmt.format(dates.get(9))); + + + // With no end date but only first, check it behaves + dates.clear(); + currentDate.set(2011,7-1,19,10,30); + RecurrenceHelper.buildDailyRecurrences( + currentDate, dates, null, + date(2011,7,19), null, + true, 1 + ); + assertEquals(1, dates.size()); + assertEquals("2011-07-19", dateFmt.format(dates.get(0))); + + dates.clear(); + currentDate.set(2011,7-1,19,10,30); + RecurrenceHelper.buildDailyRecurrences( + currentDate, dates, null, + date(2011,7,20), null, + true, 1 + ); + assertEquals(1, dates.size()); + assertEquals("2011-07-20", dateFmt.format(dates.get(0))); + } + + private static Date date(int year, int month, int day) + { + return date(year, month, day, 0, 0); + } + private static Date date(int year, int month, int day, int hour, int minute) + { + Calendar c = Calendar.getInstance(); + c.set(year, month-1, day, hour, minute, 0); + c.set(Calendar.MILLISECOND, 0); + return c.getTime(); + } + + private static class RecurrenceHelper extends CalendarRecurrenceHelper + { + protected static void buildDailyRecurrences(Calendar currentDate, List dates, + Map params, Date onOrAfter, Date until, boolean firstOnly, int interval) + { + CalendarRecurrenceHelper.buildDailyRecurrences( + currentDate, dates, params, onOrAfter, until, firstOnly, interval); + } + } +} diff --git a/source/java/org/alfresco/service/cmr/calendar/CalendarRecurrenceHelper.java b/source/java/org/alfresco/service/cmr/calendar/CalendarRecurrenceHelper.java index 538dfb39f1..8caf9d7949 100644 --- a/source/java/org/alfresco/service/cmr/calendar/CalendarRecurrenceHelper.java +++ b/source/java/org/alfresco/service/cmr/calendar/CalendarRecurrenceHelper.java @@ -188,236 +188,22 @@ public class CalendarRecurrenceHelper Calendar currentDate = Calendar.getInstance(); currentDate.setTime(entry.getStart()); - if ("WEEKLY".equals(freq)) - { - // Get a sorted list of the days it applies to - List daysOfWeek = new ArrayList(); - for(String dayS : params.get("BYDAY").split(",")) - { - Integer day = DAY_NAMES_TO_CALENDAR_DAYS.get(dayS); - if(day == null) - { - logger.warn("Invalid day " + dayS); - } - else - { - daysOfWeek.add(day); - } - } - Collections.sort(daysOfWeek); - - // Wind forward - boolean valid = false; - while(true) - { - // Check each day - for(int day : daysOfWeek) - { - currentDate.set(Calendar.DAY_OF_WEEK, day); - if(!valid) - { - if(currentDate.before(onOrAfter)) - { - // To early - } - else - { - // Now in the right range - valid = true; - } - } - if(valid) - { - if(until != null) - { - if(currentDate.after(until)) - { - // Too late - break; - } - } - dates.add(currentDate.getTime()); - if(firstOnly) - { - break; - } - } - } - - // Wind on to the next week - currentDate.set(Calendar.DAY_OF_WEEK, daysOfWeek.get(0)); - currentDate.add(Calendar.DATE, interval*7); - } - } - else if ("DAILY".equals(freq)) + if ("DAILY".equals(freq)) { - // Nice and easy - while(currentDate.before(onOrAfter)) - { - currentDate.add(Calendar.DATE, 1); - } - - if(firstOnly) - { - // Save the first date, if valid - if(until != null) - { - if(currentDate.before(until)) - { - dates.add(currentDate.getTime()); - } - } - else - { - dates.add(currentDate.getTime()); - } - } - else - { - // Run until the end - while(currentDate.before(until)) - { - dates.add(currentDate.getTime()); - currentDate.add(Calendar.DATE, 1); - } - } + buildDailyRecurrences(currentDate, dates, params, onOrAfter, until, firstOnly, interval); + } + else if ("WEEKLY".equals(freq)) + { + buildWeeklyRecurrences(currentDate, dates, params, onOrAfter, until, firstOnly, interval); } - else if ("MONTHLY".equals(freq)) { - if (params.get("BYMONTHDAY") != null) - { - // eg the 15th of each month - int dayOfMonth = Integer.parseInt(params.get("BYMONTHDAY")); - if(currentDate.get(Calendar.DAY_OF_MONTH) < dayOfMonth) - { - // Move forward to start - addMonthToDayOfMonth(currentDate, dayOfMonth); - } - - // Go until in the ok range - while(currentDate.before(onOrAfter)) - { - addMonthToDayOfMonth(currentDate, dayOfMonth); - } - while(true) - { - if(until != null) - { - if(currentDate.after(until)) - { - break; - } - } - - dates.add(currentDate.getTime()); - if(firstOnly) - { - break; - } - - addMonthToDayOfMonth(currentDate, dayOfMonth); - } - } - else if (params.get("BYSETPOS") != null) - { - // eg the first Thursday of the month - int dayOfWeek = DAY_NAMES_TO_CALENDAR_DAYS.get(params.get("BYSETPOS")); - if(currentDate.get(Calendar.DAY_OF_MONTH) > 8) - { - // Move to start, in next month - addMonthToFirstDayOfWeek(currentDate, dayOfWeek); - } - else if(currentDate.get(Calendar.DAY_OF_WEEK) != dayOfWeek) - { - // Move forward to start - Date t = currentDate.getTime(); - currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek); - if(currentDate.before(t)) - { - currentDate.add(Calendar.DATE, 7); - } - } - - while(currentDate.before(onOrAfter)) - { - addMonthToFirstDayOfWeek(currentDate, dayOfWeek); - } - while(true) - { - if(until != null) - { - if(currentDate.after(until)) - { - break; - } - } - - dates.add(currentDate.getTime()); - if(firstOnly) - { - break; - } - - addMonthToFirstDayOfWeek(currentDate, dayOfWeek); - } - } + buildMonthlyRecurrences(currentDate, dates, params, onOrAfter, until, firstOnly, interval); } - else if ("YEARLY".equals(freq)) { - int month = Integer.parseInt(params.get("BYMONTH")); - - if (params.get("BYMONTHDAY") != null) - { - // eg the 2nd of March every year - int dayOfMonth = Integer.parseInt(params.get("BYMONTHDAY")); - if(currentDate.get(Calendar.MONTH) == month && - currentDate.get(Calendar.DAY_OF_MONTH) == dayOfMonth) - { - // Correct start time - } - else - { - currentDate.set(Calendar.YEAR, currentDate.get(Calendar.YEAR) + 1); - currentDate.set(Calendar.MONTH, month); - currentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); - } - - while(currentDate.before(onOrAfter)) - { - currentDate.set(Calendar.YEAR, currentDate.get(Calendar.YEAR) + 1); - currentDate.set(Calendar.MONTH, month); - currentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); - } - while(true) - { - if(until != null) - { - if(currentDate.after(until)) - { - break; - } - } - - dates.add(currentDate.getTime()); - if(firstOnly) - { - break; - } - - currentDate.set(Calendar.YEAR, currentDate.get(Calendar.YEAR) + 1); - currentDate.set(Calendar.MONTH, month); - currentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); - } - } - else - { - // eg the first Tuesday in February every year - int dayOfWeek = DAY_NAMES_TO_CALENDAR_DAYS.get(params.get("BYSETPOS")); - // TODO - } + buildYearlyRecurrences(currentDate, dates, params, onOrAfter, until, firstOnly, interval); } else { @@ -434,6 +220,243 @@ public class CalendarRecurrenceHelper } } + protected static void buildDailyRecurrences(Calendar currentDate, List dates, + Map params, Date onOrAfter, Date until, boolean firstOnly, int interval) + { + // Nice and easy + while(currentDate.getTime().before(onOrAfter)) + { + currentDate.add(Calendar.DATE, 1); + } + + if(firstOnly) + { + // Save the first date, if valid + if(until != null) + { + if(currentDate.getTime().before(until)) + { + dates.add(currentDate.getTime()); + } + } + else + { + dates.add(currentDate.getTime()); + } + } + else + { + // Run until the end + while(currentDate.getTime().before(until)) + { + dates.add(currentDate.getTime()); + currentDate.add(Calendar.DATE, 1); + } + } + } + + protected static void buildWeeklyRecurrences(Calendar currentDate, List dates, + Map params, Date onOrAfter, Date until, boolean firstOnly, int interval) + { + // Get a sorted list of the days it applies to + List daysOfWeek = new ArrayList(); + for(String dayS : params.get("BYDAY").split(",")) + { + Integer day = DAY_NAMES_TO_CALENDAR_DAYS.get(dayS); + if(day == null) + { + logger.warn("Invalid day " + dayS); + } + else + { + daysOfWeek.add(day); + } + } + Collections.sort(daysOfWeek); + + // Wind forward + boolean valid = false; + while(true) + { + // Check each day + for(int day : daysOfWeek) + { + currentDate.set(Calendar.DAY_OF_WEEK, day); + if(!valid) + { + if(currentDate.before(onOrAfter)) + { + // To early + } + else + { + // Now in the right range + valid = true; + } + } + if(valid) + { + if(until != null) + { + if(currentDate.after(until)) + { + // Too late + break; + } + } + dates.add(currentDate.getTime()); + if(firstOnly) + { + break; + } + } + } + + // Wind on to the next week + currentDate.set(Calendar.DAY_OF_WEEK, daysOfWeek.get(0)); + currentDate.add(Calendar.DATE, interval*7); + } + } + + protected static void buildMonthlyRecurrences(Calendar currentDate, List dates, + Map params, Date onOrAfter, Date until, boolean firstOnly, int interval) + { + if (params.get("BYMONTHDAY") != null) + { + // eg the 15th of each month + int dayOfMonth = Integer.parseInt(params.get("BYMONTHDAY")); + if(currentDate.get(Calendar.DAY_OF_MONTH) < dayOfMonth) + { + // Move forward to start + addMonthToDayOfMonth(currentDate, dayOfMonth); + } + + // Go until in the ok range + while(currentDate.before(onOrAfter)) + { + addMonthToDayOfMonth(currentDate, dayOfMonth); + } + while(true) + { + if(until != null) + { + if(currentDate.after(until)) + { + break; + } + } + + dates.add(currentDate.getTime()); + if(firstOnly) + { + break; + } + + addMonthToDayOfMonth(currentDate, dayOfMonth); + } + } + else if (params.get("BYSETPOS") != null) + { + // eg the first Thursday of the month + int dayOfWeek = DAY_NAMES_TO_CALENDAR_DAYS.get(params.get("BYSETPOS")); + if(currentDate.get(Calendar.DAY_OF_MONTH) > 8) + { + // Move to start, in next month + addMonthToFirstDayOfWeek(currentDate, dayOfWeek); + } + else if(currentDate.get(Calendar.DAY_OF_WEEK) != dayOfWeek) + { + // Move forward to start + Date t = currentDate.getTime(); + currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek); + if(currentDate.before(t)) + { + currentDate.add(Calendar.DATE, 7); + } + } + + while(currentDate.before(onOrAfter)) + { + addMonthToFirstDayOfWeek(currentDate, dayOfWeek); + } + while(true) + { + if(until != null) + { + if(currentDate.after(until)) + { + break; + } + } + + dates.add(currentDate.getTime()); + if(firstOnly) + { + break; + } + + addMonthToFirstDayOfWeek(currentDate, dayOfWeek); + } + } + } + + protected static void buildYearlyRecurrences(Calendar currentDate, List dates, + Map params, Date onOrAfter, Date until, boolean firstOnly, int interval) + { + int month = Integer.parseInt(params.get("BYMONTH")); + + if (params.get("BYMONTHDAY") != null) + { + // eg the 2nd of March every year + int dayOfMonth = Integer.parseInt(params.get("BYMONTHDAY")); + if(currentDate.get(Calendar.MONTH) == month && + currentDate.get(Calendar.DAY_OF_MONTH) == dayOfMonth) + { + // Correct start time + } + else + { + currentDate.set(Calendar.YEAR, currentDate.get(Calendar.YEAR) + 1); + currentDate.set(Calendar.MONTH, month); + currentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + } + + while(currentDate.before(onOrAfter)) + { + currentDate.set(Calendar.YEAR, currentDate.get(Calendar.YEAR) + 1); + currentDate.set(Calendar.MONTH, month); + currentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + } + while(true) + { + if(until != null) + { + if(currentDate.after(until)) + { + break; + } + } + + dates.add(currentDate.getTime()); + if(firstOnly) + { + break; + } + + currentDate.set(Calendar.YEAR, currentDate.get(Calendar.YEAR) + 1); + currentDate.set(Calendar.MONTH, month); + currentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + } + } + else + { + // eg the first Tuesday in February every year + int dayOfWeek = DAY_NAMES_TO_CALENDAR_DAYS.get(params.get("BYSETPOS")); + // TODO + } + } + + private static void addMonthToDayOfMonth(Calendar c, int dayOfMonth) { // Set it to the 1st