org.silverpeas.core.webapi.calendar.CalendarEventEntity.java Source code

Java tutorial

Introduction

Here is the source code for org.silverpeas.core.webapi.calendar.CalendarEventEntity.java

Source

/*
 * Copyright (C) 2000 - 2018 Silverpeas
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * As a special exception to the terms and conditions of version 3.0 of
 * the GPL, you may redistribute this Program in connection with Free/Libre
 * Open Source Software ("FLOSS") applications as described in Silverpeas's
 * FLOSS exception. You should have received a copy of the text describing
 * the FLOSS exception, and it is also available here:
 * "http://www.silverpeas.org/docs/core/legal/floss_exception.html"
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.silverpeas.core.webapi.calendar;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.silverpeas.core.admin.user.model.User;
import org.silverpeas.core.calendar.Calendar;
import org.silverpeas.core.calendar.CalendarComponent;
import org.silverpeas.core.calendar.CalendarEvent;
import org.silverpeas.core.calendar.Priority;
import org.silverpeas.core.calendar.VisibilityLevel;
import org.silverpeas.core.contribution.content.renderer.ContributionContentRenderer;
import org.silverpeas.core.contribution.model.LocalizedContribution;
import org.silverpeas.core.contribution.model.WysiwygContent;
import org.silverpeas.core.date.Period;
import org.silverpeas.core.util.StringUtil;
import org.silverpeas.core.webapi.attachment.AttachmentParameterEntity;
import org.silverpeas.core.webapi.base.WebEntity;
import org.silverpeas.core.webapi.pdc.PdcClassificationEntity;
import org.silverpeas.core.webapi.reminder.ReminderEntity;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import java.net.URI;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.silverpeas.core.cache.service.VolatileCacheServiceProvider.getSessionVolatileResourceCacheService;
import static org.silverpeas.core.calendar.CalendarEventUtil.formatDateWithOffset;
import static org.silverpeas.core.calendar.CalendarEventUtil.formatTitle;
import static org.silverpeas.core.util.StringUtil.isDefined;

/**
 * It represents the state of a calendar event in a calendar as transmitted within the
 * body of an HTTP response or an HTTP request.
 * @author Yohann Chastagnier
 */
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
@JsonIgnoreProperties(ignoreUnknown = true)
public class CalendarEventEntity implements WebEntity {

    private URI eventUri;
    private URI calendarUri;
    private URI eventPermalinkUrl;

    private String eventId;
    private String calendarId;
    private String calendarZoneId;
    private String title;
    private String description;
    private String content;
    private String location;
    private boolean onAllDay;
    private String startDate;
    private String endDate;
    private VisibilityLevel visibility;
    private Priority priority;
    private CalendarEventRecurrenceEntity recurrence;
    private List<CalendarEventAttendeeEntity> attendees = new ArrayList<>();
    private List<CalendarEventAttributeEntity> attributes = new ArrayList<>();
    private String ownerName;
    private Date createDate;
    private String createdById;
    private Date lastUpdateDate;
    private String lastUpdatedById;
    private boolean canBeAccessed;
    private boolean canBeModified;
    private boolean canBeDeleted;
    private List<AttachmentParameterEntity> attachmentParameters = new ArrayList<>();
    private ReminderEntity reminder;
    private PdcClassificationEntity pdcClassification;

    protected CalendarEventEntity() {
    }

    public static CalendarEventEntity fromEvent(final CalendarEvent event, final String componentInstanceId,
            final ZoneId zoneId, final boolean isEditionMode) {
        return new CalendarEventEntity().decorate(event, componentInstanceId, zoneId, isEditionMode);
    }

    /**
     * Sets a URI to this entity. With this URI, it can then be accessed through the Web.
     * @param eventUri the web entity URI.
     * @return itself.
     */
    @SuppressWarnings("unchecked")
    public CalendarEventEntity withEventURI(final URI eventUri) {
        this.eventUri = eventUri;
        return this;
    }

    /**
     * Sets a URI to linked calendar entity. With this URI, it can then be accessed through the Web.
     * @param calendarUri the linked calendar web entity URI.
     * @return itself.
     */
    @SuppressWarnings("unchecked")
    public CalendarEventEntity withCalendarURI(final URI calendarUri) {
        this.calendarUri = calendarUri;
        return this;
    }

    /**
     * Sets a URI to this entity. With this URI, it can then be accessed through the Web.
     * @param permalinkUrl the web entity URI.
     * @return itself.
     */
    @SuppressWarnings("unchecked")
    public CalendarEventEntity withEventPermalinkURL(final URI permalinkUrl) {
        this.eventPermalinkUrl = permalinkUrl;
        return this;
    }

    /**
     * Sets attendees to linked calendar event entity.
     * @param attendees the linked calendar event attendees web entity.
     * @return itself.
     */
    public CalendarEventEntity withAttendees(final List<CalendarEventAttendeeEntity> attendees) {
        this.attendees = attendees;
        return this;
    }

    /**
     * Sets attributes to linked calendar event entity.
     * @param attributes the linked calendar event attributes web entity.
     * @return itself.
     */
    public CalendarEventEntity withAttributes(final List<CalendarEventAttributeEntity> attributes) {
        this.attributes = attributes;
        return this;
    }

    @Override
    public URI getURI() {
        return getEventUri();
    }

    protected void setURI(final URI uri) {
        setEventUri(uri);
    }

    public URI getEventUri() {
        return eventUri;
    }

    protected void setEventUri(final URI eventUri) {
        this.eventUri = eventUri;
    }

    public URI getCalendarUri() {
        return calendarUri;
    }

    protected void setCalendarUri(final URI calendarUri) {
        this.calendarUri = calendarUri;
    }

    public URI getEventPermalinkUrl() {
        return eventPermalinkUrl;
    }

    public void setEventPermalinkUrl(final URI eventPermalinkUrl) {
        this.eventPermalinkUrl = eventPermalinkUrl;
    }

    public String getId() {
        return getEventId();
    }

    protected void setId(String eventId) {
        setEventId(eventId);
    }

    public String getEventId() {
        return eventId;
    }

    protected void setEventId(final String eventId) {
        this.eventId = eventId;
    }

    public String getCalendarId() {
        return calendarId;
    }

    protected void setCalendarId(final String calendarId) {
        this.calendarId = calendarId;
    }

    public String getCalendarZoneId() {
        return calendarZoneId;
    }

    protected void setCalendarZoneId(final String calendarZoneId) {
        this.calendarZoneId = calendarZoneId;
    }

    public String getTitle() {
        return title;
    }

    protected void setTitle(final String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    protected void setDescription(String description) {
        this.description = description;
    }

    public String getContent() {
        return content;
    }

    protected void setContent(final String content) {
        this.content = content;
    }

    public String getLocation() {
        return location;
    }

    protected void setLocation(final String location) {
        this.location = location;
    }

    public boolean isOnAllDay() {
        return onAllDay;
    }

    protected void setOnAllDay(final boolean onAllDay) {
        this.onAllDay = onAllDay;
    }

    public String getStartDate() {
        return startDate;
    }

    protected void setStartDate(final String startDate) {
        this.startDate = startDate;
    }

    public String getEndDate() {
        return endDate;
    }

    protected void setEndDate(final String endDate) {
        this.endDate = endDate;
    }

    public VisibilityLevel getVisibility() {
        return visibility;
    }

    protected void setVisibility(final VisibilityLevel visibility) {
        this.visibility = visibility;
    }

    public Priority getPriority() {
        return priority;
    }

    protected void setPriority(final Priority priority) {
        this.priority = priority;
    }

    public CalendarEventRecurrenceEntity getRecurrence() {
        return recurrence;
    }

    public void setRecurrence(final CalendarEventRecurrenceEntity recurrence) {
        this.recurrence = recurrence;
    }

    public List<CalendarEventAttendeeEntity> getAttendees() {
        return attendees;
    }

    public void setAttendees(final List<CalendarEventAttendeeEntity> attendees) {
        withAttendees(attendees);
    }

    public List<CalendarEventAttributeEntity> getAttributes() {
        return attributes;
    }

    public void setAttributes(final List<CalendarEventAttributeEntity> attributes) {
        withAttributes(attributes);
    }

    @XmlElement
    public String getOwnerName() {
        return ownerName;
    }

    @XmlElement
    public Date getCreateDate() {
        return createDate;
    }

    @XmlElement
    public String getCreatedById() {
        return createdById;
    }

    public Date getLastUpdateDate() {
        return lastUpdateDate;
    }

    protected void setLastUpdateDate(final Date lastUpdateDate) {
        this.lastUpdateDate = lastUpdateDate;
    }

    public String getLastUpdatedById() {
        return lastUpdatedById;
    }

    public void setLastUpdatedById(final String lastUpdatedById) {
        this.lastUpdatedById = lastUpdatedById;
    }

    @XmlElement
    public boolean canBeAccessed() {
        return canBeAccessed;
    }

    @XmlElement
    public boolean canBeModified() {
        return canBeModified;
    }

    @XmlElement
    public boolean canBeDeleted() {
        return canBeDeleted;
    }

    /**
     * Gets the parameters of the attachments of this event.
     * <p>
     * At creation time, files can be attached to the event but attachment can only be done to
     * existing contributions and not to contributions not yet effectively created. So, to do such an
     * attachment the files are first transparently uploaded in the background and for each uploaded
     * file a set of parameters is returned to the UI in order to retrieve them later in Silverpeas.
     * Once the creation of the event is validated by the user and the event is eventually created,
     * the attachment parameters sent with this Web representation are used to get the previously
     * uploaded files to be attached to the created event.
     * </p>
     * @return all the parameters about any previously uploaded files to attach to this event.
     */
    @XmlElement
    public Map<String, String[]> getAttachmentParameters() {
        return attachmentParameters.stream()
                .collect(Collectors.toMap(p -> p.getName(), p -> new String[] { p.getValue() }));
    }

    /**
     * Gets the pdc classification of this event.
     * <p>
     * PDC classification can be set on the save of an event.<br>
     * Once the creation of the event is validated by the user and the event is eventually created,
     * the PDC classification sent with this Web representation is used with PDC services.
     * </p>
     * @return all the parameters about any previously uploaded files to attach to this event.
     */
    @XmlElement
    public PdcClassificationEntity getPdcClassification() {
        return pdcClassification != null ? pdcClassification : PdcClassificationEntity.undefinedClassification();
    }

    /**
     * Gets reminder data about the entity if any.
     * @return reminder data, null otherwise.
     */
    @XmlElement
    public ReminderEntity getReminder() {
        return reminder;
    }

    /**
     * Gets the period of the event.
     * @return a period instance.
     */
    @XmlTransient
    Period getPeriod() {
        final Period eventPeriod;
        if (isOnAllDay()) {
            eventPeriod = Period.between(LocalDate.parse(startDate), LocalDate.parse(endDate));
        } else {
            eventPeriod = Period.between(OffsetDateTime.parse(startDate), OffsetDateTime.parse(endDate));
        }
        return eventPeriod;
    }

    /**
     * Get the persistent data representation of an event merged with the entity data.
     * The data of the entity are applied to the returned instance.
     * @param componentInstanceId identifier of the component instance host.
     * @return a {@link CalendarEvent} instance.
     */
    @XmlTransient
    CalendarEvent getMergedEvent(final String componentInstanceId) {
        final CalendarEvent event;
        if (isDefined(getEventId()) && !getSessionVolatileResourceCacheService().couldBeVolatileId(getEventId())) {
            event = CalendarEvent.getById(getEventId());
        } else {
            event = CalendarEvent.on(getPeriod());
        }
        applyOn(event);
        applyOn(event.asCalendarComponent());
        return event;
    }

    /**
     * Get the persistent data representation of an event merged with the entity data.
     * The data of the entity are applied to the returned instance.
     * @param event the event aimed to apply modification.
     */
    @XmlTransient
    void applyOn(final CalendarEvent event) {
        String currentText = getContent() == null ? "" : getContent();
        if (event.getContent().isPresent()) {
            event.getContent().get().setData(currentText);
        } else if (!currentText.isEmpty()) {
            WysiwygContent wysiwygContent = new WysiwygContent(LocalizedContribution.from(event));
            wysiwygContent.setData(currentText);
            event.setContent(wysiwygContent);
        }
        event.withVisibilityLevel(getVisibility());
        if (getRecurrence() != null) {
            getRecurrence().applyOn(event, getPeriod());
        } else {
            event.unsetRecurrence();
        }
    }

    /**
     * Applies to the given calendar component the data of the WEB entity.
     * @param component the component aimed to apply modification.
     */
    @XmlTransient
    void applyOn(final CalendarComponent component) {
        component.setPeriod(getPeriod());
        component.setTitle(getTitle());
        component.setDescription(getDescription());
        component.setLocation(getLocation());
        component.setPriority(getPriority());
        List<String> newAttendeeIds = new ArrayList<>(getAttendees().size());
        for (CalendarEventAttendeeEntity attendeeEntity : getAttendees()) {
            attendeeEntity.addTo(component);
            newAttendeeIds.add(attendeeEntity.getId());
        }
        component.getAttendees().removeIf(attendee -> !newAttendeeIds.contains(attendee.getId()));
        List<String> newAttributeNames = new ArrayList<>(getAttributes().size());
        for (CalendarEventAttributeEntity attributeEntity : getAttributes()) {
            if (isDefined(attributeEntity.getValue())) {
                component.getAttributes().set(attributeEntity.getName(), attributeEntity.getValue());
                newAttributeNames.add(attributeEntity.getName());
            }
        }
        component.getAttributes().removeIf(attribute -> !newAttributeNames.contains(attribute.getKey()));
    }

    protected CalendarEventEntity decorate(final CalendarEvent calendarEvent, final String componentInstanceId,
            final ZoneId zoneId, final boolean isEditionMode) {
        User currentUser = User.getCurrentRequester();
        final Calendar calendar = calendarEvent.getCalendar();
        final CalendarComponent component = calendarEvent.asCalendarComponent();
        eventId = calendarEvent.getId();
        calendarId = calendar.getId();
        calendarZoneId = calendar.getZoneId().toString();
        onAllDay = calendarEvent.isOnAllDay();
        startDate = formatDateWithOffset(component, calendarEvent.getStartDate(), zoneId);
        endDate = formatDateWithOffset(component, calendarEvent.getEndDate(), zoneId);
        createDate = component.getCreationDate();
        createdById = component.getCreatorId();
        lastUpdateDate = component.getLastUpdateDate();
        lastUpdatedById = component.getLastUpdaterId();
        ownerName = calendarEvent.getCreator().getDisplayedName();
        canBeAccessed = calendarEvent.canBeAccessedBy(currentUser);
        title = formatTitle(component, componentInstanceId, canBeAccessed);
        if (canBeAccessed) {
            description = calendarEvent.getDescription();
            final Optional<WysiwygContent> wysiwyg = calendarEvent.getContent();
            if (wysiwyg.isPresent()) {
                final ContributionContentRenderer wysiwygRenderer = wysiwyg.get().getRenderer();
                content = isEditionMode ? wysiwygRenderer.renderEdition() : wysiwygRenderer.renderView();
            } else {
                content = StringUtil.EMPTY;
            }
            location = calendarEvent.getLocation();
            visibility = calendarEvent.getVisibilityLevel();
            priority = calendarEvent.getPriority();
            recurrence = CalendarEventRecurrenceEntity.from(calendarEvent, zoneId);
            canBeModified = calendarEvent.canBeModifiedBy(currentUser);
            canBeDeleted = calendarEvent.canBeDeletedBy(currentUser);
        } else {
            canBeModified = false;
            canBeDeleted = false;
        }
        return this;
    }

    @Override
    public String toString() {
        return toStringBuilder().toString();
    }

    protected ToStringBuilder toStringBuilder() {
        ToStringBuilder builder = new ToStringBuilder(this);
        builder.append("eventUri", getURI());
        builder.append("eventId", getEventId());
        builder.append("calendarId", getCalendarId());
        builder.append("calendarZoneId", getCalendarZoneId());
        builder.append("title", getTitle());
        builder.append("description", getDescription());
        builder.append("startDate", getStartDate());
        builder.append("endDate", getEndDate());
        builder.append("onAllDay", isOnAllDay());
        builder.append("visibility", getVisibility());
        builder.append("priority", getPriority());
        builder.append("recurrence", getRecurrence());
        builder.append("ownerName", getOwnerName());
        builder.append("createDate", getCreateDate());
        builder.append("createdById", getCreatedById());
        builder.append("lastUpdateDate", getLastUpdateDate());
        builder.append("lastUpdatedById", getLastUpdatedById());
        return builder;
    }
}