diff --git a/common/src/main/java/envoy/data/Contact.java b/common/src/main/java/envoy/data/Contact.java index 9a5fd0a..3fe71da 100644 --- a/common/src/main/java/envoy/data/Contact.java +++ b/common/src/main/java/envoy/data/Contact.java @@ -17,9 +17,10 @@ import java.util.Set; */ public abstract class Contact implements Serializable { - private final long id; - private final transient Set contacts; - private String name; + protected final long id; + protected final transient Set contacts; + + protected String name; private static final long serialVersionUID = 0L; @@ -55,19 +56,13 @@ public abstract class Contact implements Serializable { */ public void setName(String name) { this.name = name; } - /** - * {@inheritDoc} - */ - @Override - public String toString() { return String.format("Contact[id=%d,name=%s, contacts=%s]", id, name, contacts); } - /** * Provides a hash code based on the ID of this contact. * * @since Envoy Common v0.1-beta */ @Override - public int hashCode() { return Objects.hash(id); } + public final int hashCode() { return Objects.hash(id); } /** * Tests equality to another object. If that object is a contact as well, @@ -77,7 +72,7 @@ public abstract class Contact implements Serializable { * @return {code true} if both objects are contacts and have identical IDs */ @Override - public boolean equals(Object obj) { + public final boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Contact)) return false; return id == ((Contact) obj).id; diff --git a/common/src/main/java/envoy/data/Group.java b/common/src/main/java/envoy/data/Group.java index 4eb6b02..53f816f 100644 --- a/common/src/main/java/envoy/data/Group.java +++ b/common/src/main/java/envoy/data/Group.java @@ -36,6 +36,9 @@ public final class Group extends Contact { */ public Group(long id, String name, Set members) { super(id, name, members); } + @Override + public String toString() { return String.format("Group[id=%d,name=%s,%d member(s)]", id, name, contacts.size()); } + private void readObject(ObjectInputStream inputStream) throws Exception { inputStream.defaultReadObject(); var contacts = Contact.class.getDeclaredField("contacts"); @@ -51,5 +54,5 @@ public final class Group extends Contact { @SuppressWarnings("unchecked") @Override - public Set getContacts() { return (Set) super.getContacts(); } + public Set getContacts() { return (Set) contacts; } } diff --git a/common/src/main/java/envoy/data/User.java b/common/src/main/java/envoy/data/User.java index 7751ce3..a423934 100644 --- a/common/src/main/java/envoy/data/User.java +++ b/common/src/main/java/envoy/data/User.java @@ -99,7 +99,9 @@ public final class User extends Contact { } @Override - public String toString() { return String.format("User[id=%d,name=%s,status=%s,contacts=%s]", getID(), getName(), status, getContacts()); } + public String toString() { + return String.format("User[id=%d,name=%s,status=%s", id, name, status) + (contacts.isEmpty() ? "]" : "," + contacts.size() + " contact(s)]"); + } /** * @return the current status of this user diff --git a/server/src/main/java/envoy/server/data/Contact.java b/server/src/main/java/envoy/server/data/Contact.java index 79cd720..43a9983 100644 --- a/server/src/main/java/envoy/server/data/Contact.java +++ b/server/src/main/java/envoy/server/data/Contact.java @@ -103,5 +103,5 @@ public abstract class Contact { public void setCreationDate(Instant creationDate) { this.creationDate = creationDate; } @Override - public String toString() { return String.format("%s[id=%d,name=%s, %d contact(s)]", getClass().getSimpleName(), id, name, contacts.size()); } + public String toString() { return String.format("%s[id=%d,name=%s,%d contact(s)]", getClass().getSimpleName(), id, name, contacts.size()); } } diff --git a/server/src/main/java/envoy/server/data/GroupMessage.java b/server/src/main/java/envoy/server/data/GroupMessage.java index bb96895..45be27d 100644 --- a/server/src/main/java/envoy/server/data/GroupMessage.java +++ b/server/src/main/java/envoy/server/data/GroupMessage.java @@ -19,10 +19,10 @@ import envoy.data.Group; @Entity @NamedQuery( name = GroupMessage.getPendingGroupMsg, - query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE (KEY(s) = :userId) AND ((m.creationDate > :lastSeen)" - + "OR ((m.status = envoy.data.Message$MessageStatus.RECEIVED) AND (m.receivedDate > :lastSeen))" - + "OR ((m.status = envoy.data.Message$MessageStatus.READ) AND (m.readDate > :lastSeen))" - + "OR ((m.lastStatusChangeDate > :lastSeen)))" + query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE KEY(s) = :userId AND (m.creationDate > :lastSeen " + + "OR m.status = envoy.data.Message$MessageStatus.RECEIVED AND m.receivedDate > :lastSeen " + + "OR m.status = envoy.data.Message$MessageStatus.READ AND m.readDate > :lastSeen " + + "OR m.lastStatusChangeDate > :lastSeen)" ) public class GroupMessage extends Message { diff --git a/server/src/main/java/envoy/server/data/Message.java b/server/src/main/java/envoy/server/data/Message.java index d99b3b0..fc564a2 100755 --- a/server/src/main/java/envoy/server/data/Message.java +++ b/server/src/main/java/envoy/server/data/Message.java @@ -12,11 +12,15 @@ import envoy.data.Message.MessageStatus; import envoy.data.MessageBuilder; /** - * This class serves as a way to let Hibernate communicate with the server - * without bringing the dependency of JPA/Hibernate into the client.
- * It will be referenced as "database message" to clarify between the different - * message objects.
- *
+ * 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. + *

* Project: envoy-server-standalone
* File: Message.java
* Created: 02.01.2020
@@ -29,9 +33,14 @@ import envoy.data.MessageBuilder; @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @NamedQuery( name = Message.getPending, - query = "SELECT m FROM Message m WHERE (m.recipient = :user AND m.status = envoy.data.Message$MessageStatus.SENT) " - + "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))" + 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 { @@ -107,17 +116,14 @@ public class Message { * message * @since Envoy Server Standalone v0.1-alpha */ - public envoy.data.Message toCommon() { - return prepareBuilder().build(); - } + 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() { - var builder = new MessageBuilder(sender.getID(), recipient.getID(), id).setText( - text) + var builder = new MessageBuilder(sender.getID(), recipient.getID(), id).setText(text) .setCreationDate(creationDate) .setReceivedDate(receivedDate) .setReadDate(readDate) diff --git a/server/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/server/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index 479e249..f7ee34e 100755 --- a/server/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/server/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -123,7 +123,11 @@ public final class LoginCredentialProcessor implements ObjectProcessor - writeProxy.write(socketID, new GroupMessageStatusChange(gmsg.getID(), memberStatus, gmsg.getLastStatusChangeDate(), memberID))); + gmsg.getMemberMessageStatus() + .forEach((memberID, memberStatus) -> writeProxy.write(socketID, + new GroupMessageStatusChange(gmsg.getID(), memberStatus, gmsg.getLastStatusChangeDate(), memberID))); } // Deliver just a status change instead of the whole message