001 package biweekly.property;
002
003 import java.util.ArrayList;
004 import java.util.Date;
005 import java.util.List;
006
007 import biweekly.component.ICalComponent;
008
009 /*
010 Copyright (c) 2013, Michael Angstadt
011 All rights reserved.
012
013 Redistribution and use in source and binary forms, with or without
014 modification, are permitted provided that the following conditions are met:
015
016 1. Redistributions of source code must retain the above copyright notice, this
017 list of conditions and the following disclaimer.
018 2. Redistributions in binary form must reproduce the above copyright notice,
019 this list of conditions and the following disclaimer in the documentation
020 and/or other materials provided with the distribution.
021
022 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
023 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
024 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
025 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
026 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
027 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
028 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
029 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
030 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
031 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
032 */
033
034 /**
035 * <p>
036 * Defines how often a component repeats.
037 * </p>
038 * <p>
039 * <b>Examples:</b>
040 *
041 * <pre>
042 * //bi-weekly
043 * RecurrenceRule rrule = new RecurrenceRule(Frequency.WEEKLY);
044 * rrule.setInterval(2);
045 * </pre>
046 *
047 * </p>
048 * @author Michael Angstadt
049 * @see <a href="http://tools.ietf.org/html/rfc5545#page-122">RFC 5545
050 * p.122-32</a>
051 */
052 public class RecurrenceRule extends ICalProperty {
053 private Frequency frequency;
054 private Integer interval;
055 private Integer count;
056 private Date until;
057 private boolean untilHasTime;
058 private List<Integer> bySecond = new ArrayList<Integer>();
059 private List<Integer> byMinute = new ArrayList<Integer>();
060 private List<Integer> byHour = new ArrayList<Integer>();
061 private List<Integer> byMonthDay = new ArrayList<Integer>();
062 private List<Integer> byYearDay = new ArrayList<Integer>();
063 private List<Integer> byWeekNo = new ArrayList<Integer>();
064 private List<Integer> byMonth = new ArrayList<Integer>();
065 private List<Integer> bySetPos = new ArrayList<Integer>();
066 private List<DayOfWeek> byDay = new ArrayList<DayOfWeek>();
067 private List<Integer> byDayPrefixes = new ArrayList<Integer>();
068 private DayOfWeek workweekStarts;
069
070 /**
071 * Creates a new recurrence rule property.
072 * @param frequency the frequency of the recurrence rule
073 */
074 public RecurrenceRule(Frequency frequency) {
075 setFrequency(frequency);
076 }
077
078 public Frequency getFrequency() {
079 return frequency;
080 }
081
082 public void setFrequency(Frequency frequency) {
083 this.frequency = frequency;
084 }
085
086 public Date getUntil() {
087 return until;
088 }
089
090 public void setUntil(Date until) {
091 setUntil(until, true);
092 }
093
094 public void setUntil(Date until, boolean hasTime) {
095 this.until = until;
096 untilHasTime = hasTime;
097 }
098
099 public boolean hasTimeUntilDate() {
100 return untilHasTime;
101 }
102
103 public Integer getCount() {
104 return count;
105 }
106
107 public void setCount(Integer count) {
108 this.count = count;
109 }
110
111 public Integer getInterval() {
112 return interval;
113 }
114
115 public void setInterval(Integer interval) {
116 this.interval = interval;
117 }
118
119 public List<Integer> getBySecond() {
120 return bySecond;
121 }
122
123 public void setBySecond(List<Integer> bySecond) {
124 this.bySecond = bySecond;
125 }
126
127 public List<Integer> getByMinute() {
128 return byMinute;
129 }
130
131 public void setByMinute(List<Integer> byMinute) {
132 this.byMinute = byMinute;
133 }
134
135 public List<Integer> getByHour() {
136 return byHour;
137 }
138
139 public void setByHour(List<Integer> byHour) {
140 this.byHour = byHour;
141 }
142
143 public void addByDay(DayOfWeek day) {
144 addByDay(null, day);
145 }
146
147 public void addByDay(Integer prefix, DayOfWeek day) {
148 byDayPrefixes.add(prefix);
149 byDay.add(day);
150 }
151
152 public List<DayOfWeek> getByDay() {
153 return byDay;
154 }
155
156 public List<Integer> getByDayPrefixes() {
157 return byDayPrefixes;
158 }
159
160 public List<Integer> getByMonthDay() {
161 return byMonthDay;
162 }
163
164 public void setByMonthDay(List<Integer> byMonthDay) {
165 this.byMonthDay = byMonthDay;
166 }
167
168 public List<Integer> getByYearDay() {
169 return byYearDay;
170 }
171
172 public void setByYearDay(List<Integer> byYearDay) {
173 this.byYearDay = byYearDay;
174 }
175
176 public List<Integer> getByWeekNo() {
177 return byWeekNo;
178 }
179
180 public void setByWeekNo(List<Integer> byWeekNo) {
181 this.byWeekNo = byWeekNo;
182 }
183
184 public List<Integer> getByMonth() {
185 return byMonth;
186 }
187
188 public void setByMonth(List<Integer> byMonth) {
189 this.byMonth = byMonth;
190 }
191
192 public List<Integer> getBySetPos() {
193 return bySetPos;
194 }
195
196 public void setBySetPos(List<Integer> bySetPos) {
197 this.bySetPos = bySetPos;
198 }
199
200 public DayOfWeek getWorkweekStarts() {
201 return workweekStarts;
202 }
203
204 public void setWorkweekStarts(DayOfWeek workweekStarts) {
205 this.workweekStarts = workweekStarts;
206 }
207
208 @Override
209 protected void validate(List<ICalComponent> components, List<String> warnings) {
210 if (frequency == null) {
211 warnings.add("Frequency is not set (it is a required field).");
212 }
213 if (until != null && count != null) {
214 warnings.add("\"Until\" and \"count\" cannot both be set.");
215 }
216 }
217
218 /**
219 * Represents the frequency at which the recurrence rule repeats itself.
220 * @author Michael Angstadt
221 */
222 public static enum Frequency {
223 SECONDLY, MINUTELY, HOURLY, DAILY, WEEKLY, MONTHLY, YEARLY
224 }
225
226 /**
227 * Represents each of the seven days of the week.
228 * @author Michael Angstadt
229 */
230 public static enum DayOfWeek {
231 MONDAY("MO"), TUESDAY("TU"), WEDNESDAY("WE"), THURSDAY("TH"), FRIDAY("FR"), SATURDAY("SA"), SUNDAY("SU");
232
233 private final String abbr;
234
235 private DayOfWeek(String abbr) {
236 this.abbr = abbr;
237 }
238
239 /**
240 * Gets the day's abbreviation.
241 * @return the abbreviation (e.g. "MO" for Monday)
242 */
243 public String getAbbr() {
244 return abbr;
245 }
246
247 /**
248 * Gets a day by its abbreviation.
249 * @param abbr the abbreviation (case-insensitive, e.g. "MO" for Monday)
250 * @return the day or null if not found
251 */
252 public static DayOfWeek valueOfAbbr(String abbr) {
253 for (DayOfWeek day : values()) {
254 if (day.abbr.equalsIgnoreCase(abbr)) {
255 return day;
256 }
257 }
258 return null;
259 }
260 }
261 }