001package biweekly.property; 002 003import java.util.ArrayList; 004import java.util.Date; 005import java.util.List; 006 007import biweekly.ICalVersion; 008import biweekly.Warning; 009import biweekly.component.ICalComponent; 010import biweekly.util.ICalDate; 011import biweekly.util.Period; 012 013/* 014 Copyright (c) 2013-2015, Michael Angstadt 015 All rights reserved. 016 017 Redistribution and use in source and binary forms, with or without 018 modification, are permitted provided that the following conditions are met: 019 020 1. Redistributions of source code must retain the above copyright notice, this 021 list of conditions and the following disclaimer. 022 2. Redistributions in binary form must reproduce the above copyright notice, 023 this list of conditions and the following disclaimer in the documentation 024 and/or other materials provided with the distribution. 025 026 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 027 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 028 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 029 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 030 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 031 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 032 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 033 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 034 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 035 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 036 */ 037 038/** 039 * <p> 040 * Defines a list of dates or time periods that help define a recurrence rule. 041 * It must contain either dates or time periods. It cannot contain a combination 042 * of both. 043 * </p> 044 * <p> 045 * <b>Code sample:</b> 046 * 047 * <pre class="brush:java"> 048 * VEvent event = new VEvent(); 049 * 050 * //date-time values 051 * Date datetime = ... 052 * RecurrenceDates rdate = new RecurrenceDates(); 053 * rdate.addDate(new ICalDate(datetime, true)); 054 * event.addRecurrenceDates(rdate); 055 * 056 * //date values 057 * Date date = ... 058 * RecurrenceDates rdate = new RecurrenceDates(); 059 * rdate.addDate(new ICalDate(date, false)); 060 * event.addRecurrenceDates(rdate); 061 * 062 * //periods 063 * Period period = ... 064 * rdate = new RecurrenceDates(); 065 * rdate.addPeriod(period); 066 * event.addRecurrenceDates(rdate); 067 * </pre> 068 * 069 * </p> 070 * @author Michael Angstadt 071 * @see <a href="http://tools.ietf.org/html/rfc5545#page-120">RFC 5545 072 * p.120-2</a> 073 * @see <a href="http://tools.ietf.org/html/rfc2445#page-115">RFC 2445 074 * p.115-7</a> 075 * @see <a href="http://www.imc.org/pdi/vcal-10.doc">vCal 1.0 p.34</a> 076 */ 077public class RecurrenceDates extends ICalProperty { 078 private List<ICalDate> dates = new ArrayList<ICalDate>(); 079 private List<Period> periods = new ArrayList<Period>(); 080 081 /** 082 * Gets the recurrence dates. 083 * @return the dates 084 */ 085 public List<ICalDate> getDates() { 086 return dates; 087 } 088 089 /** 090 * Adds a date. 091 * @param date the date to add 092 */ 093 public void addDate(ICalDate date) { 094 dates.add(date); 095 } 096 097 /** 098 * Adds a date 099 * @param date the date to add 100 */ 101 public void addDate(Date date) { 102 addDate(new ICalDate(date, true)); 103 } 104 105 /** 106 * Gets the time periods. 107 * @return the time periods 108 */ 109 public List<Period> getPeriods() { 110 return periods; 111 } 112 113 /** 114 * Adds a period 115 * @param period the period to add 116 */ 117 public void addPeriod(Period period) { 118 periods.add(period); 119 } 120 121 @Override 122 protected void validate(List<ICalComponent> components, ICalVersion version, List<Warning> warnings) { 123 if (dates.isEmpty() && periods.isEmpty()) { 124 //no value 125 warnings.add(Warning.validate(26)); 126 } 127 128 if (!dates.isEmpty() && !periods.isEmpty()) { 129 //can't mix dates and periods 130 warnings.add(Warning.validate(49)); 131 } 132 133 if (version == ICalVersion.V1_0 && !periods.isEmpty()) { 134 //1.0 doesn't support periods 135 warnings.add(Warning.validate(51)); 136 } 137 138 if (!dates.isEmpty()) { 139 //can't mix date and date-time values 140 boolean hasTime = dates.get(0).hasTime(); 141 for (ICalDate date : dates.subList(1, dates.size())) { 142 if (date.hasTime() != hasTime) { 143 warnings.add(Warning.validate(50)); 144 break; 145 } 146 } 147 } 148 } 149}