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