package envoy.server.data; import static envoy.data.Message.MessageStatus.*; import static envoy.server.Startup.config; import java.time.Instant; import javax.persistence.*; import envoy.data.*; import envoy.data.Attachment.AttachmentType; import envoy.data.Message.MessageStatus; /** * This JPA entity, which will be referred to as database message, stores the * information contained inside a {@link envoy.data.Message} inside the * database, while having a slightly different data layout. *

* A message can be converted to a database message by using the * {@link Message#Message(envoy.data.Message)} constructor. A database message * can be converted to a regular message using the {@link Message#toCommon()} * method. In both cases, the objects will not contain references to each other. * * @author Kai S. K. Engelbart * @since Envoy Server Standalone v0.1-alpha */ @Entity @Table(name = "messages") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @NamedQuery( name = Message.getPending, query = "SELECT m FROM Message m WHERE " // Send to or by the user before last seen + "(m.sender = :user OR m.recipient = :user) AND m.creationDate > :lastSeen " // SENT to the user + "OR m.recipient = :user AND m.status = envoy.data.Message$MessageStatus.SENT " // Sent by the user and RECEIVED / READ after last seen + "OR m.sender = :user AND (m.status = envoy.data.Message$MessageStatus.RECEIVED AND m.receivedDate > :lastSeen " + "OR m.status = envoy.data.Message$MessageStatus.READ AND m.readDate > :lastSeen)" ) public class Message { /** * Named query retrieving pending messages for a user (parameter {@code :user}) * which was last seen after a specific date (parameter {@code :lastSeen}). * * @since Envoy Server Standalone v0.1-beta */ public static final String getPending = "Message.getPending"; @Id protected long id; @ManyToOne(cascade = CascadeType.REMOVE) @JoinColumn protected User sender; @ManyToOne(cascade = CascadeType.REMOVE) @JoinColumn protected Contact recipient; @Column(name = "creation_date") protected Instant creationDate; @Column(name = "received_date") protected Instant receivedDate; @Column(name = "read_date") protected Instant readDate; protected String text; protected envoy.data.Message.MessageStatus status; protected AttachmentType attachmentType; protected byte[] attachment; protected String attachmentName; protected boolean forwarded; /** * The constructor for a database object. * * @since Envoy Server Standalone v0.1-alpha */ public Message() {} /** * Constructs a database message from a common message. * * @param message the {@link envoy.data.Message} to convert into a database * {@link Message} * @since Envoy Server Standalone v0.1-alpha */ public Message(envoy.data.Message message) { final var persistenceManager = PersistenceManager.getInstance(); id = message.getID(); status = message.getStatus(); text = message.getText(); creationDate = message.getCreationDate(); receivedDate = message.getReceivedDate(); readDate = message.getReadDate(); sender = persistenceManager.getUserByID(message.getSenderID()); recipient = persistenceManager.getContactByID(message.getRecipientID()); forwarded = message.isForwarded(); if (config.isAttachmentSupportEnabled() && message.hasAttachment()) { final var messageAttachment = message.getAttachment(); attachment = messageAttachment.getData(); attachmentName = messageAttachment.getName(); attachmentType = messageAttachment.getType(); } } /** * Converts this message into an instance of {@link envoy.data.Message}. * * @return a {@link envoy.data.Message} containing the same values as this * message * @since Envoy Server Standalone v0.1-alpha */ public envoy.data.Message toCommon() { return prepareBuilder().build(); } /** * @return a message builder containing the state of this message * @since Envoy Server Standalone v0.1-beta */ MessageBuilder prepareBuilder() { final var builder = new MessageBuilder(sender.getID(), recipient.getID(), id).setText(text) .setCreationDate(creationDate) .setReceivedDate(receivedDate) .setReadDate(readDate) .setStatus(status) .setForwarded(forwarded); if (attachment != null) builder.setAttachment(new Attachment(attachment, attachmentName, attachmentType)); return builder; } /** * Sets the message status to {@link MessageStatus#RECEIVED} and sets the * current time stamp as the received date. * * @since Envoy Server Standalone v0.1-beta */ public void received() { receivedDate = Instant.now(); status = RECEIVED; } /** * Sets the message status to {@link MessageStatus#READ} and sets the * current time stamp as the read date. * * @since Envoy Server Standalone v0.1-beta */ public void read() { readDate = Instant.now(); status = READ; } /** * @return the id of a {link envoy.data.Message} * @since Envoy Server Standalone v0.1-alpha */ public long getID() { return id; } /** * @param id the id to set * @since Envoy Server Standalone v0.1-alpha * @see Message#getID() */ public void setId(long id) { this.id = id; } /** * @return the sender of a {link envoy.data.Message} * @since Envoy Server Standalone v0.1-alpha */ public User getSender() { return sender; } /** * @param sender the sender to set * @since Envoy Server Standalone v0.1-alpha * @see Message#getSender() */ public void setSender(User sender) { this.sender = sender; } /** * @return the recipient of a {link envoy.data.Message} * @since Envoy Server Standalone v0.1-alpha */ public Contact getRecipient() { return recipient; } /** * @param recipient the recipient to set * @since Envoy Server Standalone v0.1-alpha * @see Message#getRecipient() */ public void setRecipient(User recipient) { this.recipient = recipient; } /** * @return the date at which a {link envoy.data.Message} has been created * @since Envoy Server Standalone v0.2-beta */ public Instant getCreationDate() { return creationDate; } /** * @param creationDate the creation date to set * @since Envoy Server Standalone v0.2-beta * @see Message#getCreationDate() */ public void setCreationDate(Instant creationDate) { this.creationDate = creationDate; } /** * @return the date at which a {link envoy.data.Message} has been received by * the server * @since Envoy Server Standalone v0.2-beta */ public Instant getReceivedDate() { return receivedDate; } /** * @param receivedDate the received date to set * @since Envoy Server Standalone v0.2-beta * @see Message#getReceivedDate() */ public void setReceivedDate(Instant receivedDate) { this.receivedDate = receivedDate; } /** * @return the date at which a {link envoy.data.Message} has been read * @since Envoy Server Standalone v0.2-beta */ public Instant getReadDate() { return readDate; } /** * @param readDate the read date to set * @since Envoy Server Standalone v0.2-beta * @see Message#getReadDate() */ public void setReadDate(Instant readDate) { this.readDate = readDate; } /** * @return the status of a {link envoy.data.Message} * @since Envoy Server Standalone v0.1-alpha */ public envoy.data.Message.MessageStatus getStatus() { return status; } /** * @param status the new status of a {link envoy.data.Message} * @since Envoy Server Standalone v0.1-alpha */ public void setStatus(envoy.data.Message.MessageStatus status) { this.status = status; } /** * @return the text content of a {link envoy.data.Message} * @since Envoy Server Standalone v0.1-alpha */ public String getText() { return text; } /** * @param text the new text content of a {@link envoy.data.Message} * @since Envoy Server Standalone v0.1-alpha */ public void setText(String text) { this.text = text; } /** * @return the attachment of a {@link envoy.data.Message} * @since Envoy Server Standalone v0.1-alpha */ public byte[] getAttachment() { return attachment; } /** * @param attachment the new attachment * @since Envoy Server Standalone v0.1-alpha */ public void setAttachment(byte[] attachment) { this.attachment = attachment; } /** * @return the attachmentType * @since Envoy Server Standalone v0.1-beta */ public AttachmentType getAttachmentType() { return attachmentType; } /** * @param attachmentType the attachmentType to set * @since Envoy Server Standalone v0.1-beta */ public void setAttachmentType(AttachmentType attachmentType) { this.attachmentType = attachmentType; } /** * @return the attachmentName * @since Envoy Server v0.2-beta */ public String getAttachmentName() { return attachmentName; } /** * @param attachmentName the attachmentName to set * @since Envoy Server v0.2-beta */ public void setAttachmentName(String attachmentName) { this.attachmentName = attachmentName; } /** * @return whether this message is a forwarded message * @since Envoy Server Standalone v0.1-alpha */ public boolean isForwarded() { return forwarded; } /** * @param forwarded this message should be a forwarded message. * @since Envoy Server Standalone v0.1-alpha */ public void setForwarded(boolean forwarded) { this.forwarded = forwarded; } }