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