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