/**
* Licensed to Apereo under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright ownership. Apereo
* licenses this file to you 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 the
* following location:
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>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 org.jasig.portlet.calendar.mvc;
import net.fortuna.ical4j.model.component.VEvent;
import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.format.DateTimeFormatter;
/**
* Object that summarizes the portion of an event on a specific day. If the event spans multiple
* days, a <code>CalendarDisplayEvent</code> instance would be created for each day the event occurs
* on.
*
* @author Jen Bourey, jbourey@unicon.net
* @version $Revision$
*/
public class CalendarDisplayEvent implements Comparable<CalendarDisplayEvent> {
private final DateTime dayStart;
private final DateTime dayEnd;
private final boolean isAllDay;
private final boolean isMultiDay;
private final String summary;
private final String description;
private final String location;
private final String dateStartTime;
private final String dateEndTime;
private final String startTime;
private final String endTime;
private final String startDate;
private final String endDate;
/**
* Constructs an object from specified data.
*
* @param event "Raw" Event object
* @param eventInterval Interval portion of the event that applies to this specific day
* @param theSpecificDay Interval of the specific day in question
* @param df date formatter to represent date displays
* @param tf time formatter to represent time displays
*/
public CalendarDisplayEvent(
VEvent event,
Interval eventInterval,
Interval theSpecificDay,
DateTimeFormatter df,
DateTimeFormatter tf) {
assert theSpecificDay.abuts(eventInterval) || theSpecificDay.overlaps(eventInterval)
: "Event interval is not in the specified day!";
this.summary = event.getSummary() != null ? event.getSummary().getValue() : null;
this.description = event.getDescription() != null ? event.getDescription().getValue() : null;
this.location = event.getLocation() != null ? event.getLocation().getValue() : null;
boolean multi = false;
if (eventInterval.getStart().isBefore(theSpecificDay.getStart())) {
dayStart = theSpecificDay.getStart();
multi = true;
} else {
dayStart = eventInterval.getStart();
}
if (event.getEndDate() == null) {
dayEnd = dayStart;
} else if (eventInterval.getEnd().isAfter(theSpecificDay.getEnd())) {
dayEnd = theSpecificDay.getEnd();
multi = true;
} else {
dayEnd = eventInterval.getEnd();
}
this.isMultiDay = multi;
this.dateStartTime = tf.print(dayStart);
this.startTime = tf.print(eventInterval.getStart());
this.startDate = df.print(eventInterval.getStart());
if (event.getEndDate() != null) {
this.dateEndTime = tf.print(dayEnd);
this.endTime = tf.print(eventInterval.getEnd());
this.endDate = df.print(eventInterval.getEnd());
} else {
this.dateEndTime = null;
this.endTime = null;
this.endDate = null;
}
Interval dayEventInterval = new Interval(dayStart, dayEnd);
this.isAllDay = dayEventInterval.equals(theSpecificDay);
}
public String getSummary() {
return this.summary;
}
public String getDescription() {
return this.description;
}
public String getLocation() {
return this.location;
}
public String getDateStartTime() {
return this.dateStartTime;
}
public String getDateEndTime() {
return this.dateEndTime;
}
public String getStartTime() {
return this.startTime;
}
public String getEndTime() {
return this.endTime;
}
public String getStartDate() {
return this.startDate;
}
public String getEndDate() {
return this.endDate;
}
public boolean isAllDay() {
return this.isAllDay;
}
public boolean isMultiDay() {
return this.isMultiDay;
}
public DateTime getDayStart() {
return this.dayStart;
}
public DateTime getDayEnd() {
return this.dayEnd;
}
public int compareTo(CalendarDisplayEvent event) {
// Order events by start date, then end date, then summary.
// If all properties are equal, use the calendar and event ids to
// ensure similar events from different calendars are not misinterpreted
// as identical.
return (new CompareToBuilder())
.append(this.dayStart, event.dayStart)
.append(this.dayEnd, event.dayEnd)
.append(this.getSummary(), event.getSummary())
// The UID class doesn't implement comparable and will give
// rise to a ClassCastException if it's actually tested.
// .append(this.event.getUid(), event.event.getUid())
.toComparison();
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof CalendarDisplayEvent)) {
return false;
}
CalendarDisplayEvent event = (CalendarDisplayEvent) o;
return (new EqualsBuilder())
.append(this.dayStart, event.dayStart)
.append(this.dayEnd, event.dayEnd)
.append(this.getSummary(), event.getSummary())
// The UID class doesn't implement comparable and will give
// rise to a ClassCastException if it's actually tested.
// .append(this.event.getUid(), event.event.getUid())
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 31)
.append(this.dayStart)
.append(this.dayEnd)
.append(this.getSummary())
.toHashCode();
}
}