|
1 /** |
|
2 * Copyright (c) 2012, Ben Fortuna |
|
3 * All rights reserved. |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions |
|
7 * are met: |
|
8 * |
|
9 * o Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * o Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in the |
|
14 * documentation and/or other materials provided with the distribution. |
|
15 * |
|
16 * o Neither the name of Ben Fortuna nor the names of any other contributors |
|
17 * may be used to endorse or promote products derived from this software |
|
18 * without specific prior written permission. |
|
19 * |
|
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
31 */ |
|
32 package net.fortuna.ical4j.model.component; |
|
33 |
|
34 import java.util.Iterator; |
|
35 |
|
36 import net.fortuna.ical4j.model.Component; |
|
37 import net.fortuna.ical4j.model.ComponentList; |
|
38 import net.fortuna.ical4j.model.Parameter; |
|
39 import net.fortuna.ical4j.model.Property; |
|
40 import net.fortuna.ical4j.model.PropertyList; |
|
41 import net.fortuna.ical4j.model.ValidationException; |
|
42 import net.fortuna.ical4j.model.Validator; |
|
43 import net.fortuna.ical4j.model.parameter.Value; |
|
44 import net.fortuna.ical4j.model.property.DtEnd; |
|
45 import net.fortuna.ical4j.model.property.DtStamp; |
|
46 import net.fortuna.ical4j.model.property.DtStart; |
|
47 import net.fortuna.ical4j.model.property.Method; |
|
48 import net.fortuna.ical4j.util.PropertyValidator; |
|
49 import net.fortuna.ical4j.util.Strings; |
|
50 |
|
51 /** |
|
52 * $Id$ [Apr 5, 2004] |
|
53 * |
|
54 * Defines an iCalendar VAVAILABILITY component. |
|
55 * |
|
56 * <pre> |
|
57 Component Name: VAVAILABILITY |
|
58 |
|
59 Purpose: Provide a grouping of component properties that describe |
|
60 the availability associated with a calendar user. |
|
61 |
|
62 Format Definition: A "VAVAILABILITY" calendar component is defined |
|
63 by the following notation: |
|
64 |
|
65 availabilityc = "BEGIN" ":" "VAVAILABILITY" CRLF |
|
66 availabilityprop *availablec |
|
67 "END" ":" "VAVAILABILITY" CRLF |
|
68 |
|
69 availabilityprop = *( |
|
70 |
|
71 ; the following are REQUIRED, |
|
72 ; but MUST NOT occur more than once |
|
73 |
|
74 dtstamp / dtstart / uid |
|
75 |
|
76 ; the following are OPTIONAL, |
|
77 ; but MUST NOT occur more than once |
|
78 |
|
79 busytype / created / last-mod / |
|
80 organizer / seq / summary / url / |
|
81 |
|
82 ; either 'dtend' or 'duration' may appear |
|
83 ; in a 'availabilityprop', but 'dtend' and |
|
84 ; 'duration' MUST NOT occur in the same |
|
85 ; 'availabilityprop' |
|
86 |
|
87 dtend / duration / |
|
88 |
|
89 ; the following are OPTIONAL, |
|
90 ; and MAY occur more than once |
|
91 |
|
92 categories / comment / contact / x-prop |
|
93 |
|
94 ) |
|
95 |
|
96 * |
|
97 * </pre> |
|
98 * |
|
99 * @author Ben Fortuna |
|
100 * @author Mike Douglass |
|
101 */ |
|
102 public class VAvailability extends CalendarComponent { |
|
103 |
|
104 private static final long serialVersionUID = -3001603309266267258L; |
|
105 |
|
106 private ComponentList available; |
|
107 |
|
108 /** |
|
109 * Default constructor. |
|
110 */ |
|
111 public VAvailability() { |
|
112 super(VAVAILABILITY); |
|
113 this.available = new ComponentList(); |
|
114 getProperties().add(new DtStamp()); |
|
115 } |
|
116 |
|
117 /** |
|
118 * Constructs a new instance containing the specified properties. |
|
119 * @param properties a list of properties |
|
120 */ |
|
121 public VAvailability(final PropertyList properties) { |
|
122 super(VAVAILABILITY, properties); |
|
123 this.available = new ComponentList(); |
|
124 } |
|
125 |
|
126 /** |
|
127 * Constructor. |
|
128 * @param properties a list of properties |
|
129 * @param available a list of available components |
|
130 */ |
|
131 public VAvailability(final PropertyList properties, final ComponentList available) { |
|
132 super(VEVENT, properties); |
|
133 this.available = available; |
|
134 } |
|
135 |
|
136 /** |
|
137 * Returns the list of available times. |
|
138 * @return a component list |
|
139 */ |
|
140 public final ComponentList getAvailable() { |
|
141 return available; |
|
142 } |
|
143 |
|
144 /** |
|
145 * {@inheritDoc} |
|
146 */ |
|
147 public final String toString() { |
|
148 final StringBuffer b = new StringBuffer(); |
|
149 b.append(BEGIN); |
|
150 b.append(':'); |
|
151 b.append(getName()); |
|
152 b.append(Strings.LINE_SEPARATOR); |
|
153 b.append(getProperties()); |
|
154 b.append(getAvailable()); |
|
155 b.append(END); |
|
156 b.append(':'); |
|
157 b.append(getName()); |
|
158 b.append(Strings.LINE_SEPARATOR); |
|
159 return b.toString(); |
|
160 } |
|
161 |
|
162 /** |
|
163 * {@inheritDoc} |
|
164 */ |
|
165 public final void validate(final boolean recurse) |
|
166 throws ValidationException { |
|
167 |
|
168 // validate that getAvailable() only contains Available components |
|
169 final Iterator iterator = getAvailable().iterator(); |
|
170 while (iterator.hasNext()) { |
|
171 final Component component = (Component) iterator.next(); |
|
172 |
|
173 if (!(component instanceof Available)) { |
|
174 throw new ValidationException("Component [" |
|
175 + component.getName() + "] may not occur in VAVAILABILITY"); |
|
176 } |
|
177 } |
|
178 |
|
179 /* |
|
180 * ; dtstamp / dtstart / uid are required, but MUST NOT occur more than once / |
|
181 */ |
|
182 PropertyValidator.getInstance().assertOne(Property.DTSTART, |
|
183 getProperties()); |
|
184 PropertyValidator.getInstance().assertOne(Property.DTSTAMP, |
|
185 getProperties()); |
|
186 PropertyValidator.getInstance().assertOne(Property.UID, |
|
187 getProperties()); |
|
188 |
|
189 /* If specified, the "DTSTART" and "DTEND" properties in |
|
190 * "VAVAILABILITY" components and "AVAILABLE" sub-components MUST be |
|
191 * "DATE-TIME" values specified as either date with UTC time or date |
|
192 * with local time and a time zone reference. |
|
193 */ |
|
194 final DtStart start = (DtStart) getProperty(Property.DTSTART); |
|
195 if (Value.DATE.equals(start.getParameter(Parameter.VALUE))) { |
|
196 throw new ValidationException("Property [" + Property.DTSTART |
|
197 + "] must be a " + Value.DATE_TIME); |
|
198 } |
|
199 |
|
200 /* |
|
201 * ; either 'dtend' or 'duration' may appear in ; a 'eventprop', but 'dtend' and 'duration' ; MUST NOT occur in |
|
202 * the same 'eventprop' dtend / duration / |
|
203 */ |
|
204 if (getProperty(Property.DTEND) != null) { |
|
205 PropertyValidator.getInstance().assertOne(Property.DTEND, |
|
206 getProperties()); |
|
207 /* Must be DATE_TIME */ |
|
208 final DtEnd end = (DtEnd) getProperty(Property.DTEND); |
|
209 if (Value.DATE.equals(end.getParameter(Parameter.VALUE))) { |
|
210 throw new ValidationException("Property [" + Property.DTEND |
|
211 + "] must be a " + Value.DATE_TIME); |
|
212 } |
|
213 |
|
214 if (getProperty(Property.DURATION) != null) { |
|
215 throw new ValidationException("Only one of Property [" + Property.DTEND |
|
216 + "] or [" + Property.DURATION + |
|
217 " must appear a VAVAILABILITY"); |
|
218 } |
|
219 } |
|
220 |
|
221 /* |
|
222 * ; the following are optional, |
|
223 * ; but MUST NOT occur more than once |
|
224 * |
|
225 * busytype / created / last-mod / |
|
226 * organizer / seq / summary / url / |
|
227 */ |
|
228 PropertyValidator.getInstance().assertOneOrLess(Property.BUSYTYPE, |
|
229 getProperties()); |
|
230 PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, |
|
231 getProperties()); |
|
232 PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, |
|
233 getProperties()); |
|
234 PropertyValidator.getInstance().assertOneOrLess(Property.ORGANIZER, |
|
235 getProperties()); |
|
236 PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, |
|
237 getProperties()); |
|
238 PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY, |
|
239 getProperties()); |
|
240 PropertyValidator.getInstance().assertOneOrLess(Property.URL, |
|
241 getProperties()); |
|
242 |
|
243 /* |
|
244 * ; the following are optional, ; and MAY occur more than once |
|
245 * categories / comment / contact / x-prop |
|
246 */ |
|
247 |
|
248 if (recurse) { |
|
249 validateProperties(); |
|
250 } |
|
251 } |
|
252 |
|
253 /** |
|
254 * {@inheritDoc} |
|
255 */ |
|
256 protected Validator getValidator(Method method) { |
|
257 // TODO Auto-generated method stub |
|
258 return null; |
|
259 } |
|
260 } |