001    package biweekly.property;
002    
003    import java.util.Date;
004    import java.util.List;
005    
006    import biweekly.component.ICalComponent;
007    import biweekly.component.VTimezone;
008    import biweekly.util.DateTimeComponents;
009    import biweekly.util.ICalDateFormatter;
010    
011    /*
012     Copyright (c) 2013, Michael Angstadt
013     All rights reserved.
014    
015     Redistribution and use in source and binary forms, with or without
016     modification, are permitted provided that the following conditions are met: 
017    
018     1. Redistributions of source code must retain the above copyright notice, this
019     list of conditions and the following disclaimer. 
020     2. Redistributions in binary form must reproduce the above copyright notice,
021     this list of conditions and the following disclaimer in the documentation
022     and/or other materials provided with the distribution. 
023    
024     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
025     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
026     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
027     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
028     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
029     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
030     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
031     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
032     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
033     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
034     */
035    
036    /**
037     * Represents a property whose value is a date or a date-time.
038     * @author Michael Angstadt
039     */
040    public class DateOrDateTimeProperty extends ICalProperty {
041            protected Date value;
042            protected DateTimeComponents rawComponents;
043            protected boolean hasTime;
044            protected boolean localTime;
045    
046            /**
047             * Creates a new property.
048             * @param rawComponents the raw components of the date-time value
049             */
050            public DateOrDateTimeProperty(DateTimeComponents rawComponents) {
051                    setRawComponents(rawComponents);
052            }
053    
054            /**
055             * Creates a new property.
056             * @param value the date-time value
057             * @param hasTime true if the value has a time component, false if it is
058             * strictly a date
059             */
060            public DateOrDateTimeProperty(Date value, boolean hasTime) {
061                    setValue(value, hasTime);
062            }
063    
064            /**
065             * Gets the date-time value.
066             * @return the date-time value
067             */
068            public Date getValue() {
069                    return value;
070            }
071    
072            /**
073             * Sets the date-time value.
074             * @param value the date-time value
075             * @param hasTime true if the value has a time component, false if it is
076             * strictly a date
077             */
078            public void setValue(Date value, boolean hasTime) {
079                    this.value = value;
080                    this.hasTime = hasTime;
081            }
082    
083            /**
084             * Gets the raw components of the date-time value.
085             * @return the raw components
086             */
087            public DateTimeComponents getRawComponents() {
088                    return rawComponents;
089            }
090    
091            /**
092             * Sets the raw components of the date-time value.
093             * @param rawComponents the raw components
094             */
095            public void setRawComponents(DateTimeComponents rawComponents) {
096                    this.rawComponents = rawComponents;
097            }
098    
099            /**
100             * Determines whether the date-time value has a time component.
101             * @return true if the value has a time component, false if it is strictly a
102             * date
103             */
104            public boolean hasTime() {
105                    return hasTime;
106            }
107    
108            /**
109             * Gets whether the date should be outputted in local time (without a
110             * timezone).
111             * @return true to output the date without a timezone, false to include a
112             * timezone
113             */
114            public boolean isLocalTime() {
115                    return localTime;
116            }
117    
118            /**
119             * Sets whether the date should be outputted in local time (without a
120             * timezone). Use {@link #setTimezoneId(String)} to specify a timezone.
121             * Dates are written in UTC time by default.
122             * @param localTime true to output the date without a timezone, false to
123             * include a timezone (defaults to false)
124             */
125            public void setLocalTime(boolean localTime) {
126                    this.localTime = localTime;
127                    if (localTime) {
128                            setTimezoneId(null);
129                    }
130            }
131    
132            @Override
133            public String getTimezoneId() {
134                    return super.getTimezoneId();
135            }
136    
137            @Override
138            public void setTimezoneId(String timezoneId) {
139                    super.setTimezoneId(timezoneId);
140            }
141    
142            @Override
143            public void setTimezone(VTimezone timezone) {
144                    super.setTimezone(timezone);
145            }
146    
147            @Override
148            protected void validate(List<ICalComponent> components, List<String> warnings) {
149                    if (value == null && components == null) {
150                            warnings.add("No value set.");
151                    }
152    
153                    String tzid = getTimezoneId();
154                    if (tzid != null && tzid.contains("/") && ICalDateFormatter.parseTimeZoneId(tzid) == null) {
155                            warnings.add("Unrecognized timezone ID: " + tzid);
156                    }
157            }
158    }