src/net/fortuna/ical4j/model/component/VAlarm.java

changeset 0
fb9019fb1bf7
equal deleted inserted replaced
-1:000000000000 0:4fc893a3bf3c
1 /**
2 * Copyright (c) 2012, Ben Fortuna
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * o Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * o Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * o Neither the name of Ben Fortuna nor the names of any other contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 package net.fortuna.ical4j.model.component;
33
34 import java.util.HashMap;
35 import java.util.Map;
36
37 import net.fortuna.ical4j.model.DateTime;
38 import net.fortuna.ical4j.model.Dur;
39 import net.fortuna.ical4j.model.Property;
40 import net.fortuna.ical4j.model.PropertyList;
41 import net.fortuna.ical4j.model.ValidationException;
42 import net.fortuna.ical4j.model.Validator;
43 import net.fortuna.ical4j.model.property.Action;
44 import net.fortuna.ical4j.model.property.Attach;
45 import net.fortuna.ical4j.model.property.Description;
46 import net.fortuna.ical4j.model.property.Duration;
47 import net.fortuna.ical4j.model.property.Method;
48 import net.fortuna.ical4j.model.property.Repeat;
49 import net.fortuna.ical4j.model.property.Summary;
50 import net.fortuna.ical4j.model.property.Trigger;
51 import net.fortuna.ical4j.util.PropertyValidator;
52
53 /**
54 * $Id$ [Apr 5, 2004]
55 *
56 * Defines an iCalendar VALARM component.
57 *
58 * <pre>
59 * 4.6.6 Alarm Component
60 *
61 * Component Name: VALARM
62 *
63 * Purpose: Provide a grouping of component properties that define an
64 * alarm.
65 *
66 * Formal Definition: A &quot;VALARM&quot; calendar component is defined by the
67 * following notation:
68 *
69 * alarmc = &quot;BEGIN&quot; &quot;:&quot; &quot;VALARM&quot; CRLF
70 * (audioprop / dispprop / emailprop / procprop)
71 * &quot;END&quot; &quot;:&quot; &quot;VALARM&quot; CRLF
72 *
73 * audioprop = 2*(
74 *
75 * ; 'action' and 'trigger' are both REQUIRED,
76 * ; but MUST NOT occur more than once
77 *
78 * action / trigger /
79 *
80 * ; 'duration' and 'repeat' are both optional,
81 * ; and MUST NOT occur more than once each,
82 * ; but if one occurs, so MUST the other
83 *
84 * duration / repeat /
85 *
86 * ; the following is optional,
87 * ; but MUST NOT occur more than once
88 *
89 * attach /
90 *
91 * ; the following is optional,
92 * ; and MAY occur more than once
93 *
94 * x-prop
95 *
96 * )
97 *
98 *
99 *
100 * dispprop = 3*(
101 *
102 * ; the following are all REQUIRED,
103 * ; but MUST NOT occur more than once
104 *
105 * action / description / trigger /
106 *
107 * ; 'duration' and 'repeat' are both optional,
108 * ; and MUST NOT occur more than once each,
109 * ; but if one occurs, so MUST the other
110 *
111 * duration / repeat /
112 *
113 * ; the following is optional,
114 * ; and MAY occur more than once
115 *
116 * *x-prop
117 *
118 * )
119 *
120 *
121 *
122 * emailprop = 5*(
123 *
124 * ; the following are all REQUIRED,
125 * ; but MUST NOT occur more than once
126 *
127 * action / description / trigger / summary
128 *
129 * ; the following is REQUIRED,
130 * ; and MAY occur more than once
131 *
132 * attendee /
133 *
134 * ; 'duration' and 'repeat' are both optional,
135 * ; and MUST NOT occur more than once each,
136 * ; but if one occurs, so MUST the other
137 *
138 * duration / repeat /
139 *
140 * ; the following are optional,
141 * ; and MAY occur more than once
142 *
143 * attach / x-prop
144 *
145 * )
146 *
147 *
148 *
149 * procprop = 3*(
150 *
151 * ; the following are all REQUIRED,
152 * ; but MUST NOT occur more than once
153 *
154 * action / attach / trigger /
155 *
156 * ; 'duration' and 'repeat' are both optional,
157 * ; and MUST NOT occur more than once each,
158 * ; but if one occurs, so MUST the other
159 *
160 * duration / repeat /
161 *
162 * ; 'description' is optional,
163 * ; and MUST NOT occur more than once
164 *
165 * description /
166 *
167 * ; the following is optional,
168 * ; and MAY occur more than once
169 *
170 * x-prop
171 *
172 * )
173 * </pre>
174 *
175 * Example 1 - Creating an alarm to trigger at a specific time:
176 *
177 * <pre><code>
178 * java.util.Calendar cal = java.util.Calendar.getInstance();
179 * cal.set(java.util.Calendar.MONTH, java.util.Calendar.DECEMBER);
180 * cal.set(java.util.Calendar.DAY_OF_MONTH, 25);
181 *
182 * VAlarm christmas = new VAlarm(cal.getTime());
183 * </code></pre>
184 *
185 * Example 2 - Creating an alarm to trigger one (1) hour before the scheduled start of the parent event/the parent todo
186 * is due:
187 *
188 * <pre><code>
189 * VAlarm reminder = new VAlarm(new Dur(0, -1, 0, 0));
190 *
191 * // repeat reminder four (4) more times every fifteen (15) minutes..
192 * reminder.getProperties().add(new Repeat(4));
193 * reminder.getProperties().add(new Duration(new Dur(0, 0, 15, 0)));
194 *
195 * // display a message..
196 * reminder.getProperties().add(Action.DISPLAY);
197 * reminder.getProperties().add(new Description(&quot;Progress Meeting at 9:30am&quot;));
198 * </code></pre>
199 *
200 * @author Ben Fortuna
201 */
202 public class VAlarm extends CalendarComponent {
203
204 private static final long serialVersionUID = -8193965477414653802L;
205
206 private final Map actionValidators = new HashMap();
207 {
208 actionValidators.put(Action.AUDIO, new AudioValidator());
209 actionValidators.put(Action.DISPLAY, new DisplayValidator());
210 actionValidators.put(Action.EMAIL, new EmailValidator());
211 actionValidators.put(Action.PROCEDURE, new ProcedureValidator());
212 }
213
214 private final Validator itipValidator = new ITIPValidator();
215
216 /**
217 * Default constructor.
218 */
219 public VAlarm() {
220 super(VALARM);
221 }
222
223 /**
224 * Constructor.
225 * @param properties a list of properties
226 */
227 public VAlarm(final PropertyList properties) {
228 super(VALARM, properties);
229 }
230
231 /**
232 * Constructs a new VALARM instance that will trigger at the specified time.
233 * @param trigger the time the alarm will trigger
234 */
235 public VAlarm(final DateTime trigger) {
236 this();
237 getProperties().add(new Trigger(trigger));
238 }
239
240 /**
241 * Constructs a new VALARM instance that will trigger at the specified time relative to the event/todo component.
242 * @param trigger a duration of time relative to the parent component that the alarm will trigger at
243 */
244 public VAlarm(final Dur trigger) {
245 this();
246 getProperties().add(new Trigger(trigger));
247 }
248
249 /**
250 * {@inheritDoc}
251 */
252 public final void validate(final boolean recurse)
253 throws ValidationException {
254
255 /*
256 * ; 'action' and 'trigger' are both REQUIRED, ; but MUST NOT occur more than once action / trigger /
257 */
258 PropertyValidator.getInstance().assertOne(Property.ACTION, getProperties());
259 PropertyValidator.getInstance().assertOne(Property.TRIGGER, getProperties());
260
261 /*
262 * ; 'duration' and 'repeat' are both optional, ; and MUST NOT occur more than once each, ; but if one occurs,
263 * so MUST the other duration / repeat /
264 */
265 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
266 PropertyValidator.getInstance().assertOneOrLess(Property.REPEAT, getProperties());
267
268 try {
269 PropertyValidator.getInstance().assertNone(Property.DURATION, getProperties());
270 PropertyValidator.getInstance().assertNone(Property.REPEAT, getProperties());
271 }
272 catch (ValidationException ve) {
273 PropertyValidator.getInstance().assertOne(Property.DURATION, getProperties());
274 PropertyValidator.getInstance().assertOne(Property.REPEAT, getProperties());
275 }
276
277 /*
278 * ; the following is optional, ; and MAY occur more than once x-prop
279 */
280
281 final Validator actionValidator = (Validator) actionValidators.get(getAction());
282 if (actionValidator != null) {
283 actionValidator.validate();
284 }
285
286 if (recurse) {
287 validateProperties();
288 }
289 }
290
291 /**
292 * {@inheritDoc}
293 */
294 protected Validator getValidator(Method method) {
295 return itipValidator;
296 }
297
298 private class AudioValidator implements Validator {
299
300 private static final long serialVersionUID = 1L;
301
302 /**
303 * {@inheritDoc}
304 */
305 public void validate() throws ValidationException {
306 /*
307 * ; the following is optional, ; but MUST NOT occur more than once attach /
308 */
309 PropertyValidator.getInstance().assertOneOrLess(Property.ATTACH, getProperties());
310 }
311 }
312
313 private class DisplayValidator implements Validator {
314
315 private static final long serialVersionUID = 1L;
316
317 /**
318 * {@inheritDoc}
319 */
320 public void validate() throws ValidationException {
321 /*
322 * ; the following are all REQUIRED, ; but MUST NOT occur more than once action / description / trigger /
323 */
324 PropertyValidator.getInstance().assertOne(Property.DESCRIPTION, getProperties());
325 }
326 }
327
328 private class EmailValidator implements Validator {
329
330 private static final long serialVersionUID = 1L;
331
332 /**
333 * {@inheritDoc}
334 */
335 public void validate() throws ValidationException {
336 /*
337 * ; the following are all REQUIRED,
338 * ; but MUST NOT occur more than once action / description / trigger / summary
339 * ; the following is REQUIRED,
340 * ; and MAY occur more than once attendee /
341 * ; 'duration' and 'repeat' are both optional,
342 * ; and MUST NOT occur more than once each,
343 * ; but if one occurs, so MUST the other duration / repeat /
344 * ; the following are optional,
345 * ; and MAY occur more than once attach / x-prop
346 */
347 PropertyValidator.getInstance().assertOne(Property.DESCRIPTION, getProperties());
348 PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
349
350 PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties());
351 }
352 }
353
354 private class ProcedureValidator implements Validator {
355
356 private static final long serialVersionUID = 1L;
357
358 /**
359 * {@inheritDoc}
360 */
361 public void validate() throws ValidationException {
362 /*
363 * ; the following are all REQUIRED,
364 * ; but MUST NOT occur more than once action / attach / trigger /
365 * ; 'duration' and 'repeat' are both optional,
366 * ; and MUST NOT occur more than once each,
367 * ; but if one occurs, so MUST the other duration / repeat /
368 * ; 'description' is optional,
369 * ; and MUST NOT occur more than once description /
370 * ; the following is optional, ; and MAY occur more than once x-prop
371 */
372 PropertyValidator.getInstance().assertOne(Property.ATTACH, getProperties());
373
374 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
375 }
376 }
377
378 /**
379 * Common validation for all iTIP methods.
380 *
381 * <pre>
382 * Component/Property Presence
383 * ------------------- ----------------------------------------------
384 * VALARM 0+
385 * ACTION 1
386 * ATTACH 0+
387 * DESCRIPTION 0 or 1
388 * DURATION 0 or 1 if present REPEAT MUST be present
389 * REPEAT 0 or 1 if present DURATION MUST be present
390 * SUMMARY 0 or 1
391 * TRIGGER 1
392 * X-PROPERTY 0+
393 * </pre>
394 */
395 private class ITIPValidator implements Validator {
396
397 private static final long serialVersionUID = 1L;
398
399 /**
400 * {@inheritDoc}
401 */
402 public void validate() throws ValidationException {
403 PropertyValidator.getInstance().assertOne(Property.ACTION, getProperties());
404 PropertyValidator.getInstance().assertOne(Property.TRIGGER, getProperties());
405
406 PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
407 PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
408 PropertyValidator.getInstance().assertOneOrLess(Property.REPEAT, getProperties());
409 PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY, getProperties());
410 }
411 }
412
413 /**
414 * Returns the mandatory action property.
415 * @return the ACTION property or null if not specified
416 */
417 public final Action getAction() {
418 return (Action) getProperty(Property.ACTION);
419 }
420
421 /**
422 * Returns the mandatory trigger property.
423 * @return the TRIGGER property or null if not specified
424 */
425 public final Trigger getTrigger() {
426 return (Trigger) getProperty(Property.TRIGGER);
427 }
428
429 /**
430 * Returns the optional duration property.
431 * @return the DURATION property or null if not specified
432 */
433 public final Duration getDuration() {
434 return (Duration) getProperty(Property.DURATION);
435 }
436
437 /**
438 * Returns the optional repeat property.
439 * @return the REPEAT property or null if not specified
440 */
441 public final Repeat getRepeat() {
442 return (Repeat) getProperty(Property.REPEAT);
443 }
444
445 /**
446 * Returns the optional attachment property.
447 * @return the ATTACH property or null if not specified
448 */
449 public final Attach getAttachment() {
450 return (Attach) getProperty(Property.ATTACH);
451 }
452
453 /**
454 * Returns the optional description property.
455 * @return the DESCRIPTION property or null if not specified
456 */
457 public final Description getDescription() {
458 return (Description) getProperty(Property.DESCRIPTION);
459 }
460
461 /**
462 * Returns the optional summary property.
463 * @return the SUMMARY property or null if not specified
464 */
465 public final Summary getSummary() {
466 return (Summary) getProperty(Property.SUMMARY);
467 }
468 }

mercurial