Skip to content

Commit 3122548

Browse files
Recurrent monthly event, add possibility to specify the week day #149 (#155)
* added a new event generator * added support for dynamic monthly recurrence * refactored JS * added translations * added comments * added hint for frequency
1 parent 606abd9 commit 3122548

File tree

12 files changed

+258
-30
lines changed

12 files changed

+258
-30
lines changed

application-mocca-calendar-api/src/main/java/org/xwiki/contrib/moccacalendar/internal/generators/AbstractRecurrentEventGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public abstract class AbstractRecurrentEventGenerator implements RecurrentEventG
6161
* E.g. in case of weekly events increment it by one week.
6262
* @param cal the calendar to increment; should never be null
6363
*/
64-
protected abstract void incrementCalendarByOnePeriod(Calendar cal);
64+
protected abstract void incrementCalendarByOnePeriod(Calendar cal, int... pos);
6565

6666
/**
6767
* generate a list of event instances for the given date range
@@ -117,7 +117,7 @@ public List<EventInstance> generate(final XWikiDocument event, final Date dateFr
117117

118118
// separate helper method to actually create the events
119119
// to keep checkstyle from complaining
120-
private List<EventInstance> createEventInstances(final XWikiDocument event, final Date startDate,
120+
protected List<EventInstance> createEventInstances(final XWikiDocument event, final Date startDate,
121121
final long duration, final Date dateFrom, final Date dateTo)
122122
{
123123
Calendar cal = Calendar.getInstance();

application-mocca-calendar-api/src/main/java/org/xwiki/contrib/moccacalendar/internal/generators/BiWeeklyEventGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class BiWeeklyEventGenerator extends AbstractRecurrentEventGenerator
4040
/**
4141
* increment the calendar by two weeks.
4242
*/
43-
protected void incrementCalendarByOnePeriod(Calendar cal)
43+
protected void incrementCalendarByOnePeriod(Calendar cal, int... pos)
4444
{
4545
cal.add(Calendar.WEEK_OF_YEAR, 2);
4646
}

application-mocca-calendar-api/src/main/java/org/xwiki/contrib/moccacalendar/internal/generators/DailyEventGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class DailyEventGenerator extends AbstractRecurrentEventGenerator
4040
/**
4141
* increment the calendar by one day.
4242
*/
43-
protected void incrementCalendarByOnePeriod(Calendar cal)
43+
protected void incrementCalendarByOnePeriod(Calendar cal, int... pos)
4444
{
4545
cal.add(Calendar.DAY_OF_YEAR, 1);
4646
}

application-mocca-calendar-api/src/main/java/org/xwiki/contrib/moccacalendar/internal/generators/MonthlyEventGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class MonthlyEventGenerator extends AbstractRecurrentEventGenerator
4141
/**
4242
* increment the calendar by one month.
4343
*/
44-
protected void incrementCalendarByOnePeriod(Calendar cal)
44+
protected void incrementCalendarByOnePeriod(Calendar cal, int... pos)
4545
{
4646
cal.add(Calendar.MONTH, 1);
4747
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* See the NOTICE file distributed with this work for additional
3+
* information regarding copyright ownership.
4+
*
5+
* This is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU Lesser General Public License as
7+
* published by the Free Software Foundation; either version 2.1 of
8+
* the License, or (at your option) any later version.
9+
*
10+
* This software is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this software; if not, write to the Free
17+
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18+
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19+
*/
20+
package org.xwiki.contrib.moccacalendar.internal.generators;
21+
22+
import java.util.ArrayList;
23+
import java.util.Calendar;
24+
import java.util.Date;
25+
import java.util.List;
26+
27+
import javax.inject.Named;
28+
import javax.inject.Singleton;
29+
30+
import org.joda.time.DateTime;
31+
import org.xwiki.component.annotation.Component;
32+
import org.xwiki.contrib.moccacalendar.EventInstance;
33+
34+
import com.xpn.xwiki.doc.XWikiDocument;
35+
36+
/**
37+
* A generator for monthly events that take place on a specific day.
38+
*
39+
* @version $Id: $
40+
* @since 2.16
41+
*/
42+
@Component
43+
@Singleton
44+
@Named("monthlySpecific")
45+
public class MonthlySpecificEventGenerator extends AbstractRecurrentEventGenerator
46+
{
47+
/**
48+
* Increment the calendar by one month, to a specific day.
49+
*/
50+
protected void incrementCalendarByOnePeriod(Calendar cal, int... occurrence)
51+
{
52+
int originalDayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
53+
54+
cal.set(Calendar.DAY_OF_MONTH, 1);
55+
cal.add(Calendar.MONTH, 1);
56+
int nextMonth = cal.get(Calendar.MONTH);
57+
58+
int weekdayCount = 0;
59+
int lastOccurrenceDay = 1;
60+
while (cal.get(Calendar.MONTH) == nextMonth) {
61+
if (cal.get(Calendar.DAY_OF_WEEK) == originalDayOfWeek) {
62+
lastOccurrenceDay = cal.get(Calendar.DAY_OF_MONTH);
63+
weekdayCount++;
64+
if (weekdayCount == occurrence[0]) {
65+
return;
66+
}
67+
}
68+
cal.add(Calendar.DAY_OF_MONTH, 1);
69+
}
70+
71+
cal.add(Calendar.DAY_OF_MONTH, -1);
72+
cal.set(Calendar.DAY_OF_MONTH, lastOccurrenceDay);
73+
}
74+
75+
@Override
76+
protected List<EventInstance> createEventInstances(final XWikiDocument event, final Date startDate,
77+
final long duration, final Date dateFrom, final Date dateTo)
78+
{
79+
Calendar cal = Calendar.getInstance();
80+
cal.setTime(startDate);
81+
int occurrence = getOccurrence(cal);
82+
while (cal.getTimeInMillis() + duration < dateFrom.getTime()) {
83+
incrementCalendarByOnePeriod(cal, occurrence);
84+
}
85+
List<EventInstance> eventInstances = new ArrayList<>();
86+
while (cal.getTime().compareTo(dateTo) <= 0) {
87+
EventInstance instance = new EventInstance();
88+
instance.setStartDate(new DateTime(cal.getTimeInMillis()));
89+
instance.setEndDate(new DateTime(cal.getTimeInMillis() + duration));
90+
91+
eventInstances.add(instance);
92+
93+
if (eventInstances.size() >= MAX_INSTANCES) {
94+
break;
95+
}
96+
97+
incrementCalendarByOnePeriod(cal, occurrence);
98+
}
99+
100+
return eventInstances;
101+
}
102+
103+
/**
104+
* Calculates the occurrence index of the day of the week for the date set in calendar.
105+
*
106+
* @param cal the {@link Calendar} instance representing the target date
107+
* @return the number of times the day of the week set in calendar occurred in the month
108+
*/
109+
private int getOccurrence(Calendar cal)
110+
{
111+
int originalDayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
112+
int originalDay = cal.get(Calendar.DAY_OF_MONTH);
113+
int originalMonth = cal.get(Calendar.MONTH);
114+
115+
Calendar temp = (Calendar) cal.clone();
116+
temp.set(Calendar.DAY_OF_MONTH, 1);
117+
int occurrence = 0;
118+
while (temp.get(Calendar.MONTH) == originalMonth && temp.get(Calendar.DAY_OF_MONTH) <= originalDay) {
119+
if (temp.get(Calendar.DAY_OF_WEEK) == originalDayOfWeek) {
120+
occurrence++;
121+
}
122+
temp.add(Calendar.DAY_OF_MONTH, 1);
123+
}
124+
return occurrence;
125+
}
126+
}

application-mocca-calendar-api/src/main/java/org/xwiki/contrib/moccacalendar/internal/generators/QuarterlyEventGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class QuarterlyEventGenerator extends AbstractRecurrentEventGenerator
4040
/**
4141
* increment the calendar by three months.
4242
*/
43-
protected void incrementCalendarByOnePeriod(Calendar cal)
43+
protected void incrementCalendarByOnePeriod(Calendar cal, int... pos)
4444
{
4545
cal.add(Calendar.MONTH, 3);
4646
}

application-mocca-calendar-api/src/main/java/org/xwiki/contrib/moccacalendar/internal/generators/WeeklyEventGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class WeeklyEventGenerator extends AbstractRecurrentEventGenerator
4040
/**
4141
* increment the calendar by one week.
4242
*/
43-
protected void incrementCalendarByOnePeriod(Calendar cal)
43+
protected void incrementCalendarByOnePeriod(Calendar cal, int... pos)
4444
{
4545
cal.add(Calendar.WEEK_OF_YEAR, 1);
4646
}

application-mocca-calendar-api/src/main/java/org/xwiki/contrib/moccacalendar/internal/generators/WorkDaysEventGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class WorkDaysEventGenerator extends AbstractRecurrentEventGenerator
4141
* increment the calendar by one day, skipping weekends.
4242
* TODO: configure which days are weekdays
4343
*/
44-
protected void incrementCalendarByOnePeriod(Calendar cal)
44+
protected void incrementCalendarByOnePeriod(Calendar cal, int... pos)
4545
{
4646
do {
4747
cal.add(Calendar.DAY_OF_YEAR, 1);

application-mocca-calendar-api/src/main/java/org/xwiki/contrib/moccacalendar/internal/generators/YearlyEventGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class YearlyEventGenerator extends AbstractRecurrentEventGenerator
4040
/**
4141
* increment the calendar by one year.
4242
*/
43-
protected void incrementCalendarByOnePeriod(Calendar cal)
43+
protected void incrementCalendarByOnePeriod(Calendar cal, int... pos)
4444
{
4545
cal.add(Calendar.YEAR, 1);
4646
}

application-mocca-calendar-api/src/main/resources/META-INF/components.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ org.xwiki.contrib.moccacalendar.internal.generators.WorkDaysEventGenerator
88
org.xwiki.contrib.moccacalendar.internal.generators.WeeklyEventGenerator
99
org.xwiki.contrib.moccacalendar.internal.generators.BiWeeklyEventGenerator
1010
org.xwiki.contrib.moccacalendar.internal.generators.MonthlyEventGenerator
11+
org.xwiki.contrib.moccacalendar.internal.generators.MonthlySpecificEventGenerator
1112
org.xwiki.contrib.moccacalendar.internal.generators.QuarterlyEventGenerator
1213
org.xwiki.contrib.moccacalendar.internal.generators.YearlyEventGenerator
1314
org.xwiki.contrib.moccacalendar.internal.meetings.MeetingEventSource

0 commit comments

Comments
 (0)