Tue, 10 Feb 2015 19:58:00 +0100
Upgrade the upgraded ical4j component to use org.apache.commons.lang3.
michael@0 | 1 | /** |
michael@0 | 2 | * Copyright (c) 2012, Ben Fortuna |
michael@0 | 3 | * All rights reserved. |
michael@0 | 4 | * |
michael@0 | 5 | * Redistribution and use in source and binary forms, with or without |
michael@0 | 6 | * modification, are permitted provided that the following conditions |
michael@0 | 7 | * are met: |
michael@0 | 8 | * |
michael@0 | 9 | * o Redistributions of source code must retain the above copyright |
michael@0 | 10 | * notice, this list of conditions and the following disclaimer. |
michael@0 | 11 | * |
michael@0 | 12 | * o Redistributions in binary form must reproduce the above copyright |
michael@0 | 13 | * notice, this list of conditions and the following disclaimer in the |
michael@0 | 14 | * documentation and/or other materials provided with the distribution. |
michael@0 | 15 | * |
michael@0 | 16 | * o Neither the name of Ben Fortuna nor the names of any other contributors |
michael@0 | 17 | * may be used to endorse or promote products derived from this software |
michael@0 | 18 | * without specific prior written permission. |
michael@0 | 19 | * |
michael@0 | 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
michael@0 | 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
michael@0 | 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
michael@0 | 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
michael@0 | 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
michael@0 | 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
michael@0 | 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
michael@0 | 27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
michael@0 | 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
michael@0 | 29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
michael@0 | 30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 31 | */ |
michael@0 | 32 | package net.fortuna.ical4j.model.property; |
michael@0 | 33 | |
michael@0 | 34 | import java.text.ParseException; |
michael@0 | 35 | |
michael@0 | 36 | import net.fortuna.ical4j.model.DateList; |
michael@0 | 37 | import net.fortuna.ical4j.model.Parameter; |
michael@0 | 38 | import net.fortuna.ical4j.model.ParameterList; |
michael@0 | 39 | import net.fortuna.ical4j.model.PeriodList; |
michael@0 | 40 | import net.fortuna.ical4j.model.PropertyFactoryImpl; |
michael@0 | 41 | import net.fortuna.ical4j.model.TimeZone; |
michael@0 | 42 | import net.fortuna.ical4j.model.ValidationException; |
michael@0 | 43 | import net.fortuna.ical4j.model.parameter.Value; |
michael@0 | 44 | import net.fortuna.ical4j.util.ParameterValidator; |
michael@0 | 45 | import net.fortuna.ical4j.util.Strings; |
michael@0 | 46 | |
michael@0 | 47 | /** |
michael@0 | 48 | * $Id$ |
michael@0 | 49 | * |
michael@0 | 50 | * Created: [Apr 6, 2004] |
michael@0 | 51 | * |
michael@0 | 52 | * Defines an RDATE iCalendar component property. |
michael@0 | 53 | * |
michael@0 | 54 | * <pre> |
michael@0 | 55 | * 4.8.5.3 Recurrence Date/Times |
michael@0 | 56 | * |
michael@0 | 57 | * Property Name: RDATE |
michael@0 | 58 | * |
michael@0 | 59 | * Purpose: This property defines the list of date/times for a |
michael@0 | 60 | * recurrence set. |
michael@0 | 61 | * |
michael@0 | 62 | * Value Type: The default value type for this property is DATE-TIME. |
michael@0 | 63 | * The value type can be set to DATE or PERIOD. |
michael@0 | 64 | * |
michael@0 | 65 | * Property Parameters: Non-standard, value data type and time zone |
michael@0 | 66 | * identifier property parameters can be specified on this property. |
michael@0 | 67 | * |
michael@0 | 68 | * Conformance: The property can be specified in "VEVENT", "VTODO", |
michael@0 | 69 | * "VJOURNAL" or "VTIMEZONE" calendar components. |
michael@0 | 70 | * |
michael@0 | 71 | * Description: This property can appear along with the "RRULE" property |
michael@0 | 72 | * to define an aggregate set of repeating occurrences. When they both |
michael@0 | 73 | * appear in an iCalendar object, the recurring events are defined by |
michael@0 | 74 | * the union of occurrences defined by both the "RDATE" and "RRULE". |
michael@0 | 75 | * |
michael@0 | 76 | * The recurrence dates, if specified, are used in computing the |
michael@0 | 77 | * recurrence set. The recurrence set is the complete set of recurrence |
michael@0 | 78 | * instances for a calendar component. The recurrence set is generated |
michael@0 | 79 | * by considering the initial "DTSTART" property along with the "RRULE", |
michael@0 | 80 | * "RDATE", "EXDATE" and "EXRULE" properties contained within the |
michael@0 | 81 | * iCalendar object. The "DTSTART" property defines the first instance |
michael@0 | 82 | * in the recurrence set. Multiple instances of the "RRULE" and "EXRULE" |
michael@0 | 83 | * properties can also be specified to define more sophisticated |
michael@0 | 84 | * recurrence sets. The final recurrence set is generated by gathering |
michael@0 | 85 | * all of the start date/times generated by any of the specified "RRULE" |
michael@0 | 86 | * and "RDATE" properties, and excluding any start date/times which fall |
michael@0 | 87 | * within the union of start date/times generated by any specified |
michael@0 | 88 | * "EXRULE" and "EXDATE" properties. This implies that start date/times |
michael@0 | 89 | * within exclusion related properties (i.e., "EXDATE" and "EXRULE") |
michael@0 | 90 | * take precedence over those specified by inclusion properties (i.e., |
michael@0 | 91 | * "RDATE" and "RRULE"). Where duplicate instances are generated by the |
michael@0 | 92 | * "RRULE" and "RDATE" properties, only one recurrence is considered. |
michael@0 | 93 | * Duplicate instances are ignored. |
michael@0 | 94 | * |
michael@0 | 95 | * Format Definition: The property is defined by the following notation: |
michael@0 | 96 | * |
michael@0 | 97 | * rdate = "RDATE" rdtparam ":" rdtval *("," rdtval) CRLF |
michael@0 | 98 | * |
michael@0 | 99 | * rdtparam = *( |
michael@0 | 100 | * |
michael@0 | 101 | * ; the following are optional, |
michael@0 | 102 | * ; but MUST NOT occur more than once |
michael@0 | 103 | * |
michael@0 | 104 | * (";" "VALUE" "=" ("DATE-TIME" |
michael@0 | 105 | * / "DATE" / "PERIOD")) / |
michael@0 | 106 | * (";" tzidparam) / |
michael@0 | 107 | * |
michael@0 | 108 | * ; the following is optional, |
michael@0 | 109 | * ; and MAY occur more than once |
michael@0 | 110 | * |
michael@0 | 111 | * (";" xparam) |
michael@0 | 112 | * |
michael@0 | 113 | * ) |
michael@0 | 114 | * |
michael@0 | 115 | * rdtval = date-time / date / period |
michael@0 | 116 | * ;Value MUST match value type |
michael@0 | 117 | * |
michael@0 | 118 | * Example: The following are examples of this property: |
michael@0 | 119 | * |
michael@0 | 120 | * RDATE:19970714T123000Z |
michael@0 | 121 | * |
michael@0 | 122 | * RDATE;TZID=US-EASTERN:19970714T083000 |
michael@0 | 123 | * |
michael@0 | 124 | * RDATE;VALUE=PERIOD:19960403T020000Z/19960403T040000Z, |
michael@0 | 125 | * 19960404T010000Z/PT3H |
michael@0 | 126 | * |
michael@0 | 127 | * RDATE;VALUE=DATE:19970101,19970120,19970217,19970421 |
michael@0 | 128 | * 19970526,19970704,19970901,19971014,19971128,19971129,19971225 |
michael@0 | 129 | * </pre> |
michael@0 | 130 | * |
michael@0 | 131 | * @author Ben Fortuna |
michael@0 | 132 | */ |
michael@0 | 133 | public class RDate extends DateListProperty { |
michael@0 | 134 | |
michael@0 | 135 | private static final long serialVersionUID = -3320381650013860193L; |
michael@0 | 136 | |
michael@0 | 137 | private PeriodList periods; |
michael@0 | 138 | |
michael@0 | 139 | /** |
michael@0 | 140 | * Default constructor. |
michael@0 | 141 | */ |
michael@0 | 142 | public RDate() { |
michael@0 | 143 | super(RDATE, PropertyFactoryImpl.getInstance()); |
michael@0 | 144 | periods = new PeriodList(false, true); |
michael@0 | 145 | } |
michael@0 | 146 | |
michael@0 | 147 | /** |
michael@0 | 148 | * @param aList a list of parameters for this component |
michael@0 | 149 | * @param aValue a value string for this component |
michael@0 | 150 | * @throws ParseException where the specified value string is not a valid date-time/date representation |
michael@0 | 151 | */ |
michael@0 | 152 | public RDate(final ParameterList aList, final String aValue) |
michael@0 | 153 | throws ParseException { |
michael@0 | 154 | super(RDATE, aList, PropertyFactoryImpl.getInstance()); |
michael@0 | 155 | periods = new PeriodList(false, true); |
michael@0 | 156 | setValue(aValue); |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | /** |
michael@0 | 160 | * Constructor. Date or Date-Time format is determined based on the presence of a VALUE parameter. |
michael@0 | 161 | * @param dates a list of dates |
michael@0 | 162 | */ |
michael@0 | 163 | public RDate(final DateList dates) { |
michael@0 | 164 | super(RDATE, dates, PropertyFactoryImpl.getInstance()); |
michael@0 | 165 | periods = new PeriodList(false, true); |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | /** |
michael@0 | 169 | * Constructor. Date or Date-Time format is determined based on the presence of a VALUE parameter. |
michael@0 | 170 | * @param aList a list of parameters for this component |
michael@0 | 171 | * @param dates a list of dates |
michael@0 | 172 | */ |
michael@0 | 173 | public RDate(final ParameterList aList, final DateList dates) { |
michael@0 | 174 | super(RDATE, aList, dates, PropertyFactoryImpl.getInstance()); |
michael@0 | 175 | periods = new PeriodList(false, true); |
michael@0 | 176 | } |
michael@0 | 177 | |
michael@0 | 178 | /** |
michael@0 | 179 | * Constructor. |
michael@0 | 180 | * @param periods a list of periods |
michael@0 | 181 | */ |
michael@0 | 182 | public RDate(final PeriodList periods) { |
michael@0 | 183 | super(RDATE, new DateList(true), PropertyFactoryImpl.getInstance()); |
michael@0 | 184 | this.periods = periods; |
michael@0 | 185 | } |
michael@0 | 186 | |
michael@0 | 187 | /** |
michael@0 | 188 | * Constructor. |
michael@0 | 189 | * @param aList a list of parameters for this component |
michael@0 | 190 | * @param periods a list of periods |
michael@0 | 191 | */ |
michael@0 | 192 | public RDate(final ParameterList aList, final PeriodList periods) { |
michael@0 | 193 | super(RDATE, aList, new DateList(true), PropertyFactoryImpl.getInstance()); |
michael@0 | 194 | this.periods = periods; |
michael@0 | 195 | } |
michael@0 | 196 | |
michael@0 | 197 | /** |
michael@0 | 198 | * {@inheritDoc} |
michael@0 | 199 | */ |
michael@0 | 200 | public final void validate() throws ValidationException { |
michael@0 | 201 | |
michael@0 | 202 | /* |
michael@0 | 203 | * ; the following are optional, ; but MUST NOT occur more than once (";" "VALUE" "=" ("DATE-TIME" / "DATE" / |
michael@0 | 204 | * "PERIOD")) / (";" tzidparam) / |
michael@0 | 205 | */ |
michael@0 | 206 | ParameterValidator.getInstance().assertOneOrLess(Parameter.VALUE, |
michael@0 | 207 | getParameters()); |
michael@0 | 208 | |
michael@0 | 209 | final Parameter valueParam = getParameter(Parameter.VALUE); |
michael@0 | 210 | |
michael@0 | 211 | if (valueParam != null && !Value.DATE_TIME.equals(valueParam) |
michael@0 | 212 | && !Value.DATE.equals(valueParam) |
michael@0 | 213 | && !Value.PERIOD.equals(valueParam)) { |
michael@0 | 214 | throw new ValidationException("Parameter [" + Parameter.VALUE |
michael@0 | 215 | + "] is invalid"); |
michael@0 | 216 | } |
michael@0 | 217 | |
michael@0 | 218 | ParameterValidator.getInstance().assertOneOrLess(Parameter.TZID, |
michael@0 | 219 | getParameters()); |
michael@0 | 220 | |
michael@0 | 221 | /* |
michael@0 | 222 | * ; the following is optional, ; and MAY occur more than once (";" xparam) |
michael@0 | 223 | */ |
michael@0 | 224 | } |
michael@0 | 225 | |
michael@0 | 226 | /** |
michael@0 | 227 | * @return Returns the period list. |
michael@0 | 228 | */ |
michael@0 | 229 | public final PeriodList getPeriods() { |
michael@0 | 230 | return periods; |
michael@0 | 231 | } |
michael@0 | 232 | |
michael@0 | 233 | /** |
michael@0 | 234 | * {@inheritDoc} |
michael@0 | 235 | */ |
michael@0 | 236 | public final void setValue(final String aValue) throws ParseException { |
michael@0 | 237 | if (Value.PERIOD.equals(getParameter(Parameter.VALUE))) { |
michael@0 | 238 | periods = new PeriodList(aValue); |
michael@0 | 239 | } |
michael@0 | 240 | else { |
michael@0 | 241 | super.setValue(aValue); |
michael@0 | 242 | } |
michael@0 | 243 | } |
michael@0 | 244 | |
michael@0 | 245 | /** |
michael@0 | 246 | * {@inheritDoc} |
michael@0 | 247 | */ |
michael@0 | 248 | public final String getValue() { |
michael@0 | 249 | if (periods != null && !(periods.isEmpty() && periods.isUnmodifiable())) { |
michael@0 | 250 | return Strings.valueOf(getPeriods()); |
michael@0 | 251 | } |
michael@0 | 252 | return super.getValue(); |
michael@0 | 253 | } |
michael@0 | 254 | |
michael@0 | 255 | /** |
michael@0 | 256 | * {@inheritDoc} |
michael@0 | 257 | */ |
michael@0 | 258 | public final void setTimeZone(TimeZone timezone) { |
michael@0 | 259 | if (periods != null && !(periods.isEmpty() && periods.isUnmodifiable())) { |
michael@0 | 260 | periods.setTimeZone(timezone); |
michael@0 | 261 | } |
michael@0 | 262 | else { |
michael@0 | 263 | super.setTimeZone(timezone); |
michael@0 | 264 | } |
michael@0 | 265 | } |
michael@0 | 266 | } |