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