001    package biweekly.parameter;
002    
003    import java.util.List;
004    
005    import biweekly.component.VTimezone;
006    import biweekly.property.FreeBusy;
007    import biweekly.property.RecurrenceId;
008    import biweekly.property.RelatedTo;
009    import biweekly.property.TimezoneId;
010    import biweekly.property.Trigger;
011    import biweekly.util.ListMultimap;
012    
013    /*
014     Copyright (c) 2013, Michael Angstadt
015     All rights reserved.
016    
017     Redistribution and use in source and binary forms, with or without
018     modification, are permitted provided that the following conditions are met: 
019    
020     1. Redistributions of source code must retain the above copyright notice, this
021     list of conditions and the following disclaimer. 
022     2. Redistributions in binary form must reproduce the above copyright notice,
023     this list of conditions and the following disclaimer in the documentation
024     and/or other materials provided with the distribution. 
025    
026     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
027     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
028     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
029     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
030     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
031     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
032     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
033     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
034     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
035     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
036     */
037    
038    /**
039     * Contains the list of parameters that belong to a property.
040     * @author Michael Angstadt
041     */
042    public class ICalParameters extends ListMultimap<String, String> {
043            public static final String CN = "CN";
044            public static final String ALTREP = "ALTREP";
045            public static final String CUTYPE = "CUTYPE";
046            public static final String DELEGATED_FROM = "DELEGATED-FROM";
047            public static final String DELEGATED_TO = "DELEGATED-TO";
048            public static final String DIR = "DIR";
049            public static final String ENCODING = "ENCODING";
050            public static final String FMTTYPE = "FMTTYPE";
051            public static final String FBTYPE = "FBTYPE";
052            public static final String LANGUAGE = "LANGUAGE";
053            public static final String MEMBER = "MEMBER";
054            public static final String PARTSTAT = "PARTSTAT";
055            public static final String RANGE = "RANGE";
056            public static final String RELATED = "RELATED";
057            public static final String RELTYPE = "RELTYPE";
058            public static final String ROLE = "ROLE";
059            public static final String RSVP = "RSVP";
060            public static final String SENT_BY = "SENT-BY";
061            public static final String TZID = "TZID";
062            public static final String VALUE = "VALUE";
063    
064            /**
065             * Creates a parameters list.
066             */
067            public ICalParameters() {
068                    super(0); //initialize map size to 0 because most properties don't use any parameters
069            }
070    
071            /**
072             * Copies an existing parameters list.
073             * @param parameters the list to copy
074             */
075            public ICalParameters(ICalParameters parameters) {
076                    super(parameters);
077            }
078    
079            /**
080             * Gets a URI pointing to additional information about the entity
081             * represented by the property.
082             * @return the URI or null if not set
083             * @see <a href="http://tools.ietf.org/html/rfc5545#page-14">RFC 5545
084             * p.14-5</a>
085             */
086            public String getAltRepresentation() {
087                    return first(ALTREP);
088            }
089    
090            /**
091             * Sets a URI pointing to additional information about the entity
092             * represented by the property.
093             * @param uri the URI or null to remove
094             * @see <a href="http://tools.ietf.org/html/rfc5545#page-14">RFC 5545
095             * p.14-5</a>
096             */
097            public void setAltRepresentation(String uri) {
098                    replace(ALTREP, uri);
099            }
100    
101            /**
102             * Gets the display name of a person.
103             * @return the display name (e.g. "John Doe") or null if not set
104             * @see <a href="http://tools.ietf.org/html/rfc5545#page-15">RFC 5545
105             * p.15-6</a>
106             */
107            public String getCommonName() {
108                    return first(CN);
109            }
110    
111            /**
112             * Sets the display name of a person.
113             * @param cn the display name (e.g. "John Doe") or null to remove
114             * @see <a href="http://tools.ietf.org/html/rfc5545#page-15">RFC 5545
115             * p.15-6</a>
116             */
117            public void setCommonName(String cn) {
118                    replace(CN, cn);
119            }
120    
121            /**
122             * Gets the type of user an attendee is (for example, an "individual" or a
123             * "room").
124             * @return the calendar user type or null if not set
125             * @see <a href="http://tools.ietf.org/html/rfc5545#page-16">RFC 5545
126             * p.16</a>
127             */
128            public CalendarUserType getCalendarUserType() {
129                    String value = first(CUTYPE);
130                    return (value == null) ? null : CalendarUserType.get(value);
131            }
132    
133            /**
134             * Sets the type of user an attendee is (for example, an "individual" or a
135             * "room").
136             * @param cutype the calendar user type or null to remove
137             * @see <a href="http://tools.ietf.org/html/rfc5545#page-16">RFC 5545
138             * p.16</a>
139             */
140            public void setCalendarUserType(CalendarUserType cutype) {
141                    replace(CUTYPE, (cutype == null) ? null : cutype.getValue());
142            }
143    
144            /**
145             * Gets the people who have delegated their responsibility to an attendee.
146             * @return the delegators (typically email URIs, e.g.
147             * "mailto:janedoe@example.com")
148             * @see <a href="http://tools.ietf.org/html/rfc5545#page-17">RFC 5545
149             * p.17</a>
150             */
151            public List<String> getDelegatedFrom() {
152                    return get(DELEGATED_FROM);
153            }
154    
155            /**
156             * Adds a person who has delegated his or her responsibility to an attendee.
157             * @param uri the delegator (typically an email URI, e.g.
158             * "mailto:janedoe@example.com")
159             * @see <a href="http://tools.ietf.org/html/rfc5545#page-17">RFC 5545
160             * p.17</a>
161             */
162            public void addDelegatedFrom(String uri) {
163                    put(DELEGATED_FROM, uri);
164            }
165    
166            /**
167             * Removes a person who has delegated his or her responsibility to an
168             * attendee.
169             * @param uri the delegator to remove (typically an email URI, e.g.
170             * "mailto:janedoe@example.com")
171             * @see <a href="http://tools.ietf.org/html/rfc5545#page-17">RFC 5545
172             * p.17</a>
173             */
174            public void removeDelegatedFrom(String uri) {
175                    remove(DELEGATED_FROM, uri);
176            }
177    
178            /**
179             * Removes everyone who has delegated his or her responsibility to an
180             * attendee.
181             * @see <a href="http://tools.ietf.org/html/rfc5545#page-17">RFC 5545
182             * p.17</a>
183             */
184            public void removeDelegatedFrom() {
185                    removeAll(DELEGATED_FROM);
186            }
187    
188            /**
189             * Gets the people to which an attendee has delegated his or her
190             * responsibility.
191             * @return the delegatees (typically email URIs, e.g.
192             * "mailto:janedoe@example.com")
193             * @see <a href="http://tools.ietf.org/html/rfc5545#page-17">RFC 5545
194             * p.17-8</a>
195             */
196            public List<String> getDelegatedTo() {
197                    return get(DELEGATED_TO);
198            }
199    
200            /**
201             * Adds a person to which an attendee has delegated his or her
202             * responsibility.
203             * @param uri the delegatee (typically an email URI, e.g.
204             * "mailto:janedoe@example.com")
205             * @see <a href="http://tools.ietf.org/html/rfc5545#page-17">RFC 5545
206             * p.17-8</a>
207             */
208            public void addDelegatedTo(String uri) {
209                    put(DELEGATED_TO, uri);
210            }
211    
212            /**
213             * Removes a person to which an attendee has delegated his or her
214             * responsibility.
215             * @param uri the delegatee to remove (typically an email URI, e.g.
216             * "mailto:janedoe@example.com")
217             * @see <a href="http://tools.ietf.org/html/rfc5545#page-17">RFC 5545
218             * p.17-8</a>
219             */
220            public void removeDelegatedTo(String uri) {
221                    remove(DELEGATED_TO, uri);
222            }
223    
224            /**
225             * Removes everyone to which an attendee has delegated his or her
226             * responsibility.
227             * @see <a href="http://tools.ietf.org/html/rfc5545#page-17">RFC 5545
228             * p.17-8</a>
229             */
230            public void removeDelegatedTo() {
231                    removeAll(DELEGATED_TO);
232            }
233    
234            /**
235             * Gets a URI that contains additional information about the person.
236             * @return the URI (e.g. an LDAP URI) or null if not set
237             * @see <a href="http://tools.ietf.org/html/rfc5545#page-18">RFC 5545
238             * p.18</a>
239             */
240            public String getDirectoryEntry() {
241                    return first(DIR);
242            }
243    
244            /**
245             * Sets a URI that contains additional information about the person.
246             * @param uri the URI (e.g. an LDAP URI) or null to remove
247             * @see <a href="http://tools.ietf.org/html/rfc5545#page-18">RFC 5545
248             * p.18</a>
249             */
250            public void setDirectoryEntry(String uri) {
251                    replace(DIR, uri);
252            }
253    
254            /**
255             * Gets the encoding of the property value (for example, "base64").
256             * @return the encoding or null if not set
257             * @see <a href="http://tools.ietf.org/html/rfc5545#page-18">RFC 5545
258             * p.18-9</a>
259             */
260            public Encoding getEncoding() {
261                    String value = first(ENCODING);
262                    return (value == null) ? null : Encoding.get(value);
263            }
264    
265            /**
266             * Sets the encoding of the property value (for example, "base64").
267             * @param encoding the encoding or null to remove
268             * @see <a href="http://tools.ietf.org/html/rfc5545#page-18">RFC 5545
269             * p.18-9</a>
270             */
271            public void setEncoding(Encoding encoding) {
272                    replace(ENCODING, (encoding == null) ? null : encoding.getValue());
273            }
274    
275            /**
276             * Gets the content-type of the property's value.
277             * @return the content type (e.g. "image/png") or null if not set
278             * @see <a href="http://tools.ietf.org/html/rfc5545#page-19">RFC 5545
279             * p.19-20</a>
280             */
281            public String getFormatType() {
282                    return first(FMTTYPE);
283            }
284    
285            /**
286             * Sets the content-type of the property's value.
287             * @param formatType the content type (e.g. "image/png") or null to remove
288             * @see <a href="http://tools.ietf.org/html/rfc5545#page-19">RFC 5545
289             * p.19-20</a>
290             */
291            public void setFormatType(String formatType) {
292                    replace(FMTTYPE, formatType);
293            }
294    
295            /**
296             * Gets the person's status over the time periods that are specified in a
297             * {@link FreeBusy} property (for example, "free" or "busy"). If not set,
298             * the user should be considered "busy".
299             * @return the type or null if not set
300             * @see <a href="http://tools.ietf.org/html/rfc5545#page-20">RFC 5545
301             * p.20</a>
302             */
303            public FreeBusyType getFreeBusyType() {
304                    String value = first(FBTYPE);
305                    return (value == null) ? null : FreeBusyType.get(value);
306            }
307    
308            /**
309             * Sets the person's status over the time periods that are specified in a
310             * {@link FreeBusy} property (for example, "free" or "busy"). If not set,
311             * the user should be considered "busy".
312             * @param fbType the type or null to remove
313             * @see <a href="http://tools.ietf.org/html/rfc5545#page-20">RFC 5545
314             * p.20</a>
315             */
316            public void setFreeBusyType(FreeBusyType fbType) {
317                    replace(FBTYPE, (fbType == null) ? null : fbType.getValue());
318            }
319    
320            /**
321             * Gets the language that the property value is written in.
322             * @return the language (e.g. "en" for English) or null if not set
323             * @see <a href="http://tools.ietf.org/html/rfc5545#page-21">RFC 5545
324             * p.21</a>
325             */
326            public String getLanguage() {
327                    return first(LANGUAGE);
328            }
329    
330            /**
331             * Sets the language that the property value is written in.
332             * @param language the language (e.g. "en" for English) or null to remove
333             * @see <a href="http://tools.ietf.org/html/rfc5545#page-21">RFC 5545
334             * p.21</a>
335             */
336            public void setLanguage(String language) {
337                    replace(LANGUAGE, language);
338            }
339    
340            /**
341             * Adds a group that an attendee is a member of.
342             * @param uri the group URI (typically, an email address URI, e.g.
343             * "mailto:mailinglist@example.com")
344             * @see <a href="http://tools.ietf.org/html/rfc5545#page-21">RFC 5545
345             * p.21-2</a>
346             */
347            public void addMember(String uri) {
348                    put(MEMBER, uri);
349            }
350    
351            /**
352             * Gets the groups that an attendee is a member of.
353             * @return the group URIs (typically, these are email address URIs, e.g.
354             * "mailto:mailinglist@example.com")
355             * @see <a href="http://tools.ietf.org/html/rfc5545#page-21">RFC 5545
356             * p.21-2</a>
357             */
358            public List<String> getMembers() {
359                    return get(MEMBER);
360            }
361    
362            /**
363             * Removes a group that an attendee is a member of.
364             * @param uri the group URI to remove (typically, an email address URI, e.g.
365             * "mailto:mailinglist@example.com")
366             * @see <a href="http://tools.ietf.org/html/rfc5545#page-21">RFC 5545
367             * p.21-2</a>
368             */
369            public void removeMember(String uri) {
370                    remove(MEMBER, uri);
371            }
372    
373            /**
374             * Removes all groups that an attendee is a member of.
375             * @see <a href="http://tools.ietf.org/html/rfc5545#page-21">RFC 5545
376             * p.21-2</a>
377             */
378            public void removeMembers() {
379                    removeAll(MEMBER);
380            }
381    
382            /**
383             * Gets an attendee's level of participation.
384             * @return the participation status or null if not set
385             * @see <a href="http://tools.ietf.org/html/rfc5545#page-22">RFC 5545
386             * p.22-3</a>
387             */
388            public ParticipationStatus getParticipationStatus() {
389                    String value = first(PARTSTAT);
390                    return (value == null) ? null : ParticipationStatus.get(value);
391            }
392    
393            /**
394             * Sets an attendee's level of participation.
395             * @param status the participation status or null to remove
396             * @see <a href="http://tools.ietf.org/html/rfc5545#page-22">RFC 5545
397             * p.22-3</a>
398             */
399            public void setParticipationStatus(ParticipationStatus status) {
400                    replace(PARTSTAT, (status == null) ? null : status.getValue());
401            }
402    
403            /**
404             * Gets the effective range of recurrence instances from the instance
405             * specified by a {@link RecurrenceId} property.
406             * @return the range or null if not set
407             * @see <a href="http://tools.ietf.org/html/rfc5545#page-23">RFC 5545
408             * p.23-4</a>
409             */
410            public Range getRange() {
411                    String value = first(RANGE);
412                    return (value == null) ? null : Range.get(value);
413            }
414    
415            /**
416             * Sets the effective range of recurrence instances from the instance
417             * specified by a {@link RecurrenceId} property.
418             * @param range the range or null to remove
419             * @see <a href="http://tools.ietf.org/html/rfc5545#page-23">RFC 5545
420             * p.23-4</a>
421             */
422            public void setRange(Range range) {
423                    replace(RANGE, (range == null) ? null : range.getValue());
424            }
425    
426            /**
427             * Gets the date-time field that the duration in a {@link Trigger} property
428             * is relative to.
429             * @return the field or null if not set
430             * @see <a href="http://tools.ietf.org/html/rfc5545#page-24">RFC 5545
431             * p.24</a>
432             */
433            public Related getRelated() {
434                    String value = first(RELATED);
435                    return (value == null) ? null : Related.get(value);
436            }
437    
438            /**
439             * Sets the date-time field that the duration in a {@link Trigger} property
440             * is relative to.
441             * @param related the field or null to remove
442             * @see <a href="http://tools.ietf.org/html/rfc5545#page-24">RFC 5545
443             * p.24</a>
444             */
445            public void setRelated(Related related) {
446                    replace(RELATED, (related == null) ? null : related.getValue());
447            }
448    
449            /**
450             * Gets the relationship type of a {@link RelatedTo} property.
451             * @return the relationship type (e.g. "child") or null if not set
452             * @see <a href="http://tools.ietf.org/html/rfc5545#page-25">RFC 5545
453             * p.25</a>
454             */
455            public RelationshipType getRelationshipType() {
456                    String value = first(RELTYPE);
457                    return (value == null) ? null : RelationshipType.get(value);
458            }
459    
460            /**
461             * Sets the relationship type of a {@link RelatedTo} property.
462             * @param relationshipType the relationship type (e.g. "child") or null to
463             * remove
464             * @see <a href="http://tools.ietf.org/html/rfc5545#page-25">RFC 5545
465             * p.25</a>
466             */
467            public void setRelationshipType(RelationshipType relationshipType) {
468                    replace(RELTYPE, (relationshipType == null) ? null : relationshipType.getValue());
469            }
470    
471            /**
472             * Gets an attendee's role (for example, "chair" or "required participant").
473             * @return the role or null if not set
474             * @see <a href="http://tools.ietf.org/html/rfc5545#page-25">RFC 5545
475             * p.25-6</a>
476             */
477            public Role getRole() {
478                    String value = first(ROLE);
479                    return (value == null) ? null : Role.get(value);
480            }
481    
482            /**
483             * Sets an attendee's role (for example, "chair" or "required participant").
484             * @param role the role or null to remove
485             * @see <a href="http://tools.ietf.org/html/rfc5545#page-25">RFC 5545
486             * p.25-6</a>
487             */
488            public void setRole(Role role) {
489                    replace(ROLE, (role == null) ? null : role.getValue());
490            }
491    
492            /**
493             * Gets whether the organizer requests a response from an attendee.
494             * @return true if an RSVP is requested, false if not, null if not set
495             * @see <a href="http://tools.ietf.org/html/rfc5545#page-26">RFC 5545
496             * p.26-7</a>
497             */
498            public Boolean getRsvp() {
499                    String value = first(RSVP);
500                    return (value == null) ? null : Boolean.valueOf(value);
501            }
502    
503            /**
504             * Sets whether the organizer requests a response from an attendee.
505             * @param rsvp true if an RSVP has been requested, false if not, null to
506             * remove
507             * @see <a href="http://tools.ietf.org/html/rfc5545#page-26">RFC 5545
508             * p.26-7</a>
509             */
510            public void setRsvp(Boolean rsvp) {
511                    replace(RSVP, (rsvp == null) ? null : rsvp.toString().toUpperCase());
512            }
513    
514            /**
515             * Gets a person that is acting on behalf of the person defined in the
516             * property.
517             * @return a URI representing the person (typically, an email URI, e.g.
518             * "mailto:janedoe@example.com") or null if not set
519             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
520             * p.27</a>
521             */
522            public String getSentBy() {
523                    return first(SENT_BY);
524            }
525    
526            /**
527             * Sets a person that is acting on behalf of the person defined in the
528             * property.
529             * @param uri a URI representing the person (typically, an email URI, e.g.
530             * "mailto:janedoe@example.com") or null to remove
531             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
532             * p.27</a>
533             */
534            public void setSentBy(String uri) {
535                    replace(SENT_BY, uri);
536            }
537    
538            /**
539             * Gets the timezone identifier. This either (a) references the
540             * {@link TimezoneId} property of a {@link VTimezone} component, or (b)
541             * specifies a globally-defined timezone (e.g. "America/New_York"). For a
542             * list of globally-defined timezones, see the <a
543             * href="http://www.twinsun.com/tz/tz-link.htm">TZ database</a>.
544             * @return the timezone identifier or null if not set
545             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
546             * p.27-8</a>
547             */
548            public String getTimezoneId() {
549                    return first(TZID);
550            }
551    
552            /**
553             * Sets the timezone identifier. This either (a) references the
554             * {@link TimezoneId} property of a {@link VTimezone} component, or (b)
555             * specifies a globally-defined timezone (e.g. "America/New_York"). For a
556             * list of globally-defined timezones, see the <a
557             * href="http://www.twinsun.com/tz/tz-link.htm">TZ database</a>.
558             * @param timezoneId the timezone identifier or null to remove
559             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
560             * p.27-8</a>
561             */
562            public void setTimezoneId(String timezoneId) {
563                    replace(TZID, timezoneId);
564            }
565    
566            /**
567             * Gets the data type of the property's value (for example, "text" or
568             * "datetime").
569             * @return the data type or null if not set
570             * @see <a href="http://tools.ietf.org/html/rfc5545#page-29">RFC 5545
571             * p.29-50</a>
572             */
573            public Value getValue() {
574                    String value = first(VALUE);
575                    return (value == null) ? null : Value.get(value);
576            }
577    
578            /**
579             * Sets the data type of the property's value (for example, "text" or
580             * "datetime").
581             * @param value the data type or null to remove
582             * @see <a href="http://tools.ietf.org/html/rfc5545#page-29">RFC 5545
583             * p.29-50</a>
584             */
585            public void setValue(Value value) {
586                    replace(VALUE, (value == null) ? null : value.getValue());
587            }
588    
589            @Override
590            protected String sanitizeKey(String key) {
591                    return key.toUpperCase();
592            }
593    }