001    package biweekly.component;
002    
003    import java.util.Date;
004    import java.util.List;
005    
006    import biweekly.property.LastModified;
007    import biweekly.property.TimezoneId;
008    import biweekly.property.TimezoneUrl;
009    
010    /*
011     Copyright (c) 2013, Michael Angstadt
012     All rights reserved.
013    
014     Redistribution and use in source and binary forms, with or without
015     modification, are permitted provided that the following conditions are met: 
016    
017     1. Redistributions of source code must retain the above copyright notice, this
018     list of conditions and the following disclaimer. 
019     2. Redistributions in binary form must reproduce the above copyright notice,
020     this list of conditions and the following disclaimer in the documentation
021     and/or other materials provided with the distribution. 
022    
023     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
024     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
025     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
026     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
027     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
028     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
029     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
030     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
031     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
032     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
033     */
034    
035    /**
036     * <p>
037     * Defines a timezone.
038     * </p>
039     * 
040     * <p>
041     * <b>Examples:</b>
042     * 
043     * <pre>
044     * VTimezone timezone = new VTimezone(&quot;EST&quot;);
045     * 
046     * StandardTime standard = ...
047     * timezone.addStandardTime(standard);
048     * 
049     * DaylightSavingsTime daylightSavings = ...
050     * timezone.addDaylightSavingsTime(daylightSavings);
051     * </pre>
052     * 
053     * </p>
054     * @author Michael Angstadt
055     * @see <a href="http://tools.ietf.org/html/rfc5545#page-62">RFC 5545
056     * p.62-71</a>
057     */
058    public class VTimezone extends ICalComponent {
059            /**
060             * Creates a new timezone component.
061             * @param identifier a unique identifier for this timezone (allows it to be
062             * referenced by date-time properties that support timezones).
063             */
064            public VTimezone(String identifier) {
065                    setTimezoneId(identifier);
066            }
067    
068            /**
069             * Gets the ID for this timezone. This is a <b>required</b> property.
070             * @return the timezone ID or null if not set
071             * @see <a href="http://tools.ietf.org/html/rfc5545#page-102">RFC 5545
072             * p.102-3</a>
073             */
074            public TimezoneId getTimezoneId() {
075                    return getProperty(TimezoneId.class);
076            }
077    
078            /**
079             * Sets an ID for this timezone. This is a <b>required</b> property.
080             * @param timezoneId the timezone ID or null to remove
081             * @see <a href="http://tools.ietf.org/html/rfc5545#page-102">RFC 5545
082             * p.102-3</a>
083             */
084            public void setTimezoneId(TimezoneId timezoneId) {
085                    setProperty(TimezoneId.class, timezoneId);
086            }
087    
088            /**
089             * Sets an ID for this timezone. This is a <b>required</b> property.
090             * @param timezoneId the timezone ID or null to remove
091             * @see <a href="http://tools.ietf.org/html/rfc5545#page-102">RFC 5545
092             * p.102-3</a>
093             */
094            public TimezoneId setTimezoneId(String timezoneId) {
095                    TimezoneId prop = (timezoneId == null) ? null : new TimezoneId(timezoneId);
096                    setTimezoneId(prop);
097                    return prop;
098            }
099    
100            /**
101             * Gets the date-time that the timezone data was last changed.
102             * @return the last modified date or null if not set
103             * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
104             * p.138</a>
105             */
106            public LastModified getLastModified() {
107                    return getProperty(LastModified.class);
108            }
109    
110            /**
111             * Sets the date-time that the timezone data was last changed.
112             * @param lastModified the last modified date or null to remove
113             * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
114             * p.138</a>
115             */
116            public void setLastModified(LastModified lastModified) {
117                    setProperty(LastModified.class, lastModified);
118            }
119    
120            /**
121             * Sets the date-time that the timezone data was last changed.
122             * @param lastModified the last modified date or null to remove
123             * @return the property that was created
124             * @see <a href="http://tools.ietf.org/html/rfc5545#page-138">RFC 5545
125             * p.138</a>
126             */
127            public LastModified setLastModified(Date lastModified) {
128                    LastModified prop = (lastModified == null) ? null : new LastModified(lastModified);
129                    setLastModified(prop);
130                    return prop;
131            }
132    
133            /**
134             * Gets the timezone URL, which points to an iCalendar object that contains
135             * further information on the timezone.
136             * @return the URL or null if not set
137             * @see <a href="http://tools.ietf.org/html/rfc5545#page-106">RFC 5545
138             * p.106</a>
139             */
140            public TimezoneUrl getTimezoneUrl() {
141                    return getProperty(TimezoneUrl.class);
142            }
143    
144            /**
145             * Sets the timezone URL, which points to an iCalendar object that contains
146             * further information on the timezone.
147             * @param url the URL or null to remove
148             * @see <a href="http://tools.ietf.org/html/rfc5545#page-106">RFC 5545
149             * p.106</a>
150             */
151            public void setTimezoneUrl(TimezoneUrl url) {
152                    setProperty(TimezoneUrl.class, url);
153            }
154    
155            /**
156             * Sets the timezone URL, which points to an iCalendar object that contains
157             * further information on the timezone.
158             * @param url the timezone URL (e.g.
159             * "http://example.com/America-New_York.ics") or null to remove
160             * @return the property that was created
161             * @see <a href="http://tools.ietf.org/html/rfc5545#page-106">RFC 5545
162             * p.106</a>
163             */
164            public TimezoneUrl setTimezoneUrl(String url) {
165                    TimezoneUrl prop = (url == null) ? null : new TimezoneUrl(url);
166                    setTimezoneUrl(prop);
167                    return prop;
168            }
169    
170            /**
171             * Gets the timezone's "standard" observance time ranges.
172             * @return the "standard" observance time ranges
173             */
174            public List<StandardTime> getStandardTimes() {
175                    return getComponents(StandardTime.class);
176            }
177    
178            /**
179             * Adds a "standard" observance time range.
180             * @param standardTime the "standard" observance time
181             */
182            public void addStandardTime(StandardTime standardTime) {
183                    addComponent(standardTime);
184            }
185    
186            /**
187             * Gets the timezone's "daylight savings" observance time ranges.
188             * @return the "daylight savings" observance time ranges
189             */
190            public List<DaylightSavingsTime> getDaylightSavingsTime() {
191                    return getComponents(DaylightSavingsTime.class);
192            }
193    
194            /**
195             * Adds a "daylight savings" observance time range.
196             * @param daylightSavingsTime the "daylight savings" observance time
197             */
198            public void addDaylightSavingsTime(DaylightSavingsTime daylightSavingsTime) {
199                    addComponent(daylightSavingsTime);
200            }
201    
202            @SuppressWarnings("unchecked")
203            @Override
204            protected void validate(List<ICalComponent> components, List<String> warnings) {
205                    checkRequiredCardinality(warnings, TimezoneId.class);
206                    checkOptionalCardinality(warnings, LastModified.class, TimezoneUrl.class);
207    
208                    if (getStandardTimes().isEmpty() && getDaylightSavingsTime().isEmpty()) {
209                            warnings.add("At least one " + StandardTime.class.getSimpleName() + " or one " + DaylightSavingsTime.class.getSimpleName() + " must be specified.");
210                    }
211            }
212    }