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 }