001    package biweekly.component.marshaller;
002    
003    import java.util.ArrayList;
004    import java.util.Collection;
005    import java.util.Collections;
006    import java.util.Comparator;
007    import java.util.Date;
008    import java.util.List;
009    
010    import biweekly.component.VFreeBusy;
011    import biweekly.property.FreeBusy;
012    import biweekly.property.ICalProperty;
013    import biweekly.util.Period;
014    
015    /*
016     Copyright (c) 2013, Michael Angstadt
017     All rights reserved.
018    
019     Redistribution and use in source and binary forms, with or without
020     modification, are permitted provided that the following conditions are met: 
021    
022     1. Redistributions of source code must retain the above copyright notice, this
023     list of conditions and the following disclaimer. 
024     2. Redistributions in binary form must reproduce the above copyright notice,
025     this list of conditions and the following disclaimer in the documentation
026     and/or other materials provided with the distribution. 
027    
028     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
029     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
030     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
032     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
034     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
035     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
036     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
037     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
038     */
039    
040    /**
041     * @author Michael Angstadt
042     */
043    public class VFreeBusyMarshaller extends ICalComponentMarshaller<VFreeBusy> {
044            public VFreeBusyMarshaller() {
045                    super(VFreeBusy.class, "VFREEBUSY");
046            }
047    
048            @Override
049            public Collection<ICalProperty> getProperties(VFreeBusy component) {
050                    //sort FREEBUSY properties by start date
051                    //TODO this will require that a List be returned
052                    List<FreeBusy> fb = new ArrayList<FreeBusy>(component.getFreeBusy());
053                    Collections.sort(fb, new Comparator<FreeBusy>() {
054                            public int compare(FreeBusy one, FreeBusy two) {
055                                    Date oneStart = getEarliestStartDate(one);
056                                    Date twoStart = getEarliestStartDate(two);
057                                    if (oneStart == null && twoStart == null) {
058                                            return 0;
059                                    }
060                                    if (oneStart == null) {
061                                            return 1;
062                                    }
063                                    if (twoStart == null) {
064                                            return -1;
065                                    }
066                                    return oneStart.compareTo(twoStart);
067                            }
068    
069                            private Date getEarliestStartDate(FreeBusy fb) {
070                                    Date date = null;
071                                    for (Period tp : fb.getValues()) {
072                                            if (tp.getStartDate() == null) {
073                                                    continue;
074                                            }
075                                            if (date == null || date.compareTo(tp.getStartDate()) > 0) {
076                                                    date = tp.getStartDate();
077                                            }
078                                    }
079                                    return date;
080                            }
081                    });
082    
083                    //make sure the FREEBUSY properties appear in sorted order
084                    Collection<ICalProperty> all = super.getProperties(component);
085                    for (FreeBusy f : fb) {
086                            if (all.remove(f)) {
087                                    all.add(f);
088                            }
089                    }
090    
091                    return all;
092            }
093    
094            @Override
095            protected VFreeBusy _newInstance() {
096                    return new VFreeBusy();
097            }
098    }