michael@0: /** michael@0: * Copyright (c) 2012, Ben Fortuna michael@0: * All rights reserved. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * michael@0: * o Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * michael@0: * o Redistributions in binary form must reproduce the above copyright michael@0: * notice, this list of conditions and the following disclaimer in the michael@0: * documentation and/or other materials provided with the distribution. michael@0: * michael@0: * o Neither the name of Ben Fortuna nor the names of any other contributors michael@0: * may be used to endorse or promote products derived from this software michael@0: * without specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR michael@0: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, michael@0: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, michael@0: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR michael@0: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF michael@0: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING michael@0: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS michael@0: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: */ michael@0: package net.fortuna.ical4j.model.component; michael@0: michael@0: import java.util.Iterator; michael@0: michael@0: import net.fortuna.ical4j.model.Component; michael@0: import net.fortuna.ical4j.model.ComponentList; michael@0: import net.fortuna.ical4j.model.Parameter; michael@0: import net.fortuna.ical4j.model.Property; michael@0: import net.fortuna.ical4j.model.PropertyList; michael@0: import net.fortuna.ical4j.model.ValidationException; michael@0: import net.fortuna.ical4j.model.Validator; michael@0: import net.fortuna.ical4j.model.parameter.Value; michael@0: import net.fortuna.ical4j.model.property.DtEnd; michael@0: import net.fortuna.ical4j.model.property.DtStamp; michael@0: import net.fortuna.ical4j.model.property.DtStart; michael@0: import net.fortuna.ical4j.model.property.Method; michael@0: import net.fortuna.ical4j.util.PropertyValidator; michael@0: import net.fortuna.ical4j.util.Strings; michael@0: michael@0: /** michael@0: * $Id$ [Apr 5, 2004] michael@0: * michael@0: * Defines an iCalendar VAVAILABILITY component. michael@0: * michael@0: *
michael@0: Component Name: VAVAILABILITY michael@0: michael@0: Purpose: Provide a grouping of component properties that describe michael@0: the availability associated with a calendar user. michael@0: michael@0: Format Definition: A "VAVAILABILITY" calendar component is defined michael@0: by the following notation: michael@0: michael@0: availabilityc = "BEGIN" ":" "VAVAILABILITY" CRLF michael@0: availabilityprop *availablec michael@0: "END" ":" "VAVAILABILITY" CRLF michael@0: michael@0: availabilityprop = *( michael@0: michael@0: ; the following are REQUIRED, michael@0: ; but MUST NOT occur more than once michael@0: michael@0: dtstamp / dtstart / uid michael@0: michael@0: ; the following are OPTIONAL, michael@0: ; but MUST NOT occur more than once michael@0: michael@0: busytype / created / last-mod / michael@0: organizer / seq / summary / url / michael@0: michael@0: ; either 'dtend' or 'duration' may appear michael@0: ; in a 'availabilityprop', but 'dtend' and michael@0: ; 'duration' MUST NOT occur in the same michael@0: ; 'availabilityprop' michael@0: michael@0: dtend / duration / michael@0: michael@0: ; the following are OPTIONAL, michael@0: ; and MAY occur more than once michael@0: michael@0: categories / comment / contact / x-prop michael@0: michael@0: ) michael@0: michael@0: * michael@0: *michael@0: * michael@0: * @author Ben Fortuna michael@0: * @author Mike Douglass michael@0: */ michael@0: public class VAvailability extends CalendarComponent { michael@0: michael@0: private static final long serialVersionUID = -3001603309266267258L; michael@0: michael@0: private ComponentList available; michael@0: michael@0: /** michael@0: * Default constructor. michael@0: */ michael@0: public VAvailability() { michael@0: super(VAVAILABILITY); michael@0: this.available = new ComponentList(); michael@0: getProperties().add(new DtStamp()); michael@0: } michael@0: michael@0: /** michael@0: * Constructs a new instance containing the specified properties. michael@0: * @param properties a list of properties michael@0: */ michael@0: public VAvailability(final PropertyList properties) { michael@0: super(VAVAILABILITY, properties); michael@0: this.available = new ComponentList(); michael@0: } michael@0: michael@0: /** michael@0: * Constructor. michael@0: * @param properties a list of properties michael@0: * @param available a list of available components michael@0: */ michael@0: public VAvailability(final PropertyList properties, final ComponentList available) { michael@0: super(VEVENT, properties); michael@0: this.available = available; michael@0: } michael@0: michael@0: /** michael@0: * Returns the list of available times. michael@0: * @return a component list michael@0: */ michael@0: public final ComponentList getAvailable() { michael@0: return available; michael@0: } michael@0: michael@0: /** michael@0: * {@inheritDoc} michael@0: */ michael@0: public final String toString() { michael@0: final StringBuffer b = new StringBuffer(); michael@0: b.append(BEGIN); michael@0: b.append(':'); michael@0: b.append(getName()); michael@0: b.append(Strings.LINE_SEPARATOR); michael@0: b.append(getProperties()); michael@0: b.append(getAvailable()); michael@0: b.append(END); michael@0: b.append(':'); michael@0: b.append(getName()); michael@0: b.append(Strings.LINE_SEPARATOR); michael@0: return b.toString(); michael@0: } michael@0: michael@0: /** michael@0: * {@inheritDoc} michael@0: */ michael@0: public final void validate(final boolean recurse) michael@0: throws ValidationException { michael@0: michael@0: // validate that getAvailable() only contains Available components michael@0: final Iterator iterator = getAvailable().iterator(); michael@0: while (iterator.hasNext()) { michael@0: final Component component = (Component) iterator.next(); michael@0: michael@0: if (!(component instanceof Available)) { michael@0: throw new ValidationException("Component [" michael@0: + component.getName() + "] may not occur in VAVAILABILITY"); michael@0: } michael@0: } michael@0: michael@0: /* michael@0: * ; dtstamp / dtstart / uid are required, but MUST NOT occur more than once / michael@0: */ michael@0: PropertyValidator.getInstance().assertOne(Property.DTSTART, michael@0: getProperties()); michael@0: PropertyValidator.getInstance().assertOne(Property.DTSTAMP, michael@0: getProperties()); michael@0: PropertyValidator.getInstance().assertOne(Property.UID, michael@0: getProperties()); michael@0: michael@0: /* If specified, the "DTSTART" and "DTEND" properties in michael@0: * "VAVAILABILITY" components and "AVAILABLE" sub-components MUST be michael@0: * "DATE-TIME" values specified as either date with UTC time or date michael@0: * with local time and a time zone reference. michael@0: */ michael@0: final DtStart start = (DtStart) getProperty(Property.DTSTART); michael@0: if (Value.DATE.equals(start.getParameter(Parameter.VALUE))) { michael@0: throw new ValidationException("Property [" + Property.DTSTART michael@0: + "] must be a " + Value.DATE_TIME); michael@0: } michael@0: michael@0: /* michael@0: * ; either 'dtend' or 'duration' may appear in ; a 'eventprop', but 'dtend' and 'duration' ; MUST NOT occur in michael@0: * the same 'eventprop' dtend / duration / michael@0: */ michael@0: if (getProperty(Property.DTEND) != null) { michael@0: PropertyValidator.getInstance().assertOne(Property.DTEND, michael@0: getProperties()); michael@0: /* Must be DATE_TIME */ michael@0: final DtEnd end = (DtEnd) getProperty(Property.DTEND); michael@0: if (Value.DATE.equals(end.getParameter(Parameter.VALUE))) { michael@0: throw new ValidationException("Property [" + Property.DTEND michael@0: + "] must be a " + Value.DATE_TIME); michael@0: } michael@0: michael@0: if (getProperty(Property.DURATION) != null) { michael@0: throw new ValidationException("Only one of Property [" + Property.DTEND michael@0: + "] or [" + Property.DURATION + michael@0: " must appear a VAVAILABILITY"); michael@0: } michael@0: } michael@0: michael@0: /* michael@0: * ; the following are optional, michael@0: * ; but MUST NOT occur more than once michael@0: * michael@0: * busytype / created / last-mod / michael@0: * organizer / seq / summary / url / michael@0: */ michael@0: PropertyValidator.getInstance().assertOneOrLess(Property.BUSYTYPE, michael@0: getProperties()); michael@0: PropertyValidator.getInstance().assertOneOrLess(Property.CREATED, michael@0: getProperties()); michael@0: PropertyValidator.getInstance().assertOneOrLess(Property.LAST_MODIFIED, michael@0: getProperties()); michael@0: PropertyValidator.getInstance().assertOneOrLess(Property.ORGANIZER, michael@0: getProperties()); michael@0: PropertyValidator.getInstance().assertOneOrLess(Property.SEQUENCE, michael@0: getProperties()); michael@0: PropertyValidator.getInstance().assertOneOrLess(Property.SUMMARY, michael@0: getProperties()); michael@0: PropertyValidator.getInstance().assertOneOrLess(Property.URL, michael@0: getProperties()); michael@0: michael@0: /* michael@0: * ; the following are optional, ; and MAY occur more than once michael@0: * categories / comment / contact / x-prop michael@0: */ michael@0: michael@0: if (recurse) { michael@0: validateProperties(); michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * {@inheritDoc} michael@0: */ michael@0: protected Validator getValidator(Method method) { michael@0: // TODO Auto-generated method stub michael@0: return null; michael@0: } michael@0: }