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