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