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