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 class="brush:java">
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 = Duration.builder().hours(1).build();
057     * freeBusy.addValue(fourPM, oneHour);
058     * </pre>
059     * 
060     * </p>
061     * @author Michael Angstadt
062     * @rfc 5545 p.100-1
063     */
064    public class FreeBusy extends ICalProperty {
065            private final List<Period> values = new ArrayList<Period>();
066    
067            /**
068             * Adds a time period.
069             * @param start the start date
070             * @param end the end date
071             */
072            public void addValue(Date start, Date end) {
073                    values.add(new Period(start, end));
074            }
075    
076            /**
077             * Adds a time period.
078             * @param start the start date
079             * @param duration the duration
080             */
081            public void addValue(Date start, Duration duration) {
082                    values.add(new Period(start, duration));
083            }
084    
085            /**
086             * Gets all time periods.
087             * @return the time periods
088             */
089            public List<Period> getValues() {
090                    return values;
091            }
092    
093            /**
094             * Gets the person's status over the time periods that are specified in this
095             * property (for example, "free" or "busy"). If not set, the user should be
096             * considered "busy".
097             * @return the type or null if not set
098             * @rfc 5545 p.20
099             */
100            public FreeBusyType getType() {
101                    return parameters.getFreeBusyType();
102            }
103    
104            /**
105             * Sets the person's status over the time periods that are specified in this
106             * property (for example, "free" or "busy"). If not set, the user should be
107             * considered "busy".
108             * @param fbType the type or null to remove
109             * @rfc 5545 p.20
110             */
111            public void setType(FreeBusyType fbType) {
112                    parameters.setFreeBusyType(fbType);
113            }
114    
115            @Override
116            protected void validate(List<ICalComponent> components, List<String> warnings) {
117                    if (values.isEmpty()) {
118                            warnings.add("No time periods are defined.");
119                    } else {
120                            for (Period timePeriod : values) {
121                                    if (timePeriod.getStartDate() == null) {
122                                            warnings.add("One or more time periods do not have start dates.");
123                                            break;
124                                    }
125                            }
126    
127                            for (Period timePeriod : values) {
128                                    if (timePeriod.getEndDate() == null && timePeriod.getDuration() == null) {
129                                            warnings.add("One or more time periods do not have either an end date or a duration.");
130                                            break;
131                                    }
132                            }
133                    }
134            }
135    }