1.1 --- a/src/net/fortuna/ical4j/model/component/VTimeZone.java Thu Feb 12 18:02:00 2015 +0100 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,378 +0,0 @@ 1.4 -/** 1.5 - * Copyright (c) 2012, Ben Fortuna 1.6 - * All rights reserved. 1.7 - * 1.8 - * Redistribution and use in source and binary forms, with or without 1.9 - * modification, are permitted provided that the following conditions 1.10 - * are met: 1.11 - * 1.12 - * o Redistributions of source code must retain the above copyright 1.13 - * notice, this list of conditions and the following disclaimer. 1.14 - * 1.15 - * o Redistributions in binary form must reproduce the above copyright 1.16 - * notice, this list of conditions and the following disclaimer in the 1.17 - * documentation and/or other materials provided with the distribution. 1.18 - * 1.19 - * o Neither the name of Ben Fortuna nor the names of any other contributors 1.20 - * may be used to endorse or promote products derived from this software 1.21 - * without specific prior written permission. 1.22 - * 1.23 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.24 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.25 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.26 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 1.27 - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1.28 - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1.29 - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 1.30 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 1.31 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 1.32 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 1.33 - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.34 - */ 1.35 -package net.fortuna.ical4j.model.component; 1.36 - 1.37 -import java.io.IOException; 1.38 -import java.net.URISyntaxException; 1.39 -import java.text.ParseException; 1.40 -import java.util.Iterator; 1.41 - 1.42 -import net.fortuna.ical4j.model.Component; 1.43 -import net.fortuna.ical4j.model.ComponentList; 1.44 -import net.fortuna.ical4j.model.Date; 1.45 -import net.fortuna.ical4j.model.Property; 1.46 -import net.fortuna.ical4j.model.PropertyList; 1.47 -import net.fortuna.ical4j.model.ValidationException; 1.48 -import net.fortuna.ical4j.model.Validator; 1.49 -import net.fortuna.ical4j.model.property.LastModified; 1.50 -import net.fortuna.ical4j.model.property.Method; 1.51 -import net.fortuna.ical4j.model.property.TzId; 1.52 -import net.fortuna.ical4j.model.property.TzUrl; 1.53 -import net.fortuna.ical4j.util.PropertyValidator; 1.54 -import net.fortuna.ical4j.util.Strings; 1.55 - 1.56 -import org.apache.commons.lang3.ObjectUtils; 1.57 -import org.apache.commons.lang3.builder.HashCodeBuilder; 1.58 - 1.59 -/** 1.60 - * $Id$ [Apr 5, 2004] 1.61 - * 1.62 - * Defines an iCalendar VTIMEZONE component. 1.63 - * 1.64 - * <pre> 1.65 - * 4.6.5 Time Zone Component 1.66 - * 1.67 - * Component Name: VTIMEZONE 1.68 - * 1.69 - * Purpose: Provide a grouping of component properties that defines a 1.70 - * time zone. 1.71 - * 1.72 - * Formal Definition: A "VTIMEZONE" calendar component is defined by the 1.73 - * following notation: 1.74 - * 1.75 - * timezonec = "BEGIN" ":" "VTIMEZONE" CRLF 1.76 - * 1.77 - * 2*( 1.78 - * 1.79 - * ; 'tzid' is required, but MUST NOT occur more 1.80 - * ; than once 1.81 - * 1.82 - * tzid / 1.83 - * 1.84 - * ; 'last-mod' and 'tzurl' are optional, 1.85 - * but MUST NOT occur more than once 1.86 - * 1.87 - * last-mod / tzurl / 1.88 - * 1.89 - * ; one of 'standardc' or 'daylightc' MUST occur 1.90 - * ..; and each MAY occur more than once. 1.91 - * 1.92 - * standardc / daylightc / 1.93 - * 1.94 - * ; the following is optional, 1.95 - * ; and MAY occur more than once 1.96 - * 1.97 - * x-prop 1.98 - * 1.99 - * ) 1.100 - * 1.101 - * "END" ":" "VTIMEZONE" CRLF 1.102 - * 1.103 - * standardc = "BEGIN" ":" "STANDARD" CRLF 1.104 - * 1.105 - * tzprop 1.106 - * 1.107 - * "END" ":" "STANDARD" CRLF 1.108 - * 1.109 - * daylightc = "BEGIN" ":" "DAYLIGHT" CRLF 1.110 - * 1.111 - * tzprop 1.112 - * 1.113 - * "END" ":" "DAYLIGHT" CRLF 1.114 - * 1.115 - * tzprop = 3*( 1.116 - * 1.117 - * ; the following are each REQUIRED, 1.118 - * ; but MUST NOT occur more than once 1.119 - * 1.120 - * dtstart / tzoffsetto / tzoffsetfrom / 1.121 - * 1.122 - * ; the following are optional, 1.123 - * ; and MAY occur more than once 1.124 - * 1.125 - * comment / rdate / rrule / tzname / x-prop 1.126 - * 1.127 - * ) 1.128 - * </pre> 1.129 - * 1.130 - * @author Ben Fortuna 1.131 - */ 1.132 -public class VTimeZone extends CalendarComponent { 1.133 - 1.134 - private static final long serialVersionUID = 5629679741050917815L; 1.135 - 1.136 - private final Validator itipValidator = new ITIPValidator(); 1.137 - 1.138 - private ComponentList observances; 1.139 - 1.140 - /** 1.141 - * Default constructor. 1.142 - */ 1.143 - public VTimeZone() { 1.144 - super(VTIMEZONE); 1.145 - this.observances = new ComponentList(); 1.146 - } 1.147 - 1.148 - /** 1.149 - * Constructs a new instance containing the specified properties. 1.150 - * @param properties a list of properties 1.151 - */ 1.152 - public VTimeZone(final PropertyList properties) { 1.153 - super(VTIMEZONE, properties); 1.154 - this.observances = new ComponentList(); 1.155 - } 1.156 - 1.157 - /** 1.158 - * Constructs a new vtimezone component with no properties and the specified list of type components. 1.159 - * @param observances a list of type components 1.160 - */ 1.161 - public VTimeZone(final ComponentList observances) { 1.162 - super(VTIMEZONE); 1.163 - this.observances = observances; 1.164 - } 1.165 - 1.166 - /** 1.167 - * Constructor. 1.168 - * @param properties a list of properties 1.169 - * @param observances a list of timezone types 1.170 - */ 1.171 - public VTimeZone(final PropertyList properties, 1.172 - final ComponentList observances) { 1.173 - super(VTIMEZONE, properties); 1.174 - this.observances = observances; 1.175 - } 1.176 - 1.177 - /** 1.178 - * {@inheritDoc} 1.179 - */ 1.180 - public final String toString() { 1.181 - final StringBuffer b = new StringBuffer(); 1.182 - b.append(BEGIN); 1.183 - b.append(':'); 1.184 - b.append(getName()); 1.185 - b.append(Strings.LINE_SEPARATOR); 1.186 - b.append(getProperties()); 1.187 - b.append(observances); 1.188 - b.append(END); 1.189 - b.append(':'); 1.190 - b.append(getName()); 1.191 - b.append(Strings.LINE_SEPARATOR); 1.192 - return b.toString(); 1.193 - } 1.194 - 1.195 - /** 1.196 - * {@inheritDoc} 1.197 - */ 1.198 - public final void validate(final boolean recurse) 1.199 - throws ValidationException { 1.200 - 1.201 - /* 1.202 - * ; 'tzid' is required, but MUST NOT occur more ; than once tzid / 1.203 - */ 1.204 - PropertyValidator.getInstance().assertOne(Property.TZID, 1.205 - getProperties()); 1.206 - 1.207 - /* 1.208 - * ; 'last-mod' and 'tzurl' are optional, but MUST NOT occur more than once last-mod / tzurl / 1.209 - */ 1.210 - PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, 1.211 - getProperties()); 1.212 - PropertyValidator.getInstance().assertOneOrLess(Property.TZURL, 1.213 - getProperties()); 1.214 - 1.215 - /* 1.216 - * ; one of 'standardc' or 'daylightc' MUST occur ..; and each MAY occur more than once. standardc / daylightc / 1.217 - */ 1.218 - if (getObservances().getComponent(Observance.STANDARD) == null 1.219 - && getObservances().getComponent(Observance.DAYLIGHT) == null) { 1.220 - throw new ValidationException("Sub-components [" 1.221 - + Observance.STANDARD + "," + Observance.DAYLIGHT 1.222 - + "] must be specified at least once"); 1.223 - } 1.224 - 1.225 - for (final Iterator i = getObservances().iterator(); i.hasNext();) { 1.226 - ((Component) i.next()).validate(recurse); 1.227 - } 1.228 - 1.229 - /* 1.230 - * ; the following is optional, ; and MAY occur more than once x-prop 1.231 - */ 1.232 - 1.233 - if (recurse) { 1.234 - validateProperties(); 1.235 - } 1.236 - } 1.237 - 1.238 - /** 1.239 - * {@inheritDoc} 1.240 - */ 1.241 - protected Validator getValidator(Method method) { 1.242 - return itipValidator; 1.243 - } 1.244 - 1.245 - /** 1.246 - * Common validation for all iTIP methods. 1.247 - * 1.248 - * <pre> 1.249 - * Component/Property Presence 1.250 - * ------------------- ---------------------------------------------- 1.251 - * VTIMEZONE 0+ MUST be present if any date/time refers 1.252 - * to timezone 1.253 - * DAYLIGHT 0+ MUST be one or more of either STANDARD or 1.254 - * DAYLIGHT 1.255 - * COMMENT 0 or 1 1.256 - * DTSTART 1 MUST be local time format 1.257 - * RDATE 0+ if present RRULE MUST NOT be present 1.258 - * RRULE 0+ if present RDATE MUST NOT be present 1.259 - * TZNAME 0 or 1 1.260 - * TZOFFSET 1 1.261 - * TZOFFSETFROM 1 1.262 - * TZOFFSETTO 1 1.263 - * X-PROPERTY 0+ 1.264 - * LAST-MODIFIED 0 or 1 1.265 - * STANDARD 0+ MUST be one or more of either STANDARD or 1.266 - * DAYLIGHT 1.267 - * COMMENT 0 or 1 1.268 - * DTSTART 1 MUST be local time format 1.269 - * RDATE 0+ if present RRULE MUST NOT be present 1.270 - * RRULE 0+ if present RDATE MUST NOT be present 1.271 - * TZNAME 0 or 1 1.272 - * TZOFFSETFROM 1 1.273 - * TZOFFSETTO 1 1.274 - * X-PROPERTY 0+ 1.275 - * TZID 1 1.276 - * TZURL 0 or 1 1.277 - * X-PROPERTY 0+ 1.278 - * </pre> 1.279 - */ 1.280 - private class ITIPValidator implements Validator { 1.281 - 1.282 - private static final long serialVersionUID = 1L; 1.283 - 1.284 - /** 1.285 - * {@inheritDoc} 1.286 - */ 1.287 - public void validate() throws ValidationException { 1.288 - for (final Iterator i = getObservances().iterator(); i.hasNext();) { 1.289 - final Observance observance = (Observance) i.next(); 1.290 - PropertyValidator.getInstance().assertOne(Property.DTSTART, observance.getProperties()); 1.291 - PropertyValidator.getInstance().assertOne(Property.TZOFFSETFROM, observance.getProperties()); 1.292 - PropertyValidator.getInstance().assertOne(Property.TZOFFSETTO, observance.getProperties()); 1.293 - 1.294 - PropertyValidator.getInstance().assertOneOrLess(Property.TZNAME, observance.getProperties()); 1.295 - } 1.296 - } 1.297 - } 1.298 - 1.299 - /** 1.300 - * @return Returns the types. 1.301 - */ 1.302 - public final ComponentList getObservances() { 1.303 - return observances; 1.304 - } 1.305 - 1.306 - /** 1.307 - * Returns the latest applicable timezone observance for the specified date. 1.308 - * @param date the latest possible date for a timezone observance onset 1.309 - * @return the latest applicable timezone observance for the specified date or null if there are no applicable 1.310 - * observances 1.311 - */ 1.312 - public final Observance getApplicableObservance(final Date date) { 1.313 - Observance latestObservance = null; 1.314 - Date latestOnset = null; 1.315 - for (final Iterator i = getObservances().iterator(); i.hasNext();) { 1.316 - final Observance observance = (Observance) i.next(); 1.317 - final Date onset = observance.getLatestOnset(date); 1.318 - if (latestOnset == null 1.319 - || (onset != null && onset.after(latestOnset))) { 1.320 - latestOnset = onset; 1.321 - latestObservance = observance; 1.322 - } 1.323 - } 1.324 - return latestObservance; 1.325 - } 1.326 - 1.327 - /** 1.328 - * @return the mandatory timezone identifier property 1.329 - */ 1.330 - public final TzId getTimeZoneId() { 1.331 - return (TzId) getProperty(Property.TZID); 1.332 - } 1.333 - 1.334 - /** 1.335 - * @return the optional last-modified property 1.336 - */ 1.337 - public final LastModified getLastModified() { 1.338 - return (LastModified) getProperty(Property.LAST_MODIFIED); 1.339 - } 1.340 - 1.341 - /** 1.342 - * @return the optional timezone url property 1.343 - */ 1.344 - public final TzUrl getTimeZoneUrl() { 1.345 - return (TzUrl) getProperty(Property.TZURL); 1.346 - } 1.347 - 1.348 - /** 1.349 - * {@inheritDoc} 1.350 - */ 1.351 - public boolean equals(final Object arg0) { 1.352 - if (arg0 instanceof VTimeZone) { 1.353 - return super.equals(arg0) 1.354 - && ObjectUtils.equals(observances, ((VTimeZone) arg0) 1.355 - .getObservances()); 1.356 - } 1.357 - return super.equals(arg0); 1.358 - } 1.359 - 1.360 - /** 1.361 - * {@inheritDoc} 1.362 - */ 1.363 - public int hashCode() { 1.364 - return new HashCodeBuilder().append(getName()).append(getProperties()) 1.365 - .append(getObservances()).toHashCode(); 1.366 - } 1.367 - 1.368 - /** 1.369 - * Overrides default copy method to add support for copying observance sub-components. 1.370 - * @return a copy of the instance 1.371 - * @throws ParseException where an error occurs parsing data 1.372 - * @throws IOException where an error occurs reading data 1.373 - * @throws URISyntaxException where an invalid URI is encountered 1.374 - * @see net.fortuna.ical4j.model.Component#copy() 1.375 - */ 1.376 - public Component copy() throws ParseException, IOException, URISyntaxException { 1.377 - final VTimeZone copy = (VTimeZone) super.copy(); 1.378 - copy.observances = new ComponentList(observances); 1.379 - return copy; 1.380 - } 1.381 -}