src/net/fortuna/ical4j/model/component/VEvent.java

branch
ICAL4J_EMBED_1
changeset 15
cc93757aeca3
parent 14
5ae3e5665a0b
child 18
6dcaece8ec41
     1.1 --- a/src/net/fortuna/ical4j/model/component/VEvent.java	Thu Feb 12 18:02:00 2015 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1522 +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.HashMap;
    1.41 -import java.util.Iterator;
    1.42 -import java.util.Map;
    1.43 -
    1.44 -import net.fortuna.ical4j.model.Component;
    1.45 -import net.fortuna.ical4j.model.ComponentList;
    1.46 -import net.fortuna.ical4j.model.Date;
    1.47 -import net.fortuna.ical4j.model.DateTime;
    1.48 -import net.fortuna.ical4j.model.Dur;
    1.49 -import net.fortuna.ical4j.model.Parameter;
    1.50 -import net.fortuna.ical4j.model.Period;
    1.51 -import net.fortuna.ical4j.model.PeriodList;
    1.52 -import net.fortuna.ical4j.model.Property;
    1.53 -import net.fortuna.ical4j.model.PropertyList;
    1.54 -import net.fortuna.ical4j.model.ValidationException;
    1.55 -import net.fortuna.ical4j.model.Validator;
    1.56 -import net.fortuna.ical4j.model.parameter.Value;
    1.57 -import net.fortuna.ical4j.model.property.Clazz;
    1.58 -import net.fortuna.ical4j.model.property.Created;
    1.59 -import net.fortuna.ical4j.model.property.Description;
    1.60 -import net.fortuna.ical4j.model.property.DtEnd;
    1.61 -import net.fortuna.ical4j.model.property.DtStamp;
    1.62 -import net.fortuna.ical4j.model.property.DtStart;
    1.63 -import net.fortuna.ical4j.model.property.Duration;
    1.64 -import net.fortuna.ical4j.model.property.Geo;
    1.65 -import net.fortuna.ical4j.model.property.LastModified;
    1.66 -import net.fortuna.ical4j.model.property.Location;
    1.67 -import net.fortuna.ical4j.model.property.Method;
    1.68 -import net.fortuna.ical4j.model.property.Organizer;
    1.69 -import net.fortuna.ical4j.model.property.Priority;
    1.70 -import net.fortuna.ical4j.model.property.RecurrenceId;
    1.71 -import net.fortuna.ical4j.model.property.Sequence;
    1.72 -import net.fortuna.ical4j.model.property.Status;
    1.73 -import net.fortuna.ical4j.model.property.Summary;
    1.74 -import net.fortuna.ical4j.model.property.Transp;
    1.75 -import net.fortuna.ical4j.model.property.Uid;
    1.76 -import net.fortuna.ical4j.model.property.Url;
    1.77 -import net.fortuna.ical4j.util.CompatibilityHints;
    1.78 -import net.fortuna.ical4j.util.ComponentValidator;
    1.79 -import net.fortuna.ical4j.util.Dates;
    1.80 -import net.fortuna.ical4j.util.PropertyValidator;
    1.81 -import net.fortuna.ical4j.util.Strings;
    1.82 -
    1.83 -import org.apache.commons.lang3.ObjectUtils;
    1.84 -import org.apache.commons.lang3.builder.HashCodeBuilder;
    1.85 -
    1.86 -/**
    1.87 - * $Id$ [Apr 5, 2004]
    1.88 - *
    1.89 - * Defines an iCalendar VEVENT component.
    1.90 - * 
    1.91 - * <pre>
    1.92 - *       4.6.1 Event Component
    1.93 - *   
    1.94 - *          Component Name: &quot;VEVENT&quot;
    1.95 - *   
    1.96 - *          Purpose: Provide a grouping of component properties that describe an
    1.97 - *          event.
    1.98 - *   
    1.99 - *          Format Definition: A &quot;VEVENT&quot; calendar component is defined by the
   1.100 - *          following notation:
   1.101 - *   
   1.102 - *            eventc     = &quot;BEGIN&quot; &quot;:&quot; &quot;VEVENT&quot; CRLF
   1.103 - *                         eventprop *alarmc
   1.104 - *                         &quot;END&quot; &quot;:&quot; &quot;VEVENT&quot; CRLF
   1.105 - *   
   1.106 - *            eventprop  = *(
   1.107 - *   
   1.108 - *                       ; the following are optional,
   1.109 - *                       ; but MUST NOT occur more than once
   1.110 - *   
   1.111 - *                       class / created / description / dtstart / geo /
   1.112 - *                       last-mod / location / organizer / priority /
   1.113 - *                       dtstamp / seq / status / summary / transp /
   1.114 - *                       uid / url / recurid /
   1.115 - *   
   1.116 - *                       ; either 'dtend' or 'duration' may appear in
   1.117 - *                       ; a 'eventprop', but 'dtend' and 'duration'
   1.118 - *                       ; MUST NOT occur in the same 'eventprop'
   1.119 - *   
   1.120 - *                       dtend / duration /
   1.121 - *   
   1.122 - *                       ; the following are optional,
   1.123 - *                       ; and MAY occur more than once
   1.124 - *   
   1.125 - *                       attach / attendee / categories / comment /
   1.126 - *                       contact / exdate / exrule / rstatus / related /
   1.127 - *                       resources / rdate / rrule / x-prop
   1.128 - *   
   1.129 - *                       )
   1.130 - * </pre>
   1.131 - * 
   1.132 - * Example 1 - Creating a new all-day event:
   1.133 - * 
   1.134 - * <pre><code>
   1.135 - * java.util.Calendar cal = java.util.Calendar.getInstance();
   1.136 - * cal.set(java.util.Calendar.MONTH, java.util.Calendar.DECEMBER);
   1.137 - * cal.set(java.util.Calendar.DAY_OF_MONTH, 25);
   1.138 - * 
   1.139 - * VEvent christmas = new VEvent(cal.getTime(), &quot;Christmas Day&quot;);
   1.140 - * 
   1.141 - * // initialise as an all-day event..
   1.142 - * christmas.getProperties().getProperty(Property.DTSTART).getParameters().add(
   1.143 - *         Value.DATE);
   1.144 - * 
   1.145 - * // add timezone information..
   1.146 - * VTimeZone tz = VTimeZone.getDefault();
   1.147 - * TzId tzParam = new TzId(tz.getProperties().getProperty(Property.TZID)
   1.148 - *         .getValue());
   1.149 - * christmas.getProperties().getProperty(Property.DTSTART).getParameters().add(
   1.150 - *         tzParam);
   1.151 - * </code></pre>
   1.152 - * 
   1.153 - * Example 2 - Creating an event of one (1) hour duration:
   1.154 - * 
   1.155 - * <pre><code>
   1.156 - * java.util.Calendar cal = java.util.Calendar.getInstance();
   1.157 - * // tomorrow..
   1.158 - * cal.add(java.util.Calendar.DAY_OF_MONTH, 1);
   1.159 - * cal.set(java.util.Calendar.HOUR_OF_DAY, 9);
   1.160 - * cal.set(java.util.Calendar.MINUTE, 30);
   1.161 - * 
   1.162 - * VEvent meeting = new VEvent(cal.getTime(), 1000 * 60 * 60, &quot;Progress Meeting&quot;);
   1.163 - * 
   1.164 - * // add timezone information..
   1.165 - * VTimeZone tz = VTimeZone.getDefault();
   1.166 - * TzId tzParam = new TzId(tz.getProperties().getProperty(Property.TZID)
   1.167 - *         .getValue());
   1.168 - * meeting.getProperties().getProperty(Property.DTSTART).getParameters().add(
   1.169 - *         tzParam);
   1.170 - * </code></pre>
   1.171 - * 
   1.172 - * Example 3 - Retrieve a list of periods representing a recurring event in a specified range:
   1.173 - * 
   1.174 - * <pre><code>
   1.175 - * Calendar weekday9AM = Calendar.getInstance();
   1.176 - * weekday9AM.set(2005, Calendar.MARCH, 7, 9, 0, 0);
   1.177 - * weekday9AM.set(Calendar.MILLISECOND, 0);
   1.178 - * 
   1.179 - * Calendar weekday5PM = Calendar.getInstance();
   1.180 - * weekday5PM.set(2005, Calendar.MARCH, 7, 17, 0, 0);
   1.181 - * weekday5PM.set(Calendar.MILLISECOND, 0);
   1.182 - * 
   1.183 - * // Do the recurrence until December 31st.
   1.184 - * Calendar untilCal = Calendar.getInstance();
   1.185 - * untilCal.set(2005, Calendar.DECEMBER, 31);
   1.186 - * untilCal.set(Calendar.MILLISECOND, 0);
   1.187 - * 
   1.188 - * // 9:00AM to 5:00PM Rule
   1.189 - * Recur recur = new Recur(Recur.WEEKLY, untilCal.getTime());
   1.190 - * recur.getDayList().add(WeekDay.MO);
   1.191 - * recur.getDayList().add(WeekDay.TU);
   1.192 - * recur.getDayList().add(WeekDay.WE);
   1.193 - * recur.getDayList().add(WeekDay.TH);
   1.194 - * recur.getDayList().add(WeekDay.FR);
   1.195 - * recur.setInterval(3);
   1.196 - * recur.setWeekStartDay(WeekDay.MO.getDay());
   1.197 - * RRule rrule = new RRule(recur);
   1.198 - * 
   1.199 - * Summary summary = new Summary(&quot;TEST EVENTS THAT HAPPEN 9-5 MON-FRI&quot;);
   1.200 - * 
   1.201 - * weekdayNineToFiveEvents = new VEvent();
   1.202 - * weekdayNineToFiveEvents.getProperties().add(rrule);
   1.203 - * weekdayNineToFiveEvents.getProperties().add(summary);
   1.204 - * weekdayNineToFiveEvents.getProperties().add(new DtStart(weekday9AM.getTime()));
   1.205 - * weekdayNineToFiveEvents.getProperties().add(new DtEnd(weekday5PM.getTime()));
   1.206 - * 
   1.207 - * // Test Start 04/01/2005, End One month later.
   1.208 - * // Query Calendar Start and End Dates.
   1.209 - * Calendar queryStartDate = Calendar.getInstance();
   1.210 - * queryStartDate.set(2005, Calendar.APRIL, 1, 14, 47, 0);
   1.211 - * queryStartDate.set(Calendar.MILLISECOND, 0);
   1.212 - * Calendar queryEndDate = Calendar.getInstance();
   1.213 - * queryEndDate.set(2005, Calendar.MAY, 1, 11, 15, 0);
   1.214 - * queryEndDate.set(Calendar.MILLISECOND, 0);
   1.215 - * 
   1.216 - * // This range is monday to friday every three weeks, starting from
   1.217 - * // March 7th 2005, which means for our query dates we need
   1.218 - * // April 18th through to the 22nd.
   1.219 - * PeriodList periods = weekdayNineToFiveEvents.getPeriods(queryStartDate
   1.220 - *         .getTime(), queryEndDate.getTime());
   1.221 - * </code></pre>
   1.222 - * 
   1.223 - * @author Ben Fortuna
   1.224 - */
   1.225 -public class VEvent extends CalendarComponent {
   1.226 -
   1.227 -    private static final long serialVersionUID = 2547948989200697335L;
   1.228 -
   1.229 -    private final Map methodValidators = new HashMap();
   1.230 -    {
   1.231 -        methodValidators.put(Method.ADD, new AddValidator());
   1.232 -        methodValidators.put(Method.CANCEL, new CancelValidator());
   1.233 -        methodValidators.put(Method.COUNTER, new CounterValidator());
   1.234 -        methodValidators.put(Method.DECLINE_COUNTER, new DeclineCounterValidator());
   1.235 -        methodValidators.put(Method.PUBLISH, new PublishValidator());
   1.236 -        methodValidators.put(Method.REFRESH, new RefreshValidator());
   1.237 -        methodValidators.put(Method.REPLY, new ReplyValidator());
   1.238 -        methodValidators.put(Method.REQUEST, new RequestValidator());
   1.239 -    }
   1.240 -    
   1.241 -    private ComponentList alarms;
   1.242 -
   1.243 -    /**
   1.244 -     * Default constructor.
   1.245 -     */
   1.246 -    public VEvent() {
   1.247 -        super(VEVENT);
   1.248 -        this.alarms = new ComponentList();
   1.249 -        getProperties().add(new DtStamp());
   1.250 -    }
   1.251 -
   1.252 -    /**
   1.253 -     * Constructor.
   1.254 -     * @param properties a list of properties
   1.255 -     */
   1.256 -    public VEvent(final PropertyList properties) {
   1.257 -        super(VEVENT, properties);
   1.258 -        this.alarms = new ComponentList();
   1.259 -    }
   1.260 -
   1.261 -    /**
   1.262 -     * Constructor.
   1.263 -     * @param properties a list of properties
   1.264 -     * @param alarms a list of alarms
   1.265 -     */
   1.266 -    public VEvent(final PropertyList properties, final ComponentList alarms) {
   1.267 -        super(VEVENT, properties);
   1.268 -        this.alarms = alarms;
   1.269 -    }
   1.270 -
   1.271 -    /**
   1.272 -     * Constructs a new VEVENT instance starting at the specified time with the specified summary.
   1.273 -     * @param start the start date of the new event
   1.274 -     * @param summary the event summary
   1.275 -     */
   1.276 -    public VEvent(final Date start, final String summary) {
   1.277 -        this();
   1.278 -        getProperties().add(new DtStart(start));
   1.279 -        getProperties().add(new Summary(summary));
   1.280 -    }
   1.281 -
   1.282 -    /**
   1.283 -     * Constructs a new VEVENT instance starting and ending at the specified times with the specified summary.
   1.284 -     * @param start the start date of the new event
   1.285 -     * @param end the end date of the new event
   1.286 -     * @param summary the event summary
   1.287 -     */
   1.288 -    public VEvent(final Date start, final Date end, final String summary) {
   1.289 -        this();
   1.290 -        getProperties().add(new DtStart(start));
   1.291 -        getProperties().add(new DtEnd(end));
   1.292 -        getProperties().add(new Summary(summary));
   1.293 -    }
   1.294 -
   1.295 -    /**
   1.296 -     * Constructs a new VEVENT instance starting at the specified times, for the specified duration, with the specified
   1.297 -     * summary.
   1.298 -     * @param start the start date of the new event
   1.299 -     * @param duration the duration of the new event
   1.300 -     * @param summary the event summary
   1.301 -     */
   1.302 -    public VEvent(final Date start, final Dur duration, final String summary) {
   1.303 -        this();
   1.304 -        getProperties().add(new DtStart(start));
   1.305 -        getProperties().add(new Duration(duration));
   1.306 -        getProperties().add(new Summary(summary));
   1.307 -    }
   1.308 -
   1.309 -    /**
   1.310 -     * Returns the list of alarms for this event.
   1.311 -     * @return a component list
   1.312 -     */
   1.313 -    public final ComponentList getAlarms() {
   1.314 -        return alarms;
   1.315 -    }
   1.316 -
   1.317 -    /**
   1.318 -     * {@inheritDoc}
   1.319 -     */
   1.320 -    public final String toString() {
   1.321 -        final StringBuffer b = new StringBuffer();
   1.322 -        b.append(BEGIN);
   1.323 -        b.append(':');
   1.324 -        b.append(getName());
   1.325 -        b.append(Strings.LINE_SEPARATOR);
   1.326 -        b.append(getProperties());
   1.327 -        b.append(getAlarms());
   1.328 -        b.append(END);
   1.329 -        b.append(':');
   1.330 -        b.append(getName());
   1.331 -        b.append(Strings.LINE_SEPARATOR);
   1.332 -        return b.toString();
   1.333 -    }
   1.334 -
   1.335 -    /**
   1.336 -     * {@inheritDoc}
   1.337 -     */
   1.338 -    public final void validate(final boolean recurse) throws ValidationException {
   1.339 -
   1.340 -        // validate that getAlarms() only contains VAlarm components
   1.341 -        final Iterator iterator = getAlarms().iterator();
   1.342 -        while (iterator.hasNext()) {
   1.343 -            final Component component = (Component) iterator.next();
   1.344 -
   1.345 -            if (!(component instanceof VAlarm)) {
   1.346 -                throw new ValidationException("Component ["
   1.347 -                        + component.getName() + "] may not occur in VEVENT");
   1.348 -            }
   1.349 -            
   1.350 -            ((VAlarm) component).validate(recurse);
   1.351 -        }
   1.352 -
   1.353 -        if (!CompatibilityHints
   1.354 -                .isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) {
   1.355 -
   1.356 -            // From "4.8.4.7 Unique Identifier":
   1.357 -            // Conformance: The property MUST be specified in the "VEVENT", "VTODO",
   1.358 -            // "VJOURNAL" or "VFREEBUSY" calendar components.
   1.359 -            PropertyValidator.getInstance().assertOne(Property.UID,
   1.360 -                    getProperties());
   1.361 -
   1.362 -            // From "4.8.7.2 Date/Time Stamp":
   1.363 -            // Conformance: This property MUST be included in the "VEVENT", "VTODO",
   1.364 -            // "VJOURNAL" or "VFREEBUSY" calendar components.
   1.365 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP,
   1.366 -                    getProperties());
   1.367 -        }
   1.368 -
   1.369 -        /*
   1.370 -         * ; the following are optional, ; but MUST NOT occur more than once class / created / description / dtstart /
   1.371 -         * geo / last-mod / location / organizer / priority / dtstamp / seq / status / summary / transp / uid / url /
   1.372 -         * recurid /
   1.373 -         */
   1.374 -        PropertyValidator.getInstance().assertOneOrLess(Property.CLASS,
   1.375 -                getProperties());
   1.376 -        PropertyValidator.getInstance().assertOneOrLess(Property.CREATED,
   1.377 -                getProperties());
   1.378 -        PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION,
   1.379 -                getProperties());
   1.380 -        PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART,
   1.381 -                getProperties());
   1.382 -        PropertyValidator.getInstance().assertOneOrLess(Property.GEO,
   1.383 -                getProperties());
   1.384 -        PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED,
   1.385 -                getProperties());
   1.386 -        PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION,
   1.387 -                getProperties());
   1.388 -        PropertyValidator.getInstance().assertOneOrLess(Property.ORGANIZER,
   1.389 -                getProperties());
   1.390 -        PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY,
   1.391 -                getProperties());
   1.392 -        PropertyValidator.getInstance().assertOneOrLess(Property.DTSTAMP,
   1.393 -                getProperties());
   1.394 -        PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE,
   1.395 -                getProperties());
   1.396 -        PropertyValidator.getInstance().assertOneOrLess(Property.STATUS,
   1.397 -                getProperties());
   1.398 -        PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY,
   1.399 -                getProperties());
   1.400 -        PropertyValidator.getInstance().assertOneOrLess(Property.TRANSP,
   1.401 -                getProperties());
   1.402 -        PropertyValidator.getInstance().assertOneOrLess(Property.UID,
   1.403 -                getProperties());
   1.404 -        PropertyValidator.getInstance().assertOneOrLess(Property.URL,
   1.405 -                getProperties());
   1.406 -        PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID,
   1.407 -                getProperties());
   1.408 -
   1.409 -        final Status status = (Status) getProperty(Property.STATUS);
   1.410 -        if (status != null && !Status.VEVENT_TENTATIVE.getValue().equals(status.getValue())
   1.411 -                && !Status.VEVENT_CONFIRMED.getValue().equals(status.getValue())
   1.412 -                && !Status.VEVENT_CANCELLED.getValue().equals(status.getValue())) {
   1.413 -            throw new ValidationException("Status property ["
   1.414 -                    + status.toString() + "] is not applicable for VEVENT");
   1.415 -        }
   1.416 -
   1.417 -        /*
   1.418 -         * ; either 'dtend' or 'duration' may appear in ; a 'eventprop', but 'dtend' and 'duration' ; MUST NOT occur in
   1.419 -         * the same 'eventprop' dtend / duration /
   1.420 -         */
   1.421 -        try {
   1.422 -            PropertyValidator.getInstance().assertNone(Property.DTEND,
   1.423 -                    getProperties());
   1.424 -        }
   1.425 -        catch (ValidationException ve) {
   1.426 -            PropertyValidator.getInstance().assertNone(Property.DURATION,
   1.427 -                    getProperties());
   1.428 -        }
   1.429 -
   1.430 -        if (getProperty(Property.DTEND) != null) {
   1.431 -
   1.432 -            /*
   1.433 -             * The "VEVENT" is also the calendar component used to specify an anniversary or daily reminder within a
   1.434 -             * calendar. These events have a DATE value type for the "DTSTART" property instead of the default data type
   1.435 -             * of DATE-TIME. If such a "VEVENT" has a "DTEND" property, it MUST be specified as a DATE value also. The
   1.436 -             * anniversary type of "VEVENT" can span more than one date (i.e, "DTEND" property value is set to a
   1.437 -             * calendar date after the "DTSTART" property value).
   1.438 -             */
   1.439 -            final DtStart start = (DtStart) getProperty(Property.DTSTART);
   1.440 -            final DtEnd end = (DtEnd) getProperty(Property.DTEND);
   1.441 -
   1.442 -            if (start != null) {
   1.443 -                final Parameter startValue = start.getParameter(Parameter.VALUE);
   1.444 -                final Parameter endValue = end.getParameter(Parameter.VALUE);
   1.445 -                
   1.446 -                boolean startEndValueMismatch = false;
   1.447 -                if (endValue != null) {
   1.448 -                    if (startValue != null && !endValue.equals(startValue)) {
   1.449 -                        // invalid..
   1.450 -                        startEndValueMismatch = true;
   1.451 -                    }
   1.452 -                    else if (startValue == null && !Value.DATE_TIME.equals(endValue)) {
   1.453 -                        // invalid..
   1.454 -                        startEndValueMismatch = true;
   1.455 -                    }
   1.456 -                }
   1.457 -                else if (startValue != null && !Value.DATE_TIME.equals(startValue)) {
   1.458 -                    //invalid..
   1.459 -                    startEndValueMismatch = true;
   1.460 -                }
   1.461 -                if (startEndValueMismatch) {
   1.462 -                    throw new ValidationException("Property [" + Property.DTEND
   1.463 -                            + "] must have the same [" + Parameter.VALUE
   1.464 -                            + "] as [" + Property.DTSTART + "]");
   1.465 -                }
   1.466 -            }
   1.467 -        }
   1.468 -
   1.469 -        /*
   1.470 -         * ; the following are optional, ; and MAY occur more than once attach / attendee / categories / comment /
   1.471 -         * contact / exdate / exrule / rstatus / related / resources / rdate / rrule / x-prop
   1.472 -         */
   1.473 -        
   1.474 -        if (recurse) {
   1.475 -            validateProperties();
   1.476 -        }
   1.477 -    }
   1.478 -    
   1.479 -    /**
   1.480 -     * {@inheritDoc}
   1.481 -     */
   1.482 -    protected Validator getValidator(Method method) {
   1.483 -        return (Validator) methodValidators.get(method);
   1.484 -    }
   1.485 -    
   1.486 -    /**
   1.487 -     * METHOD:ADD Validator.
   1.488 -     * 
   1.489 -     * <pre>
   1.490 -     * Component/Property  Presence
   1.491 -     * ------------------- ----------------------------------------------
   1.492 -     * METHOD              1      MUST be "ADD"
   1.493 -     * VEVENT              1
   1.494 -     *     DTSTAMP         1
   1.495 -     *     DTSTART         1
   1.496 -     *     ORGANIZER       1
   1.497 -     *     SEQUENCE        1      MUST be greater than 0
   1.498 -     *     SUMMARY         1      Can be null
   1.499 -     *     UID             1      MUST match that of the original event
   1.500 -     * 
   1.501 -     *     ATTACH          0+
   1.502 -     *     ATTENDEE        0+
   1.503 -     *     CATEGORIES      0 or 1 This property MAY contain a list of values
   1.504 -     *     CLASS           0 or 1
   1.505 -     *     COMMENT         0 or 1
   1.506 -     *     CONTACT         0+
   1.507 -     *     CREATED         0 or 1
   1.508 -     *     DESCRIPTION     0 or 1  Can be null
   1.509 -     *     DTEND           0 or 1  if present DURATION MUST NOT be present
   1.510 -     *     DURATION        0 or 1  if present DTEND MUST NOT be present
   1.511 -     *     EXDATE          0+
   1.512 -     *     EXRULE          0+
   1.513 -     *     GEO             0 or 1
   1.514 -     *     LAST-MODIFIED   0 or 1
   1.515 -     *     LOCATION        0 or 1
   1.516 -     *     PRIORITY        0 or 1
   1.517 -     *     RDATE           0+
   1.518 -     *     RELATED-TO      0+
   1.519 -     *     RESOURCES       0 or 1  This property MAY contain a list of values
   1.520 -     *     RRULE           0+
   1.521 -     *     STATUS          0 or 1  MAY be one of TENTATIVE/CONFIRMED
   1.522 -     *     TRANSP          0 or 1
   1.523 -     *     URL             0 or 1
   1.524 -     *     X-PROPERTY      0+
   1.525 -     * 
   1.526 -     *     RECURRENCE-ID   0
   1.527 -     *     REQUEST-STATUS  0
   1.528 -     * 
   1.529 -     * VALARM              0+
   1.530 -     * VTIMEZONE           0+     MUST be present if any date/time refers to
   1.531 -     *                            a timezone
   1.532 -     * X-COMPONENT         0+
   1.533 -     * 
   1.534 -     * VFREEBUSY           0
   1.535 -     * VTODO               0
   1.536 -     * VJOURNAL            0
   1.537 -     * </pre>
   1.538 -     * 
   1.539 -     */
   1.540 -    private class AddValidator implements Validator {
   1.541 -        
   1.542 -		private static final long serialVersionUID = 1L;
   1.543 -
   1.544 -		public void validate() throws ValidationException {
   1.545 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
   1.546 -            PropertyValidator.getInstance().assertOne(Property.DTSTART, getProperties());
   1.547 -            PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
   1.548 -            PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties());
   1.549 -            PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
   1.550 -            PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
   1.551 -            
   1.552 -            PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
   1.553 -            PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
   1.554 -            PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
   1.555 -            PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
   1.556 -            PropertyValidator.getInstance().assertOneOrLess(Property.DTEND, getProperties());
   1.557 -            PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
   1.558 -            PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
   1.559 -            PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
   1.560 -            PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
   1.561 -            PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
   1.562 -            PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
   1.563 -            PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
   1.564 -            PropertyValidator.getInstance().assertOneOrLess(Property.TRANSP, getProperties());
   1.565 -            PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
   1.566 -            
   1.567 -            PropertyValidator.getInstance().assertNone(Property.RECURRENCE_ID, getProperties());
   1.568 -            PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
   1.569 -            
   1.570 -            for (final Iterator i = getAlarms().iterator(); i.hasNext();) {
   1.571 -                final VAlarm alarm = (VAlarm) i.next();
   1.572 -                alarm.validate(Method.ADD);
   1.573 -            }
   1.574 -        }
   1.575 -    }
   1.576 -    
   1.577 -    /**
   1.578 -     * METHOD:CANCEL Validator.
   1.579 -     * 
   1.580 -     * <pre>
   1.581 -     * Component/Property  Presence
   1.582 -     * ------------------- ----------------------------------------------
   1.583 -     * METHOD              1      MUST be "CANCEL"
   1.584 -     * 
   1.585 -     * VEVENT              1+     All must have the same UID
   1.586 -     *     ATTENDEE        0+     MUST include all "Attendees" being removed
   1.587 -     *                            the event. MUST include all "Attendees" if
   1.588 -     *                            the entire event is cancelled.
   1.589 -     *     DTSTAMP         1
   1.590 -     *     ORGANIZER       1
   1.591 -     *     SEQUENCE        1
   1.592 -     *     UID             1       MUST be the UID of the original REQUEST
   1.593 -     * 
   1.594 -     *     COMMENT         0 or 1
   1.595 -     *     ATTACH          0+
   1.596 -     *     CATEGORIES      0 or 1  This property may contain a list of values
   1.597 -     *     CLASS           0 or 1
   1.598 -     *     CONTACT         0+
   1.599 -     *     CREATED         0 or 1
   1.600 -     *     DESCRIPTION     0 or 1
   1.601 -     *     DTEND           0 or 1 if present DURATION MUST NOT be present
   1.602 -     *     DTSTART         0 or 1
   1.603 -     *     DURATION        0 or 1 if present DTEND MUST NOT be present
   1.604 -     *     EXDATE          0+
   1.605 -     *     EXRULE          0+
   1.606 -     *     GEO             0 or 1
   1.607 -     *     LAST-MODIFIED   0 or 1
   1.608 -     *     LOCATION        0 or 1
   1.609 -     *     PRIORITY        0 or 1
   1.610 -     *     RDATE           0+
   1.611 -     *     RECURRENCE-ID   0 or 1  MUST be present if referring to one or
   1.612 -     *                             more or more recurring instances.
   1.613 -     *                             Otherwise it MUST NOT be present
   1.614 -     *     RELATED-TO      0+
   1.615 -     *     RESOURCES       0 or 1
   1.616 -     *     RRULE           0+
   1.617 -     *     STATUS          0 or 1  MUST be set to CANCELLED. If uninviting
   1.618 -     *                             specific "Attendees" then MUST NOT be
   1.619 -     *                             included.
   1.620 -     *     SUMMARY         0 or 1
   1.621 -     *     TRANSP          0 or 1
   1.622 -     *     URL             0 or 1
   1.623 -     *     X-PROPERTY      0+
   1.624 -     *     REQUEST-STATUS  0
   1.625 -     * 
   1.626 -     * VTIMEZONE           0+     MUST be present if any date/time refers to
   1.627 -     *                            a timezone
   1.628 -     * X-COMPONENT         0+
   1.629 -     * 
   1.630 -     * VTODO               0
   1.631 -     * VJOURNAL            0
   1.632 -     * VFREEBUSY           0
   1.633 -     * VALARM              0
   1.634 -     * </pre>
   1.635 -     * 
   1.636 -     */
   1.637 -    private class CancelValidator implements Validator {
   1.638 -        
   1.639 -		private static final long serialVersionUID = 1L;
   1.640 -
   1.641 -        public final void validate() throws ValidationException {
   1.642 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
   1.643 -            PropertyValidator.getInstance().assertOne(Property.DTSTART, getProperties());
   1.644 -            PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
   1.645 -            PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties());
   1.646 -            PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
   1.647 -            
   1.648 -            PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
   1.649 -            PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
   1.650 -            PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
   1.651 -            PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
   1.652 -            PropertyValidator.getInstance().assertOneOrLess(Property.DTEND, getProperties());
   1.653 -            PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties());
   1.654 -            PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
   1.655 -            PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
   1.656 -            PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
   1.657 -            PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
   1.658 -            PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
   1.659 -            PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
   1.660 -            PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
   1.661 -            PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
   1.662 -            PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY, getProperties());
   1.663 -            PropertyValidator.getInstance().assertOneOrLess(Property.TRANSP, getProperties());
   1.664 -            PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
   1.665 -            
   1.666 -            PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
   1.667 -            
   1.668 -            ComponentValidator.assertNone(Component.VALARM, getAlarms());
   1.669 -        }
   1.670 -    }
   1.671 -    
   1.672 -    /**
   1.673 -     * METHOD:COUNTER Validator.
   1.674 -     * 
   1.675 -     * <pre>
   1.676 -     * Component/Property  Presence
   1.677 -     * ------------------- ----------------------------------------------
   1.678 -     * METHOD              1      MUST be "COUNTER"
   1.679 -     * 
   1.680 -     * VEVENT              1
   1.681 -     *     DTSTAMP         1
   1.682 -     *     DTSTART         1
   1.683 -     *     ORGANIZER       1       MUST be the "Organizer" of the original
   1.684 -     *                             event
   1.685 -     *     SEQUENCE        1       MUST be present if value is greater than 0,
   1.686 -     *                             MAY be present if 0
   1.687 -     *     SUMMARY         1       Can be null
   1.688 -     *     UID             1       MUST be the UID associated with the REQUEST
   1.689 -     *                             being countered
   1.690 -     * 
   1.691 -     *     ATTACH          0+
   1.692 -     *     ATTENDEE        0+      Can also  be used to propose other
   1.693 -     *                             "Attendees"
   1.694 -     *     CATEGORIES      0 or 1  This property may contain a list of values
   1.695 -     *     CLASS           0 or 1
   1.696 -     *     COMMENT         0 or 1
   1.697 -     *     CONTACT         0+
   1.698 -     *     CREATED         0 or 1
   1.699 -     *     DESCRIPTION     0 or 1
   1.700 -     *     DTEND           0 or 1  if present DURATION MUST NOT be present
   1.701 -     *     DURATION        0 or 1  if present DTEND MUST NOT be present
   1.702 -     *     EXDATE          0+
   1.703 -     *     EXRULE          0+
   1.704 -     *     GEO             0 or 1
   1.705 -     *     LAST-MODIFIED   0 or 1
   1.706 -     *     LOCATION        0 or 1
   1.707 -     *     PRIORITY        0 or 1
   1.708 -     *     RDATE           0+
   1.709 -     *     RECURRENCE-ID   0 or 1  MUST only if referring to an instance of a
   1.710 -     *                             recurring calendar component.  Otherwise it
   1.711 -     *                             MUST NOT be present.
   1.712 -     *     RELATED-TO      0+
   1.713 -     *     REQUEST-STATUS  0+
   1.714 -     *     RESOURCES       0 or 1  This property may contain a list of values
   1.715 -     *     RRULE           0+
   1.716 -     *     STATUS          0 or 1  Value must be one of CONFIRMED/TENATIVE/
   1.717 -     *                             CANCELLED
   1.718 -     *     TRANSP          0 or 1
   1.719 -     *     URL             0 or 1
   1.720 -     *     X-PROPERTY      0+
   1.721 -     * 
   1.722 -     * VALARM              0+
   1.723 -     * VTIMEZONE           0+      MUST be present if any date/time refers to
   1.724 -     *                             a timezone
   1.725 -     * X-COMPONENT         0+
   1.726 -     * 
   1.727 -     * VTODO               0
   1.728 -     * VJOURNAL            0
   1.729 -     * VFREEBUSY           0
   1.730 -     * </pre>
   1.731 -     * 
   1.732 -     */
   1.733 -    private class CounterValidator implements Validator {
   1.734 -        
   1.735 -		private static final long serialVersionUID = 1L;
   1.736 -
   1.737 -        public void validate() throws ValidationException {
   1.738 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
   1.739 -            PropertyValidator.getInstance().assertOne(Property.DTSTART, getProperties());
   1.740 -            
   1.741 -            if (!CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) {
   1.742 -                PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
   1.743 -            }
   1.744 -            
   1.745 -            PropertyValidator.getInstance().assertOne(Property.SEQUENCE, getProperties());
   1.746 -            PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
   1.747 -            PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
   1.748 -            
   1.749 -            PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
   1.750 -            PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
   1.751 -            PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
   1.752 -            PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
   1.753 -            PropertyValidator.getInstance().assertOneOrLess(Property.DTEND, getProperties());
   1.754 -            PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
   1.755 -            PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
   1.756 -            PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
   1.757 -            PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
   1.758 -            PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
   1.759 -            PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
   1.760 -            PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
   1.761 -            PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
   1.762 -            PropertyValidator.getInstance().assertOneOrLess(Property.TRANSP, getProperties());
   1.763 -            PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
   1.764 -            
   1.765 -            for (final Iterator i = getAlarms().iterator(); i.hasNext();) {
   1.766 -                final VAlarm alarm = (VAlarm) i.next();
   1.767 -                alarm.validate(Method.COUNTER);
   1.768 -            }
   1.769 -        }
   1.770 -    }
   1.771 -    
   1.772 -    /**
   1.773 -     * METHOD:DECLINECOUNTER Validator.
   1.774 -     * 
   1.775 -     * <pre>
   1.776 -     * Component/Property  Presence
   1.777 -     * ------------------- ----------------------------------------------
   1.778 -     * METHOD              1      MUST be "DECLINECOUNTER"
   1.779 -     * 
   1.780 -     * VEVENT              1
   1.781 -     *     DTSTAMP         1
   1.782 -     *     ORGANIZER       1
   1.783 -     *     UID             1       MUST, same UID specified in original
   1.784 -     *                             REQUEST and subsequent COUNTER
   1.785 -     *     COMMENT         0 or 1
   1.786 -     *     RECURRENCE-ID   0 or 1  MUST only if referring to an instance of a
   1.787 -     *                             recurring calendar component.  Otherwise it
   1.788 -     *                             MUST NOT be present.
   1.789 -     *     REQUEST-STATUS  0+
   1.790 -     *     SEQUENCE        0 OR 1  MUST be present if value is greater than 0,
   1.791 -     *                             MAY be present if 0
   1.792 -     *     X-PROPERTY      0+
   1.793 -     *     ATTACH          0
   1.794 -     *     ATTENDEE        0
   1.795 -     *     CATEGORIES      0
   1.796 -     *     CLASS           0
   1.797 -     *     CONTACT         0
   1.798 -     *     CREATED         0
   1.799 -     *     DESCRIPTION     0
   1.800 -     *     DTEND           0
   1.801 -     *     DTSTART         0
   1.802 -     *     DURATION        0
   1.803 -     *     EXDATE          0
   1.804 -     *     EXRULE          0
   1.805 -     *     GEO             0
   1.806 -     *     LAST-MODIFIED   0
   1.807 -     *     LOCATION        0
   1.808 -     *     PRIORITY        0
   1.809 -     *     RDATE           0
   1.810 -     *     RELATED-TO      0
   1.811 -     *     RESOURCES       0
   1.812 -     *     RRULE           0
   1.813 -     *     STATUS          0
   1.814 -     *     SUMMARY         0
   1.815 -     *     TRANSP          0
   1.816 -     *     URL             0
   1.817 -     * 
   1.818 -     * X-COMPONENT         0+
   1.819 -     * VTODO               0
   1.820 -     * VJOURNAL            0
   1.821 -     * VFREEBUSY           0
   1.822 -     * VTIMEZONE           0
   1.823 -     * VALARM              0
   1.824 -     * </pre>
   1.825 -     * 
   1.826 -     */
   1.827 -    private class DeclineCounterValidator implements Validator {
   1.828 -        
   1.829 -		private static final long serialVersionUID = 1L;
   1.830 -
   1.831 -        public void validate() throws ValidationException {
   1.832 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
   1.833 -            PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
   1.834 -            PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
   1.835 -            
   1.836 -            PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
   1.837 -            PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties());
   1.838 -            
   1.839 -            PropertyValidator.getInstance().assertNone(Property.ATTACH, getProperties());
   1.840 -            PropertyValidator.getInstance().assertNone(Property.ATTENDEE, getProperties());
   1.841 -            PropertyValidator.getInstance().assertNone(Property.CATEGORIES, getProperties());
   1.842 -            PropertyValidator.getInstance().assertNone(Property.CLASS, getProperties());
   1.843 -            PropertyValidator.getInstance().assertNone(Property.CONTACT, getProperties());
   1.844 -            PropertyValidator.getInstance().assertNone(Property.CREATED, getProperties());
   1.845 -            PropertyValidator.getInstance().assertNone(Property.DESCRIPTION, getProperties());
   1.846 -            PropertyValidator.getInstance().assertNone(Property.DTEND, getProperties());
   1.847 -            PropertyValidator.getInstance().assertNone(Property.DTSTART, getProperties());
   1.848 -            PropertyValidator.getInstance().assertNone(Property.DURATION, getProperties());
   1.849 -            PropertyValidator.getInstance().assertNone(Property.EXDATE, getProperties());
   1.850 -            PropertyValidator.getInstance().assertNone(Property.EXRULE, getProperties());
   1.851 -            PropertyValidator.getInstance().assertNone(Property.GEO, getProperties());
   1.852 -            PropertyValidator.getInstance().assertNone(Property.LAST_MODIFIED, getProperties());
   1.853 -            PropertyValidator.getInstance().assertNone(Property.LOCATION, getProperties());
   1.854 -            PropertyValidator.getInstance().assertNone(Property.PRIORITY, getProperties());
   1.855 -            PropertyValidator.getInstance().assertNone(Property.RDATE, getProperties());
   1.856 -            PropertyValidator.getInstance().assertNone(Property.RELATED_TO, getProperties());
   1.857 -            PropertyValidator.getInstance().assertNone(Property.RESOURCES, getProperties());
   1.858 -            PropertyValidator.getInstance().assertNone(Property.RRULE, getProperties());
   1.859 -            PropertyValidator.getInstance().assertNone(Property.STATUS, getProperties());
   1.860 -            PropertyValidator.getInstance().assertNone(Property.SUMMARY, getProperties());
   1.861 -            PropertyValidator.getInstance().assertNone(Property.TRANSP, getProperties());
   1.862 -            PropertyValidator.getInstance().assertNone(Property.URL, getProperties());
   1.863 -            
   1.864 -            ComponentValidator.assertNone(Component.VALARM, getAlarms());
   1.865 -        }
   1.866 -    }
   1.867 -    
   1.868 -    /**
   1.869 -     * METHOD:PUBLISH Validator.
   1.870 -     * 
   1.871 -     * <pre>
   1.872 -     * Component/Property  Presence
   1.873 -     * ------------------- ----------------------------------------------
   1.874 -     * METHOD              1       MUST equal "PUBLISH"
   1.875 -     * VEVENT              1+
   1.876 -     *      DTSTAMP        1
   1.877 -     *      DTSTART        1
   1.878 -     *      ORGANIZER      1
   1.879 -     *      SUMMARY        1       Can be null.
   1.880 -     *      UID            1
   1.881 -     *      RECURRENCE-ID  0 or 1  only if referring to an instance of a
   1.882 -     *                             recurring calendar component.  Otherwise
   1.883 -     *                             it MUST NOT be present.
   1.884 -     *      SEQUENCE       0 or 1  MUST be present if value is greater than
   1.885 -     *                             0, MAY be present if 0
   1.886 -     *      ATTACH         0+
   1.887 -     *      CATEGORIES     0 or 1  This property may contain a list of
   1.888 -     *                             values
   1.889 -     *      CLASS          0 or 1
   1.890 -     *      COMMENT        0 or 1
   1.891 -     *      CONTACT        0+
   1.892 -     *      CREATED        0 or 1
   1.893 -     *      DESCRIPTION    0 or 1  Can be null
   1.894 -     *      DTEND          0 or 1  if present DURATION MUST NOT be present
   1.895 -     *      DURATION       0 or 1  if present DTEND MUST NOT be present
   1.896 -     *      EXDATE         0+
   1.897 -     *      EXRULE         0+
   1.898 -     *      GEO            0 or 1
   1.899 -     *      LAST-MODIFIED  0 or 1
   1.900 -     *      LOCATION       0 or 1
   1.901 -     *      PRIORITY       0 or 1
   1.902 -     *      RDATE          0+
   1.903 -     *      RELATED-TO     0+
   1.904 -     *      RESOURCES      0 or 1 This property MAY contain a list of values
   1.905 -     *      RRULE          0+
   1.906 -     *      STATUS         0 or 1 MAY be one of TENTATIVE/CONFIRMED/CANCELLED
   1.907 -     *      TRANSP         0 or 1
   1.908 -     *      URL            0 or 1
   1.909 -     *      X-PROPERTY     0+
   1.910 -     * 
   1.911 -     *      ATTENDEE       0
   1.912 -     *      REQUEST-STATUS 0
   1.913 -     * 
   1.914 -     * VALARM              0+
   1.915 -     * VFREEBUSY           0
   1.916 -     * VJOURNAL            0
   1.917 -     * VTODO               0
   1.918 -     * VTIMEZONE           0+    MUST be present if any date/time refers to
   1.919 -     *                           a timezone
   1.920 -     * X-COMPONENT         0+
   1.921 -     * </pre>
   1.922 -     * 
   1.923 -     */
   1.924 -    private class PublishValidator implements Validator {
   1.925 -        
   1.926 -		private static final long serialVersionUID = 1L;
   1.927 -
   1.928 -        public void validate() throws ValidationException {
   1.929 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
   1.930 -            PropertyValidator.getInstance().assertOne(Property.DTSTART, getProperties());
   1.931 -            
   1.932 -            if (!CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) {
   1.933 -                PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
   1.934 -                PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
   1.935 -            }
   1.936 -            
   1.937 -            PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
   1.938 -            
   1.939 -            PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
   1.940 -            PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties());
   1.941 -            PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
   1.942 -            PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
   1.943 -            PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
   1.944 -            PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
   1.945 -            PropertyValidator.getInstance().assertOneOrLess(Property.DTEND, getProperties());
   1.946 -            PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
   1.947 -            PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
   1.948 -            PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
   1.949 -            PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
   1.950 -            PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
   1.951 -            PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
   1.952 -            PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
   1.953 -            PropertyValidator.getInstance().assertOneOrLess(Property.TRANSP, getProperties());
   1.954 -            PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
   1.955 -            
   1.956 -            if (!CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) {
   1.957 -                PropertyValidator.getInstance().assertNone(Property.ATTENDEE, getProperties());
   1.958 -            }
   1.959 -            
   1.960 -            PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
   1.961 -            
   1.962 -            for (final Iterator i = getAlarms().iterator(); i.hasNext();) {
   1.963 -                final VAlarm alarm = (VAlarm) i.next();
   1.964 -                alarm.validate(Method.PUBLISH);
   1.965 -            }
   1.966 -        }
   1.967 -    }
   1.968 -    
   1.969 -    /**
   1.970 -     * METHOD:REFRESH Validator.
   1.971 -     * 
   1.972 -     * <pre>
   1.973 -     * Component/Property  Presence
   1.974 -     * ------------------- ----------------------------------------------
   1.975 -     * METHOD              1      MUST be "REFRESH"
   1.976 -     * 
   1.977 -     * VEVENT              1
   1.978 -     *     ATTENDEE        1      MUST be the address of requestor
   1.979 -     *     DTSTAMP         1
   1.980 -     *     ORGANIZER       1
   1.981 -     *     UID             1      MUST be the UID associated with original
   1.982 -     *                            REQUEST
   1.983 -     *     COMMENT         0 or 1
   1.984 -     *     RECURRENCE-ID   0 or 1 MUST only if referring to an instance of a
   1.985 -     *                            recurring calendar component.  Otherwise
   1.986 -     *                            it must NOT be present.
   1.987 -     *     X-PROPERTY      0+
   1.988 -     * 
   1.989 -     *     ATTACH          0
   1.990 -     *     CATEGORIES      0
   1.991 -     *     CLASS           0
   1.992 -     *     CONTACT         0
   1.993 -     *     CREATED         0
   1.994 -     *     DESCRIPTION     0
   1.995 -     *     DTEND           0
   1.996 -     *     DTSTART         0
   1.997 -     *     DURATION        0
   1.998 -     *     EXDATE          0
   1.999 -     *     EXRULE          0
  1.1000 -     *     GEO             0
  1.1001 -     *     LAST-MODIFIED   0
  1.1002 -     *     LOCATION        0
  1.1003 -     *     PRIORITY        0
  1.1004 -     *     RDATE           0
  1.1005 -     *     RELATED-TO      0
  1.1006 -     *     REQUEST-STATUS  0
  1.1007 -     *     RESOURCES       0
  1.1008 -     *     RRULE           0
  1.1009 -     *     SEQUENCE        0
  1.1010 -     *     STATUS          0
  1.1011 -     *     SUMMARY         0
  1.1012 -     *     TRANSP          0
  1.1013 -     *     URL             0
  1.1014 -     * 
  1.1015 -     * X-COMPONENT         0+
  1.1016 -     * 
  1.1017 -     * VTODO               0
  1.1018 -     * VJOURNAL            0
  1.1019 -     * VFREEBUSY           0
  1.1020 -     * VTIMEZONE           0
  1.1021 -     * VALARM              0
  1.1022 -     * </pre>
  1.1023 -     * 
  1.1024 -     */
  1.1025 -    private class RefreshValidator implements Validator {
  1.1026 -        
  1.1027 -		private static final long serialVersionUID = 1L;
  1.1028 -
  1.1029 -        public void validate() throws ValidationException {
  1.1030 -            PropertyValidator.getInstance().assertOne(Property.ATTENDEE, getProperties());
  1.1031 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
  1.1032 -            PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
  1.1033 -            PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
  1.1034 -            
  1.1035 -            PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
  1.1036 -            
  1.1037 -            PropertyValidator.getInstance().assertNone(Property.ATTACH, getProperties());
  1.1038 -            PropertyValidator.getInstance().assertNone(Property.CATEGORIES, getProperties());
  1.1039 -            PropertyValidator.getInstance().assertNone(Property.CLASS, getProperties());
  1.1040 -            PropertyValidator.getInstance().assertNone(Property.CONTACT, getProperties());
  1.1041 -            PropertyValidator.getInstance().assertNone(Property.CREATED, getProperties());
  1.1042 -            PropertyValidator.getInstance().assertNone(Property.DESCRIPTION, getProperties());
  1.1043 -            PropertyValidator.getInstance().assertNone(Property.DTEND, getProperties());
  1.1044 -            PropertyValidator.getInstance().assertNone(Property.DTSTART, getProperties());
  1.1045 -            PropertyValidator.getInstance().assertNone(Property.DURATION, getProperties());
  1.1046 -            PropertyValidator.getInstance().assertNone(Property.EXDATE, getProperties());
  1.1047 -            PropertyValidator.getInstance().assertNone(Property.EXRULE, getProperties());
  1.1048 -            PropertyValidator.getInstance().assertNone(Property.GEO, getProperties());
  1.1049 -            PropertyValidator.getInstance().assertNone(Property.LAST_MODIFIED, getProperties());
  1.1050 -            PropertyValidator.getInstance().assertNone(Property.LOCATION, getProperties());
  1.1051 -            PropertyValidator.getInstance().assertNone(Property.PRIORITY, getProperties());
  1.1052 -            PropertyValidator.getInstance().assertNone(Property.RDATE, getProperties());
  1.1053 -            PropertyValidator.getInstance().assertNone(Property.RELATED_TO, getProperties());
  1.1054 -            PropertyValidator.getInstance().assertNone(Property.REQUEST_STATUS, getProperties());
  1.1055 -            PropertyValidator.getInstance().assertNone(Property.RESOURCES, getProperties());
  1.1056 -            PropertyValidator.getInstance().assertNone(Property.RRULE, getProperties());
  1.1057 -            PropertyValidator.getInstance().assertNone(Property.SEQUENCE, getProperties());
  1.1058 -            PropertyValidator.getInstance().assertNone(Property.STATUS, getProperties());
  1.1059 -            PropertyValidator.getInstance().assertNone(Property.SUMMARY, getProperties());
  1.1060 -            PropertyValidator.getInstance().assertNone(Property.TRANSP, getProperties());
  1.1061 -            PropertyValidator.getInstance().assertNone(Property.URL, getProperties());
  1.1062 -            
  1.1063 -            ComponentValidator.assertNone(Component.VALARM, getAlarms());
  1.1064 -        }
  1.1065 -    }
  1.1066 -    
  1.1067 -    /**
  1.1068 -     * METHOD:REPLY Validator.
  1.1069 -     * 
  1.1070 -     * <pre>
  1.1071 -     * Component/Property  Presence
  1.1072 -     * ------------------- ----------------------------------------------
  1.1073 -     * METHOD              1       MUST be "REPLY"
  1.1074 -     * VEVENT              1+      All components MUST have the same UID
  1.1075 -     *     ATTENDEE        1       MUST be the address of the Attendee
  1.1076 -     *                             replying.
  1.1077 -     *     DTSTAMP         1
  1.1078 -     *     ORGANIZER       1
  1.1079 -     *     RECURRENCE-ID   0 or 1  only if referring to an instance of a
  1.1080 -     *                             recurring calendar component.  Otherwise
  1.1081 -     *                             it must NOT be present.
  1.1082 -     *     UID             1       MUST be the UID of the original REQUEST
  1.1083 -     *     
  1.1084 -     *     SEQUENCE        0 or 1  MUST if non-zero, MUST be the sequence
  1.1085 -     *                             number of the original REQUEST. MAY be
  1.1086 -     *                             present if 0.
  1.1087 -     *     
  1.1088 -     *     ATTACH          0+
  1.1089 -     *     CATEGORIES      0 or 1  This property may contain a list of values
  1.1090 -     *     CLASS           0 or 1
  1.1091 -     *     COMMENT         0 or 1
  1.1092 -     *     CONTACT         0+
  1.1093 -     *     CREATED         0 or 1
  1.1094 -     *     DESCRIPTION     0 or 1
  1.1095 -     *     DTEND           0 or 1  if present DURATION MUST NOT be present
  1.1096 -     *     DTSTART         0 or 1
  1.1097 -     *     DURATION        0 or 1  if present DTEND MUST NOT be present
  1.1098 -     *     EXDATE          0+
  1.1099 -     *     EXRULE          0+
  1.1100 -     *     GEO             0 or 1
  1.1101 -     *     LAST-MODIFIED   0 or 1
  1.1102 -     *     LOCATION        0 or 1
  1.1103 -     *     PRIORITY        0 or 1
  1.1104 -     *     RDATE           0+
  1.1105 -     *     RELATED-TO      0+
  1.1106 -     *     RESOURCES       0 or 1  This property MAY contain a list of values
  1.1107 -     *     REQUEST-STATUS  0+
  1.1108 -     *     RRULE           0+
  1.1109 -     *     STATUS          0 or 1
  1.1110 -     *     SUMMARY         0 or 1
  1.1111 -     *     TRANSP          0 or 1
  1.1112 -     *     URL             0 or 1
  1.1113 -     *     X-PROPERTY      0+
  1.1114 -     *     
  1.1115 -     * VTIMEZONE           0 or 1 MUST be present if any date/time refers
  1.1116 -     *                            to a timezone
  1.1117 -     * X-COMPONENT         0+
  1.1118 -     * 
  1.1119 -     * VALARM              0
  1.1120 -     * VFREEBUSY           0
  1.1121 -     * VJOURNAL            0
  1.1122 -     * VTODO               0
  1.1123 -     * </pre>
  1.1124 -     * 
  1.1125 -     */
  1.1126 -    private class ReplyValidator implements Validator {
  1.1127 -        
  1.1128 -		private static final long serialVersionUID = 1L;
  1.1129 -
  1.1130 -        public void validate() throws ValidationException {
  1.1131 -            PropertyValidator.getInstance().assertOne(Property.ATTENDEE, getProperties());
  1.1132 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
  1.1133 -            PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
  1.1134 -            PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
  1.1135 -            
  1.1136 -            PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
  1.1137 -            PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties());
  1.1138 -            PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
  1.1139 -            PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
  1.1140 -            PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
  1.1141 -            PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
  1.1142 -            PropertyValidator.getInstance().assertOneOrLess(Property.DTEND, getProperties());
  1.1143 -            PropertyValidator.getInstance().assertOneOrLess(Property.DTSTART, getProperties());
  1.1144 -            PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
  1.1145 -            PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
  1.1146 -            PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
  1.1147 -            PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
  1.1148 -            PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
  1.1149 -            PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
  1.1150 -            PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
  1.1151 -            PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY, getProperties());
  1.1152 -            PropertyValidator.getInstance().assertOneOrLess(Property.TRANSP, getProperties());
  1.1153 -            PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
  1.1154 -            
  1.1155 -            ComponentValidator.assertNone(Component.VALARM, getAlarms());
  1.1156 -        }
  1.1157 -    }
  1.1158 -    
  1.1159 -    /**
  1.1160 -     * METHOD:REQUEST Validator.
  1.1161 -     * 
  1.1162 -     * <pre>
  1.1163 -     * Component/Property  Presence
  1.1164 -     * -----------------------------------------------------------------
  1.1165 -     * METHOD              1       MUST be "REQUEST"
  1.1166 -     * VEVENT              1+      All components MUST have the same UID
  1.1167 -     *     ATTENDEE        1+
  1.1168 -     *     DTSTAMP         1
  1.1169 -     *     DTSTART         1
  1.1170 -     *     ORGANIZER       1
  1.1171 -     *     SEQUENCE        0 or 1  MUST be present if value is greater than 0,
  1.1172 -     *                             MAY be present if 0
  1.1173 -     *     SUMMARY         1       Can be null
  1.1174 -     *     UID             1
  1.1175 -     *     
  1.1176 -     *     ATTACH          0+
  1.1177 -     *     CATEGORIES      0 or 1  This property may contain a list of values
  1.1178 -     *     CLASS           0 or 1
  1.1179 -     *     COMMENT         0 or 1
  1.1180 -     *     CONTACT         0+
  1.1181 -     *     CREATED         0 or 1
  1.1182 -     *     DESCRIPTION     0 or 1  Can be null
  1.1183 -     *     DTEND           0 or 1  if present DURATION MUST NOT be present
  1.1184 -     *     DURATION        0 or 1  if present DTEND MUST NOT be present
  1.1185 -     *     EXDATE          0+
  1.1186 -     *     EXRULE          0+
  1.1187 -     *     GEO             0 or 1
  1.1188 -     *     LAST-MODIFIED   0 or 1
  1.1189 -     *     LOCATION        0 or 1
  1.1190 -     *     PRIORITY        0 or 1
  1.1191 -     *     RDATE           0+
  1.1192 -     *     RECURRENCE-ID   0 or 1  only if referring to an instance of a
  1.1193 -     *                             recurring calendar component.  Otherwise it
  1.1194 -     *                             MUST NOT be present.
  1.1195 -     *     RELATED-TO      0+
  1.1196 -     *     REQUEST-STATUS  0+
  1.1197 -     *     RESOURCES       0 or 1  This property MAY contain a list of values
  1.1198 -     *     RRULE           0+
  1.1199 -     *     STATUS          0 or 1  MAY be one of TENTATIVE/CONFIRMED
  1.1200 -     *     TRANSP          0 or 1
  1.1201 -     *     URL             0 or 1
  1.1202 -     *     X-PROPERTY      0+
  1.1203 -     *     
  1.1204 -     * VALARM              0+
  1.1205 -     * VTIMEZONE           0+      MUST be present if any date/time refers to
  1.1206 -     *                             a timezone
  1.1207 -     * X-COMPONENT         0+
  1.1208 -     * VFREEBUSY           0
  1.1209 -     * VJOURNAL            0
  1.1210 -     * VTODO               0
  1.1211 -     * </pre>
  1.1212 -     * 
  1.1213 -     */
  1.1214 -    private class RequestValidator implements Validator {
  1.1215 -        
  1.1216 -		private static final long serialVersionUID = 1L;
  1.1217 -
  1.1218 -        public void validate() throws ValidationException {
  1.1219 -            if (!CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION)) {
  1.1220 -                PropertyValidator.getInstance().assertOneOrMore(Property.ATTENDEE, getProperties());
  1.1221 -            }
  1.1222 -            
  1.1223 -            PropertyValidator.getInstance().assertOne(Property.DTSTAMP, getProperties());
  1.1224 -            PropertyValidator.getInstance().assertOne(Property.DTSTART, getProperties());
  1.1225 -            PropertyValidator.getInstance().assertOne(Property.ORGANIZER, getProperties());
  1.1226 -            PropertyValidator.getInstance().assertOne(Property.SUMMARY, getProperties());
  1.1227 -            PropertyValidator.getInstance().assertOne(Property.UID, getProperties());
  1.1228 -            
  1.1229 -            PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, getProperties());
  1.1230 -            PropertyValidator.getInstance().assertOneOrLess(Property.CATEGORIES, getProperties());
  1.1231 -            PropertyValidator.getInstance().assertOneOrLess(Property.CLASS, getProperties());
  1.1232 -            PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, getProperties());
  1.1233 -            PropertyValidator.getInstance().assertOneOrLess(Property.DESCRIPTION, getProperties());
  1.1234 -            PropertyValidator.getInstance().assertOneOrLess(Property.DTEND, getProperties());
  1.1235 -            PropertyValidator.getInstance().assertOneOrLess(Property.DURATION, getProperties());
  1.1236 -            PropertyValidator.getInstance().assertOneOrLess(Property.GEO, getProperties());
  1.1237 -            PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, getProperties());
  1.1238 -            PropertyValidator.getInstance().assertOneOrLess(Property.LOCATION, getProperties());
  1.1239 -            PropertyValidator.getInstance().assertOneOrLess(Property.PRIORITY, getProperties());
  1.1240 -            PropertyValidator.getInstance().assertOneOrLess(Property.RECURRENCE_ID, getProperties());
  1.1241 -            PropertyValidator.getInstance().assertOneOrLess(Property.RESOURCES, getProperties());
  1.1242 -            PropertyValidator.getInstance().assertOneOrLess(Property.STATUS, getProperties());
  1.1243 -            PropertyValidator.getInstance().assertOneOrLess(Property.TRANSP, getProperties());
  1.1244 -            PropertyValidator.getInstance().assertOneOrLess(Property.URL, getProperties());
  1.1245 -            
  1.1246 -            for (final Iterator i = getAlarms().iterator(); i.hasNext();) {
  1.1247 -                final VAlarm alarm = (VAlarm) i.next();
  1.1248 -                alarm.validate(Method.REQUEST);
  1.1249 -            }
  1.1250 -        }
  1.1251 -    }
  1.1252 -    /**
  1.1253 -     * Returns a normalised list of periods representing the consumed time for this event.
  1.1254 -     * @param rangeStart the start of a range
  1.1255 -     * @param rangeEnd the end of a range
  1.1256 -     * @return a normalised list of periods representing consumed time for this event
  1.1257 -     * @see VEvent#getConsumedTime(Date, Date, boolean)
  1.1258 -     */
  1.1259 -    public final PeriodList getConsumedTime(final Date rangeStart,
  1.1260 -            final Date rangeEnd) {
  1.1261 -        return getConsumedTime(rangeStart, rangeEnd, true);
  1.1262 -    }
  1.1263 -
  1.1264 -    /**
  1.1265 -     * Returns a list of periods representing the consumed time for this event in the specified range. Note that the
  1.1266 -     * returned list may contain a single period for non-recurring components or multiple periods for recurring
  1.1267 -     * components. If no time is consumed by this event an empty list is returned.
  1.1268 -     * @param rangeStart the start of the range to check for consumed time
  1.1269 -     * @param rangeEnd the end of the range to check for consumed time
  1.1270 -     * @param normalise indicate whether the returned list of periods should be normalised
  1.1271 -     * @return a list of periods representing consumed time for this event
  1.1272 -     */
  1.1273 -    public final PeriodList getConsumedTime(final Date rangeStart,
  1.1274 -            final Date rangeEnd, final boolean normalise) {
  1.1275 -        PeriodList periods = new PeriodList();
  1.1276 -        // if component is transparent return empty list..
  1.1277 -        if (!Transp.TRANSPARENT.equals(getProperty(Property.TRANSP))) {
  1.1278 -
  1.1279 -//          try {
  1.1280 -          periods = calculateRecurrenceSet(new Period(new DateTime(rangeStart),
  1.1281 -                  new DateTime(rangeEnd)));
  1.1282 -//          }
  1.1283 -//          catch (ValidationException ve) {
  1.1284 -//              log.error("Invalid event data", ve);
  1.1285 -//              return periods;
  1.1286 -//          }
  1.1287 -
  1.1288 -          // if periods already specified through recurrence, return..
  1.1289 -          // ..also normalise before returning.
  1.1290 -          if (!periods.isEmpty() && normalise) {
  1.1291 -              periods = periods.normalise();
  1.1292 -          }
  1.1293 -        }
  1.1294 -
  1.1295 -        return periods;
  1.1296 -    }
  1.1297 -
  1.1298 -    /**
  1.1299 -     * Returns a single occurrence of a recurring event.
  1.1300 -     * @param date a date on which the occurence should occur
  1.1301 -     * @return a single non-recurring event instance for the specified date, or null if the event doesn't
  1.1302 -     * occur on the specified date
  1.1303 -     * @throws IOException where an error occurs reading data
  1.1304 -     * @throws URISyntaxException where an invalid URI is encountered
  1.1305 -     * @throws ParseException where an error occurs parsing data
  1.1306 -     */
  1.1307 -    public final VEvent getOccurrence(final Date date) throws IOException,
  1.1308 -        URISyntaxException, ParseException {
  1.1309 -        
  1.1310 -        final PeriodList consumedTime = getConsumedTime(date, date);
  1.1311 -        for (final Iterator i = consumedTime.iterator(); i.hasNext();) {
  1.1312 -            final Period p = (Period) i.next();
  1.1313 -            if (p.getStart().equals(date)) {
  1.1314 -                final VEvent occurrence = (VEvent) this.copy();
  1.1315 -                occurrence.getProperties().add(new RecurrenceId(date));
  1.1316 -                return occurrence;
  1.1317 -            }
  1.1318 -        }
  1.1319 -        return null;
  1.1320 -    }
  1.1321 -    
  1.1322 -    /**
  1.1323 -     * @return the optional access classification property for an event
  1.1324 -     */
  1.1325 -    public final Clazz getClassification() {
  1.1326 -        return (Clazz) getProperty(Property.CLASS);
  1.1327 -    }
  1.1328 -
  1.1329 -    /**
  1.1330 -     * @return the optional creation-time property for an event
  1.1331 -     */
  1.1332 -    public final Created getCreated() {
  1.1333 -        return (Created) getProperty(Property.CREATED);
  1.1334 -    }
  1.1335 -
  1.1336 -    /**
  1.1337 -     * @return the optional description property for an event
  1.1338 -     */
  1.1339 -    public final Description getDescription() {
  1.1340 -        return (Description) getProperty(Property.DESCRIPTION);
  1.1341 -    }
  1.1342 -
  1.1343 -    /**
  1.1344 -     * Convenience method to pull the DTSTART out of the property list.
  1.1345 -     * @return The DtStart object representation of the start Date
  1.1346 -     */
  1.1347 -    public final DtStart getStartDate() {
  1.1348 -        return (DtStart) getProperty(Property.DTSTART);
  1.1349 -    }
  1.1350 -
  1.1351 -    /**
  1.1352 -     * @return the optional geographic position property for an event
  1.1353 -     */
  1.1354 -    public final Geo getGeographicPos() {
  1.1355 -        return (Geo) getProperty(Property.GEO);
  1.1356 -    }
  1.1357 -
  1.1358 -    /**
  1.1359 -     * @return the optional last-modified property for an event
  1.1360 -     */
  1.1361 -    public final LastModified getLastModified() {
  1.1362 -        return (LastModified) getProperty(Property.LAST_MODIFIED);
  1.1363 -    }
  1.1364 -
  1.1365 -    /**
  1.1366 -     * @return the optional location property for an event
  1.1367 -     */
  1.1368 -    public final Location getLocation() {
  1.1369 -        return (Location) getProperty(Property.LOCATION);
  1.1370 -    }
  1.1371 -
  1.1372 -    /**
  1.1373 -     * @return the optional organizer property for an event
  1.1374 -     */
  1.1375 -    public final Organizer getOrganizer() {
  1.1376 -        return (Organizer) getProperty(Property.ORGANIZER);
  1.1377 -    }
  1.1378 -
  1.1379 -    /**
  1.1380 -     * @return the optional priority property for an event
  1.1381 -     */
  1.1382 -    public final Priority getPriority() {
  1.1383 -        return (Priority) getProperty(Property.PRIORITY);
  1.1384 -    }
  1.1385 -
  1.1386 -    /**
  1.1387 -     * @return the optional date-stamp property
  1.1388 -     */
  1.1389 -    public final DtStamp getDateStamp() {
  1.1390 -        return (DtStamp) getProperty(Property.DTSTAMP);
  1.1391 -    }
  1.1392 -
  1.1393 -    /**
  1.1394 -     * @return the optional sequence number property for an event
  1.1395 -     */
  1.1396 -    public final Sequence getSequence() {
  1.1397 -        return (Sequence) getProperty(Property.SEQUENCE);
  1.1398 -    }
  1.1399 -
  1.1400 -    /**
  1.1401 -     * @return the optional status property for an event
  1.1402 -     */
  1.1403 -    public final Status getStatus() {
  1.1404 -        return (Status) getProperty(Property.STATUS);
  1.1405 -    }
  1.1406 -
  1.1407 -    /**
  1.1408 -     * @return the optional summary property for an event
  1.1409 -     */
  1.1410 -    public final Summary getSummary() {
  1.1411 -        return (Summary) getProperty(Property.SUMMARY);
  1.1412 -    }
  1.1413 -
  1.1414 -    /**
  1.1415 -     * @return the optional time transparency property for an event
  1.1416 -     */
  1.1417 -    public final Transp getTransparency() {
  1.1418 -        return (Transp) getProperty(Property.TRANSP);
  1.1419 -    }
  1.1420 -
  1.1421 -    /**
  1.1422 -     * @return the optional URL property for an event
  1.1423 -     */
  1.1424 -    public final Url getUrl() {
  1.1425 -        return (Url) getProperty(Property.URL);
  1.1426 -    }
  1.1427 -
  1.1428 -    /**
  1.1429 -     * @return the optional recurrence identifier property for an event
  1.1430 -     */
  1.1431 -    public final RecurrenceId getRecurrenceId() {
  1.1432 -        return (RecurrenceId) getProperty(Property.RECURRENCE_ID);
  1.1433 -    }
  1.1434 -
  1.1435 -    /**
  1.1436 -     * Returns the end date of this event. Where an end date is not available it will be derived from the event
  1.1437 -     * duration.
  1.1438 -     * @return a DtEnd instance, or null if one cannot be derived
  1.1439 -     */
  1.1440 -    public final DtEnd getEndDate() {
  1.1441 -        return getEndDate(true);
  1.1442 -    }
  1.1443 -
  1.1444 -    /**
  1.1445 -     * Convenience method to pull the DTEND out of the property list. If DTEND was not specified, use the DTSTART +
  1.1446 -     * DURATION to calculate it.
  1.1447 -     * @param deriveFromDuration specifies whether to derive an end date from the event duration where an end date is
  1.1448 -     * not found
  1.1449 -     * @return The end for this VEVENT.
  1.1450 -     */
  1.1451 -    public final DtEnd getEndDate(final boolean deriveFromDuration) {
  1.1452 -        DtEnd dtEnd = (DtEnd) getProperty(Property.DTEND);
  1.1453 -        // No DTEND? No problem, we'll use the DURATION.
  1.1454 -        if (dtEnd == null && deriveFromDuration && getStartDate() != null) {
  1.1455 -            final DtStart dtStart = getStartDate();
  1.1456 -            final Duration vEventDuration;
  1.1457 -            if (getDuration() != null) {
  1.1458 -                vEventDuration = getDuration();
  1.1459 -            } else if (dtStart.getDate() instanceof DateTime) {
  1.1460 -                // If "DTSTART" is a DATE-TIME, then the event's duration is zero (see: RFC 5545, 3.6.1 Event Component)
  1.1461 -                vEventDuration = new Duration(new Dur(0, 0, 0, 0));
  1.1462 -            } else {
  1.1463 -                // If "DTSTART" is a DATE, then the event's duration is one day (see: RFC 5545, 3.6.1 Event Component)
  1.1464 -                vEventDuration = new Duration(new Dur(1, 0, 0, 0));
  1.1465 -            }
  1.1466 -
  1.1467 -            dtEnd = new DtEnd(Dates.getInstance(vEventDuration.getDuration()
  1.1468 -                    .getTime(dtStart.getDate()), (Value) dtStart
  1.1469 -                    .getParameter(Parameter.VALUE)));
  1.1470 -            if (dtStart.isUtc()) {
  1.1471 -                dtEnd.setUtc(true);
  1.1472 -            }
  1.1473 -        }
  1.1474 -        return dtEnd;
  1.1475 -    }
  1.1476 -
  1.1477 -    /**
  1.1478 -     * @return the optional Duration property
  1.1479 -     */
  1.1480 -    public final Duration getDuration() {
  1.1481 -        return (Duration) getProperty(Property.DURATION);
  1.1482 -    }
  1.1483 -
  1.1484 -    /**
  1.1485 -     * Returns the UID property of this component if available.
  1.1486 -     * @return a Uid instance, or null if no UID property exists
  1.1487 -     */
  1.1488 -    public final Uid getUid() {
  1.1489 -        return (Uid) getProperty(Property.UID);
  1.1490 -    }
  1.1491 -
  1.1492 -    /**
  1.1493 -     * {@inheritDoc}
  1.1494 -     */
  1.1495 -    public boolean equals(final Object arg0) {
  1.1496 -        if (arg0 instanceof VEvent) {
  1.1497 -            return super.equals(arg0)
  1.1498 -                    && ObjectUtils.equals(alarms, ((VEvent) arg0).getAlarms());
  1.1499 -        }
  1.1500 -        return super.equals(arg0);
  1.1501 -    }
  1.1502 -
  1.1503 -    /**
  1.1504 -     * {@inheritDoc}
  1.1505 -     */
  1.1506 -    public int hashCode() {
  1.1507 -        return new HashCodeBuilder().append(getName()).append(getProperties())
  1.1508 -                .append(getAlarms()).toHashCode();
  1.1509 -    }
  1.1510 -
  1.1511 -    /**
  1.1512 -     * Overrides default copy method to add support for copying alarm sub-components.
  1.1513 -     * @return a copy of the instance
  1.1514 -     * @throws ParseException where values in the instance cannot be parsed
  1.1515 -     * @throws IOException where values in the instance cannot be read
  1.1516 -     * @throws URISyntaxException where an invalid URI value is encountered in the instance
  1.1517 -     * @see net.fortuna.ical4j.model.Component#copy()
  1.1518 -     */
  1.1519 -    public Component copy() throws ParseException, IOException,
  1.1520 -            URISyntaxException {
  1.1521 -        final VEvent copy = (VEvent) super.copy();
  1.1522 -        copy.alarms = new ComponentList(alarms);
  1.1523 -        return copy;
  1.1524 -    }
  1.1525 -}

mercurial