diff --git a/client/src/main/java/envoy/client/data/ClientConfig.java b/client/src/main/java/envoy/client/data/ClientConfig.java index 49e7892..fbbdc94 100644 --- a/client/src/main/java/envoy/client/data/ClientConfig.java +++ b/client/src/main/java/envoy/client/data/ClientConfig.java @@ -5,10 +5,8 @@ import static java.util.function.Function.identity; import java.io.File; import java.util.logging.Level; -import envoy.client.ui.Startup; import envoy.data.Config; import envoy.data.ConfigItem; -import envoy.data.LoginCredentials; /** * Implements a configuration specific to the Envoy Client with default values @@ -105,11 +103,4 @@ public class ClientConfig extends Config { * @since Envoy Client v0.3-alpha */ public boolean hasLoginCredentials() { return getUser() != null && getPassword() != null; } - - /** - * @return login credentials for the specified user name and password, without - * the registration option - * @since Envoy Client v0.3-alpha - */ - public LoginCredentials getLoginCredentials() { return new LoginCredentials(getUser(), getPassword(), false, Startup.VERSION); } } diff --git a/client/src/main/java/envoy/client/data/GroupChat.java b/client/src/main/java/envoy/client/data/GroupChat.java index aafd3a0..6592e8e 100644 --- a/client/src/main/java/envoy/client/data/GroupChat.java +++ b/client/src/main/java/envoy/client/data/GroupChat.java @@ -1,7 +1,7 @@ package envoy.client.data; import java.io.IOException; -import java.time.LocalDateTime; +import java.time.Instant; import envoy.client.net.WriteProxy; import envoy.data.Contact; @@ -46,7 +46,7 @@ public class GroupChat extends Chat { else { gmsg.getMemberStatuses().replace(sender.getID(), MessageStatus.READ); writeProxy - .writeMessageStatusChange(new GroupMessageStatusChange(gmsg.getID(), MessageStatus.READ, LocalDateTime.now(), sender.getID())); + .writeMessageStatusChange(new GroupMessageStatusChange(gmsg.getID(), MessageStatus.READ, Instant.now(), sender.getID())); } } } diff --git a/client/src/main/java/envoy/client/data/LocalDB.java b/client/src/main/java/envoy/client/data/LocalDB.java index 421cb38..d344d98 100644 --- a/client/src/main/java/envoy/client/data/LocalDB.java +++ b/client/src/main/java/envoy/client/data/LocalDB.java @@ -1,5 +1,6 @@ package envoy.client.data; +import java.time.Instant; import java.util.*; import envoy.data.*; @@ -20,11 +21,12 @@ import envoy.event.NameChange; */ public abstract class LocalDB { - protected User user; - protected Map users = new HashMap<>(); - protected List chats = new ArrayList<>(); - protected IDGenerator idGenerator; - protected CacheMap cacheMap = new CacheMap(); + protected User user; + protected Map users = new HashMap<>(); + protected List chats = new ArrayList<>(); + protected IDGenerator idGenerator; + protected CacheMap cacheMap = new CacheMap(); + protected Instant lastSync = Instant.EPOCH; { cacheMap.put(Message.class, new Cache<>()); @@ -42,10 +44,11 @@ public abstract class LocalDB { * Stores all users. If the client user is specified, their chats will be stored * as well. The message id generator will also be saved if present. * + * @param isOnline determines which {@code lastSync} time stamp is saved * @throws Exception if the saving process failed * @since Envoy Client v0.3-alpha */ - public void save() throws Exception {} + public void save(boolean isOnline) throws Exception {} /** * Loads all user data. @@ -77,7 +80,7 @@ public abstract class LocalDB { * @since Envoy Client v0.1-beta */ public void synchronize() { - user.getContacts().stream().filter(u -> u instanceof User && !users.containsKey(u.getName())).forEach(u -> users.put(u.getName(), u)); + user.getContacts().stream().filter(u -> u instanceof User && !users.containsKey(u.getName())).forEach(u -> users.put(u.getName(), (User) u)); users.put(user.getName(), user); // Synchronize user status data @@ -98,7 +101,7 @@ public abstract class LocalDB { * user names as keys * @since Envoy Client v0.2-alpha */ - public Map getUsers() { return users; } + public Map getUsers() { return users; } /** * @return all saved {@link Chat} objects that list the client user as the @@ -148,6 +151,12 @@ public abstract class LocalDB { */ public CacheMap getCacheMap() { return cacheMap; } + /** + * @return the time stamp when the database was last saved + * @since Envoy Client v0.2-beta + */ + public Instant getLastSync() { return lastSync; } + /** * Searches for a message by ID. * diff --git a/client/src/main/java/envoy/client/data/PersistentLocalDB.java b/client/src/main/java/envoy/client/data/PersistentLocalDB.java index 182a4c8..1b0c310 100644 --- a/client/src/main/java/envoy/client/data/PersistentLocalDB.java +++ b/client/src/main/java/envoy/client/data/PersistentLocalDB.java @@ -1,6 +1,7 @@ package envoy.client.data; import java.io.*; +import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; @@ -26,7 +27,7 @@ public final class PersistentLocalDB extends LocalDB { /** * Constructs an empty local database. To serialize any user-specific data to * the file system, call {@link PersistentLocalDB#initializeUserStorage()} first - * and then {@link PersistentLocalDB#save()}. + * and then {@link PersistentLocalDB#save(boolean)}. * * @param dbDir the directory in which to persist data * @throws IOException if {@code dbDir} is a file (and not a directory) @@ -57,12 +58,12 @@ public final class PersistentLocalDB extends LocalDB { } @Override - public void save() throws IOException { + public void save(boolean isOnline) throws IOException { // Save users SerializationUtils.write(usersFile, users); - // Save user data - if (user != null) SerializationUtils.write(userFile, chats, cacheMap); + // Save user data and last sync time stamp + if (user != null) SerializationUtils.write(userFile, chats, cacheMap, isOnline ? Instant.now() : lastSync); // Save id generator if (hasIDGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator); @@ -76,6 +77,7 @@ public final class PersistentLocalDB extends LocalDB { try (var in = new ObjectInputStream(new FileInputStream(userFile))) { chats = (ArrayList) in.readObject(); cacheMap = (CacheMap) in.readObject(); + lastSync = (Instant) in.readObject(); } } diff --git a/client/src/main/java/envoy/client/ui/Startup.java b/client/src/main/java/envoy/client/ui/Startup.java index 99f163e..464b8e3 100644 --- a/client/src/main/java/envoy/client/ui/Startup.java +++ b/client/src/main/java/envoy/client/ui/Startup.java @@ -121,12 +121,13 @@ public final class Startup extends Application { @Override public void stop() { try { + logger.log(Level.INFO, "Saving local database and settings..."); + localDB.save(client.isOnline()); + Settings.getInstance().save(); + logger.log(Level.INFO, "Closing connection..."); client.close(); - logger.log(Level.INFO, "Saving local database and settings..."); - localDB.save(); - Settings.getInstance().save(); logger.log(Level.INFO, "Envoy was terminated by its user"); } catch (final Exception e) { logger.log(Level.SEVERE, "Unable to save local files: ", e); diff --git a/client/src/main/java/envoy/client/ui/controller/ChatScene.java b/client/src/main/java/envoy/client/ui/controller/ChatScene.java index 920d93f..c8c9062 100644 --- a/client/src/main/java/envoy/client/ui/controller/ChatScene.java +++ b/client/src/main/java/envoy/client/ui/controller/ChatScene.java @@ -183,12 +183,11 @@ public final class ChatScene implements Restorable { final var contact = e.get(); switch (e.getOperationType()) { case ADD: - localDB.getUsers().put(contact.getName(), contact); + if (contact instanceof User) localDB.getUsers().put(contact.getName(), (User) contact); Chat chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact); Platform.runLater(() -> chatList.getItems().add(chat)); break; case REMOVE: - localDB.getUsers().remove(contact.getName()); Platform.runLater(() -> chatList.getItems().removeIf(c -> c.getRecipient().equals(contact))); break; } diff --git a/client/src/main/java/envoy/client/ui/controller/LoginScene.java b/client/src/main/java/envoy/client/ui/controller/LoginScene.java index 3f0df5b..93978e8 100644 --- a/client/src/main/java/envoy/client/ui/controller/LoginScene.java +++ b/client/src/main/java/envoy/client/ui/controller/LoginScene.java @@ -2,6 +2,7 @@ package envoy.client.ui.controller; import java.io.FileNotFoundException; import java.io.IOException; +import java.time.Instant; import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -94,7 +95,8 @@ public final class LoginScene { userTextField.requestFocus(); // Perform automatic login if configured - if (config.hasLoginCredentials()) performHandshake(config.getLoginCredentials()); + if (config.hasLoginCredentials()) + performHandshake(new LoginCredentials(config.getUser(), config.getPassword(), false, Startup.VERSION, loadLastSync(config.getUser()))); } @FXML @@ -108,12 +110,13 @@ public final class LoginScene { new Alert(AlertType.ERROR, "The entered user name is not valid (" + Bounds.CONTACT_NAME_PATTERN + ")").showAndWait(); userTextField.getTextField().clear(); } else performHandshake(new LoginCredentials(userTextField.getTextField().getText(), passwordField.getText(), registerCheckBox.isSelected(), - Startup.VERSION)); + Startup.VERSION, loadLastSync(userTextField.getTextField().getText()))); } @FXML private void offlineModeButtonPressed() { - attemptOfflineMode(new LoginCredentials(userTextField.getTextField().getText(), passwordField.getText(), false, Startup.VERSION)); + attemptOfflineMode( + new LoginCredentials(userTextField.getTextField().getText(), passwordField.getText(), false, Startup.VERSION, localDB.getLastSync())); } @FXML @@ -130,6 +133,18 @@ public final class LoginScene { System.exit(0); } + private Instant loadLastSync(String identifier) { + try { + localDB.loadUsers(); + localDB.setUser(localDB.getUsers().get(identifier)); + localDB.initializeUserStorage(); + localDB.loadUserData(); + } catch (Exception e) { + // User storage empty, wrong user name etc. -> default lastSync + } + return localDB.getLastSync(); + } + private void performHandshake(LoginCredentials credentials) { try { client.performHandshake(credentials, cacheMap); diff --git a/client/src/main/java/envoy/client/ui/listcell/MessageControl.java b/client/src/main/java/envoy/client/ui/listcell/MessageControl.java index 8b7115b..a6ecae5 100644 --- a/client/src/main/java/envoy/client/ui/listcell/MessageControl.java +++ b/client/src/main/java/envoy/client/ui/listcell/MessageControl.java @@ -3,6 +3,7 @@ package envoy.client.ui.listcell; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.io.ByteArrayInputStream; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Map; import java.util.logging.Level; @@ -35,11 +36,12 @@ import envoy.util.EnvoyLog; */ public class MessageControl extends Label { - private static User client; - private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); - private static final Map statusImages = IconUtil.loadByEnum(MessageStatus.class, 16); + private static User client; - private static final Logger logger = EnvoyLog.getLogger(MessageControl.class); + private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss") + .withZone(ZoneId.systemDefault()); + private static final Map statusImages = IconUtil.loadByEnum(MessageStatus.class, 16); + private static final Logger logger = EnvoyLog.getLogger(MessageControl.class); /** * @@ -68,7 +70,8 @@ public class MessageControl extends Label { if (message.hasAttachment()) { switch (message.getAttachment().getType()) { case PICTURE: - vbox.getChildren().add(new ImageView(new Image(new ByteArrayInputStream(message.getAttachment().getData()), 256, 256, true, true))); + vbox.getChildren() + .add(new ImageView(new Image(new ByteArrayInputStream(message.getAttachment().getData()), 256, 256, true, true))); break; case VIDEO: break; diff --git a/common/src/main/java/envoy/data/GroupMessage.java b/common/src/main/java/envoy/data/GroupMessage.java index 7fb0d4a..93b8658 100644 --- a/common/src/main/java/envoy/data/GroupMessage.java +++ b/common/src/main/java/envoy/data/GroupMessage.java @@ -1,6 +1,6 @@ package envoy.data; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.Collections; import java.util.Map; @@ -16,7 +16,7 @@ public final class GroupMessage extends Message { private final Map memberStatuses; - private static final long serialVersionUID = 0L; + private static final long serialVersionUID = 1L; /** * Initializes a {@link GroupMessage} with values for all of its properties. The @@ -38,9 +38,9 @@ public final class GroupMessage extends Message { * @param forwarded whether this message was forwarded * @param memberStatuses a map of all members and their status according to this * {@link GroupMessage} - * @since Envoy Common v0.1-beta + * @since Envoy Common v0.2-beta */ - GroupMessage(long id, long senderID, long groupID, LocalDateTime creationDate, LocalDateTime receivedDate, LocalDateTime readDate, String text, + GroupMessage(long id, long senderID, long groupID, Instant creationDate, Instant receivedDate, Instant readDate, String text, Attachment attachment, MessageStatus status, boolean forwarded, Map memberStatuses) { super(id, senderID, groupID, creationDate, receivedDate, readDate, text, attachment, status, forwarded); this.memberStatuses = memberStatuses; @@ -55,10 +55,10 @@ public final class GroupMessage extends Message { setStatus(Collections.min(memberStatuses.values())); switch (getStatus()) { case RECEIVED: - setReceivedDate(LocalDateTime.now()); + setReceivedDate(Instant.now()); break; case READ: - setReadDate(LocalDateTime.now()); + setReadDate(Instant.now()); break; } } diff --git a/common/src/main/java/envoy/data/LoginCredentials.java b/common/src/main/java/envoy/data/LoginCredentials.java index 6257c10..0bef595 100644 --- a/common/src/main/java/envoy/data/LoginCredentials.java +++ b/common/src/main/java/envoy/data/LoginCredentials.java @@ -1,6 +1,7 @@ package envoy.data; import java.io.Serializable; +import java.time.Instant; /** * Contains a {@link User}'s login / registration information as well as the @@ -17,8 +18,9 @@ public final class LoginCredentials implements Serializable { private final String identifier, password, clientVersion; private final boolean registration; + private final Instant lastSync; - private static final long serialVersionUID = 2; + private static final long serialVersionUID = 3; /** * Initializes login credentials for a handshake. @@ -28,18 +30,24 @@ public final class LoginCredentials implements Serializable { * @param registration signifies that these credentials are used for user * registration instead of user login * @param clientVersion the version of the client sending these credentials - * @since Envoy Common v0.1-beta + * @param lastSync the time stamp of the last synchronization + * @since Envoy Common v0.2-beta */ - public LoginCredentials(String identifier, String password, boolean registration, String clientVersion) { + public LoginCredentials(String identifier, String password, boolean registration, String clientVersion, Instant lastSync) { this.identifier = identifier; this.password = password; this.registration = registration; this.clientVersion = clientVersion; + this.lastSync = lastSync; } @Override public String toString() { - return String.format("LoginCredentials[identifier=%s,registration=%b,clientVersion=%s]", identifier, registration, clientVersion); + return String.format("LoginCredentials[identifier=%s,registration=%b,clientVersion=%s,lastSync=%s]", + identifier, + registration, + clientVersion, + lastSync); } /** @@ -66,4 +74,10 @@ public final class LoginCredentials implements Serializable { * @since Envoy Common v0.1-beta */ public String getClientVersion() { return clientVersion; } + + /** + * @return the time stamp of the last synchronization + * @since Envoy Common v0.2-beta + */ + public Instant getLastSync() { return lastSync; } } diff --git a/common/src/main/java/envoy/data/Message.java b/common/src/main/java/envoy/data/Message.java index 040ad59..8d31bd3 100644 --- a/common/src/main/java/envoy/data/Message.java +++ b/common/src/main/java/envoy/data/Message.java @@ -1,8 +1,7 @@ package envoy.data; import java.io.Serializable; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; +import java.time.Instant; /** * Represents a unique message with a unique, numeric ID. Further metadata @@ -50,14 +49,14 @@ public class Message implements Serializable { private final long id, senderID, recipientID; private final boolean forwarded; - private final LocalDateTime creationDate; + private final Instant creationDate; private final String text; private final Attachment attachment; - private LocalDateTime receivedDate, readDate; + private Instant receivedDate, readDate; private MessageStatus status; - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 2L; /** * Initializes a {@link Message} with values for all of its properties. The use @@ -75,9 +74,9 @@ public class Message implements Serializable { * @param attachment the attachment of the message, if present * @param status the current {@link MessageStatus} of the message * @param forwarded whether this message was forwarded - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - Message(long id, long senderID, long recipientID, LocalDateTime creationDate, LocalDateTime receivedDate, LocalDateTime readDate, String text, + Message(long id, long senderID, long recipientID, Instant creationDate, Instant receivedDate, Instant readDate, String text, Attachment attachment, MessageStatus status, boolean forwarded) { this.id = id; this.senderID = senderID; @@ -115,7 +114,7 @@ public class Message implements Serializable { id, senderID, recipientID, - DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss").format(creationDate), + creationDate, status, text, forwarded, @@ -142,34 +141,34 @@ public class Message implements Serializable { /** * @return the date at which this message was created - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - public LocalDateTime getCreationDate() { return creationDate; } + public Instant getCreationDate() { return creationDate; } /** * @return the date at which the message has been received by the sender - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - public LocalDateTime getReceivedDate() { return receivedDate; } + public Instant getReceivedDate() { return receivedDate; } /** * @param receivedDate the date at which the message has been received by the * sender - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - public void setReceivedDate(LocalDateTime receivedDate) { this.receivedDate = receivedDate; } + public void setReceivedDate(Instant receivedDate) { this.receivedDate = receivedDate; } /** * @return the date at which the message has been read by the sender - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - public LocalDateTime getReadDate() { return readDate; } + public Instant getReadDate() { return readDate; } /** * @param readDate at which the message has been read by the sender - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - public void setReadDate(LocalDateTime readDate) { this.readDate = readDate; } + public void setReadDate(Instant readDate) { this.readDate = readDate; } /** * @return the text content of this message diff --git a/common/src/main/java/envoy/data/MessageBuilder.java b/common/src/main/java/envoy/data/MessageBuilder.java index 917adc4..82df03d 100644 --- a/common/src/main/java/envoy/data/MessageBuilder.java +++ b/common/src/main/java/envoy/data/MessageBuilder.java @@ -1,6 +1,6 @@ package envoy.data; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.HashMap; import java.util.Map; @@ -23,7 +23,7 @@ public class MessageBuilder { // Properties with default values private long id; - private LocalDateTime creationDate, receivedDate, readDate; + private Instant creationDate, receivedDate, readDate; private String text; private Attachment attachment; private Message.MessageStatus status; @@ -70,7 +70,7 @@ public class MessageBuilder { public MessageBuilder(Message msg, long recipientID, IDGenerator iDGenerator) { this(msg.getRecipientID(), recipientID, iDGenerator.next()); this.attachment = msg.getAttachment(); - this.creationDate = LocalDateTime.now(); + this.creationDate = Instant.now(); this.forwarded = true; this.text = msg.getText(); this.status = MessageStatus.WAITING; @@ -83,7 +83,7 @@ public class MessageBuilder { * * * - * * * @@ -113,8 +113,8 @@ public class MessageBuilder { *
*
{@code date}{@code LocalDateTime.now()} and {@code null} for {@code receivedDate} and + * {@code Instant.now()} and {@code null} for {@code receivedDate} and * {@code readDate}
* - * - * + * + * * * * @@ -140,8 +140,8 @@ public class MessageBuilder { *
*
{@code date}{@code new Date()}{@code time stamp}{@code Instant.now()}
{@code text}
* - * - * + * + * * * * @@ -162,7 +162,7 @@ public class MessageBuilder { } private void supplyDefaults() { - if (creationDate == null) creationDate = LocalDateTime.now(); + if (creationDate == null) creationDate = Instant.now(); if (text == null) text = ""; if (status == null) status = MessageStatus.WAITING; } @@ -170,9 +170,9 @@ public class MessageBuilder { /** * @param creationDate the creation date of the {@link Message} to create * @return this {@link MessageBuilder} - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - public MessageBuilder setCreationDate(LocalDateTime creationDate) { + public MessageBuilder setCreationDate(Instant creationDate) { this.creationDate = creationDate; return this; } @@ -180,9 +180,9 @@ public class MessageBuilder { /** * @param receivedDate the received date of the {@link Message} to create * @return this {@link MessageBuilder} - * @since Envoy Common v0.1-beta + * @since Envoy Common v0.2-beta */ - public MessageBuilder setReceivedDate(LocalDateTime receivedDate) { + public MessageBuilder setReceivedDate(Instant receivedDate) { this.receivedDate = receivedDate; return this; } @@ -190,9 +190,9 @@ public class MessageBuilder { /** * @param readDate the read date of the {@link Message} to create * @return this {@link MessageBuilder} - * @since Envoy Common v0.1-beta + * @since Envoy Common v0.2-beta */ - public MessageBuilder setReadDate(LocalDateTime readDate) { + public MessageBuilder setReadDate(Instant readDate) { this.readDate = readDate; return this; } diff --git a/common/src/main/java/envoy/event/GroupMessageStatusChange.java b/common/src/main/java/envoy/event/GroupMessageStatusChange.java index 01f63ae..6bf4626 100644 --- a/common/src/main/java/envoy/event/GroupMessageStatusChange.java +++ b/common/src/main/java/envoy/event/GroupMessageStatusChange.java @@ -1,6 +1,6 @@ package envoy.event; -import java.time.LocalDateTime; +import java.time.Instant; import envoy.data.GroupMessage; import envoy.data.Message.MessageStatus; @@ -27,9 +27,9 @@ public class GroupMessageStatusChange extends MessageStatusChange { * @param date the date at which the MessageStatus change occurred for * this specific member * @param memberID the ID of the group member that caused the status change - * @since Envoy Common v0.1-beta + * @since Envoy Common v0.2-beta */ - public GroupMessageStatusChange(long id, MessageStatus status, LocalDateTime date, long memberID) { + public GroupMessageStatusChange(long id, MessageStatus status, Instant date, long memberID) { super(id, status, date); this.memberID = memberID; } diff --git a/common/src/main/java/envoy/event/MessageStatusChange.java b/common/src/main/java/envoy/event/MessageStatusChange.java index 01e5c70..aa94e6d 100644 --- a/common/src/main/java/envoy/event/MessageStatusChange.java +++ b/common/src/main/java/envoy/event/MessageStatusChange.java @@ -1,6 +1,6 @@ package envoy.event; -import java.time.LocalDateTime; +import java.time.Instant; import envoy.data.Message; @@ -14,8 +14,8 @@ import envoy.data.Message; */ public class MessageStatusChange extends Event { - private final long id; - private final LocalDateTime date; + private final long id; + private final Instant date; private static final long serialVersionUID = 0L; @@ -26,9 +26,9 @@ public class MessageStatusChange extends Event { * @param status the status of the {@link Message} this event is related * to * @param date the date at which the MessageStatus change occurred - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - public MessageStatusChange(long id, Message.MessageStatus status, LocalDateTime date) { + public MessageStatusChange(long id, Message.MessageStatus status, Instant date) { super(status); this.id = id; this.date = date; @@ -40,7 +40,7 @@ public class MessageStatusChange extends Event { * @param message the message from which to build the event * @since Envoy Common v0.2-alpha */ - public MessageStatusChange(Message message) { this(message.getID(), message.getStatus(), LocalDateTime.now()); } + public MessageStatusChange(Message message) { this(message.getID(), message.getStatus(), Instant.now()); } /** * @return the ID of the {@link Message} this event is related to @@ -50,9 +50,9 @@ public class MessageStatusChange extends Event { /** * @return the date at which the status change occurred - * @since Envoy Common v0.2-alpha + * @since Envoy Common v0.2-beta */ - public LocalDateTime getDate() { return date; } + public Instant getDate() { return date; } @Override public String toString() { return String.format("MessageStatusChange[id=%d,status=%s,date=%s]", id, value, date); } diff --git a/server/src/main/java/envoy/server/data/Contact.java b/server/src/main/java/envoy/server/data/Contact.java index c802837..79cd720 100644 --- a/server/src/main/java/envoy/server/data/Contact.java +++ b/server/src/main/java/envoy/server/data/Contact.java @@ -1,6 +1,6 @@ package envoy.server.data; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.Set; import javax.persistence.*; @@ -28,7 +28,7 @@ public abstract class Contact { protected String name; @Column(name = "creation_date") - private LocalDateTime creationDate; + private Instant creationDate; @ManyToMany(fetch = FetchType.EAGER) protected Set contacts; @@ -92,15 +92,15 @@ public abstract class Contact { /** * @return the creationDate - * @since Envoy Server Standalone v0.1-beta + * @since Envoy Server Standalone v0.2-beta */ - public LocalDateTime getCreationDate() { return creationDate; } + public Instant getCreationDate() { return creationDate; } /** * @param creationDate the creationDate to set - * @since Envoy Server Standalone v0.1-beta + * @since Envoy Server Standalone v0.2-beta */ - public void setCreationDate(LocalDateTime creationDate) { this.creationDate = creationDate; } + 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()); } diff --git a/server/src/main/java/envoy/server/data/GroupMessage.java b/server/src/main/java/envoy/server/data/GroupMessage.java index 90ad823..bb96895 100644 --- a/server/src/main/java/envoy/server/data/GroupMessage.java +++ b/server/src/main/java/envoy/server/data/GroupMessage.java @@ -1,6 +1,6 @@ package envoy.server.data; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.HashMap; import java.util.Map; @@ -39,7 +39,7 @@ public class GroupMessage extends Message { private Map memberMessageStatus; @Column(name = "last_status_change_date") - protected LocalDateTime lastStatusChangeDate; + protected Instant lastStatusChangeDate; /** * The constructor for a database object. @@ -55,9 +55,9 @@ public class GroupMessage extends Message { * into a * database {@link GroupMessage} * @param lastStatusChangeDate the time stamp to set - * @since Envoy Server Standalone v0.1-beta + * @since Envoy Server Standalone v0.2-beta */ - public GroupMessage(envoy.data.GroupMessage groupMessage, LocalDateTime lastStatusChangeDate) { + public GroupMessage(envoy.data.GroupMessage groupMessage, Instant lastStatusChangeDate) { super(groupMessage); memberMessageStatus = groupMessage.getMemberStatuses(); this.lastStatusChangeDate = lastStatusChangeDate; @@ -92,13 +92,13 @@ public class GroupMessage extends Message { /** * @return the date at which one of the member statuses changed last - * @since Envoy Server Standalone v0.1-beta + * @since Envoy Server Standalone v0.2-beta */ - public LocalDateTime getLastStatusChangeDate() { return lastStatusChangeDate; } + public Instant getLastStatusChangeDate() { return lastStatusChangeDate; } /** * @param date the date to set - * @since Envoy Server Standalone v0.1-beta + * @since Envoy Server Standalone v0.2-beta */ - public void setLastStatusChangeDate(LocalDateTime date) { lastStatusChangeDate = date; } + public void setLastStatusChangeDate(Instant date) { lastStatusChangeDate = date; } } diff --git a/server/src/main/java/envoy/server/data/Message.java b/server/src/main/java/envoy/server/data/Message.java index afe66c7..d99b3b0 100755 --- a/server/src/main/java/envoy/server/data/Message.java +++ b/server/src/main/java/envoy/server/data/Message.java @@ -2,7 +2,7 @@ package envoy.server.data; import static envoy.data.Message.MessageStatus.*; -import java.time.LocalDateTime; +import java.time.Instant; import javax.persistence.*; @@ -55,13 +55,13 @@ public class Message { protected Contact recipient; @Column(name = "creation_date") - protected LocalDateTime creationDate; + protected Instant creationDate; @Column(name = "received_date") - protected LocalDateTime receivedDate; + protected Instant receivedDate; @Column(name = "read_date") - protected LocalDateTime readDate; + protected Instant readDate; protected String text; protected envoy.data.Message.MessageStatus status; @@ -134,7 +134,7 @@ public class Message { * @since Envoy Server Standalone v0.1-beta */ public void received() { - receivedDate = LocalDateTime.now(); + receivedDate = Instant.now(); status = RECEIVED; } @@ -145,7 +145,7 @@ public class Message { * @since Envoy Server Standalone v0.1-beta */ public void read() { - readDate = LocalDateTime.now(); + readDate = Instant.now(); status = READ; } @@ -190,43 +190,43 @@ public class Message { /** * @return the date at which a {link envoy.data.Message} has been created - * @since Envoy Server Standalone v0.1-alpha + * @since Envoy Server Standalone v0.2-beta */ - public LocalDateTime getCreationDate() { return creationDate; } + public Instant getCreationDate() { return creationDate; } /** * @param creationDate the creation date to set - * @since Envoy Server Standalone v0.1-alpha + * @since Envoy Server Standalone v0.2-beta * @see Message#getCreationDate() */ - public void setCreationDate(LocalDateTime creationDate) { this.creationDate = creationDate; } + 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.1-alpha + * @since Envoy Server Standalone v0.2-beta */ - public LocalDateTime getReceivedDate() { return receivedDate; } + public Instant getReceivedDate() { return receivedDate; } /** * @param receivedDate the received date to set - * @since Envoy Server Standalone v0.1-alpha + * @since Envoy Server Standalone v0.2-beta * @see Message#getReceivedDate() */ - public void setReceivedDate(LocalDateTime receivedDate) { this.receivedDate = receivedDate; } + 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.1-alpha + * @since Envoy Server Standalone v0.2-beta */ - public LocalDateTime getReadDate() { return readDate; } + public Instant getReadDate() { return readDate; } /** * @param readDate the read date to set - * @since Envoy Server Standalone v0.1-alpha + * @since Envoy Server Standalone v0.2-beta * @see Message#getReadDate() */ - public void setReadDate(LocalDateTime readDate) { this.readDate = readDate; } + public void setReadDate(Instant readDate) { this.readDate = readDate; } /** * @return the status of a {link envoy.data.Message} diff --git a/server/src/main/java/envoy/server/data/PersistenceManager.java b/server/src/main/java/envoy/server/data/PersistenceManager.java index 3432846..7ec3524 100755 --- a/server/src/main/java/envoy/server/data/PersistenceManager.java +++ b/server/src/main/java/envoy/server/data/PersistenceManager.java @@ -1,6 +1,6 @@ package envoy.server.data; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.List; import javax.persistence.EntityManager; @@ -38,7 +38,7 @@ public class PersistenceManager { .getOnlineUsers() .stream() .map(this::getUserByID) - .forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(LocalDateTime.now()); entityManager.merge(user); }); + .forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(Instant.now()); entityManager.merge(user); }); transaction.commit(); })); } @@ -182,31 +182,29 @@ public class PersistenceManager { * Returns all messages received while being offline or the ones that have * changed. * - * @param user the user who wants to receive his unread messages + * @param user the user who wants to receive his unread messages + * @param lastSync the time stamp of the last synchronization * @return all messages that the client does not yet have (unread messages) - * @since Envoy Server Standalone v0.1-alpha + * @since Envoy Server Standalone v0.2-beta */ - public List getPendingMessages(User user) { - return entityManager - .createNamedQuery(Message.getPending) - .setParameter("user", user) - .setParameter("lastSeen", user.getLastSeen()) - .getResultList(); + public List getPendingMessages(User user, Instant lastSync) { + return entityManager.createNamedQuery(Message.getPending).setParameter("user", user).setParameter("lastSeen", lastSync).getResultList(); } /** * Returns all groupMessages received while being offline or the ones that have * changed. * - * @param user the user who wants to receive his unread groupMessages + * @param user the user who wants to receive his unread groupMessages + * @param lastSync the time stamp of the last synchronization * @return all groupMessages that the client does not yet have (unread * groupMessages) - * @since Envoy Server Standalone v0.1-alpha + * @since Envoy Server Standalone v0.2-beta */ - public List getPendingGroupMessages(User user) { + public List getPendingGroupMessages(User user, Instant lastSync) { return entityManager.createNamedQuery(GroupMessage.getPendingGroupMsg) .setParameter("userId", user.getID()) - .setParameter("lastSeen", user.getLastSeen()) + .setParameter("lastSeen", lastSync) .getResultList(); } @@ -221,8 +219,7 @@ public class PersistenceManager { * @since Envoy Server Standalone v0.1-alpha */ public List searchUsers(String searchPhrase, long userId) { - return entityManager.createNamedQuery( - User.searchByName) + return entityManager.createNamedQuery(User.searchByName) .setParameter("searchPhrase", searchPhrase + "%") .setParameter("context", getUserByID(userId)) .getResultList(); diff --git a/server/src/main/java/envoy/server/data/User.java b/server/src/main/java/envoy/server/data/User.java index 81b4d9e..b9e3d85 100755 --- a/server/src/main/java/envoy/server/data/User.java +++ b/server/src/main/java/envoy/server/data/User.java @@ -1,6 +1,6 @@ package envoy.server.data; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.Set; import java.util.stream.Collectors; @@ -66,7 +66,7 @@ public class User extends Contact { private String passwordHash; @Column(name = "last_seen") - private LocalDateTime lastSeen; + private Instant lastSeen; private UserStatus status; @@ -92,15 +92,15 @@ public class User extends Contact { /** * @return the last date the user has been online - * @since Envoy Server Standalone v0.1-alpha + * @since Envoy Server Standalone v0.2-beta */ - public LocalDateTime getLastSeen() { return lastSeen; } + public Instant getLastSeen() { return lastSeen; } /** * @param lastSeen the latest date at which the user has been online to set - * @since Envoy Server Standalone v0.1-alpha + * @since Envoy Server Standalone v0.2-beta */ - public void setLastSeen(LocalDateTime lastSeen) { this.lastSeen = lastSeen; } + public void setLastSeen(Instant lastSeen) { this.lastSeen = lastSeen; } /** * @return the status diff --git a/server/src/main/java/envoy/server/net/ConnectionManager.java b/server/src/main/java/envoy/server/net/ConnectionManager.java index e0ce7ed..99bc683 100755 --- a/server/src/main/java/envoy/server/net/ConnectionManager.java +++ b/server/src/main/java/envoy/server/net/ConnectionManager.java @@ -1,6 +1,6 @@ package envoy.server.net; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -52,7 +52,7 @@ public class ConnectionManager implements ISocketIdListener { // Notify contacts of this users offline-going envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID)); user.setStatus(UserStatus.OFFLINE); - user.setLastSeen(LocalDateTime.now()); + user.setLastSeen(Instant.now()); UserStatusChangeProcessor.updateUserStatus(user); // Remove the socket diff --git a/server/src/main/java/envoy/server/processors/GroupMessageProcessor.java b/server/src/main/java/envoy/server/processors/GroupMessageProcessor.java index 54594e3..8be1a57 100644 --- a/server/src/main/java/envoy/server/processors/GroupMessageProcessor.java +++ b/server/src/main/java/envoy/server/processors/GroupMessageProcessor.java @@ -2,7 +2,7 @@ package envoy.server.processors; import static envoy.data.Message.MessageStatus.*; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.Collections; import java.util.logging.Logger; @@ -56,7 +56,7 @@ public class GroupMessageProcessor implements ObjectProcessor { groupMessage); try { - PersistenceManager.getInstance().addMessage(new envoy.server.data.GroupMessage(groupMessage, LocalDateTime.now())); + PersistenceManager.getInstance().addMessage(new envoy.server.data.GroupMessage(groupMessage, Instant.now())); } catch (EntityExistsException e) { logger.warning("Received a groupMessage with an ID that already exists"); } diff --git a/server/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java b/server/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java index fa3bcb2..9e1077b 100644 --- a/server/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java +++ b/server/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java @@ -2,7 +2,7 @@ package envoy.server.processors; import static envoy.data.Message.MessageStatus.READ; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.Collections; import java.util.logging.Level; import java.util.logging.Logger; @@ -42,7 +42,7 @@ public class GroupMessageStatusChangeProcessor implements ObjectProcessor()); @@ -117,7 +117,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user); + List pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user, credentials.getLastSync()); logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "..."); for (var gmsg : pendingGroupMessages) { @@ -148,13 +148,13 @@ public final class LoginCredentialProcessor implements ObjectProcessor
{@code date}{@code new Date()}{@code time stamp}{@code Instant.now()}
{@code text}