/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
// www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////
package org.projectforge.plugins.teamcal.event;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeSet;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import net.fortuna.ical4j.model.Recur;
import net.fortuna.ical4j.model.property.RRule;
import org.apache.commons.lang.StringUtils;
import org.hibernate.search.annotations.DateBridge;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import org.hibernate.search.annotations.Resolution;
import org.hibernate.search.annotations.Store;
import org.projectforge.calendar.ICal4JUtils;
import org.projectforge.calendar.TimePeriod;
import org.projectforge.common.DateFormats;
import org.projectforge.core.AbstractHistorizableBaseDO;
import org.projectforge.core.DefaultBaseDO;
import org.projectforge.core.PFPersistancyBehavior;
import org.projectforge.database.Constants;
import org.projectforge.plugins.teamcal.TeamCalConfig;
import org.projectforge.plugins.teamcal.admin.TeamCalDO;
import org.projectforge.user.PFUserContext;
import de.micromata.hibernate.history.ExtendedHistorizable;
/**
* Overview of used (and may-be planned) fields:
* <ul>
* <li><b>ATTENDEE</b>: ATTENDEE;MEMBER="mailto:DEV-GROUP@example.com": mailto:joecool@example.com</li>
* <li><b>CONTACT</b>: CONTACT:Jim Dolittle\, ABC Industries\, +1-919-555-1234</li>
* <li><b>DTEND</b> - End date (DATE-TIME)</li>
* <li><b>DTSTAMP</b> - Time of creation (DATE-TIME)</li>
* <li><b>DTSTART</b> - Start date (DATE-TIME)</li>
* <li><b>EXDATE</b> - exception dates of recurrence (list of DATE-TIME)</li>
* <li><b>LAST-MODIFIED</b> - (DATE-TIME)</li>
* <li><b>PARTSTAT</b>=DECLINED:mailto:jsmith@example.com</li>
* <li><b>ORGANIZER</b>: ORGANIZER;CN=John Smith:mailto:jsmith@example.com</li>
* <li><b>RDATE</b> - Dates of recurrence</li>
* <li><b>RRULE</b> - Rule of recurrence: RRULE:FREQ=DAILY;UNTIL=19971224T000000Z</li>
* <li><b>UID</b>: UID:19960401T080045Z-4000F192713-0052@example.com
* </ul>
* @author Kai Reinhard (k.reinhard@micromata.de)
* @author M. Lauterbach (m.lauterbach@micromata.de)
*
*/
@Entity
@Indexed
@Table(name = "T_PLUGIN_CALENDAR_EVENT")
public class TeamEventDO extends DefaultBaseDO implements TeamEvent, Cloneable, ExtendedHistorizable
{
private static final long serialVersionUID = -9205582135590380919L;
@Field(index = Index.TOKENIZED, store = Store.NO)
private String subject;
@Field(index = Index.TOKENIZED, store = Store.NO)
private String location;
private boolean allDay;
@Field(index = Index.UN_TOKENIZED)
@DateBridge(resolution = Resolution.MINUTE)
private Timestamp startDate;
@Field(index = Index.UN_TOKENIZED)
@DateBridge(resolution = Resolution.MINUTE)
private Timestamp endDate;
@Field(index = Index.UN_TOKENIZED)
@DateBridge(resolution = Resolution.SECOND)
private Timestamp lastEmail;
@IndexedEmbedded(depth = 1)
private TeamCalDO calendar;
private transient RRule recurrenceRuleObject;
private String recurrenceRule, recurrenceExDate, recurrenceReferenceDate, recurrenceReferenceId;
private java.util.Date recurrenceUntil;
@Field(index = Index.TOKENIZED, store = Store.NO)
private String note;
@PFPersistancyBehavior(autoUpdateCollectionEntries = true)
private Set<TeamEventAttendeeDO> attendees;
private String organizer;
private String externalUid;
private Integer reminderDuration;
private ReminderDurationUnit reminderDurationType;
private ReminderActionType reminderActionType;
// See RFC 2445 section 4.8.7.4
private Integer sequence = 0;
// See RFC 2445 section 4.8.1.11
// private TeamEventStatus status = TeamEventStatus.UNKNOWN;
@PFPersistancyBehavior(autoUpdateCollectionEntries = true)
private Set<TeamEventAttachmentDO> attachments;
static {
AbstractHistorizableBaseDO.putNonHistorizableProperty(TeamEventDO.class, "lastEmail");
}
/**
* Clear fields for viewers with minimal access. If you add new fields don't forget to clear these fields here.
*/
public TeamEventDO clearFields()
{
subject = location = note = null;
if (attendees != null) {
attendees.clear();
}
organizer = null;
reminderDuration = null;
reminderDurationType = null;
reminderActionType = null;
lastEmail = null;
sequence = null;
if (attachments != null) {
attachments.clear();
}
// status = null;
return this;
}
public TeamEventDO()
{
}
@Transient
public String getUid()
{
return TeamCalConfig.get().createEventUid(getId());
}
@Column(length = Constants.LENGTH_SUBJECT)
public String getSubject()
{
return subject;
}
/**
* @param title
* @return this for chaining.
*/
public TeamEventDO setSubject(final String subject)
{
this.subject = subject;
return this;
}
@Column(length = Constants.LENGTH_SUBJECT)
/**
* @return the location
*/
public String getLocation()
{
return location;
}
/**
* @param location the location to set
* @return this for chaining.
*/
public TeamEventDO setLocation(final String location)
{
this.location = location;
return this;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "calendar_fk", nullable = false)
/**
* @return the calendar
*/
public TeamCalDO getCalendar()
{
return calendar;
}
@Transient
public Integer getCalendarId()
{
return calendar != null ? calendar.getId() : null;
}
/**
* @param calendar the calendar to set
* @return this for chaining.
*/
public TeamEventDO setCalendar(final TeamCalDO calendar)
{
this.calendar = calendar;
return this;
}
/**
* @return the allDay
*/
@Column(name = "all_day")
public boolean isAllDay()
{
return allDay;
}
/**
* @param allDay the allDay to set
* @return this for chaining.
*/
public TeamEventDO setAllDay(final boolean allDay)
{
this.allDay = allDay;
return this;
}
/**
* @return the startDate
*/
@Column(name = "start_date")
public Timestamp getStartDate()
{
return startDate;
}
/**
* @param startDate the startDate to set
* @return this for chaining.
*/
public TeamEventDO setStartDate(final Timestamp startDate)
{
this.startDate = startDate;
return this;
}
/**
* @return the endDate
*/
@Column(name = "end_date")
public Timestamp getEndDate()
{
return endDate;
}
/**
* @param endDate the endDate to set
* @return this for chaining.
*/
public TeamEventDO setEndDate(final Timestamp endDate)
{
this.endDate = endDate;
return this;
}
/**
* @return the lastEmail
*/
@Column(name = "last_email")
public Timestamp getLastEmail()
{
return lastEmail;
}
/**
* @param lastEmail the lastEmail to set
* @return this for chaining.
*/
public TeamEventDO setLastEmail(final Timestamp lastEmail)
{
this.lastEmail = lastEmail;
return this;
}
/**
* @return the note
*/
@Column(length = 4000)
public String getNote()
{
return note;
}
/**
* @param note the note to set
* @return this for chaining.
*/
public TeamEventDO setNote(final String note)
{
this.note = note;
return this;
}
/**
* @return the attendees
*/
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "team_event_fk")
public Set<TeamEventAttendeeDO> getAttendees()
{
return attendees;
}
/**
* @param attendees the attendees to set
* @return this for chaining.
*/
public TeamEventDO setAttendees(final Set<TeamEventAttendeeDO> attendees)
{
this.attendees = attendees;
return this;
}
/**
* Creates a {@link TreeSet}.
* @return this for chaining.
*/
public Set<TeamEventAttendeeDO> ensureAttendees()
{
if (this.attendees == null) {
this.attendees = new TreeSet<TeamEventAttendeeDO>();
}
return this.attendees;
}
public TeamEventDO addAttendee(final TeamEventAttendeeDO attendee)
{
ensureAttendees();
short number = 1;
for (final TeamEventAttendeeDO pos : attendees) {
if (pos.getNumber() >= number) {
number = pos.getNumber();
number++;
}
}
attendee.setNumber(number);
this.attendees.add(attendee);
return this;
}
/**
* @return the organizer
*/
@Column(length = 1000)
public String getOrganizer()
{
return organizer;
}
/**
* @param organizer the organizer to set
* @return this for chaining.
*/
public TeamEventDO setOrganizer(final String organizer)
{
this.organizer = organizer;
return this;
}
/**
* If the event is imported from another system, the uid of the external event is stored here.
* @return the externalUid
*/
@Column(name = "external_uid")
public String getExternalUid()
{
return externalUid;
}
/**
* @param externalUid the externalUid to set
* @return this for chaining.
*/
public TeamEventDO setExternalUid(final String externalUid)
{
this.externalUid = externalUid;
return this;
}
/**
* RRULE (rfc5545)
* @return the recurrence
*/
@Column(name = "recurrence_rule", length = 4000)
public String getRecurrenceRule()
{
return recurrenceRule;
}
/**
* @param recurrenceRule the recurrence to set
* @return this for chaining.
*/
public TeamEventDO setRecurrenceRule(final String recurrenceRule)
{
this.recurrenceRule = recurrenceRule;
this.recurrenceRuleObject = null;
recalculate();
return this;
}
/**
* @param recurData
* @return this for chaining.
*/
@Transient
public TeamEventDO setRecurrence(final TeamEventRecurrenceData recurData)
{
final String rruleString = TeamEventUtils.calculateRRule(recurData);
setRecurrenceRule(rruleString);
return this;
}
/**
* Will be renewed if {@link #setRecurrenceRule(String)} is called.
* @return the recurrenceRuleObject
*/
@Transient
public RRule getRecurrenceRuleObject()
{
if (recurrenceRuleObject == null) {
recalculate();
}
return recurrenceRuleObject;
}
/**
* @return true if any recurrenceRule is given, otherwise false.
*/
@Transient
public boolean hasRecurrence()
{
return StringUtils.isNotBlank(this.recurrenceRule);
}
public TeamEventDO clearAllRecurrenceFields()
{
setRecurrence(null).setRecurrenceExDate(null).setRecurrenceUntil(null);
return this;
}
/**
* The recurrenceUntil date is calculated by the recurrenceRule string if given, otherwise the date is set to null.
* @see org.projectforge.core.AbstractBaseDO#recalculate()
*/
@Override
public void recalculate()
{
super.recalculate();
recurrenceRuleObject = ICal4JUtils.calculateRecurrenceRule(recurrenceRule);
if (recurrenceRuleObject == null || recurrenceRuleObject.getRecur() == null) {
this.recurrenceUntil = null;
return;
}
this.recurrenceUntil = recurrenceRuleObject.getRecur().getUntil();
}
/**
* Will be renewed if {@link #setRecurrenceRule(String)} is called.
* @return the recurrenceRuleObject
*/
@Transient
public Recur getRecurrenceObject()
{
final RRule rrule = getRecurrenceRuleObject();
return rrule != null ? rrule.getRecur() : null;
}
/**
* EXDATE (rfc5545) Ex dates are time stamps of deleted events out of the recurrence events.
* @return the recurrenceExDate
*/
@Column(name = "recurrence_ex_date", length = 4000)
public String getRecurrenceExDate()
{
return recurrenceExDate;
}
/**
* @param date
* @param timeZone Only used for all day events.
* @return
*/
public TeamEventDO addRecurrenceExDate(final Date date, final TimeZone timeZone)
{
if (date == null) {
return this;
}
final String exDate;
if (isAllDay() == true) {
exDate = ICal4JUtils.asISODateString(date, timeZone);
} else {
exDate = ICal4JUtils.asISODateTimeString(date);
}
if (recurrenceExDate == null) {
recurrenceExDate = exDate;
} else if (recurrenceExDate.contains(exDate) == false) {
// Add this ex date only if not yet added:
recurrenceExDate = recurrenceExDate + "," + exDate;
}
return this;
}
/**
* @param recurrenceExDate the recurrenceExDate to set
* @return this for chaining.
*/
public TeamEventDO setRecurrenceExDate(final String recurrenceExDate)
{
this.recurrenceExDate = recurrenceExDate;
return this;
}
/**
* @param recurrenceExDate the recurrenceExDate to set
* @return this for chaining.
*/
@Transient
public TeamEventDO setRecurrenceDate(final Date recurrenceDate)
{
final DateFormat df = new SimpleDateFormat(DateFormats.ISO_TIMESTAMP_MILLIS);
// Need the user's time-zone for getting midnight of desired date.
df.setTimeZone(PFUserContext.getTimeZone());
// But print it as UTC date:
final String recurrenceDateString = df.format(recurrenceDate);
setRecurrenceDate(recurrenceDateString);
return this;
}
/**
* This field is RECURRENCE_ID. Isn't yet used (ex-date is always used instead in master event).
* @return the recurrenceId
*/
@Column(name = "recurrence_date")
public String getRecurrenceDate()
{
return recurrenceReferenceDate;
}
/**
* @param recurrenceDateString the recurrenceId to set
* @return this for chaining.
*/
public TeamEventDO setRecurrenceDate(final String recurrenceDateString)
{
this.recurrenceReferenceDate = recurrenceDateString;
return this;
}
/**
* Isn't yet used (ex-date is always used instead in master event).
* @return the recurrenceReferenceId
*/
@Column(name = "recurrence_reference_id", length = 255)
public String getRecurrenceReferenceId()
{
return recurrenceReferenceId;
}
/**
* @param recurrenceReferenceId the recurrenceReferenceId to set
* @return this for chaining.
*/
public TeamEventDO setRecurrenceReferenceId(final String recurrenceReferenceId)
{
this.recurrenceReferenceId = recurrenceReferenceId;
return this;
}
/**
* @param recurrenceReferenceId the recurrenceReferenceId to set
* @return this for chaining.
*/
public TeamEventDO setRecurrenceReferenceId(final Integer recurrenceReferenceId)
{
this.recurrenceReferenceId = recurrenceReferenceId != null ? String.valueOf(recurrenceReferenceId) : null;
return this;
}
/**
* If not given the recurrence will never ends.
* @return the recurrenceEndDate
*/
@Column(name = "recurrence_until")
public java.util.Date getRecurrenceUntil()
{
return recurrenceUntil;
}
/**
* Please note: Do not set this property manually! It's set automatically by the recurrence rule! Otherwise the display of calendar events
* may be incorrect. <br/>
* This field exist only for data-base query purposes.
* @param recurrenceUntil the recurrenceEndDate to set
* @return this for chaining.
*/
public TeamEventDO setRecurrenceUntil(final java.util.Date recurrenceUntil)
{
this.recurrenceUntil = recurrenceUntil;
return this;
}
@Transient
public TimePeriod getTimePeriod()
{
return new TimePeriod(startDate, endDate, true);
}
/**
* @return Duration in millis if startTime and stopTime is given and stopTime is after startTime, otherwise 0.
*/
@Transient
public long getDuration()
{
return getTimePeriod().getDuration();
}
/**
* Get reminder duration.
*
* @return
*/
@Column(name = "reminder_duration")
public Integer getReminderDuration()
{
return reminderDuration;
}
/**
* Get type of reminder duration minute, hour, day
*
* @return the reminderDurationType
*/
@Column(name = "reminder_duration_unit")
@Enumerated(EnumType.STRING)
public ReminderDurationUnit getReminderDurationUnit()
{
return reminderDurationType;
}
/**
* @param reminderDurationUnit the alarmReminderType to set
* @return this for chaining.
*/
public void setReminderDurationUnit(final ReminderDurationUnit reminderDurationUnit)
{
this.reminderDurationType = reminderDurationUnit;
}
/**
* @param trigger the trigger to set
* @return this for chaining.
*/
public void setReminderDuration(final Integer trigger)
{
this.reminderDuration = trigger;
}
/**
* Gets type of event action. AUDIO or DISPLAY
*
* @return the reminderType
*/
@Enumerated(EnumType.STRING)
@Column(name = "reminder_action_type")
public ReminderActionType getReminderActionType()
{
return reminderActionType;
}
/**
* Set type of event action.
*
* @param reminderActionType the reminderType to set
* @return this for chaining.
*/
public void setReminderActionType(final ReminderActionType reminderActionType)
{
this.reminderActionType = reminderActionType;
}
/**
* @return the sequence
*/
@Column
public Integer getSequence()
{
return sequence;
}
/**
* @param sequence the sequence to set
* @return this for chaining.
*/
public TeamEventDO setSequence(final Integer sequence)
{
this.sequence = sequence;
return this;
}
public void incSequence()
{
sequence++;
}
/**
* @return the attachments
*/
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "team_event_fk2")
public Set<TeamEventAttachmentDO> getAttachments()
{
return attachments;
}
/**
* @param attachments the attachments to set
* @return this for chaining.
*/
public TeamEventDO setAttachments(final Set<TeamEventAttachmentDO> attachments)
{
this.attachments = attachments;
return this;
}
/**
* Creates a {@link TreeSet}.
* @return this for chaining.
*/
public Set<TeamEventAttachmentDO> ensureAttachments()
{
if (this.attachments == null) {
this.attachments = new TreeSet<TeamEventAttachmentDO>();
}
return this.attachments;
}
public TeamEventDO addAttachment(final TeamEventAttachmentDO attachment)
{
ensureAttachments();
this.attachments.add(attachment);
return this;
}
// /**
// * @return the status
// */
// @Column
// public TeamEventStatus getStatus()
// {
// return status;
// }
//
// /**
// * @param status the status to set
// * @return this for chaining.
// */
// public TeamEventDO setStatus(final TeamEventStatus status)
// {
// this.status = status;
// return this;
// }
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + (allDay ? 1231 : 1237);
result = prime * result + ((attachments == null) ? 0 : attachments.hashCode());
result = prime * result + ((attendees == null) ? 0 : attendees.hashCode());
result = prime * result + ((calendar == null) ? 0 : calendar.hashCode());
result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
result = prime * result + ((externalUid == null) ? 0 : externalUid.hashCode());
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((note == null) ? 0 : note.hashCode());
result = prime * result + ((recurrenceExDate == null) ? 0 : recurrenceExDate.hashCode());
result = prime * result + ((recurrenceRule == null) ? 0 : recurrenceRule.hashCode());
result = prime * result + ((recurrenceUntil == null) ? 0 : recurrenceUntil.hashCode());
result = prime * result + ((startDate == null) ? 0 : startDate.hashCode());
result = prime * result + ((subject == null) ? 0 : subject.hashCode());
return result;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final TeamEventDO other = (TeamEventDO) obj;
if (allDay != other.allDay)
return false;
if (attendees == null) {
if (other.attendees != null) {
return false;
}
} else if (attendees.equals(other.attendees) == false) {
return false;
}
if (calendar == null) {
if (other.calendar != null) {
return false;
}
} else if (calendar.equals(other.calendar) == false) {
return false;
}
if (endDate == null) {
if (other.endDate != null) {
return false;
}
} else if (endDate.equals(other.endDate) == false) {
return false;
}
if (externalUid == null) {
if (other.externalUid != null) {
return false;
}
} else if (externalUid.equals(other.externalUid) == false) {
return false;
}
if (location == null) {
if (other.location != null) {
return false;
}
} else if (location.equals(other.location) == false) {
return false;
}
if (note == null) {
if (other.note != null) {
return false;
}
} else if (note.equals(other.note) == false) {
return false;
}
if (recurrenceExDate == null) {
if (other.recurrenceExDate != null) {
return false;
}
} else if (recurrenceExDate.equals(other.recurrenceExDate) == false) {
return false;
}
if (recurrenceRule == null) {
if (other.recurrenceRule != null) {
return false;
}
} else if (recurrenceRule.equals(other.recurrenceRule) == false) {
return false;
}
if (recurrenceUntil == null) {
if (other.recurrenceUntil != null) {
return false;
}
} else if (recurrenceUntil.equals(other.recurrenceUntil) == false) {
return false;
}
if (startDate == null) {
if (other.startDate != null) {
return false;
}
} else if (startDate.equals(other.startDate) == false) {
return false;
}
if (subject == null) {
if (other.subject != null) {
return false;
}
} else if (subject.equals(other.subject) == false) {
return false;
}
if (attachments == null) {
if (other.attachments != null) {
return false;
}
} else if (attachments.equals(other.attachments) == false) {
return false;
}
return true;
}
public boolean mustIncSequence(final TeamEventDO other)
{
if (location == null) {
if (other.location != null)
return true;
} else if (!location.equals(other.location))
return true;
if (startDate == null) {
if (other.startDate != null)
return true;
} else if (!startDate.equals(other.startDate))
return true;
if (endDate == null) {
if (other.endDate != null)
return true;
} else if (!endDate.equals(other.endDate))
return true;
if (recurrenceExDate == null) {
if (other.recurrenceExDate != null)
return true;
} else if (!recurrenceExDate.equals(other.recurrenceExDate))
return true;
if (recurrenceRule == null) {
if (other.recurrenceRule != null)
return true;
} else if (!recurrenceRule.equals(other.recurrenceRule))
return true;
if (recurrenceUntil == null) {
if (other.recurrenceUntil != null)
return true;
} else if (!recurrenceUntil.equals(other.recurrenceUntil))
return true;
return false;
}
/**
* @see java.lang.Object#clone()
*/
@Override
public TeamEventDO clone()
{
final TeamEventDO clone = new TeamEventDO();
clone.setCalendar(this.getCalendar());
clone.startDate = this.startDate;
clone.endDate = this.endDate;
clone.allDay = this.allDay;
clone.subject = this.subject;
clone.location = this.location;
clone.recurrenceExDate = this.recurrenceExDate;
clone.recurrenceRule = this.recurrenceRule;
clone.recurrenceReferenceDate = this.recurrenceReferenceDate;
clone.recurrenceReferenceId = this.recurrenceReferenceId;
clone.recurrenceUntil = this.recurrenceUntil;
clone.organizer = this.organizer;
clone.note = this.note;
clone.externalUid = this.externalUid;
clone.lastEmail = this.lastEmail;
clone.sequence = this.sequence;
// clone.status = this.status;
clone.reminderDuration = this.reminderDuration;
clone.reminderDurationType = this.reminderDurationType;
clone.reminderActionType = this.reminderActionType;
if (this.attendees != null && this.attendees.isEmpty() == false) {
clone.attendees = clone.ensureAttendees();
for (final TeamEventAttendeeDO attendee : this.getAttendees()) {
attendee.setId(null);
clone.addAttendee(attendee);
}
}
if (this.attachments != null && this.attachments.isEmpty() == false) {
clone.attachments = clone.ensureAttachments();
for (final TeamEventAttachmentDO attachment : this.getAttachments()) {
attachment.setId(null);
clone.addAttachment(attachment);
}
}
return clone;
}
public TeamEventDO createMinimalCopy()
{
final TeamEventDO result = new TeamEventDO();
result.externalUid = this.externalUid;
result.setId(this.getId());
result.setCalendar(this.getCalendar());
result.startDate = this.startDate;
result.endDate = this.endDate;
result.allDay = this.allDay;
result.recurrenceExDate = this.recurrenceExDate;
result.recurrenceRule = this.recurrenceRule;
result.recurrenceReferenceDate = this.recurrenceReferenceDate;
result.recurrenceReferenceId = this.recurrenceReferenceId;
result.recurrenceUntil = this.recurrenceUntil;
result.externalUid = this.externalUid;
result.sequence = this.sequence;
return result;
}
}