001 package biweekly.component;
002
003 import java.util.Date;
004 import java.util.List;
005
006 import biweekly.property.Attachment;
007 import biweekly.property.Attendee;
008 import biweekly.property.Categories;
009 import biweekly.property.Classification;
010 import biweekly.property.Comment;
011 import biweekly.property.Completed;
012 import biweekly.property.Contact;
013 import biweekly.property.Created;
014 import biweekly.property.DateDue;
015 import biweekly.property.DateStart;
016 import biweekly.property.DateTimeStamp;
017 import biweekly.property.Description;
018 import biweekly.property.DurationProperty;
019 import biweekly.property.ExceptionDates;
020 import biweekly.property.Geo;
021 import biweekly.property.LastModified;
022 import biweekly.property.Location;
023 import biweekly.property.Method;
024 import biweekly.property.Organizer;
025 import biweekly.property.PercentComplete;
026 import biweekly.property.Priority;
027 import biweekly.property.RecurrenceDates;
028 import biweekly.property.RecurrenceId;
029 import biweekly.property.RecurrenceRule;
030 import biweekly.property.RelatedTo;
031 import biweekly.property.RequestStatus;
032 import biweekly.property.Resources;
033 import biweekly.property.Sequence;
034 import biweekly.property.Status;
035 import biweekly.property.Summary;
036 import biweekly.property.Uid;
037 import biweekly.property.Url;
038
039 /*
040 Copyright (c) 2013, Michael Angstadt
041 All rights reserved.
042
043 Redistribution and use in source and binary forms, with or without
044 modification, are permitted provided that the following conditions are met:
045
046 1. Redistributions of source code must retain the above copyright notice, this
047 list of conditions and the following disclaimer.
048 2. Redistributions in binary form must reproduce the above copyright notice,
049 this list of conditions and the following disclaimer in the documentation
050 and/or other materials provided with the distribution.
051
052 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
053 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
054 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
055 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
056 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
057 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
058 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
059 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
060 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
061 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
062 */
063
064 /**
065 * Defines an action item or assignment.
066 * @author Michael Angstadt
067 * @see <a href="http://tools.ietf.org/html/rfc5545#page-55">RFC 5545 p.55-7</a>
068 */
069 public class VTodo extends ICalComponent {
070 /**
071 * <p>
072 * Creates a new to-do entry.
073 * </p>
074 * <p>
075 * The following properties are auto-generated on object creation. These
076 * properties <b>must</b> be present in order for the to-do to be valid:
077 * <ul>
078 * <li>{@link Uid} - Set to a UUID.</li>
079 * <li>{@link DateTimeStamp} - Set to the current date-time.</li>
080 * </ul>
081 * </p>
082 */
083 public VTodo() {
084 setUid(Uid.random());
085 setDateTimeStamp(new Date());
086 }
087
088 /**
089 * Gets the unique identifier for this to-do. This component object comes
090 * populated with a UID on creation. This is a <b>required</b> property.
091 * @return the UID or null if not set
092 * @see <a href="http://tools.ietf.org/html/rfc5545#page-117">RFC 5545
093 * p.117-8</a>
094 */
095 public Uid getUid() {
096 return getProperty(Uid.class);
097 }
098
099 /**
100 * Sets the unique identifier for this to-do. This component object comes
101 * populated with a UID on creation. This is a <b>required</b> property.
102 * @param uid the UID or null to remove
103 * @see <a href="http://tools.ietf.org/html/rfc5545#page-117">RFC 5545
104 * p.117-8</a>
105 */
106 public void setUid(Uid uid) {
107 setProperty(Uid.class, uid);
108 }
109
110 /**
111 * Sets the unique identifier for this to-do. This component object comes
112 * populated with a UID on creation. This is a <b>required</b> property.
113 * @param uid the UID or null to remove
114 * @return the property that was created
115 * @see <a href="http://tools.ietf.org/html/rfc5545#page-117">RFC 5545
116 * p.117-8</a>
117 */
118 public Uid setUid(String uid) {
119 Uid prop = (uid == null) ? null : new Uid(uid);
120 setUid(prop);
121 return prop;
122 }
123
124 /**
125 * Gets either (a) the creation date of the iCalendar object (if the
126 * {@link Method} property is defined) or (b) the date that the to-do was
127 * last modified (the {@link LastModified} property also holds this
128 * information). This to-do object comes populated with a
129 * {@link DateTimeStamp} property that is set to the current time. This is a
130 * <b>required</b> property.
131 * @return the date time stamp or null if not set
132 * @see <a href="http://tools.ietf.org/html/rfc5545#page-137">RFC 5545
133 * p.137-8</a>
134 */
135 public DateTimeStamp getDateTimeStamp() {
136 return getProperty(DateTimeStamp.class);
137 }
138
139 /**
140 * Sets either (a) the creation date of the iCalendar object (if the
141 * {@link Method} property is defined) or (b) the date that the to-do was
142 * last modified (the {@link LastModified} property also holds this
143 * information). This to-do object comes populated with a
144 * {@link DateTimeStamp} property that is set to the current time. This is a
145 * <b>required</b> property.
146 * @param dateTimeStamp the date time stamp or null to remove
147 * @see <a href="http://tools.ietf.org/html/rfc5545#page-137">RFC 5545
148 * p.137-8</a>
149 */
150 public void setDateTimeStamp(DateTimeStamp dateTimeStamp) {
151 setProperty(DateTimeStamp.class, dateTimeStamp);
152 }
153
154 /**
155 * Sets either (a) the creation date of the iCalendar object (if the
156 * {@link Method} property is defined) or (b) the date that the to-do was
157 * last modified (the {@link LastModified} property also holds this
158 * information). This to-do object comes populated with a
159 * {@link DateTimeStamp} property that is set to the current time. This is a
160 * <b>required</b> property.
161 * @param dateTimeStamp the date time stamp or null to remove
162 * @return the property that was created
163 * @see <a href="http://tools.ietf.org/html/rfc5545#page-137">RFC 5545
164 * p.137-8</a>
165 */
166 public DateTimeStamp setDateTimeStamp(Date dateTimeStamp) {
167 DateTimeStamp prop = (dateTimeStamp == null) ? null : new DateTimeStamp(dateTimeStamp);
168 setDateTimeStamp(prop);
169 return prop;
170 }
171
172 /**
173 * Gets the level of sensitivity of the to-do data. If not specified, the
174 * data within the to-do should be considered "public".
175 * @return the classification level or null if not set
176 * @see <a href="http://tools.ietf.org/html/rfc5545#page-82">RFC 5545
177 * p.82-3</a>
178 */
179 public Classification getClassification() {
180 return getProperty(Classification.class);
181 }
182
183 /**
184 * Sets the level of sensitivity of the to-do data. If not specified, the
185 * data within the to-do should be considered "public".
186 * @param classification the classification level or null to remove
187 * @see <a href="http://tools.ietf.org/html/rfc5545#page-82">RFC 5545
188 * p.82-3</a>
189 */
190 public void setClassification(Classification classification) {
191 setProperty(Classification.class, classification);
192 }
193
194 /**
195 * Sets the level of sensitivity of the to-do data. If not specified, the
196 * data within the to-do should be considered "public".
197 * @param classification the classification level (e.g. "CONFIDENTIAL") or
198 * null to remove
199 * @return the property that was created
200 * @see <a href="http://tools.ietf.org/html/rfc5545#page-82">RFC 5545
201 * p.82-3</a>
202 */
203 public Classification setClassification(String classification) {
204 Classification prop = (classification == null) ? null : new Classification(classification);
205 setClassification(prop);
206 return prop;
207 }
208
209 /**
210 * Gets the date and time that the to-do was completed.
211 * @return the completion date or null if not set
212 * @see <a href="http://tools.ietf.org/html/rfc5545#page-94">RFC 5545
213 * p.94-5</a>
214 */
215 public Completed getCompleted() {
216 return getProperty(Completed.class);
217 }
218
219 /**
220 * Sets the date and time that the to-do was completed.
221 * @param completed the completion date or null to remove
222 * @see <a href="http://tools.ietf.org/html/rfc5545#page-94">RFC 5545
223 * p.94-5</a>
224 */
225 public void setCompleted(Completed completed) {
226 setProperty(Completed.class, completed);
227 }
228
229 /**
230 * Sets the date and time that the to-do was completed.
231 * @param completed the completion date or null to remove
232 * @return the property that was created
233 * @see <a href="http://tools.ietf.org/html/rfc5545#page-94">RFC 5545
234 * p.94-5</a>
235 */
236 public Completed setCompleted(Date completed) {
237 Completed prop = (completed == null) ? null : new Completed(completed);
238 setCompleted(prop);
239 return prop;
240 }
241
242 /**
243 * Gets the date-time that the to-do was initially created.
244 * @return the creation date-time or null if not set
245 * @see <a href="http://tools.ietf.org/html/rfc5545#page-136">RFC 5545
246 * p.136</a>
247 */
248 public Created getCreated() {
249 return getProperty(Created.class);
250 }
251
252 /**
253 * Sets the date-time that the to-do was initially created.
254 * @param created the creation date-time or null to remove
255 * @see <a href="http://tools.ietf.org/html/rfc5545#page-136">RFC 5545
256 * p.136</a>
257 */
258 public void setCreated(Created created) {
259 setProperty(Created.class, created);
260 }
261
262 /**
263 * Sets the date-time that the to-do was initially created.
264 * @param created the creation date-time or null to remove
265 * @return the property that was created
266 * @see <a href="http://tools.ietf.org/html/rfc5545#page-136">RFC 5545
267 * p.136</a>
268 */
269 public Created setCreated(Date created) {
270 Created prop = (created == null) ? null : new Created(created);
271 setCreated(prop);
272 return prop;
273 }
274
275 /**
276 * Gets a detailed description of the to-do. The description should be more
277 * detailed than the one provided by the {@link Summary} property.
278 * @return the description or null if not set
279 * @see <a href="http://tools.ietf.org/html/rfc5545#page-84">RFC 5545
280 * p.84-5</a>
281 */
282 public Description getDescription() {
283 return getProperty(Description.class);
284 }
285
286 /**
287 * Sets a detailed description of the to-do. The description should be more
288 * detailed than the one provided by the {@link Summary} property.
289 * @param description the description or null to remove
290 * @see <a href="http://tools.ietf.org/html/rfc5545#page-84">RFC 5545
291 * p.84-5</a>
292 */
293 public void setDescription(Description description) {
294 setProperty(Description.class, description);
295 }
296
297 /**
298 * Sets a detailed description of the to-do. The description should be more
299 * detailed than the one provided by the {@link Summary} property.
300 * @param description the description or null to remove
301 * @return the property that was created
302 * @see <a href="http://tools.ietf.org/html/rfc5545#page-84">RFC 5545
303 * p.84-5</a>
304 */
305 public Description setDescription(String description) {
306 Description prop = (description == null) ? null : new Description(description);
307 setDescription(prop);
308 return prop;
309 }
310
311 /**
312 * Gets the date that the to-do starts.
313 * @return the start date or null if not set
314 * @see <a href="http://tools.ietf.org/html/rfc5545#page-97">RFC 5545
315 * p.97-8</a>
316 */
317 public DateStart getDateStart() {
318 return getProperty(DateStart.class);
319 }
320
321 /**
322 * Sets the date that the to-do starts.
323 * @param dateStart the start date or null to remove
324 * @see <a href="http://tools.ietf.org/html/rfc5545#page-97">RFC 5545
325 * p.97-8</a>
326 */
327 public void setDateStart(DateStart dateStart) {
328 setProperty(DateStart.class, dateStart);
329 }
330
331 /**
332 * Sets the date that the to-do starts.
333 * @param dateStart the start date or null to remove
334 * @return the property that was created
335 * @see <a href="http://tools.ietf.org/html/rfc5545#page-97">RFC 5545
336 * p.97-8</a>
337 */
338 public DateStart setDateStart(Date dateStart) {
339 DateStart prop = (dateStart == null) ? null : new DateStart(dateStart);
340 setDateStart(prop);
341 return prop;
342 }
343
344 /**
345 * Gets a set of geographical coordinates.
346 * @return the geographical coordinates or null if not set
347 * @see <a href="http://tools.ietf.org/html/rfc5545#page-85">RFC 5545
348 * p.85-7</a>
349 */
350 public Geo getGeo() {
351 return getProperty(Geo.class);
352 }
353
354 /**
355 * Sets a set of geographical coordinates.
356 * @param geo the geographical coordinates or null to remove
357 * @see <a href="http://tools.ietf.org/html/rfc5545#page-85">RFC 5545
358 * p.85-7</a>
359 */
360 public void setGeo(Geo geo) {
361 setProperty(Geo.class, geo);
362 }
363
364 /**
365 * Gets the date-time that the to-do was last changed.
366 * @return the last modified date or null if not set
367 * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
368 * p.138</a>
369 */
370 public LastModified getLastModified() {
371 return getProperty(LastModified.class);
372 }
373
374 /**
375 * Sets the date-time that the to-do was last changed.
376 * @param lastModified the last modified date or null to remove
377 * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
378 * p.138</a>
379 */
380 public void setLastModified(LastModified lastModified) {
381 setProperty(LastModified.class, lastModified);
382 }
383
384 /**
385 * Sets the date-time that the to-do was last changed.
386 * @param lastModified the last modified date or null to remove
387 * @return the property that was created
388 * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
389 * p.138</a>
390 */
391 public LastModified setLastModified(Date lastModified) {
392 LastModified prop = (lastModified == null) ? null : new LastModified(lastModified);
393 setLastModified(prop);
394 return prop;
395 }
396
397 /**
398 * Gets the physical location of the to-do.
399 * @return the location or null if not set
400 * @see <a href="http://tools.ietf.org/html/rfc5545#page-87">RFC 5545
401 * p.87-8</a>
402 */
403 public Location getLocation() {
404 return getProperty(Location.class);
405 }
406
407 /**
408 * Sets the physical location of the to-do.
409 * @param location the location or null to remove
410 * @see <a href="http://tools.ietf.org/html/rfc5545#page-87">RFC 5545
411 * p.87-8</a>
412 */
413 public void setLocation(Location location) {
414 setProperty(Location.class, location);
415 }
416
417 /**
418 * Sets the physical location of the to-do.
419 * @param location the location (e.g. "Room 101") or null to remove
420 * @return the property that was created
421 * @see <a href="http://tools.ietf.org/html/rfc5545#page-87">RFC 5545
422 * p.87-8</a>
423 */
424 public Location setLocation(String location) {
425 Location prop = (location == null) ? null : new Location(location);
426 setLocation(prop);
427 return prop;
428 }
429
430 /**
431 * Gets the organizer of the to-do.
432 * @return the organizer or null if not set
433 * @see <a href="http://tools.ietf.org/html/rfc5545#page-111">RFC 5545
434 * p.111-2</a>
435 */
436 public Organizer getOrganizer() {
437 return getProperty(Organizer.class);
438 }
439
440 /**
441 * Sets the organizer of the to-do.
442 * @param organizer the organizer or null to remove
443 * @see <a href="http://tools.ietf.org/html/rfc5545#page-111">RFC 5545
444 * p.111-2</a>
445 */
446 public void setOrganizer(Organizer organizer) {
447 setProperty(Organizer.class, organizer);
448 }
449
450 /**
451 * Sets the organizer of the to-do.
452 * @param email the organizer's email address (e.g. "johndoe@example.com")
453 * or null to remove
454 * @return the property that was created
455 * @see <a href="http://tools.ietf.org/html/rfc5545#page-111">RFC 5545
456 * p.111-2</a>
457 */
458 public Organizer setOrganizer(String email) {
459 Organizer prop = (email == null) ? null : Organizer.email(email);
460 setOrganizer(prop);
461 return prop;
462 }
463
464 /**
465 * Gets the amount that the to-do task has been completed.
466 * @return the percent complete or null if not set
467 * @see <a href="http://tools.ietf.org/html/rfc5545#page-88">RFC 5545
468 * p.88-9</a>
469 */
470 public PercentComplete getPercentComplete() {
471 return getProperty(PercentComplete.class);
472 }
473
474 /**
475 * Sets the amount that the to-do task has been completed.
476 * @param percentComplete the percent complete or null to remove
477 * @see <a href="http://tools.ietf.org/html/rfc5545#page-88">RFC 5545
478 * p.88-9</a>
479 */
480 public void setPercentComplete(PercentComplete percentComplete) {
481 setProperty(PercentComplete.class, percentComplete);
482 }
483
484 /**
485 * Sets the amount that the to-do task has been completed.
486 * @param percent the percent complete (e.g. "50" for 50%) or null to remove
487 * @return the property that was created
488 * @see <a href="http://tools.ietf.org/html/rfc5545#page-88">RFC 5545
489 * p.88-9</a>
490 */
491 public PercentComplete setPercentComplete(Integer percent) {
492 PercentComplete prop = (percent == null) ? null : new PercentComplete(percent);
493 setPercentComplete(prop);
494 return prop;
495 }
496
497 /**
498 * Gets the priority of the to-do.
499 * @return the priority or null if not set
500 * @see <a href="http://tools.ietf.org/html/rfc5545#page-89">RFC 5545
501 * p.89-90</a>
502 */
503 public Priority getPriority() {
504 return getProperty(Priority.class);
505 }
506
507 /**
508 * Sets the priority of the to-do.
509 * @param priority the priority or null to remove
510 * @see <a href="http://tools.ietf.org/html/rfc5545#page-89">RFC 5545
511 * p.89-90</a>
512 */
513 public void setPriority(Priority priority) {
514 setProperty(Priority.class, priority);
515 }
516
517 /**
518 * Sets the priority of the to-do.
519 * @param priority the priority ("0" is undefined, "1" is the highest, "9"
520 * is the lowest) or null to remove
521 * @return the property that was created
522 * @see <a href="http://tools.ietf.org/html/rfc5545#page-89">RFC 5545
523 * p.89-90</a>
524 */
525 public Priority setPriority(Integer priority) {
526 Priority prop = (priority == null) ? null : new Priority(priority);
527 setPriority(prop);
528 return prop;
529 }
530
531 /**
532 * Gets the original value of the {@link DateStart} property if the to-do is
533 * recurring and has been modified. Used in conjunction with the {@link Uid}
534 * and {@link Sequence} properties to uniquely identify a recurrence
535 * instance.
536 * @return the recurrence ID or null if not set
537 * @see <a href="http://tools.ietf.org/html/rfc5545#page-112">RFC 5545
538 * p.112-4</a>
539 */
540 public RecurrenceId getRecurrenceId() {
541 return getProperty(RecurrenceId.class);
542 }
543
544 /**
545 * Sets the original value of the {@link DateStart} property if the to-do is
546 * recurring and has been modified. Used in conjunction with the {@link Uid}
547 * and {@link Sequence} properties to uniquely identify a recurrence
548 * instance.
549 * @param recurrenceId the recurrence ID or null to remove
550 * @see <a href="http://tools.ietf.org/html/rfc5545#page-112">RFC 5545
551 * p.112-4</a>
552 */
553 public void setRecurrenceId(RecurrenceId recurrenceId) {
554 setProperty(RecurrenceId.class, recurrenceId);
555 }
556
557 /**
558 * Sets the original value of the {@link DateStart} property if the to-do is
559 * recurring and has been modified. Used in conjunction with the {@link Uid}
560 * and {@link Sequence} properties to uniquely identify a recurrence
561 * instance.
562 * @param originalStartDate the original start date or null to remove
563 * @see <a href="http://tools.ietf.org/html/rfc5545#page-112">RFC 5545
564 * p.112-4</a>
565 */
566 public RecurrenceId setRecurrenceId(Date originalStartDate) {
567 RecurrenceId prop = (originalStartDate == null) ? null : new RecurrenceId(originalStartDate);
568 setRecurrenceId(prop);
569 return prop;
570 }
571
572 /**
573 * Gets the revision number of the to-do. The organizer can increment this
574 * number every time he or she makes a significant change.
575 * @return the sequence number
576 * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
577 * p.138-9</a>
578 */
579 public Sequence getSequence() {
580 return getProperty(Sequence.class);
581 }
582
583 /**
584 * Sets the revision number of the to-do. The organizer can increment this
585 * number every time he or she makes a significant change.
586 * @param sequence the sequence number
587 * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
588 * p.138-9</a>
589 */
590 public void setSequence(Sequence sequence) {
591 setProperty(Sequence.class, sequence);
592 }
593
594 /**
595 * Sets the revision number of the to-do. The organizer can increment this
596 * number every time he or she makes a significant change.
597 * @param sequence the sequence number
598 * @return the property that was created
599 * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
600 * p.138-9</a>
601 */
602 public Sequence setSequence(Integer sequence) {
603 Sequence prop = (sequence == null) ? null : new Sequence(sequence);
604 setSequence(prop);
605 return prop;
606 }
607
608 /**
609 * Increments the revision number of the to-do. The organizer can increment
610 * this number every time he or she makes a significant change.
611 * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
612 * p.138-9</a>
613 */
614 public void incrementSequence() {
615 Sequence sequence = getSequence();
616 if (sequence == null) {
617 setSequence(1);
618 } else {
619 sequence.increment();
620 }
621 }
622
623 /**
624 * Gets the status of the to-do.
625 * @return the status or null if not set
626 * @see <a href="http://tools.ietf.org/html/rfc5545#page-92">RFC 5545
627 * p.92-3</a>
628 */
629 public Status getStatus() {
630 return getProperty(Status.class);
631 }
632
633 /**
634 * Sets the status of the to-do.
635 * <p>
636 * Valid to-do status codes are:
637 * <ul>
638 * <li>NEEDS-ACTION</li>
639 * <li>COMPLETED</li>
640 * <li>IN-PROGRESS</li>
641 * <li>CANCELLED</li>
642 * </ul>
643 * </p>
644 * @param status the status or null to remove
645 * @see <a href="http://tools.ietf.org/html/rfc5545#page-92">RFC 5545
646 * p.92-3</a>
647 */
648 public void setStatus(Status status) {
649 setProperty(Status.class, status);
650 }
651
652 /**
653 * Gets the summary of the to-do.
654 * @return the summary or null if not set
655 * @see <a href="http://tools.ietf.org/html/rfc5545#page-93">RFC 5545
656 * p.93-4</a>
657 */
658 public Summary getSummary() {
659 return getProperty(Summary.class);
660 }
661
662 /**
663 * Sets the summary of the to-do.
664 * @param summary the summary or null to remove
665 * @see <a href="http://tools.ietf.org/html/rfc5545#page-93">RFC 5545
666 * p.93-4</a>
667 */
668 public void setSummary(Summary summary) {
669 setProperty(Summary.class, summary);
670 }
671
672 /**
673 * Sets the summary of the to-do.
674 * @param summary the summary or null to remove
675 * @return the property that was created
676 * @see <a href="http://tools.ietf.org/html/rfc5545#page-93">RFC 5545
677 * p.93-4</a>
678 */
679 public Summary setSummary(String summary) {
680 Summary prop = (summary == null) ? null : new Summary(summary);
681 setSummary(prop);
682 return prop;
683 }
684
685 /**
686 * Gets a URL to a resource that contains additional information about the
687 * to-do.
688 * @return the URL or null if not set
689 * @see <a href="http://tools.ietf.org/html/rfc5545#page-116">RFC 5545
690 * p.116-7</a>
691 */
692 public Url getUrl() {
693 return getProperty(Url.class);
694 }
695
696 /**
697 * Sets a URL to a resource that contains additional information about the
698 * to-do.
699 * @param url the URL or null to remove
700 * @see <a href="http://tools.ietf.org/html/rfc5545#page-116">RFC 5545
701 * p.116-7</a>
702 */
703 public void setUrl(Url url) {
704 setProperty(Url.class, url);
705 }
706
707 /**
708 * Sets a URL to a resource that contains additional information about the
709 * to-do.
710 * @param url the URL (e.g. "http://example.com/resource.ics") or null to
711 * remove
712 * @return the property that was created
713 * @see <a href="http://tools.ietf.org/html/rfc5545#page-116">RFC 5545
714 * p.116-7</a>
715 */
716 public Url setUrl(String url) {
717 Url prop = (url == null) ? null : new Url(url);
718 setUrl(prop);
719 return prop;
720 }
721
722 /**
723 * Gets how often the to-do repeats.
724 * @return the recurrence rule or null if not set
725 * @see <a href="http://tools.ietf.org/html/rfc5545#page-122">RFC 5545
726 * p.122-32</a>
727 */
728 public RecurrenceRule getRecurrenceRule() {
729 return getProperty(RecurrenceRule.class);
730 }
731
732 /**
733 * Sets how often the to-do repeats.
734 * @param recurrenceRule the recurrence rule or null to remove
735 * @see <a href="http://tools.ietf.org/html/rfc5545#page-122">RFC 5545
736 * p.122-32</a>
737 */
738 public void setRecurrenceRule(RecurrenceRule recurrenceRule) {
739 setProperty(RecurrenceRule.class, recurrenceRule);
740 }
741
742 /**
743 * Gets the date that a to-do is due by.
744 * @return the due date or null if not set
745 * @see <a href="http://tools.ietf.org/html/rfc5545#page-96">RFC 5545
746 * p.96-7</a>
747 */
748 public DateDue getDateDue() {
749 return getProperty(DateDue.class);
750 }
751
752 /**
753 * Sets the date that a to-do is due by. This must NOT be set if a
754 * {@link DurationProperty} is defined.
755 * @param dateDue the due date or null to remove
756 * @see <a href="http://tools.ietf.org/html/rfc5545#page-96">RFC 5545
757 * p.96-7</a>
758 */
759 public void setDateDue(DateDue dateDue) {
760 setProperty(DateDue.class, dateDue);
761 }
762
763 /**
764 * Sets the date that a to-do is due by. This must NOT be set if a
765 * {@link DurationProperty} is defined.
766 * @param dateDue the due date or null to remove
767 * @return the property that was created
768 * @see <a href="http://tools.ietf.org/html/rfc5545#page-96">RFC 5545
769 * p.96-7</a>
770 */
771 public DateDue setDateDue(Date dateDue) {
772 DateDue prop = (dateDue == null) ? null : new DateDue(dateDue);
773 setDateDue(prop);
774 return prop;
775 }
776
777 /**
778 * Gets the duration of the to-do.
779 * @return the duration or null if not set
780 * @see <a href="http://tools.ietf.org/html/rfc5545#page-99">RFC 5545
781 * p.99</a>
782 */
783 public DurationProperty getDuration() {
784 return getProperty(DurationProperty.class);
785 }
786
787 /**
788 * Sets the duration of the to-do. This must NOT be set if a {@link DateDue}
789 * is defined.
790 * @param duration the duration or null to remove
791 * @see <a href="http://tools.ietf.org/html/rfc5545#page-99">RFC 5545
792 * p.99</a>
793 */
794 public void setDuration(DurationProperty duration) {
795 setProperty(DurationProperty.class, duration);
796 }
797
798 /**
799 * Gets any attachments that are associated with the to-do.
800 * @return the attachments
801 * @see <a href="http://tools.ietf.org/html/rfc5545#page-80">RFC 5545
802 * p.80-1</a>
803 */
804 public List<Attachment> getAttachments() {
805 return getProperties(Attachment.class);
806 }
807
808 /**
809 * Adds an attachment to the to-do.
810 * @param attachment the attachment to add
811 * @see <a href="http://tools.ietf.org/html/rfc5545#page-80">RFC 5545
812 * p.80-1</a>
813 */
814 public void addAttachment(Attachment attachment) {
815 addProperty(attachment);
816 }
817
818 /**
819 * Gets the people who are involved in the to-do.
820 * @return the attendees
821 * @see <a href="http://tools.ietf.org/html/rfc5545#page-107">RFC 5545
822 * p.107-9</a>
823 */
824 public List<Attendee> getAttendees() {
825 return getProperties(Attendee.class);
826 }
827
828 /**
829 * Adds a person who is involved in the to-do.
830 * @param attendee the attendee
831 * @see <a href="http://tools.ietf.org/html/rfc5545#page-107">RFC 5545
832 * p.107-9</a>
833 */
834 public void addAttendee(Attendee attendee) {
835 addProperty(attendee);
836 }
837
838 /**
839 * Adds a person who is involved in the to-do.
840 * @param email the attendee's email address
841 * @return the property that was created
842 * @see <a href="http://tools.ietf.org/html/rfc5545#page-107">RFC 5545
843 * p.107-9</a>
844 */
845 public Attendee addAttendee(String email) {
846 Attendee prop = Attendee.email(email);
847 addAttendee(prop);
848 return prop;
849 }
850
851 /**
852 * Gets a list of "tags" or "keywords" that describe the to-do.
853 * @return the categories
854 * @see <a href="http://tools.ietf.org/html/rfc5545#page-81">RFC 5545
855 * p.81-2</a>
856 */
857 public List<Categories> getCategories() {
858 return getProperties(Categories.class);
859 }
860
861 /**
862 * Adds a list of "tags" or "keywords" that describe the to-do. Note that a
863 * single property can hold multiple keywords.
864 * @param categories the categories to add
865 * @see <a href="http://tools.ietf.org/html/rfc5545#page-81">RFC 5545
866 * p.81-2</a>
867 */
868 public void addCategories(Categories categories) {
869 addProperty(categories);
870 }
871
872 /**
873 * Adds a list of "tags" or "keywords" that describe the to-do.
874 * @param categories the categories to add
875 * @return the property that was created
876 * @see <a href="http://tools.ietf.org/html/rfc5545#page-81">RFC 5545
877 * p.81-2</a>
878 */
879 public Categories addCategories(String... categories) {
880 Categories prop = new Categories(categories);
881 addCategories(prop);
882 return prop;
883 }
884
885 /**
886 * Adds a list of "tags" or "keywords" that describe the to-do.
887 * @param categories the categories to add
888 * @return the property that was created
889 * @see <a href="http://tools.ietf.org/html/rfc5545#page-81">RFC 5545
890 * p.81-2</a>
891 */
892 public Categories addCategories(List<String> categories) {
893 Categories prop = new Categories(categories);
894 addCategories(prop);
895 return prop;
896 }
897
898 /**
899 * Gets the comments attached to the to-do.
900 * @return the comments
901 * @see <a href="http://tools.ietf.org/html/rfc5545#page-83">RFC 5545
902 * p.83-4</a>
903 */
904 public List<Comment> getComments() {
905 return getProperties(Comment.class);
906 }
907
908 /**
909 * Adds a comment to the to-do.
910 * @param comment the comment to add
911 * @see <a href="http://tools.ietf.org/html/rfc5545#page-83">RFC 5545
912 * p.83-4</a>
913 */
914 public void addComment(Comment comment) {
915 addProperty(comment);
916 }
917
918 /**
919 * Adds a comment to the to-do.
920 * @param comment the comment to add
921 * @return the property that was created
922 * @see <a href="http://tools.ietf.org/html/rfc5545#page-83">RFC 5545
923 * p.83-4</a>
924 */
925 public Comment addComment(String comment) {
926 Comment prop = new Comment(comment);
927 addComment(prop);
928 return prop;
929 }
930
931 /**
932 * Gets the contacts associated with the to-do.
933 * @return the contacts
934 * @see <a href="http://tools.ietf.org/html/rfc5545#page-109">RFC 5545
935 * p.109-11</a>
936 */
937 public List<Contact> getContacts() {
938 return getProperties(Contact.class);
939 }
940
941 /**
942 * Adds a contact to the to-do.
943 * @param contact the contact
944 * @see <a href="http://tools.ietf.org/html/rfc5545#page-109">RFC 5545
945 * p.109-11</a>
946 */
947 public void addContact(Contact contact) {
948 addProperty(contact);
949 }
950
951 /**
952 * Adds a contact to the to-do.
953 * @param contact the contact (e.g. "ACME Co - (123) 555-1234")
954 * @return the property that was created
955 * @see <a href="http://tools.ietf.org/html/rfc5545#page-109">RFC 5545
956 * p.109-11</a>
957 */
958 public Contact addContact(String contact) {
959 Contact prop = new Contact(contact);
960 addContact(prop);
961 return prop;
962 }
963
964 /**
965 * Gets the list of exceptions to the recurrence rule defined in the to-do
966 * (if one is defined).
967 * @return the list of exceptions
968 * @see <a href="http://tools.ietf.org/html/rfc5545#page-118">RFC 5545
969 * p.118-20</a>
970 */
971 public List<ExceptionDates> getExceptionDates() {
972 return getProperties(ExceptionDates.class);
973 }
974
975 /**
976 * Adds a list of exceptions to the recurrence rule defined in the to-do (if
977 * one is defined). Note that this property can contain multiple dates.
978 * @param exceptionDates the list of exceptions
979 * @see <a href="http://tools.ietf.org/html/rfc5545#page-118">RFC 5545
980 * p.118-20</a>
981 */
982 public void addExceptionDates(ExceptionDates exceptionDates) {
983 addProperty(exceptionDates);
984 }
985
986 /**
987 * Gets the response to a scheduling request.
988 * @return the response
989 * @see <a href="http://tools.ietf.org/html/rfc5545#page-141">RFC 5545
990 * p.141-3</a>
991 */
992 public RequestStatus getRequestStatus() {
993 return getProperty(RequestStatus.class);
994 }
995
996 /**
997 * Sets the response to a scheduling request.
998 * @param requestStatus the response
999 * @see <a href="http://tools.ietf.org/html/rfc5545#page-141">RFC 5545
1000 * p.141-3</a>
1001 */
1002 public void setRequestStatus(RequestStatus requestStatus) {
1003 setProperty(RequestStatus.class, requestStatus);
1004 }
1005
1006 /**
1007 * Gets the components that the to-do is related to.
1008 * @return the relationships
1009 * @see <a href="http://tools.ietf.org/html/rfc5545#page-115">RFC 5545
1010 * p.115-6</a>
1011 */
1012 public List<RelatedTo> getRelatedTo() {
1013 return getProperties(RelatedTo.class);
1014 }
1015
1016 /**
1017 * Adds a component that the to-do is related to.
1018 * @param relatedTo the relationship
1019 * @see <a href="http://tools.ietf.org/html/rfc5545#page-115">RFC 5545
1020 * p.115-6</a>
1021 */
1022 public void addRelatedTo(RelatedTo relatedTo) {
1023 //TODO create a method that accepts a component and make the RelatedTo property invisible to the user
1024 //@formatter:off
1025 /*
1026 * addRelation(RelationshipType relType, ICalComponent component){
1027 * RelatedTo prop = new RelatedTo(component.getUid().getValue());
1028 * prop.setRelationshipType(relType);
1029 * addProperty(prop);
1030 * }
1031 */
1032 //@formatter:on
1033 addProperty(relatedTo);
1034 }
1035
1036 /**
1037 * Adds a component that the to-do is related to.
1038 * @param uid the UID of the other component
1039 * @return the property that was created
1040 * @see <a href="http://tools.ietf.org/html/rfc5545#page-115">RFC 5545
1041 * p.115-6</a>
1042 */
1043 public RelatedTo addRelatedTo(String uid) {
1044 RelatedTo prop = new RelatedTo(uid);
1045 addRelatedTo(prop);
1046 return prop;
1047 }
1048
1049 /**
1050 * Gets the resources that are needed for the to-do.
1051 * @return the resources
1052 * @see <a href="http://tools.ietf.org/html/rfc5545#page-91">RFC 5545
1053 * p.91</a>
1054 */
1055 public List<Resources> getResources() {
1056 return getProperties(Resources.class);
1057 }
1058
1059 /**
1060 * Adds a list of resources that are needed for the to-do. Note that a
1061 * single property can hold multiple resources.
1062 * @param resources the resources to add
1063 * @see <a href="http://tools.ietf.org/html/rfc5545#page-91">RFC 5545
1064 * p.91</a>
1065 */
1066 public void addResources(Resources resources) {
1067 addProperty(resources);
1068 }
1069
1070 /**
1071 * Adds a list of resources that are needed for the to-do.
1072 * @param resources the resources to add (e.g. "easel", "projector")
1073 * @return the property that was created
1074 * @see <a href="http://tools.ietf.org/html/rfc5545#page-91">RFC 5545
1075 * p.91</a>
1076 */
1077 public Resources addResources(String... resources) {
1078 Resources prop = new Resources(resources);
1079 addResources(prop);
1080 return prop;
1081 }
1082
1083 /**
1084 * Adds a list of resources that are needed for the to-do.
1085 * @param resources the resources to add (e.g. "easel", "projector")
1086 * @return the property that was created
1087 * @see <a href="http://tools.ietf.org/html/rfc5545#page-91">RFC 5545
1088 * p.91</a>
1089 */
1090 public Resources addResources(List<String> resources) {
1091 Resources prop = new Resources(resources);
1092 addResources(prop);
1093 return prop;
1094 }
1095
1096 /**
1097 * Gets the list of dates/periods that help define the recurrence rule of
1098 * this to-do (if one is defined).
1099 * @return the recurrence dates
1100 * @see <a href="http://tools.ietf.org/html/rfc5545#page-120">RFC 5545
1101 * p.120-2</a>
1102 */
1103 public List<RecurrenceDates> getRecurrenceDates() {
1104 return getProperties(RecurrenceDates.class);
1105 }
1106
1107 /**
1108 * Adds a list of dates/periods that help define the recurrence rule of this
1109 * to-do (if one is defined).
1110 * @param recurrenceDates the recurrence dates
1111 * @see <a href="http://tools.ietf.org/html/rfc5545#page-120">RFC 5545
1112 * p.120-2</a>
1113 */
1114 public void addRecurrenceDates(RecurrenceDates recurrenceDates) {
1115 addProperty(recurrenceDates);
1116 }
1117
1118 @SuppressWarnings("unchecked")
1119 @Override
1120 protected void validate(List<ICalComponent> components, List<String> warnings) {
1121 checkRequiredCardinality(warnings, Uid.class, DateTimeStamp.class);
1122 checkOptionalCardinality(warnings, Classification.class, Completed.class, Created.class, Description.class, DateStart.class, Geo.class, LastModified.class, Location.class, Organizer.class, PercentComplete.class, Priority.class, RecurrenceId.class, Sequence.class, Status.class, Summary.class, Url.class);
1123
1124 Status status = getStatus();
1125 if (status != null && (status.isTentative() || status.isConfirmed() || status.isDraft() || status.isFinal())) {
1126 warnings.add("Invalid status value of \"" + status.getValue() + "\". Valid status values for to-do tasks are \"needs-action\", \"completed\", \"in-progress\", and \"cancelled\".");
1127 }
1128
1129 DateStart dateStart = getDateStart();
1130 DateDue dateDue = getDateDue();
1131
1132 if (dateStart != null && dateDue != null) {
1133 Date start = dateStart.getValue();
1134 Date due = dateDue.getValue();
1135 if (start != null && due != null && start.compareTo(due) > 0) {
1136 warnings.add("" + DateStart.class.getSimpleName() + " must come before " + DateDue.class.getSimpleName() + ".");
1137 }
1138
1139 if (dateStart.hasTime() != dateDue.hasTime()) {
1140 warnings.add("Both " + DateStart.class.getSimpleName() + " and " + DateDue.class.getSimpleName() + " must have the same data type (they must either both be dates or both be date-times).");
1141 }
1142 }
1143
1144 if (dateDue != null && getDuration() != null) {
1145 warnings.add("A " + DateDue.class.getSimpleName() + " and a " + DurationProperty.class.getSimpleName() + " cannot both be defined in the same to-do.");
1146 }
1147 if (dateStart == null && (dateDue != null || getDuration() != null)) {
1148 warnings.add("A" + DateStart.class.getSimpleName() + " must be defined if a " + DateDue.class.getSimpleName() + " or " + DurationProperty.class.getSimpleName() + " is defined.");
1149 }
1150
1151 RecurrenceId recurrenceId = getRecurrenceId();
1152 if (recurrenceId != null && dateStart != null && dateStart.hasTime() != recurrenceId.hasTime()) {
1153 warnings.add("Both " + DateStart.class.getSimpleName() + " and " + RecurrenceId.class.getSimpleName() + " must have the same data type (they must either both be dates or both be date-times).");
1154 }
1155 }
1156 }