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