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