Tue, 10 Feb 2015 19:58:00 +0100
Upgrade the upgraded ical4j component to use org.apache.commons.lang3.
1 /**
2 * Copyright (c) 2012, Ben Fortuna
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * o Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * o Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * o Neither the name of Ben Fortuna nor the names of any other contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 package net.fortuna.ical4j.model.component;
34 import java.io.IOException;
35 import java.net.URISyntaxException;
36 import java.text.ParseException;
37 import java.util.HashMap;
38 import java.util.Iterator;
39 import java.util.Map;
41 import net.fortuna.ical4j.model.Component;
42 import net.fortuna.ical4j.model.ComponentList;
43 import net.fortuna.ical4j.model.Date;
44 import net.fortuna.ical4j.model.Dur;
45 import net.fortuna.ical4j.model.Property;
46 import net.fortuna.ical4j.model.PropertyList;
47 import net.fortuna.ical4j.model.ValidationException;
48 import net.fortuna.ical4j.model.Validator;
49 import net.fortuna.ical4j.model.property.Clazz;
50 import net.fortuna.ical4j.model.property.Completed;
51 import net.fortuna.ical4j.model.property.Created;
52 import net.fortuna.ical4j.model.property.Description;
53 import net.fortuna.ical4j.model.property.DtStamp;
54 import net.fortuna.ical4j.model.property.DtStart;
55 import net.fortuna.ical4j.model.property.Due;
56 import net.fortuna.ical4j.model.property.Duration;
57 import net.fortuna.ical4j.model.property.Geo;
58 import net.fortuna.ical4j.model.property.LastModified;
59 import net.fortuna.ical4j.model.property.Location;
60 import net.fortuna.ical4j.model.property.Method;
61 import net.fortuna.ical4j.model.property.Organizer;
62 import net.fortuna.ical4j.model.property.PercentComplete;
63 import net.fortuna.ical4j.model.property.Priority;
64 import net.fortuna.ical4j.model.property.RecurrenceId;
65 import net.fortuna.ical4j.model.property.Sequence;
66 import net.fortuna.ical4j.model.property.Status;
67 import net.fortuna.ical4j.model.property.Summary;
68 import net.fortuna.ical4j.model.property.Uid;
69 import net.fortuna.ical4j.model.property.Url;
70 import net.fortuna.ical4j.util.CompatibilityHints;
71 import net.fortuna.ical4j.util.ComponentValidator;
72 import net.fortuna.ical4j.util.PropertyValidator;
73 import net.fortuna.ical4j.util.Strings;
75 import org.apache.commons.lang3.ObjectUtils;
76 import org.apache.commons.lang3.builder.HashCodeBuilder;
78 /**
79 * $Id$ [Apr 5, 2004]
80 *
81 * Defines an iCalendar VTODO component.
82 *
83 * <pre>
84 * 4.6.2 To-do Component
85 *
86 * Component Name: VTODO
87 *
88 * Purpose: Provide a grouping of calendar properties that describe a
89 * to-do.
90 *
91 * Formal Definition: A "VTODO" calendar component is defined by the
92 * following notation:
93 *
94 * todoc = "BEGIN" ":" "VTODO" CRLF
95 * todoprop *alarmc
96 * "END" ":" "VTODO" CRLF
97 *
98 * todoprop = *(
99 *
100 * ; the following are optional,
101 * ; but MUST NOT occur more than once
102 *
103 * class / completed / created / description / dtstamp /
104 * dtstart / geo / last-mod / location / organizer /
105 * percent / priority / recurid / seq / status /
106 * summary / uid / url /
107 *
108 * ; either 'due' or 'duration' may appear in
109 * ; a 'todoprop', but 'due' and 'duration'
110 * ; MUST NOT occur in the same 'todoprop'
111 *
112 * due / duration /
113 *
114 * ; the following are optional,
115 * ; and MAY occur more than once
116 * attach / attendee / categories / comment / contact /
117 * exdate / exrule / rstatus / related / resources /
118 * rdate / rrule / x-prop
119 *
120 * )
121 * </pre>
122 *
123 * Example 1 - Creating a todo of two (2) hour duration starting tomorrow:
124 *
125 * <pre><code>
126 * java.util.Calendar cal = java.util.Calendar.getInstance();
127 * // tomorrow..
128 * cal.add(java.util.Calendar.DAY_OF_MONTH, 1);
129 * cal.set(java.util.Calendar.HOUR_OF_DAY, 11);
130 * cal.set(java.util.Calendar.MINUTE, 00);
131 *
132 * VToDo documentation = new VEvent(cal.getTime(), 1000 * 60 * 60 * 2,
133 * "Document calendar component usage");
134 *
135 * // add timezone information..
136 * VTimeZone tz = VTimeZone.getDefault();
137 * TzId tzParam = new TzId(tz.getProperties().getProperty(Property.TZID)
138 * .getValue());
139 * documentation.getProperties().getProperty(Property.DTSTART).getParameters()
140 * .add(tzParam);
141 * </code></pre>
142 *
143 * @author Ben Fortuna
144 */
145 public class VToDo extends CalendarComponent {
147 private static final long serialVersionUID = -269658210065896668L;
149 private final Map methodValidators = new HashMap();
150 {
151 methodValidators.put(Method.ADD, new AddValidator());
152 methodValidators.put(Method.CANCEL, new CancelValidator());
153 methodValidators.put(Method.COUNTER, new CounterValidator());
154 methodValidators.put(Method.DECLINE_COUNTER, new DeclineCounterValidator());
155 methodValidators.put(Method.PUBLISH, new PublishValidator());
156 methodValidators.put(Method.REFRESH, new RefreshValidator());
157 methodValidators.put(Method.REPLY, new ReplyValidator());
158 methodValidators.put(Method.REQUEST, new RequestValidator());
159 }
161 private ComponentList alarms = new ComponentList();
163 /**
164 * Default constructor.
165 */
166 public VToDo() {
167 super(VTODO);
168 getProperties().add(new DtStamp());
169 }
171 /**
172 * Constructor.
173 * @param properties a list of properties
174 */
175 public VToDo(final PropertyList properties) {
176 super(VTODO, properties);
177 }
179 /**
180 * Constructs a new VTODO instance starting at the specified time with the specified summary.
181 * @param start the start date of the new todo
182 * @param summary the todo summary
183 */
184 public VToDo(final Date start, final String summary) {
185 this();
186 getProperties().add(new DtStart(start));
187 getProperties().add(new Summary(summary));
188 }
190 /**
191 * Constructs a new VTODO instance starting and ending at the specified times with the specified summary.
192 * @param start the start date of the new todo
193 * @param due the due date of the new todo
194 * @param summary the todo summary
195 */
196 public VToDo(final Date start, final Date due, final String summary) {
197 this();
198 getProperties().add(new DtStart(start));
199 getProperties().add(new Due(due));
200 getProperties().add(new Summary(summary));
201 }
203 /**
204 * Constructs a new VTODO instance starting at the specified times, for the specified duration, with the specified
205 * summary.
206 * @param start the start date of the new todo
207 * @param duration the duration of the new todo
208 * @param summary the todo summary
209 */
210 public VToDo(final Date start, final Dur duration, final String summary) {
211 this();
212 getProperties().add(new DtStart(start));
213 getProperties().add(new Duration(duration));
214 getProperties().add(new Summary(summary));
215 }
217 /**
218 * Returns the list of alarms for this todo.
219 * @return a component list
220 */
221 public final ComponentList getAlarms() {
222 return alarms;
223 }
225 /**
226 * {@inheritDoc}
227 */
228 public final String toString() {
229 final StringBuffer buffer = new StringBuffer();
230 buffer.append(BEGIN);
231 buffer.append(':');
232 buffer.append(getName());
233 buffer.append(Strings.LINE_SEPARATOR);
234 buffer.append(getProperties());
235 buffer.append(getAlarms());
236 buffer.append(END);
237 buffer.append(':');
238 buffer.append(getName());
239 buffer.append(Strings.LINE_SEPARATOR);
240 return buffer.toString();
241 }
243 /**
244 * {@inheritDoc}
245 */
246 public final void validate(final boolean recurse)
247 throws ValidationException {
249 // validate that getAlarms() only contains VAlarm components
250 final Iterator iterator = getAlarms().iterator();
251 while (iterator.hasNext()) {
252 final Component component = (Component) iterator.next();
253 if (!(component instanceof VAlarm)) {
254 throw new ValidationException("Component ["
255 + component.getName() + "] may not occur in VTODO");
256 }
257 ((VAlarm) component).validate(recurse);
258 }
260 if (!CompatibilityHints
261 .isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) {
263 // From "4.8.4.7 Unique Identifier":
264 // Conformance: The property MUST be specified in the "VEVENT", "VTODO",
265 // "VJOURNAL" or "VFREEBUSY" calendar components.
266 PropertyValidator.getInstance().assertOne(Property.UID,
267 getProperties());
269 // From "4.8.7.2 Date/Time Stamp":
270 // Conformance: This property MUST be included in the "VEVENT", "VTODO",
271 // "VJOURNAL" or "VFREEBUSY" calendar components.
272 PropertyValidator.getInstance().assertOne(Property.DTSTAMP,
273 getProperties());
274 }
276 /*
277 * ; the following are optional, ; but MUST NOT occur more than once class / completed / created / description /
278 * dtstamp / dtstart / geo / last-mod / location / organizer / percent / priority / recurid / seq / status /
279 * summary / uid / url /
280 */
281 PropertyValidator.getInstance().assertOneOrLess(Property.CLASS,
282 getProperties());
283 PropertyValidator.getInstance().assertOneOrLess(Property.COMPLETED,
284 getProperties());
285 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED,
286 getProperties());
287 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION,
288 getProperties());
289 PropertyValidator.getInstance().assertOneOrLess(Property.DTSTAMP,
290 getProperties());
291 PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART,
292 getProperties());
293 PropertyValidator.getInstance().assertOneOrLess(Property.GEO,
294 getProperties());
295 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED,
296 getProperties());
297 PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION,
298 getProperties());
299 PropertyValidator.getInstance().assertOneOrLess(Property.ORGANIZER,
300 getProperties());
301 PropertyValidator.getInstance().assertOneOrLess(
302 Property.PERCENT_COMPLETE, getProperties());
303 PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY,
304 getProperties());
305 PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID,
306 getProperties());
307 PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE,
308 getProperties());
309 PropertyValidator.getInstance().assertOneOrLess(Property.STATUS,
310 getProperties());
311 PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY,
312 getProperties());
313 PropertyValidator.getInstance().assertOneOrLess(Property.UID,
314 getProperties());
315 PropertyValidator.getInstance().assertOneOrLess(Property.URL,
316 getProperties());
318 final Status status = (Status) getProperty(Property.STATUS);
319 if (status != null && !Status.VTODO_NEEDS_ACTION.getValue().equals(status.getValue())
320 && !Status.VTODO_COMPLETED.getValue().equals(status.getValue())
321 && !Status.VTODO_IN_PROCESS.getValue().equals(status.getValue())
322 && !Status.VTODO_CANCELLED.getValue().equals(status.getValue())) {
323 throw new ValidationException("Status property ["
324 + status.toString() + "] may not occur in VTODO");
325 }
327 /*
328 * ; either 'due' or 'duration' may appear in ; a 'todoprop', but 'due' and 'duration' ; MUST NOT occur in the
329 * same 'todoprop' due / duration /
330 */
331 try {
332 PropertyValidator.getInstance().assertNone(Property.DUE,
333 getProperties());
334 }
335 catch (ValidationException ve) {
336 PropertyValidator.getInstance().assertNone(Property.DURATION,
337 getProperties());
338 }
340 /*
341 * ; the following are optional, ; and MAY occur more than once attach / attendee / categories / comment /
342 * contact / exdate / exrule / rstatus / related / resources / rdate / rrule / x-prop
343 */
345 if (recurse) {
346 validateProperties();
347 }
348 }
350 /**
351 * {@inheritDoc}
352 */
353 protected Validator getValidator(Method method) {
354 return (Validator) methodValidators.get(method);
355 }
357 /**
358 * <pre>
359 * Component/Property Presence
360 * ------------------- ----------------------------------------------
361 * METHOD 1 MUST be "ADD"
362 * VTODO 1
363 * DTSTAMP 1
364 * ORGANIZER 1
365 * PRIORITY 1
366 * SEQUENCE 1 MUST be greater than 0
367 * SUMMARY 1 Can be null.
368 * UID 1 MUST match that of the original to-do
369 *
370 * ATTACH 0+
371 * ATTENDEE 0+
372 * CATEGORIES 0 or 1 This property may contain a list of
373 * values
374 * CLASS 0 or 1
375 * COMMENT 0 or 1
376 * CONTACT 0+
377 * CREATED 0 or 1
378 * DESCRIPTION 0 or 1 Can be null
379 * DTSTART 0 or 1
380 * DUE 0 or 1 If present DURATION MUST NOT be present
381 * DURATION 0 or 1 If present DUE MUST NOT be present
382 * EXDATE 0+
383 * EXRULE 0+
384 * GEO 0 or 1
385 * LAST-MODIFIED 0 or 1
386 * LOCATION 0 or 1
387 * PERCENT-COMPLETE 0 or 1
388 * RDATE 0+
389 * RELATED-TO 0+
390 * RESOURCES 0 or 1 This property may contain a list of
391 * values
392 * RRULE 0+
393 * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN-
394 * PROCESS
395 * URL 0 or 1
396 * X-PROPERTY 0+
397 *
398 * RECURRENCE-ID 0
399 * REQUEST-STATUS 0
400 *
401 * VALARM 0+
402 * VTIMEZONE 0+ MUST be present if any date/time refers
403 * to a timezone
404 * X-COMPONENT 0+
405 *
406 * VEVENT 0
407 * VJOURNAL 0
408 * VFREEBUSY 0
409 * </pre>
410 *
411 */
412 private class AddValidator implements Validator {
414 private static final long serialVersionUID = 1L;
416 public void validate() throws ValidationException {
417 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
418 PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
419 PropertyValidator.getInstance().assertOne(Property.PRIORITY, getProperties());
420 PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties());
421 PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
422 PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
424 PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
425 PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
426 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
427 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
428 PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties());
429 PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties());
430 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
431 PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
432 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
433 PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
434 PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties());
435 PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
436 PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
437 PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
439 PropertyValidator.getInstance().assertNone(Property.RECURRENCE_ID, getProperties());
440 PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
442 for (final Iterator i = getAlarms().iterator(); i.hasNext();) {
443 final VAlarm alarm = (VAlarm) i.next();
444 alarm.validate(Method.ADD);
445 }
446 }
447 }
449 /**
450 * <pre>
451 * Component/Property Presence
452 * ------------------- ---------------------------------------------
453 * METHOD 1 MUST be "CANCEL"
454 * VTODO 1
455 * ATTENDEE 0+ include all "Attendees" being removed from
456 * the todo. MUST include all "Attendees" if
457 * the entire todo is cancelled.
458 * UID 1 MUST echo original UID
459 * DTSTAMP 1
460 * ORGANIZER 1
461 * SEQUENCE 1
462 *
463 * ATTACH 0+
464 * CATEGORIES 0 or 1 This property MAY contain a list of values
465 * CLASS 0 or 1
466 * COMMENT 0 or 1
467 * CONTACT 0+
468 * CREATED 0 or 1
469 * DESCRIPTION 0 or 1
470 * DTSTART 0 or 1
471 * DUE 0 or 1 If present DURATION MUST NOT be present
472 * DURATION 0 or 1 If present DUE MUST NOT be present
473 * EXDATE 0+
474 * EXRULE 0+
475 * GEO 0 or 1
476 * LAST-MODIFIED 0 or 1
477 * LOCATION 0 or 1
478 * PERCENT-COMPLETE 0 or 1
479 * RDATE 0+
480 * RECURRENCE-ID 0 or 1 MUST only if referring to one or more
481 * instances of a recurring calendar
482 * component. Otherwise it MUST NOT be
483 * present.
484 * RELATED-TO 0+
485 * RESOURCES 0 or 1 This property MAY contain a list of values
486 * RRULE 0+
487 * PRIORITY 0 or 1
488 * STATUS 0 or 1 If present it MUST be set to "CANCELLED".
489 * MUST NOT be used if purpose is to remove
490 * "ATTENDEES" rather than cancel the entire
491 * VTODO.
492 * URL 0 or 1
493 * X-PROPERTY 0+
494 *
495 * REQUEST-STATUS 0
496 *
497 * VTIMEZONE 0 or 1 MUST be present if any date/time refers to
498 * a timezone
499 * X-COMPONENT 0+
500 *
501 * VALARM 0
502 * VEVENT 0
503 * VFREEBUSY 0
504 * </pre>
505 *
506 */
507 private class CancelValidator implements Validator {
509 private static final long serialVersionUID = 1L;
511 public void validate() throws ValidationException {
512 PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
513 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
514 PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
515 PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties());
517 PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
518 PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
519 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
520 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
521 PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties());
522 PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties());
523 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
524 PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
525 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
526 PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
527 PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties());
528 PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
529 PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
530 PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
531 PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
532 PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
534 PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
536 ComponentValidator.assertNone(Component.VALARM, getAlarms());
537 }
538 }
540 /**
541 * <pre>
542 * Component/Property Presence
543 * ------------------- ----------------------------------------------
544 * METHOD 1 MUST be "COUNTER"
545 * VTODO 1
546 * ATTENDEE 1+
547 * DTSTAMP 1
548 * ORGANIZER 1
549 * PRIORITY 1
550 * SUMMARY 1 Can be null
551 * UID 1
552 *
553 * ATTACH 0+
554 * CATEGORIES 0 or 1 This property MAY contain a list of values
555 * CLASS 0 or 1
556 * COMMENT 0 or 1
557 * CONTACT 0+
558 * CREATED 0 or 1
559 * DESCRIPTION 0 or 1 Can be null
560 * DTSTART 0 or 1
561 * DUE 0 or 1 If present DURATION MUST NOT be present
562 * DURATION 0 or 1 If present DUE MUST NOT be present
563 * EXDATE 0+
564 * EXRULE 0+
565 * GEO 0 or 1
566 * LAST-MODIFIED 0 or 1
567 * LOCATION 0 or 1
568 * PERCENT-COMPLETE 0 or 1
569 * RDATE 0+
570 * RECURRENCE-ID 0 or 1 MUST only 3.5if referring to an instance of a
571 * recurring calendar component. Otherwise it
572 * MUST NOT be present.
573 * RELATED-TO 0+
574 * REQUEST-STATUS 0+
575 * RESOURCES 0 or 1 This property MAY contain a list of values
576 * RRULE 0 or 1
577 * SEQUENCE 0 or 1 MUST echo the original SEQUENCE number.
578 * MUST be present if non-zero. MAY be present
579 * if zero.
580 * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN-
581 * PROCESS/CANCELLED
582 * URL 0 or 1
583 * X-PROPERTY 0+
584 *
585 *
586 * VALARM 0+
587 * VTIMEZONE 0 or 1 MUST be present if any date/time refers to
588 * a timezone
589 * X-COMPONENT 0+
590 *
591 * VEVENT 0
592 * VFREEBUSY 0
593 * </pre>
594 *
595 */
596 private class CounterValidator implements Validator {
598 private static final long serialVersionUID = 1L;
600 public void validate() throws ValidationException {
601 PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties());
603 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
604 PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
605 PropertyValidator.getInstance().assertOne(Property.PRIORITY, getProperties());
606 PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
607 PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
609 PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
610 PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
611 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
612 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
613 PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties());
614 PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties());
615 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
616 PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
617 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
618 PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
619 PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties());
620 PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
621 PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
622 PropertyValidator.getInstance().assertOneOrLess(Property.RRULE, getProperties());
623 PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties());
624 PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
625 PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
627 for (final Iterator i = getAlarms().iterator(); i.hasNext();) {
628 final VAlarm alarm = (VAlarm) i.next();
629 alarm.validate(Method.COUNTER);
630 }
631 }
632 }
634 /**
635 * <pre>
636 * Component/Property Presence
637 * ------------------- ---------------------------------------------
638 * METHOD 1 MUST be "DECLINECOUNTER"
639 *
640 * VTODO 1
641 * ATTENDEE 1+ MUST for all attendees
642 * DTSTAMP 1
643 * ORGANIZER 1
644 * SEQUENCE 1 MUST echo the original SEQUENCE number
645 * UID 1 MUST echo original UID
646 * ATTACH 0+
647 * CATEGORIES 0 or 1 This property may contain a list of values
648 * CLASS 0 or 1
649 * COMMENT 0 or 1
650 * CONTACT 0+
651 * CREATED 0 or 1
652 * DESCRIPTION 0 or 1
653 * DTSTART 0 or 1
654 * DUE 0 or 1 If present DURATION MUST NOT be present
655 * DURATION 0 or 1 If present DUE MUST NOT be present
656 * EXDATE 0+
657 * EXRULE 0+
658 * GEO 0 or 1
659 * LAST-MODIFIED 0 or 1
660 * LOCATION 0 or 1
661 * PERCENT-COMPLETE 0 or 1
662 * PRIORITY 0 or 1
663 * RDATE 0+
664 * RECURRENCE-ID 0 or 1 MUST only if referring to an instance of a
665 * recurring calendar component. Otherwise
666 * it MUST NOT be present.
667 * RELATED-TO 0+
668 * REQUEST-STATUS 0+
669 * RESOURCES 0 or 1 This property MAY contain a list of values
670 * RRULE 0+
671 * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN-
672 * PROCESS
673 * URL 0 or 1
674 * X-PROPERTY 0+
675 *
676 * VTIMEZONE 0+ MUST be present if any date/time refers to
677 * a timezone
678 * X-COMPONENT 0+
679 *
680 * VALARM 0
681 * VEVENT 0
682 * VFREEBUSY 0
683 * </pre>
684 *
685 */
686 private class DeclineCounterValidator implements Validator {
688 private static final long serialVersionUID = 1L;
690 public void validate() throws ValidationException {
691 PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties());
693 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
694 PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
695 PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties());
696 PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
698 PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
699 PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
700 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
701 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
702 PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties());
703 PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties());
704 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
705 PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
706 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
707 PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
708 PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties());
709 PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
710 PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
711 PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
712 PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
713 PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
715 ComponentValidator.assertNone(Component.VALARM, getAlarms());
716 }
717 }
719 /**
720 * <pre>
721 * Component/Property Presence
722 * ------------------- ----------------------------------------------
723 * METHOD 1 MUST be "PUBLISH"
724 * VTODO 1+
725 * DTSTAMP 1
726 * DTSTART 1
727 * ORGANIZER 1
728 * PRIORITY 1
729 * SEQUENCE 0 or 1 MUST be present if value is greater than
730 * 0, MAY be present if 0
731 * SUMMARY 1 Can be null.
732 * UID 1
733 *
734 * ATTACH 0+
735 * CATEGORIES 0 or 1 This property may contain a list of values
736 * CLASS 0 or 1
737 * COMMENT 0 or 1
738 * CONTACT 0+
739 * CREATED 0 or 1
740 * DESCRIPTION 0 or 1 Can be null
741 * DUE 0 or 1 If present DURATION MUST NOT be present
742 * DURATION 0 or 1 If present DUE MUST NOT be present
743 * EXDATE 0+
744 * EXRULE 0+
745 * GEO 0 or 1
746 * LAST-MODIFIED 0 or 1
747 * LOCATION 0 or 1
748 * PERCENT-COMPLETE 0 or 1
749 * RDATE 0+
750 * RECURRENCE-ID 0 or 1 MUST only if referring to an instance of a
751 * recurring calendar component. Otherwise
752 * it MUST NOT be present.
753 *
754 * RELATED-TO 0+
755 * RESOURCES 0 or 1 This property may contain a list of values
756 * RRULE 0+
757 * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN-
758 * PROCESS/CANCELLED
759 * URL 0 or 1
760 * X-PROPERTY 0+
761 *
762 * ATTENDEE 0
763 * REQUEST-STATUS 0
764 *
765 * VTIMEZONE 0+ MUST be present if any date/time refers to
766 * a timezone
767 * VALARM 0+
768 * X-COMPONENT 0+
769 *
770 * VFREEBUSY 0
771 * VEVENT 0
772 * VJOURNAL 0
773 * </pre>
774 *
775 */
776 private class PublishValidator implements Validator {
778 private static final long serialVersionUID = 1L;
780 public void validate() throws ValidationException {
781 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
783 if (!CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) {
784 PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
785 PropertyValidator.getInstance().assertOne(Property.PRIORITY, getProperties());
786 }
788 PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
789 PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
791 // DTSTART: RFC2446 conflicts with RCF2445..
792 PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties());
793 PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties());
794 PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
795 PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
796 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
797 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
798 PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties());
799 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
800 PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
801 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
802 PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
803 PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties());
804 PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
805 PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
806 PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
807 PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
809 PropertyValidator.getInstance().assertNone(Property.ATTENDEE, getProperties());
810 PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
812 for (final Iterator i = getAlarms().iterator(); i.hasNext();) {
813 final VAlarm alarm = (VAlarm) i.next();
814 alarm.validate(Method.PUBLISH);
815 }
816 }
817 }
819 /**
820 * <pre>
821 * Component/Property Presence
822 * ------------------- ---------------------------------------------
823 * METHOD 1 MUST be "REFRESH"
824 * VTODO 1
825 * ATTENDEE 1
826 * DTSTAMP 1
827 * UID 1 MUST echo original UID
828 *
829 * RECURRENCE-ID 0 or 1 MUST only if referring to an instance of a
830 * Recurring calendar component. Otherwise it
831 * MUST NOT be present
832 * X-PROPERTY 0+
833 *
834 * ATTACH 0
835 * CATEGORIES 0
836 * CLASS 0
837 * COMMENT 0
838 * CONTACT 0
839 * CREATED 0
840 * DESCRIPTION 0
841 * DTSTART 0
842 * DUE 0
843 * DURATION 0
844 * EXDATE 0
845 * EXRULE 0
846 * GEO 0
847 * LAST-MODIFIED 0
848 * LOCATION 0
849 * ORGANIZER 0
850 * PERCENT-COMPLETE 0
851 * PRIORITY 0
852 * RDATE 0
853 * RELATED-TO 0
854 * REQUEST-STATUS 0
855 * RESOURCES 0
856 * RRULE 0
857 * SEQUENCE 0
858 * STATUS 0
859 * URL 0
860 *
861 * X-COMPONENT 0+
862 *
863 * VALARM 0
864 * VEVENT 0
865 * VFREEBUSY 0
866 * VTIMEZONE 0
867 * </pre>
868 *
869 */
870 private class RefreshValidator implements Validator {
872 private static final long serialVersionUID = 1L;
874 public void validate() throws ValidationException {
875 PropertyValidator.getInstance().assertOne(Property.ATTENDEE, getProperties());
876 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
877 PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
879 PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
881 PropertyValidator.getInstance().assertNone(Property.ATTACH, getProperties());
882 PropertyValidator.getInstance().assertNone(Property.CATEGORIES, getProperties());
883 PropertyValidator.getInstance().assertNone(Property.CLASS, getProperties());
884 PropertyValidator.getInstance().assertNone(Property.CONTACT, getProperties());
885 PropertyValidator.getInstance().assertNone(Property.CREATED, getProperties());
886 PropertyValidator.getInstance().assertNone(Property.DESCRIPTION, getProperties());
887 PropertyValidator.getInstance().assertNone(Property.DTSTART, getProperties());
888 PropertyValidator.getInstance().assertNone(Property.DUE, getProperties());
889 PropertyValidator.getInstance().assertNone(Property.DURATION, getProperties());
890 PropertyValidator.getInstance().assertNone(Property.EXDATE, getProperties());
891 PropertyValidator.getInstance().assertNone(Property.EXRULE, getProperties());
892 PropertyValidator.getInstance().assertNone(Property.GEO, getProperties());
893 PropertyValidator.getInstance().assertNone(Property.LAST_MODIFIED, getProperties());
894 PropertyValidator.getInstance().assertNone(Property.LOCATION, getProperties());
895 PropertyValidator.getInstance().assertNone(Property.ORGANIZER, getProperties());
896 PropertyValidator.getInstance().assertNone(Property.PERCENT_COMPLETE, getProperties());
897 PropertyValidator.getInstance().assertNone(Property.PRIORITY, getProperties());
898 PropertyValidator.getInstance().assertNone(Property.RDATE, getProperties());
899 PropertyValidator.getInstance().assertNone(Property.RELATED_TO, getProperties());
900 PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
901 PropertyValidator.getInstance().assertNone(Property.RESOURCES, getProperties());
902 PropertyValidator.getInstance().assertNone(Property.RRULE, getProperties());
903 PropertyValidator.getInstance().assertNone(Property.SEQUENCE, getProperties());
904 PropertyValidator.getInstance().assertNone(Property.STATUS, getProperties());
905 PropertyValidator.getInstance().assertNone(Property.URL, getProperties());
907 ComponentValidator.assertNone(Component.VALARM, getAlarms());
908 }
909 }
911 /**
912 * <pre>
913 * Component/Property Presence
914 * ------------------- ---------------------------------------------
915 * METHOD 1 MUST be "REPLY"
916 * VTODO 1+ All component MUST have the same UID
917 * ATTENDEE 1+
918 * DTSTAMP 1
919 * ORGANIZER 1
920 * UID 1 MUST must be the address of the replying
921 * attendee
922 * REQUEST-STATUS 0+
923 * ATTACH 0+
924 * CATEGORIES 0 or 1 This property may contain a list of values
925 * CLASS 0 or 1
926 * COMMENT 0 or 1
927 * CONTACT 0+
928 * CREATED 0 or 1
929 * DESCRIPTION 0 or 1
930 * DTSTART 0 or 1
931 * DUE 0 or 1 If present DURATION MUST NOT be present
932 * DURATION 0 or 1 If present DUE MUST NOT be present
933 * EXDATE 0+
934 * EXRULE 0+
935 * GEO 0 or 1
936 * LAST-MODIFIED 0 or 1
937 * LOCATION 0 or 1
938 * PERCENT-COMPLETE 0 or 1
939 * PRIORITY 0 or 1
940 * RDATE 0+
941 * RELATED-TO 0+
942 * RESOURCES 0 or 1 This property may contain a list of values
943 * RRULE 0+
944 * RECURRENCE-ID 0 or 1 MUST only if referring to an instance of a
945 * Recurring calendar component. Otherwise it
946 * MUST NOT be present
947 * SEQUENCE 0 or 1 MUST be the sequence number of
948 * the original REQUEST if greater than 0.
949 * MAY be present if 0.
950 * STATUS 0 or 1
951 * SUMMARY 0 or 1 Can be null
952 * URL 0 or 1
953 * X-PROPERTY 0+
954 *
955 * VTIMEZONE 0 or 1 MUST be present if any date/time refers to
956 * a timezone
957 * X-COMPONENT 0+
958 *
959 * VALARM 0
960 * VEVENT 0
961 * VFREEBUSY 0
962 * </pre>
963 *
964 */
965 private class ReplyValidator implements Validator {
967 private static final long serialVersionUID = 1L;
969 public void validate() throws ValidationException {
970 PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties());
972 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
973 PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
974 PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
976 PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
977 PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
978 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
979 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
980 PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties());
981 PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties());
982 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
983 PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
984 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
985 PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
986 PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties());
987 PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
988 PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
989 PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
990 PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties());
991 PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
992 PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY, getProperties());
993 PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
995 ComponentValidator.assertNone(Component.VALARM, getAlarms());
996 }
997 }
999 /**
1000 * <pre>
1001 * Component/Property Presence
1002 * ------------------- ----------------------------------------------
1003 * METHOD 1 MUST be "REQUEST"
1004 * VTODO 1+ All components must have the same UID
1005 * ATTENDEE 1+
1006 * DTSTAMP 1
1007 * DTSTART 1
1008 * ORGANIZER 1
1009 * PRIORITY 1
1010 * SEQUENCE 0 or 1 MUST be present if value is greater than
1011 * 0, MAY be present if 0
1012 * SUMMARY 1 Can be null.
1013 * UID 1
1014 *
1015 * ATTACH 0+
1016 * CATEGORIES 0 or 1 This property may contain a list of
1017 * values
1018 * CLASS 0 or 1
1019 * COMMENT 0 or 1
1020 * CONTACT 0+
1021 * CREATED 0 or 1
1022 * DESCRIPTION 0 or 1 Can be null
1023 * DUE 0 or 1 If present DURATION MUST NOT be present
1024 * DURATION 0 or 1 If present DUE MUST NOT be present
1025 * EXDATE 0+
1026 * EXRULE 0+
1027 * GEO 0 or 1
1028 * LAST-MODIFIED 0 or 1
1029 * LOCATION 0 or 1
1030 * PERCENT-COMPLETE 0 or 1
1031 * RDATE 0+
1032 * RECURRENCE-ID 0 or 1 present if referring to an instance of a
1033 * recurring calendar component. Otherwise
1034 * it MUST NOT be present.
1035 * RELATED-TO 0+
1036 * RESOURCES 0 or 1 This property may contain a list of
1037 * values
1038 * RRULE 0+
1039 * STATUS 0 or 1 MAY be one of COMPLETED/NEEDS ACTION/IN-
1040 * PROCESS
1041 * URL 0 or 1
1042 * X-PROPERTY 0+
1043 *
1044 * REQUEST-STATUS 0
1045 *
1046 * VALARM 0+
1047 *
1048 * VTIMEZONE 0+ MUST be present if any date/time refers
1049 * to a timezone
1050 * X-COMPONENT 0+
1051 *
1052 * VEVENT 0
1053 * VFREEBUSY 0
1054 * VJOURNAL 0
1055 * </pre>
1056 *
1057 */
1058 private class RequestValidator implements Validator {
1060 private static final long serialVersionUID = 1L;
1062 public void validate() throws ValidationException {
1063 PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties());
1065 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
1066 PropertyValidator.getInstance().assertOne(Property.DTSTART, getProperties());
1067 PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
1068 PropertyValidator.getInstance().assertOne(Property.PRIORITY, getProperties());
1069 PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
1070 PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
1072 PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties());
1073 PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
1074 PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
1075 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
1076 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
1077 PropertyValidator.getInstance().assertOneOrLess(Property.DUE, getProperties());
1078 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
1079 PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
1080 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
1081 PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
1082 PropertyValidator.getInstance().assertOneOrLess(Property.PERCENT_COMPLETE, getProperties());
1083 PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
1084 PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
1085 PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
1086 PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
1088 PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
1090 for (final Iterator i = getAlarms().iterator(); i.hasNext();) {
1091 final VAlarm alarm = (VAlarm) i.next();
1092 alarm.validate(Method.REQUEST);
1093 }
1094 }
1095 }
1097 /**
1098 * @return the optional access classification property
1099 */
1100 public final Clazz getClassification() {
1101 return (Clazz) getProperty(Property.CLASS);
1102 }
1104 /**
1105 * @return the optional date completed property
1106 */
1107 public final Completed getDateCompleted() {
1108 return (Completed) getProperty(Property.COMPLETED);
1109 }
1111 /**
1112 * @return the optional creation-time property
1113 */
1114 public final Created getCreated() {
1115 return (Created) getProperty(Property.CREATED);
1116 }
1118 /**
1119 * @return the optional description property
1120 */
1121 public final Description getDescription() {
1122 return (Description) getProperty(Property.DESCRIPTION);
1123 }
1125 /**
1126 * Convenience method to pull the DTSTART out of the property list.
1127 * @return The DtStart object representation of the start Date
1128 */
1129 public final DtStart getStartDate() {
1130 return (DtStart) getProperty(Property.DTSTART);
1131 }
1133 /**
1134 * @return the optional geographic position property
1135 */
1136 public final Geo getGeographicPos() {
1137 return (Geo) getProperty(Property.GEO);
1138 }
1140 /**
1141 * @return the optional last-modified property
1142 */
1143 public final LastModified getLastModified() {
1144 return (LastModified) getProperty(Property.LAST_MODIFIED);
1145 }
1147 /**
1148 * @return the optional location property
1149 */
1150 public final Location getLocation() {
1151 return (Location) getProperty(Property.LOCATION);
1152 }
1154 /**
1155 * @return the optional organizer property
1156 */
1157 public final Organizer getOrganizer() {
1158 return (Organizer) getProperty(Property.ORGANIZER);
1159 }
1161 /**
1162 * @return the optional percentage complete property
1163 */
1164 public final PercentComplete getPercentComplete() {
1165 return (PercentComplete) getProperty(Property.PERCENT_COMPLETE);
1166 }
1168 /**
1169 * @return the optional priority property
1170 */
1171 public final Priority getPriority() {
1172 return (Priority) getProperty(Property.PRIORITY);
1173 }
1175 /**
1176 * @return the optional date-stamp property
1177 */
1178 public final DtStamp getDateStamp() {
1179 return (DtStamp) getProperty(Property.DTSTAMP);
1180 }
1182 /**
1183 * @return the optional sequence number property
1184 */
1185 public final Sequence getSequence() {
1186 return (Sequence) getProperty(Property.SEQUENCE);
1187 }
1189 /**
1190 * @return the optional status property
1191 */
1192 public final Status getStatus() {
1193 return (Status) getProperty(Property.STATUS);
1194 }
1196 /**
1197 * @return the optional summary property
1198 */
1199 public final Summary getSummary() {
1200 return (Summary) getProperty(Property.SUMMARY);
1201 }
1203 /**
1204 * @return the optional URL property
1205 */
1206 public final Url getUrl() {
1207 return (Url) getProperty(Property.URL);
1208 }
1210 /**
1211 * @return the optional recurrence identifier property
1212 */
1213 public final RecurrenceId getRecurrenceId() {
1214 return (RecurrenceId) getProperty(Property.RECURRENCE_ID);
1215 }
1217 /**
1218 * @return the optional Duration property
1219 */
1220 public final Duration getDuration() {
1221 return (Duration) getProperty(Property.DURATION);
1222 }
1224 /**
1225 * @return the optional due property
1226 */
1227 public final Due getDue() {
1228 return (Due) getProperty(Property.DUE);
1229 }
1231 /**
1232 * Returns the UID property of this component if available.
1233 * @return a Uid instance, or null if no UID property exists
1234 */
1235 public final Uid getUid() {
1236 return (Uid) getProperty(Property.UID);
1237 }
1239 /**
1240 * {@inheritDoc}
1241 */
1242 public boolean equals(final Object arg0) {
1243 if (arg0 instanceof VToDo) {
1244 return super.equals(arg0)
1245 && ObjectUtils.equals(alarms, ((VToDo) arg0).getAlarms());
1246 }
1247 return super.equals(arg0);
1248 }
1250 /**
1251 * {@inheritDoc}
1252 */
1253 public int hashCode() {
1254 return new HashCodeBuilder().append(getName()).append(getProperties())
1255 .append(getAlarms()).toHashCode();
1256 }
1258 /**
1259 * Overrides default copy method to add support for copying alarm sub-components.
1260 * @return a copy of the instance
1261 * @throws ParseException where an error occurs parsing data
1262 * @throws IOException where an error occurs reading data
1263 * @throws URISyntaxException where an invalid URI is encountered
1264 * @see net.fortuna.ical4j.model.Component#copy()
1265 */
1266 public Component copy() throws ParseException, IOException, URISyntaxException {
1267 final VToDo copy = (VToDo) super.copy();
1268 copy.alarms = new ComponentList(alarms);
1269 return copy;
1270 }
1271 }