NotificationMessage.java

/*
 * Copyright 2024 Global Crop Diversity Trust
 *
 * 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 org.gringlobal.model.notification;

import java.time.Instant;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.genesys.blocks.model.ClassPK;
import org.genesys.blocks.model.Copyable;
import org.genesys.blocks.model.VersionedModel;
import org.genesys.blocks.security.model.AclSid;
import org.gringlobal.model.AppResource;
import org.gringlobal.service.TemplatingService;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

/**
 * {@link NotificationMessage} holds information about a message that needs to
 * be
 * delivered to the {@link #recipient}.
 * 
 * <p>
 * Different delivery mechanisms may be used.
 * </p>
 * 
 * <p>
 * The {@link #messageType} determines which <b>template</b> is used to generate
 * the message title and body for this notification.
 * </p>
 * 
 * <p>
 * Templates are managed as {@code AppResources} and must be able to handle a
 * single messaage or a collection of messages of the same type.
 * </p>
 * <p>
 * {@link AppResource#getValueMember()} is used for message title, while
 * {@link AppResource#getDisplayMember()} is used for the message body. Template
 * language must use whatever {@link TemplatingService} is using.
 * </p>
 * 
 */
@Entity
@Table(name = "notification_message")
@Getter
@Setter
@NoArgsConstructor
@ToString(callSuper = true)
public class NotificationMessage extends VersionedModel implements Copyable<NotificationMessage> {

	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
	@JoinColumn(name = "recipient_id", nullable = false, updatable = false)
	private AclSid recipient;

	/** When was the message created? */
	@Basic
	private Instant timestamp;

	/** Message type determines which template is used to generate the message text (title and body). */
	@Basic
	@Column(length = 50, nullable = false, updatable = false)
	private String messageType;

	/** What type does this notification relate to? */
	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
	@JoinColumn(name = "related_cpk", nullable = true, updatable = false)
	private ClassPK relatedClassPK;

	/** The id of the entity this notification is related to. */
	@Column(nullable = true, updatable = false)
	private Long relatedId;


	/**
	 * When was the message sent to the {@link #recipient}?
	 * A {@code null} value indicates the message had not yet been sent.
	 */
	@Basic
	private Instant sentDate;

	/** When was the message read by the {@link #recipient}? */
	@Basic
	private Instant readDate;

	public NotificationMessage(AclSid recipient, Instant timestamp, String messageType, ClassPK relatedClassPK, Long relatedId) {
		assert(recipient.getId() != null);

		this.recipient = recipient;
		this.timestamp = timestamp;
		this.messageType = messageType;
		this.relatedClassPK = relatedClassPK;
		this.relatedId = relatedId;
	}

	@Override
	public NotificationMessage apply(NotificationMessage source) {
		this.readDate = source.readDate;
		this.sentDate = source.sentDate;
		return this;
	}

	@Override
	public boolean canEqual(Object other) {
		return other instanceof NotificationMessage;
	}
}