001    package biweekly.property;
002    
003    import java.util.ArrayList;
004    import java.util.Date;
005    import java.util.List;
006    
007    import biweekly.component.ICalComponent;
008    import biweekly.parameter.FreeBusyType;
009    import biweekly.util.Duration;
010    import biweekly.util.Period;
011    
012    /*
013     Copyright (c) 2013, 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 person's availability over certain time periods (for example,
040     * "busy" between 1pm-3pm and 4pm-5pm). Note that this property can contain
041     * multiple time periods, but only one availability type may be defined (e.g.
042     * "busy" or "free").
043     * </p>
044     * <p>
045     * <b>Examples:</b>
046     * 
047     * <pre>
048     * FreeBusy freebusy = new FreeBusy();
049     * freebusy.setType(FreeBusyType.BUSY);
050     * 
051     * Date onePM = ...
052     * Date threePM = ...
053     * freebusy.addValue(onePM, threePM);
054     * 
055     * Date fourPM = ...
056     * Duration oneHour = new Duration.Builder().hours(1).build();
057     * freeBusy.addValue(fourPM, oneHour);
058     * 
059     * </pre>
060     * 
061     * </p>
062     * @author Michael Angstadt
063     * @see <a href="http://tools.ietf.org/html/rfc5545#page-100">RFC 5545
064     * p.100-1</a>
065     */
066    public class FreeBusy extends ICalProperty {
067            private final List<Period> values = new ArrayList<Period>();
068    
069            /**
070             * Adds a time period.
071             * @param start the start date
072             * @param end the end date
073             */
074            public void addValue(Date start, Date end) {
075                    values.add(new Period(start, end));
076            }
077    
078            /**
079             * Adds a time period.
080             * @param start the start date
081             * @param duration the duration
082             */
083            public void addValue(Date start, Duration duration) {
084                    values.add(new Period(start, duration));
085            }
086    
087            /**
088             * Gets all time periods.
089             * @return the time periods
090             */
091            public List<Period> getValues() {
092                    return values;
093            }
094    
095            /**
096             * Gets the person's status over the time periods that are specified in this
097             * property (for example, "free" or "busy"). If not set, the user should be
098             * considered "busy".
099             * @return the type or null if not set
100             * @see <a href="http://tools.ietf.org/html/rfc5545#page-20">RFC 5545
101             * p.20</a>
102             */
103            public FreeBusyType getType() {
104                    return parameters.getFreeBusyType();
105            }
106    
107            /**
108             * Sets the person's status over the time periods that are specified in this
109             * property (for example, "free" or "busy"). If not set, the user should be
110             * considered "busy".
111             * @param fbType the type or null to remove
112             * @see <a href="http://tools.ietf.org/html/rfc5545#page-20">RFC 5545
113             * p.20</a>
114             */
115            public void setType(FreeBusyType fbType) {
116                    parameters.setFreeBusyType(fbType);
117            }
118    
119            @Override
120            protected void validate(List<ICalComponent> components, List<String> warnings) {
121                    if (values.isEmpty()) {
122                            warnings.add("No time periods are defined.");
123                    } else {
124                            for (Period timePeriod : values) {
125                                    if (timePeriod.getStartDate() == null) {
126                                            warnings.add("One or more time periods do not have start dates.");
127                                            break;
128                                    }
129                            }
130    
131                            for (Period timePeriod : values) {
132                                    if (timePeriod.getEndDate() == null && timePeriod.getDuration() == null) {
133                                            warnings.add("One or more time periods do not have either an end date or a duration.");
134                                            break;
135                                    }
136                            }
137                    }
138            }
139    }