Java tutorial
/** * Copyright 2011 Caleb Richardson * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.outerspacecat.icalendar; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.outerspacecat.util.ContentSource; import java.io.Serializable; import java.util.Collection; import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.ThreadSafe; /** * A representation of an iCalendar VALARM component defined by <a * href="http://tools.ietf.org/html/rfc5545">RFC 5545</a>. * <p> * {@link #getRepeat()} and {@link #getDuration()} must both return non * {@code null}, or both return {@code null}. * * @author Caleb Richardson */ @Immutable @ThreadSafe public final class VAlarm implements HasComponent, Serializable { private final static long serialVersionUID = 1L; @SuppressWarnings("unused") private final static ImmutableSet<String> RESTRICTED_PROPERTY_NAMES = ImmutableSet.of("ACTION", "TRIGGER", "REPEAT", "DURATION", "DESCRIPTION", "SUMMARY", "ATTENDEE"); private final TypedProperty<TextType> action; private final Trigger trigger; private final TypedProperty<Integer> repeat; private final TypedProperty<DurationType> duration; private final TypedProperty<TextType> description; private final TypedProperty<TextType> summary; private final ImmutableSet<ContentSource> attachments; private final ImmutableSet<Attendee> attendees; private final ImmutableMultimap<String, Property> extraProperties; /** * Creates a new alarm. * * @param action the action of the alarm. Must be non {@code null}. * @param trigger the trigger of the alarm. Must be non {@code null}. */ public VAlarm(final TypedProperty<TextType> action, final Trigger trigger, final TypedProperty<Integer> repeat, final TypedProperty<DurationType> duration, final TypedProperty<TextType> description, final TypedProperty<TextType> summary, final Collection<ContentSource> attachments, final Collection<Attendee> attendees, final Iterable<Property> extraProperties) { Preconditions.checkNotNull(action, "action required"); Preconditions.checkNotNull(trigger, "trigger required"); Preconditions.checkNotNull(attachments, "attachments required"); for (ContentSource attachment : attachments) Preconditions.checkNotNull(attachment, "all attachments must be non null"); Preconditions.checkNotNull(attendees, "attendees required"); for (Attendee attendee : attendees) Preconditions.checkNotNull(attendee, "all attendees must be non null"); Preconditions.checkNotNull(extraProperties, "extraProperties required"); for (Property extraProperty : extraProperties) Preconditions.checkNotNull(extraProperty, "all extra properties must be non null"); if (action.getValue().getValue().equalsIgnoreCase("AUDIO")) { Preconditions.checkArgument(description == null, "description must be null"); Preconditions.checkArgument(summary == null, "summary must be null"); Preconditions.checkArgument(attachments.size() <= 1, "attachments must be empty or contain exactly one element"); Preconditions.checkArgument(attendees.isEmpty(), "attendees must be empty"); } else if (action.getValue().getValue().equalsIgnoreCase("DISPLAY")) { Preconditions.checkNotNull(description, "description required"); Preconditions.checkArgument(attachments.isEmpty(), "attachments must be empty"); } else if (action.getValue().getValue().equalsIgnoreCase("EMAIL")) { Preconditions.checkNotNull(description, "description required"); Preconditions.checkNotNull(summary, "summary required"); Preconditions.checkArgument(!attendees.isEmpty(), "attendees must be non empty"); } Preconditions.checkArgument((repeat == null) == (duration == null), "repeat and duration must be specified together"); this.action = action; this.trigger = trigger; this.repeat = repeat; this.duration = duration; this.description = description; this.summary = summary; this.attachments = ImmutableSet.copyOf(attachments); this.attendees = ImmutableSet.copyOf(attendees); ImmutableMultimap.Builder<String, Property> extraPropertiesBuilder = ImmutableMultimap.builder(); for (Property prop : extraProperties) extraPropertiesBuilder.put(prop.getName().getName(), prop); this.extraProperties = extraPropertiesBuilder.build(); } /** * Parses an alarm component. * * @param comp the component to parse. Must be non {@code null}. * @return an alarm. Never {@code null}. * @throws CalendarParseException if {@code comp} does not represent a valid * time zone */ public static VAlarm parse(final Component comp) throws CalendarParseException { Preconditions.checkNotNull(comp, "comp required"); Preconditions.checkArgument(comp.getName().equals("VALARM"), "component name must be VALARM, saw: " + comp.getName()); return null; } /** * Returns the action of this alarm. * * @return the action of this alarm. Never {@code null}. */ public TypedProperty<TextType> getAction() { return action; } /** * Returns the trigger of this alarm. * * @return the trigger of this alarm. Never {@code null}. */ public Trigger getTrigger() { return trigger; } /** * Returns the repeat of this alarm. * * @return the repeat of this alarm. May be {@code null}. */ public TypedProperty<Integer> getRepeat() { return repeat; } /** * Returns the duration of this alarm. * * @return the duration of this alarm. May be {@code null}. */ public TypedProperty<DurationType> getDuration() { return duration; } /** * Returns the description of this alarm. * * @return the description of this alarm. May be {@code null}. */ public TypedProperty<TextType> getDescription() { return description; } /** * Returns the summary of this alarm. * * @return the summary of this alarm. May be {@code null}. */ public TypedProperty<TextType> getSummary() { return summary; } /** * Returns the attachments of this alarm. * * @return the attachments of this alarm. Never {@code null}, may be empty. */ public ImmutableSet<ContentSource> getAttachments() { return attachments; } /** * Returns the attendees of this alarm. * * @return the attendees of this alarm. Never {@code null}, may be empty. */ public ImmutableSet<Attendee> getAttendees() { return attendees; } /** * Returns the extra properties of this alarm. * * @return the extra parameters of this alarm. Never {@code null}, may be * empty. */ public ImmutableMultimap<String, Property> getExtraProperties() { return extraProperties; } @Override public Component toComponent(final HasTimeZones timeZones) { Preconditions.checkNotNull(timeZones, "timeZones required"); Component.Builder builder = new Component.Builder(); builder.setName("ALARM"); for (Property prop : getExtraProperties().values()) builder.addProperty(prop); return builder.build(); } @Override public int hashCode() { return Objects.hashCode(getAction(), getTrigger(), getRepeat(), getDuration(), getDescription(), getSummary(), getAttachments(), getAttendees()); } @Override public boolean equals(final Object obj) { return obj instanceof VAlarm && Objects.equal(getAction(), ((VAlarm) obj).getAction()) && Objects.equal(getTrigger(), ((VAlarm) obj).getTrigger()) && Objects.equal(getRepeat(), ((VAlarm) obj).getRepeat()) && Objects.equal(getDuration(), ((VAlarm) obj).getDuration()) && Objects.equal(getDescription(), ((VAlarm) obj).getDescription()) && Objects.equal(getSummary(), ((VAlarm) obj).getSummary()) && Objects.equal(getAttachments(), ((VAlarm) obj).getAttachments()) && Objects.equal(getAttendees(), ((VAlarm) obj).getAttendees()); } }