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