1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/net/fortuna/ical4j/model/component/VToDo.java Tue Feb 10 18:12:00 2015 +0100 1.3 @@ -0,0 +1,1279 @@ 1.4 +/** 1.5 + * Copyright (c) 2012, Ben Fortuna 1.6 + * All rights reserved. 1.7 + * 1.8 + * Redistribution and use in source and binary forms, with or without 1.9 + * modification, are permitted provided that the following conditions 1.10 + * are met: 1.11 + * 1.12 + * o Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 1.15 + * o Redistributions in binary form must reproduce the above copyright 1.16 + * notice, this list of conditions and the following disclaimer in the 1.17 + * documentation and/or other materials provided with the distribution. 1.18 + * 1.19 + * o Neither the name of Ben Fortuna nor the names of any other contributors 1.20 + * may be used to endorse or promote products derived from this software 1.21 + * without specific prior written permission. 1.22 + * 1.23 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.24 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.25 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.26 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 1.27 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1.28 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1.29 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 1.30 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 1.31 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 1.32 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 1.33 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.34 + */ 1.35 +package net.fortuna.ical4j.model.component; 1.36 + 1.37 +import java.io.IOException; 1.38 +import java.net.URISyntaxException; 1.39 +import java.text.ParseException; 1.40 +import java.util.HashMap; 1.41 +import java.util.Iterator; 1.42 +import java.util.Map; 1.43 + 1.44 +import net.fortuna.ical4j.model.Component; 1.45 +import net.fortuna.ical4j.model.ComponentList; 1.46 +import net.fortuna.ical4j.model.Date; 1.47 +import net.fortuna.ical4j.model.Dur; 1.48 +import net.fortuna.ical4j.model.Property; 1.49 +import net.fortuna.ical4j.model.PropertyList; 1.50 +import net.fortuna.ical4j.model.ValidationException; 1.51 +import net.fortuna.ical4j.model.Validator; 1.52 +import net.fortuna.ical4j.model.property.Clazz; 1.53 +import net.fortuna.ical4j.model.property.Completed; 1.54 +import net.fortuna.ical4j.model.property.Created; 1.55 +import net.fortuna.ical4j.model.property.Description; 1.56 +import net.fortuna.ical4j.model.property.DtStamp; 1.57 +import net.fortuna.ical4j.model.property.DtStart; 1.58 +import net.fortuna.ical4j.model.property.Due; 1.59 +import net.fortuna.ical4j.model.property.Duration; 1.60 +import net.fortuna.ical4j.model.property.Geo; 1.61 +import net.fortuna.ical4j.model.property.LastModified; 1.62 +import net.fortuna.ical4j.model.property.Location; 1.63 +import net.fortuna.ical4j.model.property.Method; 1.64 +import net.fortuna.ical4j.model.property.Organizer; 1.65 +import net.fortuna.ical4j.model.property.PercentComplete; 1.66 +import net.fortuna.ical4j.model.property.Priority; 1.67 +import net.fortuna.ical4j.model.property.RecurrenceId; 1.68 +import net.fortuna.ical4j.model.property.Sequence; 1.69 +import net.fortuna.ical4j.model.property.Status; 1.70 +import net.fortuna.ical4j.model.property.Summary; 1.71 +import net.fortuna.ical4j.model.property.Uid; 1.72 +import net.fortuna.ical4j.model.property.Url; 1.73 +import net.fortuna.ical4j.util.CompatibilityHints; 1.74 +import net.fortuna.ical4j.util.ComponentValidator; 1.75 +import net.fortuna.ical4j.util.PropertyValidator; 1.76 +import net.fortuna.ical4j.util.Strings; 1.77 + 1.78 +import org.apache.commons.lang.ObjectUtils; 1.79 +import org.apache.commons.lang.builder.HashCodeBuilder; 1.80 + 1.81 +/** 1.82 + * $Id$ [Apr 5, 2004] 1.83 + * 1.84 + * Defines an iCalendar VTODO component. 1.85 + * 1.86 + * <pre> 1.87 + * 4.6.2 To-do Component 1.88 + * 1.89 + * Component Name: VTODO 1.90 + * 1.91 + * Purpose: Provide a grouping of calendar properties that describe a 1.92 + * to-do. 1.93 + * 1.94 + * Formal Definition: A "VTODO" calendar component is defined by the 1.95 + * following notation: 1.96 + * 1.97 + * todoc = "BEGIN" ":" "VTODO" CRLF 1.98 + * todoprop *alarmc 1.99 + * "END" ":" "VTODO" CRLF 1.100 + * 1.101 + * todoprop = *( 1.102 + * 1.103 + * ; the following are optional, 1.104 + * ; but MUST NOT occur more than once 1.105 + * 1.106 + * class / completed / created / description / dtstamp / 1.107 + * dtstart / geo / last-mod / location / organizer / 1.108 + * percent / priority / recurid / seq / status / 1.109 + * summary / uid / url / 1.110 + * 1.111 + * ; either 'due' or 'duration' may appear in 1.112 + * ; a 'todoprop', but 'due' and 'duration' 1.113 + * ; MUST NOT occur in the same 'todoprop' 1.114 + * 1.115 + * due / duration / 1.116 + * 1.117 + * ; the following are optional, 1.118 + * ; and MAY occur more than once 1.119 + * attach / attendee / categories / comment / contact / 1.120 + * exdate / exrule / rstatus / related / resources / 1.121 + * rdate / rrule / x-prop 1.122 + * 1.123 + * ) 1.124 + * </pre> 1.125 + * 1.126 + * Example 1 - Creating a todo of two (2) hour duration starting tomorrow: 1.127 + * 1.128 + * <pre><code> 1.129 + * java.util.Calendar cal = java.util.Calendar.getInstance(); 1.130 + * // tomorrow.. 1.131 + * cal.add(java.util.Calendar.DAY_OF_MONTH, 1); 1.132 + * cal.set(java.util.Calendar.HOUR_OF_DAY, 11); 1.133 + * cal.set(java.util.Calendar.MINUTE, 00); 1.134 + * 1.135 + * VToDo documentation = new VEvent(cal.getTime(), 1000 * 60 * 60 * 2, 1.136 + * "Document calendar component usage"); 1.137 + * 1.138 + * // add timezone information.. 1.139 + * VTimeZone tz = VTimeZone.getDefault(); 1.140 + * TzId tzParam = new TzId(tz.getProperties().getProperty(Property.TZID) 1.141 + * .getValue()); 1.142 + * documentation.getProperties().getProperty(Property.DTSTART).getParameters() 1.143 + * .add(tzParam); 1.144 + * </code></pre> 1.145 + * 1.146 + * @author Ben Fortuna 1.147 + */ 1.148 +public class VToDo extends CalendarComponent { 1.149 + 1.150 + private static final long serialVersionUID = -269658210065896668L; 1.151 + 1.152 + private final Map methodValidators = new HashMap(); 1.153 + { 1.154 + methodValidators.put(Method.ADD, new AddValidator()); 1.155 + methodValidators.put(Method.CANCEL, new CancelValidator()); 1.156 + methodValidators.put(Method.COUNTER, new CounterValidator()); 1.157 + methodValidators.put(Method.DECLINE_COUNTER, new DeclineCounterValidator()); 1.158 + methodValidators.put(Method.PUBLISH, new PublishValidator()); 1.159 + methodValidators.put(Method.REFRESH, new RefreshValidator()); 1.160 + methodValidators.put(Method.REPLY, new ReplyValidator()); 1.161 + methodValidators.put(Method.REQUEST, new RequestValidator()); 1.162 + } 1.163 + 1.164 + private ComponentList alarms = new ComponentList(); 1.165 + 1.166 + /** 1.167 + * Default constructor. 1.168 + */ 1.169 + public VToDo() { 1.170 + super(VTODO); 1.171 + getProperties().add(new DtStamp()); 1.172 + } 1.173 + 1.174 + /** 1.175 + * Constructor. 1.176 + * @param properties a list of properties 1.177 + */ 1.178 + public VToDo(final PropertyList properties) { 1.179 + super(VTODO, properties); 1.180 + } 1.181 + 1.182 + /** 1.183 + * Constructs a new VTODO instance starting at the specified time with the specified summary. 1.184 + * @param start the start date of the new todo 1.185 + * @param summary the todo summary 1.186 + */ 1.187 + public VToDo(final Date start, final String summary) { 1.188 + this(); 1.189 + getProperties().add(new DtStart(start)); 1.190 + getProperties().add(new Summary(summary)); 1.191 + } 1.192 + 1.193 + /** 1.194 + * Constructs a new VTODO instance starting and ending at the specified times with the specified summary. 1.195 + * @param start the start date of the new todo 1.196 + * @param due the due date of the new todo 1.197 + * @param summary the todo summary 1.198 + */ 1.199 + public VToDo(final Date start, final Date due, final String summary) { 1.200 + this(); 1.201 + getProperties().add(new DtStart(start)); 1.202 + getProperties().add(new Due(due)); 1.203 + getProperties().add(new Summary(summary)); 1.204 + } 1.205 + 1.206 + /** 1.207 + * Constructs a new VTODO instance starting at the specified times, for the specified duration, with the specified 1.208 + * summary. 1.209 + * @param start the start date of the new todo 1.210 + * @param duration the duration of the new todo 1.211 + * @param summary the todo summary 1.212 + */ 1.213 + public VToDo(final Date start, final Dur duration, final String summary) { 1.214 + this(); 1.215 + getProperties().add(new DtStart(start)); 1.216 + getProperties().add(new Duration(duration)); 1.217 + getProperties().add(new Summary(summary)); 1.218 + } 1.219 + 1.220 + /** 1.221 + * Returns the list of alarms for this todo. 1.222 + * @return a component list 1.223 + */ 1.224 + public final ComponentList getAlarms() { 1.225 + return alarms; 1.226 + } 1.227 + 1.228 + /** 1.229 + * {@inheritDoc} 1.230 + */ 1.231 + public final String toString() { 1.232 + final StringBuffer buffer = new StringBuffer(); 1.233 + buffer.append(BEGIN); 1.234 + buffer.append(':'); 1.235 + buffer.append(getName()); 1.236 + buffer.append(Strings.LINE_SEPARATOR); 1.237 + buffer.append(getProperties()); 1.238 + buffer.append(getAlarms()); 1.239 + buffer.append(END); 1.240 + buffer.append(':'); 1.241 + buffer.append(getName()); 1.242 + buffer.append(Strings.LINE_SEPARATOR); 1.243 + return buffer.toString(); 1.244 + } 1.245 + 1.246 + /** 1.247 + * {@inheritDoc} 1.248 + */ 1.249 + public final void validate(final boolean recurse) 1.250 + throws ValidationException { 1.251 + 1.252 + // validate that getAlarms() only contains VAlarm components 1.253 + final Iterator iterator = getAlarms().iterator(); 1.254 + while (iterator.hasNext()) { 1.255 + final Component component = (Component) iterator.next(); 1.256 + if (!(component instanceof VAlarm)) { 1.257 + throw new ValidationException("Component [" 1.258 + + component.getName() + "] may not occur in VTODO"); 1.259 + } 1.260 + ((VAlarm) component).validate(recurse); 1.261 + } 1.262 + 1.263 + if (!CompatibilityHints 1.264 + .isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) { 1.265 + 1.266 + // From "4.8.4.7 Unique Identifier": 1.267 + // Conformance: The property MUST be specified in the "VEVENT", "VTODO", 1.268 + // "VJOURNAL" or "VFREEBUSY" calendar components. 1.269 + PropertyValidator.getInstance().assertOne(Property.UID, 1.270 + getProperties()); 1.271 + 1.272 + // From "4.8.7.2 Date/Time Stamp": 1.273 + // Conformance: This property MUST be included in the "VEVENT", "VTODO", 1.274 + // "VJOURNAL" or "VFREEBUSY" calendar components. 1.275 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, 1.276 + getProperties()); 1.277 + } 1.278 + 1.279 + /* 1.280 + * ; the following are optional, ; but MUST NOT occur more than once class / completed / created / description / 1.281 + * dtstamp / dtstart / geo / last-mod / location / organizer / percent / priority / recurid / seq / status / 1.282 + * summary / uid / url / 1.283 + */ 1.284 + PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, 1.285 + getProperties()); 1.286 + PropertyValidator.getInstance().assertOneOrLess(Property.COMPLETED, 1.287 + getProperties()); 1.288 + PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, 1.289 + getProperties()); 1.290 + PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, 1.291 + getProperties()); 1.292 + PropertyValidator.getInstance().assertOneOrLess(Property.DTSTAMP, 1.293 + getProperties()); 1.294 + PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, 1.295 + getProperties()); 1.296 + PropertyValidator.getInstance().assertOneOrLess(Property.GEO, 1.297 + getProperties()); 1.298 + PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, 1.299 + getProperties()); 1.300 + PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, 1.301 + getProperties()); 1.302 + PropertyValidator.getInstance().assertOneOrLess(Property.ORGANIZER, 1.303 + getProperties()); 1.304 + PropertyValidator.getInstance().assertOneOrLess( 1.305 + Property.PERCENT_COMPLETE, getProperties()); 1.306 + PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, 1.307 + getProperties()); 1.308 + PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, 1.309 + getProperties()); 1.310 + PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, 1.311 + getProperties()); 1.312 + PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, 1.313 + getProperties()); 1.314 + PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY, 1.315 + getProperties()); 1.316 + PropertyValidator.getInstance().assertOneOrLess(Property.UID, 1.317 + getProperties()); 1.318 + PropertyValidator.getInstance().assertOneOrLess(Property.URL, 1.319 + getProperties()); 1.320 + 1.321 + final Status status = (Status) getProperty(Property.STATUS); 1.322 + if (status != null && !Status.VTODO_NEEDS_ACTION.getValue().equals(status.getValue()) 1.323 + && !Status.VTODO_COMPLETED.getValue().equals(status.getValue()) 1.324 + && !Status.VTODO_IN_PROCESS.getValue().equals(status.getValue()) 1.325 + && !Status.VTODO_CANCELLED.getValue().equals(status.getValue())) { 1.326 + throw new ValidationException("Status property [" 1.327 + + status.toString() + "] may not occur in VTODO"); 1.328 + } 1.329 + 1.330 + /* 1.331 + * ; either 'due' or 'duration' may appear in ; a 'todoprop', but 'due' and 'duration' ; MUST NOT occur in the 1.332 + * same 'todoprop' due / duration / 1.333 + */ 1.334 + try { 1.335 + PropertyValidator.getInstance().assertNone(Property.DUE, 1.336 + getProperties()); 1.337 + } 1.338 + catch (ValidationException ve) { 1.339 + PropertyValidator.getInstance().assertNone(Property.DURATION, 1.340 + getProperties()); 1.341 + } 1.342 + 1.343 + /* 1.344 + * ; the following are optional, ; and MAY occur more than once attach / attendee / categories / comment / 1.345 + * contact / exdate / exrule / rstatus / related / resources / rdate / rrule / x-prop 1.346 + */ 1.347 + 1.348 + if (recurse) { 1.349 + validateProperties(); 1.350 + } 1.351 + } 1.352 + 1.353 + /** 1.354 + * {@inheritDoc} 1.355 + */ 1.356 + protected Validator getValidator(Method method) { 1.357 + return (Validator) methodValidators.get(method); 1.358 + } 1.359 + 1.360 + /** 1.361 + * <pre> 1.362 + * Component/Property Presence 1.363 + * ------------------- ---------------------------------------------- 1.364 + * METHOD 1 MUST be "ADD" 1.365 + * VTODO 1 1.366 + * DTSTAMP 1 1.367 + * ORGANIZER 1 1.368 + * PRIORITY 1 1.369 + * SEQUENCE 1 MUST be greater than 0 1.370 + * SUMMARY 1 Can be null. 1.371 + * UID 1 MUST match that of the original to-do 1.372 + * 1.373 + * ATTACH 0+ 1.374 + * ATTENDEE 0+ 1.375 + * CATEGORIES 0 or 1 This property may contain a list of 1.376 + * values 1.377 + * CLASS 0 or 1 1.378 + * COMMENT 0 or 1 1.379 + * CONTACT 0+ 1.380 + * CREATED 0 or 1 1.381 + * DESCRIPTION 0 or 1 Can be null 1.382 + * DTSTART 0 or 1 1.383 + * DUE 0 or 1 If present DURATION MUST NOT be present 1.384 + * DURATION 0 or 1 If present DUE MUST NOT be present 1.385 + * EXDATE 0+ 1.386 + * EXRULE 0+ 1.387 + * GEO 0 or 1 1.388 + * LAST-MODIFIED 0 or 1 1.389 + * LOCATION 0 or 1 1.390 + * PERCENT-COMPLETE 0 or 1 1.391 + * RDATE 0+ 1.392 + * RELATED-TO 0+ 1.393 + * RESOURCES 0 or 1 This property may contain a list of 1.394 + * values 1.395 + * RRULE 0+ 1.396 + * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN- 1.397 + * PROCESS 1.398 + * URL 0 or 1 1.399 + * X-PROPERTY 0+ 1.400 + * 1.401 + * RECURRENCE-ID 0 1.402 + * REQUEST-STATUS 0 1.403 + * 1.404 + * VALARM 0+ 1.405 + * VTIMEZONE 0+ MUST be present if any date/time refers 1.406 + * to a timezone 1.407 + * X-COMPONENT 0+ 1.408 + * 1.409 + * VEVENT 0 1.410 + * VJOURNAL 0 1.411 + * VFREEBUSY 0 1.412 + * </pre> 1.413 + * 1.414 + */ 1.415 + private class AddValidator implements Validator { 1.416 + 1.417 + private static final long serialVersionUID = 1L; 1.418 + 1.419 + public void validate() throws ValidationException { 1.420 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties()); 1.421 + PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties()); 1.422 + PropertyValidator.getInstance().assertOne(Property.PRIORITY, getProperties()); 1.423 + PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties()); 1.424 + PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties()); 1.425 + PropertyValidator.getInstance().assertOne(Property.UID, getProperties()); 1.426 + 1.427 + PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties()); 1.428 + PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties()); 1.429 + PropertyValidator.getInstance().assertOneOrLess(Property.COMMENT, getProperties()); 1.430 + PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties()); 1.431 + PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties()); 1.432 + PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties()); 1.433 + PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties()); 1.434 + PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties()); 1.435 + PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties()); 1.436 + PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties()); 1.437 + PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties()); 1.438 + PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties()); 1.439 + PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties()); 1.440 + PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties()); 1.441 + PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties()); 1.442 + 1.443 + PropertyValidator.getInstance().assertNone(Property.RECURRENCE_ID, getProperties()); 1.444 + PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties()); 1.445 + 1.446 + for (final Iterator i = getAlarms().iterator(); i.hasNext();) { 1.447 + final VAlarm alarm = (VAlarm) i.next(); 1.448 + alarm.validate(Method.ADD); 1.449 + } 1.450 + } 1.451 + } 1.452 + 1.453 + /** 1.454 + * <pre> 1.455 + * Component/Property Presence 1.456 + * ------------------- --------------------------------------------- 1.457 + * METHOD 1 MUST be "CANCEL" 1.458 + * VTODO 1 1.459 + * ATTENDEE 0+ include all "Attendees" being removed from 1.460 + * the todo. MUST include all "Attendees" if 1.461 + * the entire todo is cancelled. 1.462 + * UID 1 MUST echo original UID 1.463 + * DTSTAMP 1 1.464 + * ORGANIZER 1 1.465 + * SEQUENCE 1 1.466 + * 1.467 + * ATTACH 0+ 1.468 + * CATEGORIES 0 or 1 This property MAY contain a list of values 1.469 + * CLASS 0 or 1 1.470 + * COMMENT 0 or 1 1.471 + * CONTACT 0+ 1.472 + * CREATED 0 or 1 1.473 + * DESCRIPTION 0 or 1 1.474 + * DTSTART 0 or 1 1.475 + * DUE 0 or 1 If present DURATION MUST NOT be present 1.476 + * DURATION 0 or 1 If present DUE MUST NOT be present 1.477 + * EXDATE 0+ 1.478 + * EXRULE 0+ 1.479 + * GEO 0 or 1 1.480 + * LAST-MODIFIED 0 or 1 1.481 + * LOCATION 0 or 1 1.482 + * PERCENT-COMPLETE 0 or 1 1.483 + * RDATE 0+ 1.484 + * RECURRENCE-ID 0 or 1 MUST only if referring to one or more 1.485 + * instances of a recurring calendar 1.486 + * component. Otherwise it MUST NOT be 1.487 + * present. 1.488 + * RELATED-TO 0+ 1.489 + * RESOURCES 0 or 1 This property MAY contain a list of values 1.490 + * RRULE 0+ 1.491 + * PRIORITY 0 or 1 1.492 + * STATUS 0 or 1 If present it MUST be set to "CANCELLED". 1.493 + * MUST NOT be used if purpose is to remove 1.494 + * "ATTENDEES" rather than cancel the entire 1.495 + * VTODO. 1.496 + * URL 0 or 1 1.497 + * X-PROPERTY 0+ 1.498 + * 1.499 + * REQUEST-STATUS 0 1.500 + * 1.501 + * VTIMEZONE 0 or 1 MUST be present if any date/time refers to 1.502 + * a timezone 1.503 + * X-COMPONENT 0+ 1.504 + * 1.505 + * VALARM 0 1.506 + * VEVENT 0 1.507 + * VFREEBUSY 0 1.508 + * </pre> 1.509 + * 1.510 + */ 1.511 + private class CancelValidator implements Validator { 1.512 + 1.513 + private static final long serialVersionUID = 1L; 1.514 + 1.515 + public void validate() throws ValidationException { 1.516 + PropertyValidator.getInstance().assertOne(Property.UID, getProperties()); 1.517 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties()); 1.518 + PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties()); 1.519 + PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties()); 1.520 + 1.521 + PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties()); 1.522 + PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties()); 1.523 + PropertyValidator.getInstance().assertOneOrLess(Property.COMMENT, getProperties()); 1.524 + PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties()); 1.525 + PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties()); 1.526 + PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties()); 1.527 + PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties()); 1.528 + PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties()); 1.529 + PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties()); 1.530 + PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties()); 1.531 + PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties()); 1.532 + PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties()); 1.533 + PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties()); 1.534 + PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties()); 1.535 + PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties()); 1.536 + PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties()); 1.537 + PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties()); 1.538 + 1.539 + PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties()); 1.540 + 1.541 + ComponentValidator.assertNone(Component.VALARM, getAlarms()); 1.542 + } 1.543 + } 1.544 + 1.545 + /** 1.546 + * <pre> 1.547 + * Component/Property Presence 1.548 + * ------------------- ---------------------------------------------- 1.549 + * METHOD 1 MUST be "COUNTER" 1.550 + * VTODO 1 1.551 + * ATTENDEE 1+ 1.552 + * DTSTAMP 1 1.553 + * ORGANIZER 1 1.554 + * PRIORITY 1 1.555 + * SUMMARY 1 Can be null 1.556 + * UID 1 1.557 + * 1.558 + * ATTACH 0+ 1.559 + * CATEGORIES 0 or 1 This property MAY contain a list of values 1.560 + * CLASS 0 or 1 1.561 + * COMMENT 0 or 1 1.562 + * CONTACT 0+ 1.563 + * CREATED 0 or 1 1.564 + * DESCRIPTION 0 or 1 Can be null 1.565 + * DTSTART 0 or 1 1.566 + * DUE 0 or 1 If present DURATION MUST NOT be present 1.567 + * DURATION 0 or 1 If present DUE MUST NOT be present 1.568 + * EXDATE 0+ 1.569 + * EXRULE 0+ 1.570 + * GEO 0 or 1 1.571 + * LAST-MODIFIED 0 or 1 1.572 + * LOCATION 0 or 1 1.573 + * PERCENT-COMPLETE 0 or 1 1.574 + * RDATE 0+ 1.575 + * RECURRENCE-ID 0 or 1 MUST only 3.5if referring to an instance of a 1.576 + * recurring calendar component. Otherwise it 1.577 + * MUST NOT be present. 1.578 + * RELATED-TO 0+ 1.579 + * REQUEST-STATUS 0+ 1.580 + * RESOURCES 0 or 1 This property MAY contain a list of values 1.581 + * RRULE 0 or 1 1.582 + * SEQUENCE 0 or 1 MUST echo the original SEQUENCE number. 1.583 + * MUST be present if non-zero. MAY be present 1.584 + * if zero. 1.585 + * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN- 1.586 + * PROCESS/CANCELLED 1.587 + * URL 0 or 1 1.588 + * X-PROPERTY 0+ 1.589 + * 1.590 + * 1.591 + * VALARM 0+ 1.592 + * VTIMEZONE 0 or 1 MUST be present if any date/time refers to 1.593 + * a timezone 1.594 + * X-COMPONENT 0+ 1.595 + * 1.596 + * VEVENT 0 1.597 + * VFREEBUSY 0 1.598 + * </pre> 1.599 + * 1.600 + */ 1.601 + private class CounterValidator implements Validator { 1.602 + 1.603 + private static final long serialVersionUID = 1L; 1.604 + 1.605 + public void validate() throws ValidationException { 1.606 + PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties()); 1.607 + 1.608 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties()); 1.609 + PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties()); 1.610 + PropertyValidator.getInstance().assertOne(Property.PRIORITY, getProperties()); 1.611 + PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties()); 1.612 + PropertyValidator.getInstance().assertOne(Property.UID, getProperties()); 1.613 + 1.614 + PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties()); 1.615 + PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties()); 1.616 + PropertyValidator.getInstance().assertOneOrLess(Property.COMMENT, getProperties()); 1.617 + PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties()); 1.618 + PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties()); 1.619 + PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties()); 1.620 + PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties()); 1.621 + PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties()); 1.622 + PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties()); 1.623 + PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties()); 1.624 + PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties()); 1.625 + PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties()); 1.626 + PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties()); 1.627 + PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties()); 1.628 + PropertyValidator.getInstance().assertOneOrLess(Property.RRULE, getProperties()); 1.629 + PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties()); 1.630 + PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties()); 1.631 + PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties()); 1.632 + 1.633 + for (final Iterator i = getAlarms().iterator(); i.hasNext();) { 1.634 + final VAlarm alarm = (VAlarm) i.next(); 1.635 + alarm.validate(Method.COUNTER); 1.636 + } 1.637 + } 1.638 + } 1.639 + 1.640 + /** 1.641 + * <pre> 1.642 + * Component/Property Presence 1.643 + * ------------------- --------------------------------------------- 1.644 + * METHOD 1 MUST be "DECLINECOUNTER" 1.645 + * 1.646 + * VTODO 1 1.647 + * ATTENDEE 1+ MUST for all attendees 1.648 + * DTSTAMP 1 1.649 + * ORGANIZER 1 1.650 + * SEQUENCE 1 MUST echo the original SEQUENCE number 1.651 + * UID 1 MUST echo original UID 1.652 + * ATTACH 0+ 1.653 + * CATEGORIES 0 or 1 This property may contain a list of values 1.654 + * CLASS 0 or 1 1.655 + * COMMENT 0 or 1 1.656 + * CONTACT 0+ 1.657 + * CREATED 0 or 1 1.658 + * DESCRIPTION 0 or 1 1.659 + * DTSTART 0 or 1 1.660 + * DUE 0 or 1 If present DURATION MUST NOT be present 1.661 + * DURATION 0 or 1 If present DUE MUST NOT be present 1.662 + * EXDATE 0+ 1.663 + * EXRULE 0+ 1.664 + * GEO 0 or 1 1.665 + * LAST-MODIFIED 0 or 1 1.666 + * LOCATION 0 or 1 1.667 + * PERCENT-COMPLETE 0 or 1 1.668 + * PRIORITY 0 or 1 1.669 + * RDATE 0+ 1.670 + * RECURRENCE-ID 0 or 1 MUST only if referring to an instance of a 1.671 + * recurring calendar component. Otherwise 1.672 + * it MUST NOT be present. 1.673 + * RELATED-TO 0+ 1.674 + * REQUEST-STATUS 0+ 1.675 + * RESOURCES 0 or 1 This property MAY contain a list of values 1.676 + * RRULE 0+ 1.677 + * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN- 1.678 + * PROCESS 1.679 + * URL 0 or 1 1.680 + * X-PROPERTY 0+ 1.681 + * 1.682 + * VTIMEZONE 0+ MUST be present if any date/time refers to 1.683 + * a timezone 1.684 + * X-COMPONENT 0+ 1.685 + * 1.686 + * VALARM 0 1.687 + * VEVENT 0 1.688 + * VFREEBUSY 0 1.689 + * </pre> 1.690 + * 1.691 + */ 1.692 + private class DeclineCounterValidator implements Validator { 1.693 + 1.694 + private static final long serialVersionUID = 1L; 1.695 + 1.696 + public void validate() throws ValidationException { 1.697 + PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties()); 1.698 + 1.699 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties()); 1.700 + PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties()); 1.701 + PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties()); 1.702 + PropertyValidator.getInstance().assertOne(Property.UID, getProperties()); 1.703 + 1.704 + PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties()); 1.705 + PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties()); 1.706 + PropertyValidator.getInstance().assertOneOrLess(Property.COMMENT, getProperties()); 1.707 + PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties()); 1.708 + PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties()); 1.709 + PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties()); 1.710 + PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties()); 1.711 + PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties()); 1.712 + PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties()); 1.713 + PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties()); 1.714 + PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties()); 1.715 + PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties()); 1.716 + PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties()); 1.717 + PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties()); 1.718 + PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties()); 1.719 + PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties()); 1.720 + PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties()); 1.721 + 1.722 + ComponentValidator.assertNone(Component.VALARM, getAlarms()); 1.723 + } 1.724 + } 1.725 + 1.726 + /** 1.727 + * <pre> 1.728 + * Component/Property Presence 1.729 + * ------------------- ---------------------------------------------- 1.730 + * METHOD 1 MUST be "PUBLISH" 1.731 + * VTODO 1+ 1.732 + * DTSTAMP 1 1.733 + * DTSTART 1 1.734 + * ORGANIZER 1 1.735 + * PRIORITY 1 1.736 + * SEQUENCE 0 or 1 MUST be present if value is greater than 1.737 + * 0, MAY be present if 0 1.738 + * SUMMARY 1 Can be null. 1.739 + * UID 1 1.740 + * 1.741 + * ATTACH 0+ 1.742 + * CATEGORIES 0 or 1 This property may contain a list of values 1.743 + * CLASS 0 or 1 1.744 + * COMMENT 0 or 1 1.745 + * CONTACT 0+ 1.746 + * CREATED 0 or 1 1.747 + * DESCRIPTION 0 or 1 Can be null 1.748 + * DUE 0 or 1 If present DURATION MUST NOT be present 1.749 + * DURATION 0 or 1 If present DUE MUST NOT be present 1.750 + * EXDATE 0+ 1.751 + * EXRULE 0+ 1.752 + * GEO 0 or 1 1.753 + * LAST-MODIFIED 0 or 1 1.754 + * LOCATION 0 or 1 1.755 + * PERCENT-COMPLETE 0 or 1 1.756 + * RDATE 0+ 1.757 + * RECURRENCE-ID 0 or 1 MUST only if referring to an instance of a 1.758 + * recurring calendar component. Otherwise 1.759 + * it MUST NOT be present. 1.760 + * 1.761 + * RELATED-TO 0+ 1.762 + * RESOURCES 0 or 1 This property may contain a list of values 1.763 + * RRULE 0+ 1.764 + * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN- 1.765 + * PROCESS/CANCELLED 1.766 + * URL 0 or 1 1.767 + * X-PROPERTY 0+ 1.768 + * 1.769 + * ATTENDEE 0 1.770 + * REQUEST-STATUS 0 1.771 + * 1.772 + * VTIMEZONE 0+ MUST be present if any date/time refers to 1.773 + * a timezone 1.774 + * VALARM 0+ 1.775 + * X-COMPONENT 0+ 1.776 + * 1.777 + * VFREEBUSY 0 1.778 + * VEVENT 0 1.779 + * VJOURNAL 0 1.780 + * </pre> 1.781 + * 1.782 + */ 1.783 + private class PublishValidator implements Validator { 1.784 + 1.785 + private static final long serialVersionUID = 1L; 1.786 + 1.787 + public void validate() throws ValidationException { 1.788 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties()); 1.789 + 1.790 + if (!CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) { 1.791 + PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties()); 1.792 + PropertyValidator.getInstance().assertOne(Property.PRIORITY, getProperties()); 1.793 + } 1.794 + 1.795 + PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties()); 1.796 + PropertyValidator.getInstance().assertOne(Property.UID, getProperties()); 1.797 + 1.798 + // DTSTART: RFC2446 conflicts with RCF2445.. 1.799 + PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties()); 1.800 + PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties()); 1.801 + PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties()); 1.802 + PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties()); 1.803 + PropertyValidator.getInstance().assertOneOrLess(Property.COMMENT, getProperties()); 1.804 + PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties()); 1.805 + PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties()); 1.806 + PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties()); 1.807 + PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties()); 1.808 + PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties()); 1.809 + PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties()); 1.810 + PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties()); 1.811 + PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties()); 1.812 + PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties()); 1.813 + PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties()); 1.814 + PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties()); 1.815 + PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties()); 1.816 + 1.817 + PropertyValidator.getInstance().assertNone(Property.ATTENDEE, getProperties()); 1.818 + PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties()); 1.819 + 1.820 + for (final Iterator i = getAlarms().iterator(); i.hasNext();) { 1.821 + final VAlarm alarm = (VAlarm) i.next(); 1.822 + alarm.validate(Method.PUBLISH); 1.823 + } 1.824 + } 1.825 + } 1.826 + 1.827 + /** 1.828 + * <pre> 1.829 + * Component/Property Presence 1.830 + * ------------------- --------------------------------------------- 1.831 + * METHOD 1 MUST be "REFRESH" 1.832 + * VTODO 1 1.833 + * ATTENDEE 1 1.834 + * DTSTAMP 1 1.835 + * UID 1 MUST echo original UID 1.836 + * 1.837 + * RECURRENCE-ID 0 or 1 MUST only if referring to an instance of a 1.838 + * Recurring calendar component. Otherwise it 1.839 + * MUST NOT be present 1.840 + * X-PROPERTY 0+ 1.841 + * 1.842 + * ATTACH 0 1.843 + * CATEGORIES 0 1.844 + * CLASS 0 1.845 + * COMMENT 0 1.846 + * CONTACT 0 1.847 + * CREATED 0 1.848 + * DESCRIPTION 0 1.849 + * DTSTART 0 1.850 + * DUE 0 1.851 + * DURATION 0 1.852 + * EXDATE 0 1.853 + * EXRULE 0 1.854 + * GEO 0 1.855 + * LAST-MODIFIED 0 1.856 + * LOCATION 0 1.857 + * ORGANIZER 0 1.858 + * PERCENT-COMPLETE 0 1.859 + * PRIORITY 0 1.860 + * RDATE 0 1.861 + * RELATED-TO 0 1.862 + * REQUEST-STATUS 0 1.863 + * RESOURCES 0 1.864 + * RRULE 0 1.865 + * SEQUENCE 0 1.866 + * STATUS 0 1.867 + * URL 0 1.868 + * 1.869 + * X-COMPONENT 0+ 1.870 + * 1.871 + * VALARM 0 1.872 + * VEVENT 0 1.873 + * VFREEBUSY 0 1.874 + * VTIMEZONE 0 1.875 + * </pre> 1.876 + * 1.877 + */ 1.878 + private class RefreshValidator implements Validator { 1.879 + 1.880 + private static final long serialVersionUID = 1L; 1.881 + 1.882 + public void validate() throws ValidationException { 1.883 + PropertyValidator.getInstance().assertOne(Property.ATTENDEE, getProperties()); 1.884 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties()); 1.885 + PropertyValidator.getInstance().assertOne(Property.UID, getProperties()); 1.886 + 1.887 + PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties()); 1.888 + 1.889 + PropertyValidator.getInstance().assertNone(Property.ATTACH, getProperties()); 1.890 + PropertyValidator.getInstance().assertNone(Property.CATEGORIES, getProperties()); 1.891 + PropertyValidator.getInstance().assertNone(Property.CLASS, getProperties()); 1.892 + PropertyValidator.getInstance().assertNone(Property.COMMENT, getProperties()); 1.893 + PropertyValidator.getInstance().assertNone(Property.CONTACT, getProperties()); 1.894 + PropertyValidator.getInstance().assertNone(Property.CREATED, getProperties()); 1.895 + PropertyValidator.getInstance().assertNone(Property.DESCRIPTION, getProperties()); 1.896 + PropertyValidator.getInstance().assertNone(Property.DTSTART, getProperties()); 1.897 + PropertyValidator.getInstance().assertNone(Property.DUE, getProperties()); 1.898 + PropertyValidator.getInstance().assertNone(Property.DURATION, getProperties()); 1.899 + PropertyValidator.getInstance().assertNone(Property.EXDATE, getProperties()); 1.900 + PropertyValidator.getInstance().assertNone(Property.EXRULE, getProperties()); 1.901 + PropertyValidator.getInstance().assertNone(Property.GEO, getProperties()); 1.902 + PropertyValidator.getInstance().assertNone(Property.LAST_MODIFIED, getProperties()); 1.903 + PropertyValidator.getInstance().assertNone(Property.LOCATION, getProperties()); 1.904 + PropertyValidator.getInstance().assertNone(Property.ORGANIZER, getProperties()); 1.905 + PropertyValidator.getInstance().assertNone(Property.PERCENT_COMPLETE, getProperties()); 1.906 + PropertyValidator.getInstance().assertNone(Property.PRIORITY, getProperties()); 1.907 + PropertyValidator.getInstance().assertNone(Property.RDATE, getProperties()); 1.908 + PropertyValidator.getInstance().assertNone(Property.RELATED_TO, getProperties()); 1.909 + PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties()); 1.910 + PropertyValidator.getInstance().assertNone(Property.RESOURCES, getProperties()); 1.911 + PropertyValidator.getInstance().assertNone(Property.RRULE, getProperties()); 1.912 + PropertyValidator.getInstance().assertNone(Property.SEQUENCE, getProperties()); 1.913 + PropertyValidator.getInstance().assertNone(Property.STATUS, getProperties()); 1.914 + PropertyValidator.getInstance().assertNone(Property.URL, getProperties()); 1.915 + 1.916 + ComponentValidator.assertNone(Component.VALARM, getAlarms()); 1.917 + } 1.918 + } 1.919 + 1.920 + /** 1.921 + * <pre> 1.922 + * Component/Property Presence 1.923 + * ------------------- --------------------------------------------- 1.924 + * METHOD 1 MUST be "REPLY" 1.925 + * VTODO 1+ All component MUST have the same UID 1.926 + * ATTENDEE 1+ 1.927 + * DTSTAMP 1 1.928 + * ORGANIZER 1 1.929 + * UID 1 MUST must be the address of the replying 1.930 + * attendee 1.931 + * REQUEST-STATUS 0+ 1.932 + * ATTACH 0+ 1.933 + * CATEGORIES 0 or 1 This property may contain a list of values 1.934 + * CLASS 0 or 1 1.935 + * COMMENT 0 or 1 1.936 + * CONTACT 0+ 1.937 + * CREATED 0 or 1 1.938 + * DESCRIPTION 0 or 1 1.939 + * DTSTART 0 or 1 1.940 + * DUE 0 or 1 If present DURATION MUST NOT be present 1.941 + * DURATION 0 or 1 If present DUE MUST NOT be present 1.942 + * EXDATE 0+ 1.943 + * EXRULE 0+ 1.944 + * GEO 0 or 1 1.945 + * LAST-MODIFIED 0 or 1 1.946 + * LOCATION 0 or 1 1.947 + * PERCENT-COMPLETE 0 or 1 1.948 + * PRIORITY 0 or 1 1.949 + * RDATE 0+ 1.950 + * RELATED-TO 0+ 1.951 + * RESOURCES 0 or 1 This property may contain a list of values 1.952 + * RRULE 0+ 1.953 + * RECURRENCE-ID 0 or 1 MUST only if referring to an instance of a 1.954 + * Recurring calendar component. Otherwise it 1.955 + * MUST NOT be present 1.956 + * SEQUENCE 0 or 1 MUST be the sequence number of 1.957 + * the original REQUEST if greater than 0. 1.958 + * MAY be present if 0. 1.959 + * STATUS 0 or 1 1.960 + * SUMMARY 0 or 1 Can be null 1.961 + * URL 0 or 1 1.962 + * X-PROPERTY 0+ 1.963 + * 1.964 + * VTIMEZONE 0 or 1 MUST be present if any date/time refers to 1.965 + * a timezone 1.966 + * X-COMPONENT 0+ 1.967 + * 1.968 + * VALARM 0 1.969 + * VEVENT 0 1.970 + * VFREEBUSY 0 1.971 + * </pre> 1.972 + * 1.973 + */ 1.974 + private class ReplyValidator implements Validator { 1.975 + 1.976 + private static final long serialVersionUID = 1L; 1.977 + 1.978 + public void validate() throws ValidationException { 1.979 + PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties()); 1.980 + 1.981 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties()); 1.982 + PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties()); 1.983 + PropertyValidator.getInstance().assertOne(Property.UID, getProperties()); 1.984 + 1.985 + PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties()); 1.986 + PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties()); 1.987 + PropertyValidator.getInstance().assertOneOrLess(Property.COMMENT, getProperties()); 1.988 + PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties()); 1.989 + PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties()); 1.990 + PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties()); 1.991 + PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties()); 1.992 + PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties()); 1.993 + PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties()); 1.994 + PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties()); 1.995 + PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties()); 1.996 + PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties()); 1.997 + PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties()); 1.998 + PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties()); 1.999 + PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties()); 1.1000 + PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties()); 1.1001 + PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties()); 1.1002 + PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY, getProperties()); 1.1003 + PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties()); 1.1004 + 1.1005 + ComponentValidator.assertNone(Component.VALARM, getAlarms()); 1.1006 + } 1.1007 + } 1.1008 + 1.1009 + /** 1.1010 + * <pre> 1.1011 + * Component/Property Presence 1.1012 + * ------------------- ---------------------------------------------- 1.1013 + * METHOD 1 MUST be "REQUEST" 1.1014 + * VTODO 1+ All components must have the same UID 1.1015 + * ATTENDEE 1+ 1.1016 + * DTSTAMP 1 1.1017 + * DTSTART 1 1.1018 + * ORGANIZER 1 1.1019 + * PRIORITY 1 1.1020 + * SEQUENCE 0 or 1 MUST be present if value is greater than 1.1021 + * 0, MAY be present if 0 1.1022 + * SUMMARY 1 Can be null. 1.1023 + * UID 1 1.1024 + * 1.1025 + * ATTACH 0+ 1.1026 + * CATEGORIES 0 or 1 This property may contain a list of 1.1027 + * values 1.1028 + * CLASS 0 or 1 1.1029 + * COMMENT 0 or 1 1.1030 + * CONTACT 0+ 1.1031 + * CREATED 0 or 1 1.1032 + * DESCRIPTION 0 or 1 Can be null 1.1033 + * DUE 0 or 1 If present DURATION MUST NOT be present 1.1034 + * DURATION 0 or 1 If present DUE MUST NOT be present 1.1035 + * EXDATE 0+ 1.1036 + * EXRULE 0+ 1.1037 + * GEO 0 or 1 1.1038 + * LAST-MODIFIED 0 or 1 1.1039 + * LOCATION 0 or 1 1.1040 + * PERCENT-COMPLETE 0 or 1 1.1041 + * RDATE 0+ 1.1042 + * RECURRENCE-ID 0 or 1 present if referring to an instance of a 1.1043 + * recurring calendar component. Otherwise 1.1044 + * it MUST NOT be present. 1.1045 + * RELATED-TO 0+ 1.1046 + * RESOURCES 0 or 1 This property may contain a list of 1.1047 + * values 1.1048 + * RRULE 0+ 1.1049 + * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN- 1.1050 + * PROCESS 1.1051 + * URL 0 or 1 1.1052 + * X-PROPERTY 0+ 1.1053 + * 1.1054 + * REQUEST-STATUS 0 1.1055 + * 1.1056 + * VALARM 0+ 1.1057 + * 1.1058 + * VTIMEZONE 0+ MUST be present if any date/time refers 1.1059 + * to a timezone 1.1060 + * X-COMPONENT 0+ 1.1061 + * 1.1062 + * VEVENT 0 1.1063 + * VFREEBUSY 0 1.1064 + * VJOURNAL 0 1.1065 + * </pre> 1.1066 + * 1.1067 + */ 1.1068 + private class RequestValidator implements Validator { 1.1069 + 1.1070 + private static final long serialVersionUID = 1L; 1.1071 + 1.1072 + public void validate() throws ValidationException { 1.1073 + PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties()); 1.1074 + 1.1075 + PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties()); 1.1076 + PropertyValidator.getInstance().assertOne(Property.DTSTART, getProperties()); 1.1077 + PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties()); 1.1078 + PropertyValidator.getInstance().assertOne(Property.PRIORITY, getProperties()); 1.1079 + PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties()); 1.1080 + PropertyValidator.getInstance().assertOne(Property.UID, getProperties()); 1.1081 + 1.1082 + PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties()); 1.1083 + PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties()); 1.1084 + PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties()); 1.1085 + PropertyValidator.getInstance().assertOneOrLess(Property.COMMENT, getProperties()); 1.1086 + PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties()); 1.1087 + PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties()); 1.1088 + PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties()); 1.1089 + PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties()); 1.1090 + PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties()); 1.1091 + PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties()); 1.1092 + PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties()); 1.1093 + PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties()); 1.1094 + PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties()); 1.1095 + PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties()); 1.1096 + PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties()); 1.1097 + PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties()); 1.1098 + 1.1099 + PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties()); 1.1100 + 1.1101 + for (final Iterator i = getAlarms().iterator(); i.hasNext();) { 1.1102 + final VAlarm alarm = (VAlarm) i.next(); 1.1103 + alarm.validate(Method.REQUEST); 1.1104 + } 1.1105 + } 1.1106 + } 1.1107 + 1.1108 + /** 1.1109 + * @return the optional access classification property 1.1110 + */ 1.1111 + public final Clazz getClassification() { 1.1112 + return (Clazz) getProperty(Property.CLASS); 1.1113 + } 1.1114 + 1.1115 + /** 1.1116 + * @return the optional date completed property 1.1117 + */ 1.1118 + public final Completed getDateCompleted() { 1.1119 + return (Completed) getProperty(Property.COMPLETED); 1.1120 + } 1.1121 + 1.1122 + /** 1.1123 + * @return the optional creation-time property 1.1124 + */ 1.1125 + public final Created getCreated() { 1.1126 + return (Created) getProperty(Property.CREATED); 1.1127 + } 1.1128 + 1.1129 + /** 1.1130 + * @return the optional description property 1.1131 + */ 1.1132 + public final Description getDescription() { 1.1133 + return (Description) getProperty(Property.DESCRIPTION); 1.1134 + } 1.1135 + 1.1136 + /** 1.1137 + * Convenience method to pull the DTSTART out of the property list. 1.1138 + * @return The DtStart object representation of the start Date 1.1139 + */ 1.1140 + public final DtStart getStartDate() { 1.1141 + return (DtStart) getProperty(Property.DTSTART); 1.1142 + } 1.1143 + 1.1144 + /** 1.1145 + * @return the optional geographic position property 1.1146 + */ 1.1147 + public final Geo getGeographicPos() { 1.1148 + return (Geo) getProperty(Property.GEO); 1.1149 + } 1.1150 + 1.1151 + /** 1.1152 + * @return the optional last-modified property 1.1153 + */ 1.1154 + public final LastModified getLastModified() { 1.1155 + return (LastModified) getProperty(Property.LAST_MODIFIED); 1.1156 + } 1.1157 + 1.1158 + /** 1.1159 + * @return the optional location property 1.1160 + */ 1.1161 + public final Location getLocation() { 1.1162 + return (Location) getProperty(Property.LOCATION); 1.1163 + } 1.1164 + 1.1165 + /** 1.1166 + * @return the optional organizer property 1.1167 + */ 1.1168 + public final Organizer getOrganizer() { 1.1169 + return (Organizer) getProperty(Property.ORGANIZER); 1.1170 + } 1.1171 + 1.1172 + /** 1.1173 + * @return the optional percentage complete property 1.1174 + */ 1.1175 + public final PercentComplete getPercentComplete() { 1.1176 + return (PercentComplete) getProperty(Property.PERCENT_COMPLETE); 1.1177 + } 1.1178 + 1.1179 + /** 1.1180 + * @return the optional priority property 1.1181 + */ 1.1182 + public final Priority getPriority() { 1.1183 + return (Priority) getProperty(Property.PRIORITY); 1.1184 + } 1.1185 + 1.1186 + /** 1.1187 + * @return the optional date-stamp property 1.1188 + */ 1.1189 + public final DtStamp getDateStamp() { 1.1190 + return (DtStamp) getProperty(Property.DTSTAMP); 1.1191 + } 1.1192 + 1.1193 + /** 1.1194 + * @return the optional sequence number property 1.1195 + */ 1.1196 + public final Sequence getSequence() { 1.1197 + return (Sequence) getProperty(Property.SEQUENCE); 1.1198 + } 1.1199 + 1.1200 + /** 1.1201 + * @return the optional status property 1.1202 + */ 1.1203 + public final Status getStatus() { 1.1204 + return (Status) getProperty(Property.STATUS); 1.1205 + } 1.1206 + 1.1207 + /** 1.1208 + * @return the optional summary property 1.1209 + */ 1.1210 + public final Summary getSummary() { 1.1211 + return (Summary) getProperty(Property.SUMMARY); 1.1212 + } 1.1213 + 1.1214 + /** 1.1215 + * @return the optional URL property 1.1216 + */ 1.1217 + public final Url getUrl() { 1.1218 + return (Url) getProperty(Property.URL); 1.1219 + } 1.1220 + 1.1221 + /** 1.1222 + * @return the optional recurrence identifier property 1.1223 + */ 1.1224 + public final RecurrenceId getRecurrenceId() { 1.1225 + return (RecurrenceId) getProperty(Property.RECURRENCE_ID); 1.1226 + } 1.1227 + 1.1228 + /** 1.1229 + * @return the optional Duration property 1.1230 + */ 1.1231 + public final Duration getDuration() { 1.1232 + return (Duration) getProperty(Property.DURATION); 1.1233 + } 1.1234 + 1.1235 + /** 1.1236 + * @return the optional due property 1.1237 + */ 1.1238 + public final Due getDue() { 1.1239 + return (Due) getProperty(Property.DUE); 1.1240 + } 1.1241 + 1.1242 + /** 1.1243 + * Returns the UID property of this component if available. 1.1244 + * @return a Uid instance, or null if no UID property exists 1.1245 + */ 1.1246 + public final Uid getUid() { 1.1247 + return (Uid) getProperty(Property.UID); 1.1248 + } 1.1249 + 1.1250 + /** 1.1251 + * {@inheritDoc} 1.1252 + */ 1.1253 + public boolean equals(final Object arg0) { 1.1254 + if (arg0 instanceof VToDo) { 1.1255 + return super.equals(arg0) 1.1256 + && ObjectUtils.equals(alarms, ((VToDo) arg0).getAlarms()); 1.1257 + } 1.1258 + return super.equals(arg0); 1.1259 + } 1.1260 + 1.1261 + /** 1.1262 + * {@inheritDoc} 1.1263 + */ 1.1264 + public int hashCode() { 1.1265 + return new HashCodeBuilder().append(getName()).append(getProperties()) 1.1266 + .append(getAlarms()).toHashCode(); 1.1267 + } 1.1268 + 1.1269 + /** 1.1270 + * Overrides default copy method to add support for copying alarm sub-components. 1.1271 + * @return a copy of the instance 1.1272 + * @throws ParseException where an error occurs parsing data 1.1273 + * @throws IOException where an error occurs reading data 1.1274 + * @throws URISyntaxException where an invalid URI is encountered 1.1275 + * @see net.fortuna.ical4j.model.Component#copy() 1.1276 + */ 1.1277 + public Component copy() throws ParseException, IOException, URISyntaxException { 1.1278 + final VToDo copy = (VToDo) super.copy(); 1.1279 + copy.alarms = new ComponentList(alarms); 1.1280 + return copy; 1.1281 + } 1.1282 +}