src/net/fortuna/ical4j/model/Property.java

Tue, 10 Feb 2015 19:58:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 10 Feb 2015 19:58:00 +0100
changeset 4
45d57ecba757
parent 0
fb9019fb1bf7
permissions
-rw-r--r--

Upgrade the upgraded ical4j component to use org.apache.commons.lang3.

michael@0 1 /**
michael@0 2 * Copyright (c) 2012, Ben Fortuna
michael@0 3 * All rights reserved.
michael@0 4 *
michael@0 5 * Redistribution and use in source and binary forms, with or without
michael@0 6 * modification, are permitted provided that the following conditions
michael@0 7 * are met:
michael@0 8 *
michael@0 9 * o Redistributions of source code must retain the above copyright
michael@0 10 * notice, this list of conditions and the following disclaimer.
michael@0 11 *
michael@0 12 * o Redistributions in binary form must reproduce the above copyright
michael@0 13 * notice, this list of conditions and the following disclaimer in the
michael@0 14 * documentation and/or other materials provided with the distribution.
michael@0 15 *
michael@0 16 * o Neither the name of Ben Fortuna nor the names of any other contributors
michael@0 17 * may be used to endorse or promote products derived from this software
michael@0 18 * without specific prior written permission.
michael@0 19 *
michael@0 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
michael@0 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
michael@0 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
michael@0 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
michael@0 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
michael@0 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
michael@0 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
michael@0 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 31 */
michael@0 32 package net.fortuna.ical4j.model;
michael@0 33
michael@0 34 import java.io.IOException;
michael@0 35 import java.net.URISyntaxException;
michael@0 36 import java.text.ParseException;
michael@0 37 import net.fortuna.ical4j.model.parameter.Value;
michael@0 38 import net.fortuna.ical4j.model.property.XProperty;
michael@0 39
michael@0 40 import net.fortuna.ical4j.util.Strings;
michael@0 41
michael@4 42 import org.apache.commons.lang3.builder.EqualsBuilder;
michael@4 43 import org.apache.commons.lang3.builder.HashCodeBuilder;
michael@0 44
michael@0 45 /**
michael@0 46 * Defines an iCalendar property. Subclasses of this class provide additional validation and typed values for specific
michael@0 47 * iCalendar properties.
michael@0 48 *
michael@0 49 * Note that subclasses must provide a reference to the factory used to create the
michael@0 50 * property to support property cloning (copy). If no factory is specified an
michael@0 51 * {@link UnsupportedOperationException} will be thrown by the {@link #copy()} method.
michael@0 52 *
michael@0 53 * @author Ben Fortuna
michael@0 54 *
michael@0 55 * $Id$ [Apr 5, 2004]
michael@0 56 */
michael@0 57 public abstract class Property extends Content {
michael@0 58
michael@0 59 private static final long serialVersionUID = 7048785558435608687L;
michael@0 60
michael@0 61 // iCalendar properties..
michael@0 62
michael@0 63 /**
michael@0 64 * Product identifier property name.
michael@0 65 */
michael@0 66 public static final String PRODID = "PRODID";
michael@0 67
michael@0 68 /**
michael@0 69 * iCalendar version property name.
michael@0 70 */
michael@0 71 public static final String VERSION = "VERSION";
michael@0 72
michael@0 73 /**
michael@0 74 * Calendar scale property name.
michael@0 75 */
michael@0 76 public static final String CALSCALE = "CALSCALE";
michael@0 77
michael@0 78 /**
michael@0 79 * iTIP method property name.
michael@0 80 */
michael@0 81 public static final String METHOD = "METHOD";
michael@0 82
michael@0 83 // Component properties..
michael@0 84
michael@0 85 /**
michael@0 86 * Busy type property name.
michael@0 87 */
michael@0 88 public static final String BUSYTYPE = "BUSYTYPE";
michael@0 89
michael@0 90 /**
michael@0 91 * Classifier property name.
michael@0 92 */
michael@0 93 public static final String CLASS = "CLASS";
michael@0 94
michael@0 95 /**
michael@0 96 * Creation date property name.
michael@0 97 */
michael@0 98 public static final String CREATED = "CREATED";
michael@0 99
michael@0 100 /**
michael@0 101 * Description property name.
michael@0 102 */
michael@0 103 public static final String DESCRIPTION = "DESCRIPTION";
michael@0 104
michael@0 105 /**
michael@0 106 * Start date property name.
michael@0 107 */
michael@0 108 public static final String DTSTART = "DTSTART";
michael@0 109
michael@0 110 /**
michael@0 111 * Geographic location property name.
michael@0 112 */
michael@0 113 public static final String GEO = "GEO";
michael@0 114
michael@0 115 /**
michael@0 116 * Last modified date property name.
michael@0 117 */
michael@0 118 public static final String LAST_MODIFIED = "LAST-MODIFIED";
michael@0 119
michael@0 120 /**
michael@0 121 * Location property name.
michael@0 122 */
michael@0 123 public static final String LOCATION = "LOCATION";
michael@0 124
michael@0 125 /**
michael@0 126 * Organiser property name.
michael@0 127 */
michael@0 128 public static final String ORGANIZER = "ORGANIZER";
michael@0 129
michael@0 130 /**
michael@0 131 * Percentage complete property name.
michael@0 132 */
michael@0 133 public static final String PERCENT_COMPLETE = "PERCENT-COMPLETE";
michael@0 134
michael@0 135 /**
michael@0 136 * Prority property name.
michael@0 137 */
michael@0 138 public static final String PRIORITY = "PRIORITY";
michael@0 139
michael@0 140 /**
michael@0 141 * Date-stamp property name.
michael@0 142 */
michael@0 143 public static final String DTSTAMP = "DTSTAMP";
michael@0 144
michael@0 145 /**
michael@0 146 * Sequence property name.
michael@0 147 */
michael@0 148 public static final String SEQUENCE = "SEQUENCE";
michael@0 149
michael@0 150 /**
michael@0 151 * Status property name.
michael@0 152 */
michael@0 153 public static final String STATUS = "STATUS";
michael@0 154
michael@0 155 /**
michael@0 156 * Summary property name.
michael@0 157 */
michael@0 158 public static final String SUMMARY = "SUMMARY";
michael@0 159
michael@0 160 /**
michael@0 161 * Transparency property name.
michael@0 162 */
michael@0 163 public static final String TRANSP = "TRANSP";
michael@0 164
michael@0 165 /**
michael@0 166 * Unique identifier property name.
michael@0 167 */
michael@0 168 public static final String UID = "UID";
michael@0 169
michael@0 170 /**
michael@0 171 * Uniform resource locator property name.
michael@0 172 */
michael@0 173 public static final String URL = "URL";
michael@0 174
michael@0 175 /**
michael@0 176 * Recurrence identifier property name.
michael@0 177 */
michael@0 178 public static final String RECURRENCE_ID = "RECURRENCE-ID";
michael@0 179
michael@0 180 /**
michael@0 181 * Completed date property name.
michael@0 182 */
michael@0 183 public static final String COMPLETED = "COMPLETED";
michael@0 184
michael@0 185 /**
michael@0 186 * Due date property name.
michael@0 187 */
michael@0 188 public static final String DUE = "DUE";
michael@0 189
michael@0 190 /**
michael@0 191 * Free/busy property name.
michael@0 192 */
michael@0 193 public static final String FREEBUSY = "FREEBUSY";
michael@0 194
michael@0 195 /**
michael@0 196 * Timezone identifier property name.
michael@0 197 */
michael@0 198 public static final String TZID = "TZID";
michael@0 199
michael@0 200 /**
michael@0 201 * Timezone name property name.
michael@0 202 */
michael@0 203 public static final String TZNAME = "TZNAME";
michael@0 204
michael@0 205 /**
michael@0 206 * Prior timezone offset property name.
michael@0 207 */
michael@0 208 public static final String TZOFFSETFROM = "TZOFFSETFROM";
michael@0 209
michael@0 210 /**
michael@0 211 * New timezone offset property name.
michael@0 212 */
michael@0 213 public static final String TZOFFSETTO = "TZOFFSETTO";
michael@0 214
michael@0 215 /**
michael@0 216 * URL for timezone definition property name.
michael@0 217 */
michael@0 218 public static final String TZURL = "TZURL";
michael@0 219
michael@0 220 /**
michael@0 221 * Alarm action property name.
michael@0 222 */
michael@0 223 public static final String ACTION = "ACTION";
michael@0 224
michael@0 225 /**
michael@0 226 * Repeat rule property name.
michael@0 227 */
michael@0 228 public static final String REPEAT = "REPEAT";
michael@0 229
michael@0 230 /**
michael@0 231 * Alarm trigger property name.
michael@0 232 */
michael@0 233 public static final String TRIGGER = "TRIGGER";
michael@0 234
michael@0 235 /**
michael@0 236 * Request status property name.
michael@0 237 */
michael@0 238 public static final String REQUEST_STATUS = "REQUEST-STATUS";
michael@0 239
michael@0 240 /**
michael@0 241 * End date property name.
michael@0 242 */
michael@0 243 public static final String DTEND = "DTEND";
michael@0 244
michael@0 245 /**
michael@0 246 * Duration property name.
michael@0 247 */
michael@0 248 public static final String DURATION = "DURATION";
michael@0 249
michael@0 250 /**
michael@0 251 * Attachment property name.
michael@0 252 */
michael@0 253 public static final String ATTACH = "ATTACH";
michael@0 254
michael@0 255 /**
michael@0 256 * Attendee property name.
michael@0 257 */
michael@0 258 public static final String ATTENDEE = "ATTENDEE";
michael@0 259
michael@0 260 /**
michael@0 261 * Categories property name.
michael@0 262 */
michael@0 263 public static final String CATEGORIES = "CATEGORIES";
michael@0 264
michael@0 265 /**
michael@0 266 * Comment property name.
michael@0 267 */
michael@0 268 public static final String COMMENT = "COMMENT";
michael@0 269
michael@0 270 /**
michael@0 271 * Contact property name.
michael@0 272 */
michael@0 273 public static final String CONTACT = "CONTACT";
michael@0 274
michael@0 275 /**
michael@0 276 * Exclusion date property name.
michael@0 277 */
michael@0 278 public static final String EXDATE = "EXDATE";
michael@0 279
michael@0 280 /**
michael@0 281 * Exclusion rule property name.
michael@0 282 */
michael@0 283 public static final String EXRULE = "EXRULE";
michael@0 284
michael@0 285 /**
michael@0 286 * Relationship property name.
michael@0 287 */
michael@0 288 public static final String RELATED_TO = "RELATED-TO";
michael@0 289
michael@0 290 /**
michael@0 291 * Resources property name.
michael@0 292 */
michael@0 293 public static final String RESOURCES = "RESOURCES";
michael@0 294
michael@0 295 /**
michael@0 296 * Recurrence date property name.
michael@0 297 */
michael@0 298 public static final String RDATE = "RDATE";
michael@0 299
michael@0 300 /**
michael@0 301 * Recurrence rule property name.
michael@0 302 */
michael@0 303 public static final String RRULE = "RRULE";
michael@0 304
michael@0 305 /**
michael@0 306 * Prefix for non-standard properties.
michael@0 307 */
michael@0 308 public static final String EXPERIMENTAL_PREFIX = "X-";
michael@0 309
michael@0 310 /**
michael@0 311 * VVENUE country property name.
michael@0 312 */
michael@0 313 public static final String COUNTRY = "COUNTRY";
michael@0 314
michael@0 315 /**
michael@0 316 * VVENUE extended address property name.
michael@0 317 */
michael@0 318 public static final String EXTENDED_ADDRESS = "EXTENDED-ADDRESS";
michael@0 319
michael@0 320 /**
michael@0 321 * VVENUE locality property name.
michael@0 322 */
michael@0 323 public static final String LOCALITY = "LOCALITY";
michael@0 324
michael@0 325 /**
michael@0 326 * VVENUE location type property name.
michael@0 327 */
michael@0 328 public static final String LOCATION_TYPE = "LOCATION-TYPE";
michael@0 329
michael@0 330 /**
michael@0 331 * VVENUE name property name.
michael@0 332 */
michael@0 333 public static final String NAME = "NAME";
michael@0 334
michael@0 335 /**
michael@0 336 * VVENUE postal code property name.
michael@0 337 */
michael@0 338 public static final String POSTALCODE = "POSTAL-CODE";
michael@0 339
michael@0 340 /**
michael@0 341 * VVENUE region property name.
michael@0 342 */
michael@0 343 public static final String REGION = "REGION";
michael@0 344
michael@0 345 /**
michael@0 346 * VVENUE street address property name.
michael@0 347 */
michael@0 348 public static final String STREET_ADDRESS = "STREET-ADDRESS";
michael@0 349
michael@0 350 /**
michael@0 351 * VVENUE telephone property name.
michael@0 352 */
michael@0 353 public static final String TEL = "TEL";
michael@0 354
michael@0 355 private String name;
michael@0 356
michael@0 357 private ParameterList parameters;
michael@0 358
michael@0 359 private final PropertyFactory factory;
michael@0 360
michael@0 361 /**
michael@0 362 * Constructor.
michael@0 363 * @param aName property name
michael@0 364 * @param factory the factory used to create the property instance
michael@0 365 */
michael@0 366 protected Property(final String aName, PropertyFactory factory) {
michael@0 367 this(aName, new ParameterList(), factory);
michael@0 368 }
michael@0 369
michael@0 370 /**
michael@0 371 * Constructor made protected to enforce the use of <code>PropertyFactory</code> for property instantiation.
michael@0 372 * @param aName property name
michael@0 373 * @param aList a list of parameters
michael@0 374 */
michael@0 375 // protected Property(final String aName, final ParameterList aList) {
michael@0 376 // this(aName, aList, PropertyFactoryImpl.getInstance());
michael@0 377 // }
michael@0 378
michael@0 379 /**
michael@0 380 * @param aName a property identifier
michael@0 381 * @param aList a list of initial parameters
michael@0 382 * @param factory the factory used to create the property instance
michael@0 383 */
michael@0 384 protected Property(final String aName, final ParameterList aList, PropertyFactory factory) {
michael@0 385 this.name = aName;
michael@0 386 this.parameters = aList;
michael@0 387 this.factory = factory;
michael@0 388 }
michael@0 389
michael@0 390 /**
michael@0 391 * Creates a deep copy of the specified property. That is, the name, parameter list, and value are duplicated from
michael@0 392 * the specified property. This constructor should only be called from sub-classes to ensure type integrity is
michael@0 393 * maintained.
michael@0 394 * @param property a property to copy
michael@0 395 * @throws URISyntaxException where the specified property contains an invalid URI value
michael@0 396 * @throws ParseException where the specified property has invalid data
michael@0 397 * @throws IOException where an error occurs reading data from the specified property
michael@0 398 * @deprecated Use {@link #copy()} instead
michael@0 399 */
michael@0 400 protected Property(final Property property) throws IOException,
michael@0 401 URISyntaxException, ParseException {
michael@0 402 this(property.getName(), new ParameterList(property.getParameters(), false),
michael@0 403 property.factory);
michael@0 404 setValue(property.getValue());
michael@0 405 }
michael@0 406
michael@0 407 /**
michael@0 408 * {@inheritDoc}
michael@0 409 */
michael@0 410 public final String toString() {
michael@0 411 final StringBuffer buffer = new StringBuffer();
michael@0 412 buffer.append(getName());
michael@0 413 if (getParameters() != null) {
michael@0 414 buffer.append(getParameters());
michael@0 415 }
michael@0 416 buffer.append(':');
michael@0 417 boolean needsEscape = false;
michael@0 418 if (this instanceof XProperty) {
michael@0 419 Value valParam = (Value)getParameter(Parameter.VALUE);
michael@0 420 if (valParam == null || valParam.equals(Value.TEXT)) {
michael@0 421 needsEscape = true;
michael@0 422 }
michael@0 423 } else if (this instanceof Escapable) {
michael@0 424 needsEscape = true;
michael@0 425 }
michael@0 426 if (needsEscape) {
michael@0 427 buffer.append(Strings.escape(Strings.valueOf(getValue())));
michael@0 428 }
michael@0 429 else {
michael@0 430 buffer.append(Strings.valueOf(getValue()));
michael@0 431 }
michael@0 432 buffer.append(Strings.LINE_SEPARATOR);
michael@0 433
michael@0 434 return buffer.toString();
michael@0 435 }
michael@0 436
michael@0 437 /**
michael@0 438 * Indicates whether this property is a calendar property.
michael@0 439 * @return boolean
michael@0 440 */
michael@0 441 public boolean isCalendarProperty() {
michael@0 442
michael@0 443 return PRODID.equalsIgnoreCase(getName())
michael@0 444 || VERSION.equalsIgnoreCase(getName())
michael@0 445 || CALSCALE.equalsIgnoreCase(getName())
michael@0 446 || METHOD.equalsIgnoreCase(getName());
michael@0 447 }
michael@0 448
michael@0 449 /**
michael@0 450 * @return Returns the name.
michael@0 451 */
michael@0 452 public final String getName() {
michael@0 453 return name;
michael@0 454 }
michael@0 455
michael@0 456 /**
michael@0 457 * @return Returns the parameters.
michael@0 458 */
michael@0 459 public final ParameterList getParameters() {
michael@0 460 return parameters;
michael@0 461 }
michael@0 462
michael@0 463 /**
michael@0 464 * Convenience method for retrieving a list of named parameters.
michael@0 465 * @param name name of parameters to retrieve
michael@0 466 * @return a parameter list containing only parameters with the specified name
michael@0 467 */
michael@0 468 public final ParameterList getParameters(final String name) {
michael@0 469 return getParameters().getParameters(name);
michael@0 470 }
michael@0 471
michael@0 472 /**
michael@0 473 * Convenience method for retrieving a single parameter.
michael@0 474 * @param name name of the parameter to retrieve
michael@0 475 * @return the first parameter from the parameter list with the specified name
michael@0 476 */
michael@0 477 public final Parameter getParameter(final String name) {
michael@0 478 return getParameters().getParameter(name);
michael@0 479 }
michael@0 480
michael@0 481 /**
michael@0 482 * Sets the current value of the property.
michael@0 483 * @param aValue a string representation of the property value
michael@0 484 * @throws IOException possibly thrown by setting the value of certain properties
michael@0 485 * @throws URISyntaxException possibly thrown by setting the value of certain properties
michael@0 486 * @throws ParseException possibly thrown by setting the value of certain properties
michael@0 487 */
michael@0 488 public abstract void setValue(String aValue) throws IOException,
michael@0 489 URISyntaxException, ParseException;
michael@0 490
michael@0 491 /**
michael@0 492 * Perform validation on a property.
michael@0 493 * @throws ValidationException where the property is not in a valid state
michael@0 494 */
michael@0 495 public abstract void validate() throws ValidationException;
michael@0 496
michael@0 497 /**
michael@0 498 * {@inheritDoc}
michael@0 499 */
michael@0 500 public final boolean equals(final Object arg0) {
michael@0 501 if (arg0 instanceof Property) {
michael@0 502 final Property p = (Property) arg0;
michael@0 503 if (getName().equals(p.getName())) {
michael@0 504 return new EqualsBuilder().append(getValue(), p.getValue())
michael@0 505 .append(getParameters(), p.getParameters()).isEquals();
michael@0 506 } else {
michael@0 507 return false;
michael@0 508 }
michael@0 509 }
michael@0 510 return super.equals(arg0);
michael@0 511 }
michael@0 512
michael@0 513 /**
michael@0 514 * {@inheritDoc}
michael@0 515 */
michael@0 516 public int hashCode() {
michael@0 517 // as property name is case-insensitive generate hash for uppercase..
michael@0 518 return new HashCodeBuilder().append(getName().toUpperCase()).append(
michael@0 519 getValue()).append(getParameters()).toHashCode();
michael@0 520 }
michael@0 521
michael@0 522 /**
michael@0 523 * Create a (deep) copy of this property.
michael@0 524 * @return the copy of the property
michael@0 525 * @throws IOException where an error occurs reading property data
michael@0 526 * @throws URISyntaxException where the property contains an invalid URI value
michael@0 527 * @throws ParseException where the property contains an invalid date value
michael@0 528 */
michael@0 529 public Property copy() throws IOException, URISyntaxException, ParseException {
michael@0 530 if (factory == null) {
michael@0 531 throw new UnsupportedOperationException("No factory specified");
michael@0 532 }
michael@0 533 // Deep copy parameter list..
michael@0 534 final ParameterList params = new ParameterList(getParameters(), false);
michael@0 535 return factory.createProperty(getName(), params, getValue());
michael@0 536 }
michael@0 537 }

mercurial