/*
* $Id: Property.java,v 1.17 2006/04/05 10:52:00 fortuna Exp $ [Apr 5, 2004]
*
* Copyright (c) 2004, Ben Fortuna
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* o Neither the name of Ben Fortuna nor the names of any other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.fortuna.ical4j.model;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.ParseException;
import net.fortuna.ical4j.util.Strings;
/**
* Defines an iCalendar property. Subclasses of this class provide additional
* validation and typed values for specific iCalendar properties.
*
* @author Ben Fortuna
*/
public abstract class Property extends Content {
// iCalendar properties..
/**
* 'prodid' and 'version' are both REQUIRED, but MUST NOT occur more than
* once.
*/
public static final String PRODID = "PRODID";
public static final String VERSION = "VERSION";
/**
* 'calscale' and 'method' are optional, but MUST NOT occur more than once.
*/
public static final String CALSCALE = "CALSCALE";
public static final String METHOD = "METHOD";
// Component properties..
/**
* the following are optional, but MUST NOT occur more than once.
*/
public static final String CLASS = "CLASS";
public static final String CREATED = "CREATED";
public static final String DESCRIPTION = "DESCRIPTION";
public static final String DTSTART = "DTSTART";
public static final String GEO = "GEO";
public static final String LAST_MODIFIED = "LAST-MODIFIED";
public static final String LOCATION = "LOCATION";
public static final String ORGANIZER = "ORGANIZER";
public static final String PERCENT_COMPLETE = "PERCENT-COMPLETE";
public static final String PRIORITY = "PRIORITY";
public static final String DTSTAMP = "DTSTAMP";
public static final String SEQUENCE = "SEQUENCE";
public static final String STATUS = "STATUS";
public static final String SUMMARY = "SUMMARY";
public static final String TRANSP = "TRANSP";
public static final String UID = "UID";
public static final String URL = "URL";
public static final String RECURRENCE_ID = "RECURRENCE-ID";
public static final String COMPLETED = "COMPLETED";
public static final String DUE = "DUE";
public static final String FREEBUSY = "FREEBUSY";
public static final String TZID = "TZID";
public static final String TZNAME = "TZNAME";
public static final String TZOFFSETFROM = "TZOFFSETFROM";
public static final String TZOFFSETTO = "TZOFFSETTO";
public static final String TZURL = "TZURL";
public static final String ACTION = "ACTION";
public static final String REPEAT = "REPEAT";
public static final String TRIGGER = "TRIGGER";
public static final String REQUEST_STATUS = "REQUEST-STATUS";
/**
* either 'dtend' or 'duration' may appear in a 'eventprop', but 'dtend' and
* 'duration' MUST NOT occur in the same 'eventprop'.
*/
public static final String DTEND = "DTEND";
public static final String DURATION = "DURATION";
/**
* the following are optional, and MAY occur more than once.
*/
public static final String ATTACH = "ATTACH";
public static final String ATTENDEE = "ATTENDEE";
public static final String CATEGORIES = "CATEGORIES";
public static final String COMMENT = "COMMENT";
public static final String CONTACT = "CONTACT";
public static final String EXDATE = "EXDATE";
public static final String EXRULE = "EXRULE";
public static final String RELATED_TO = "RELATED-TO";
public static final String RESOURCES = "RESOURCES";
public static final String RDATE = "RDATE";
public static final String RRULE = "RRULE";
public static final String EXPERIMENTAL_PREFIX = "X-";
private String name;
private ParameterList parameters;
/**
* Constructor.
* @param aName
* property name
*/
protected Property(final String aName) {
this(aName, new ParameterList());
}
/**
* Constructor made protected to enforce the use of
* <code>PropertyFactory</code> for property instantiation.
* @param aName
* property name
* @param aList
* a list of parameters
*/
protected Property(final String aName, final ParameterList aList) {
this.name = aName;
this.parameters = aList;
}
/**
* Creates a deep copy of the specified property. That is, the name,
* parameter list, and value are duplicated from the specified property.
* This constructor should only be called from sub-classes to ensure
* type integrity is maintained.
* @param property a property to copy
* @throws URISyntaxException
*/
protected Property(final Property property) throws IOException, URISyntaxException, ParseException {
this.name = property.getName();
this.parameters = new ParameterList(property.getParameters(), false);
setValue(property.getValue());
}
/**
* @see java.lang.Object#toString()
*/
public final String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getName());
buffer.append(getParameters());
buffer.append(':');
if (this instanceof Escapable) {
buffer.append(Strings.escape(Strings.valueOf(getValue())));
}
else {
buffer.append(Strings.valueOf(getValue()));
}
buffer.append(Strings.LINE_SEPARATOR);
return buffer.toString();
}
/**
* Indicates whether this property is a
* calendar property.
* @return boolean
*/
public boolean isCalendarProperty() {
return PRODID.equalsIgnoreCase(getName()) || VERSION.equalsIgnoreCase(getName())
|| CALSCALE.equalsIgnoreCase(getName()) || METHOD.equalsIgnoreCase(getName());
}
/**
* Indicates whether this property is a
* component property.
* @return boolean
*/
public final boolean isComponentProperty() {
return false;
}
/**
* @return Returns the name.
*/
public final String getName() {
return name;
}
/**
* @return Returns the parameters.
*/
public final ParameterList getParameters() {
return parameters;
}
/**
* Convenience method for retrieving a list of named parameters.
* @param name name of parameters to retrieve
* @return a parameter list containing only parameters with the specified
* name
*/
public final ParameterList getParameters(final String name) {
return getParameters().getParameters(name);
}
/**
* Convenience method for retrieving a single parameter.
* @param name name of the parameter to retrieve
* @return the first parameter from the parameter list with the specified
* name
*/
public final Parameter getParameter(final String name) {
return getParameters().getParameter(name);
}
/**
* Sets the current value of the property.
* @param aValue a string representation of the property
* value
* @throws IOException possibly thrown by setting the value
* of certain properties
* @throws URISyntaxException possibly thrown by setting the value
* of certain properties
* @throws ParseException possibly thrown by setting the value
* of certain properties
*/
public abstract void setValue(String aValue) throws IOException, URISyntaxException, ParseException;
/**
* @return Returns the value.
*/
public abstract String getValue();
/**
* Perform validation on a property.
*
* @throws ValidationException
* where the property is not in a valid state
*/
public abstract void validate() throws ValidationException;
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
/**
* Two properties are equal if and only if their
* name, value and parameter list are equal.
* @see java.lang.Object#equals(java.lang.Object)
*/
public final boolean equals(final Object arg0) {
if (arg0 instanceof Property) {
Property p = (Property) arg0;
return getName().equals(p.getName())
&& ((getValue() != null && getValue().equals(p.getValue()))
|| p.getValue() == null)
&& getParameters().equals(p.getParameters());
}
return super.equals(arg0);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
public final int hashCode() {
// as property name is case-insensitive generate hash for uppercase..
return getName().toUpperCase().hashCode()
+ getValue().hashCode()
+ getParameters().hashCode();
}
}