Prepare handshake synchronization
Common * Replace LocalDateTime with Instant everywhere Client * Display message creation date with system time zone in MessageControl * LocalDB#users now strictly contains Users * lastSync time stamp in LocalDB (saved per user) * isOnline parameter in save function (lastSync updated if true) * lastSync time stamp in LoginCredentials * No ClientConfig#getLoginCredentials because of missing information, moved to LoginScene * Pass LocalDB#lastSync to LoginCredentials in LoginScene Server * Explicit lastSync parameter for PersistenceManager#getPending(Group)Messages This sends the correct time stamp to the server, however the JPQL queries have yet to be adjusted.
This commit is contained in:
		@@ -5,10 +5,8 @@ import static java.util.function.Function.identity;
 | 
				
			|||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.ui.Startup;
 | 
					 | 
				
			||||||
import envoy.data.Config;
 | 
					import envoy.data.Config;
 | 
				
			||||||
import envoy.data.ConfigItem;
 | 
					import envoy.data.ConfigItem;
 | 
				
			||||||
import envoy.data.LoginCredentials;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Implements a configuration specific to the Envoy Client with default values
 | 
					 * 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
 | 
						 * @since Envoy Client v0.3-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public boolean hasLoginCredentials() { return getUser() != null && getPassword() != null; }
 | 
						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); }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
package envoy.client.data;
 | 
					package envoy.client.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.net.WriteProxy;
 | 
					import envoy.client.net.WriteProxy;
 | 
				
			||||||
import envoy.data.Contact;
 | 
					import envoy.data.Contact;
 | 
				
			||||||
@@ -46,7 +46,7 @@ public class GroupChat extends Chat {
 | 
				
			|||||||
				else {
 | 
									else {
 | 
				
			||||||
					gmsg.getMemberStatuses().replace(sender.getID(), MessageStatus.READ);
 | 
										gmsg.getMemberStatuses().replace(sender.getID(), MessageStatus.READ);
 | 
				
			||||||
					writeProxy
 | 
										writeProxy
 | 
				
			||||||
						.writeMessageStatusChange(new GroupMessageStatusChange(gmsg.getID(), MessageStatus.READ, LocalDateTime.now(), sender.getID()));
 | 
											.writeMessageStatusChange(new GroupMessageStatusChange(gmsg.getID(), MessageStatus.READ, Instant.now(), sender.getID()));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
package envoy.client.data;
 | 
					package envoy.client.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.*;
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.data.*;
 | 
					import envoy.data.*;
 | 
				
			||||||
@@ -20,11 +21,12 @@ import envoy.event.NameChange;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public abstract class LocalDB {
 | 
					public abstract class LocalDB {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected User					user;
 | 
						protected User				user;
 | 
				
			||||||
	protected Map<String, Contact>	users		= new HashMap<>();
 | 
						protected Map<String, User>	users		= new HashMap<>();
 | 
				
			||||||
	protected List<Chat>			chats		= new ArrayList<>();
 | 
						protected List<Chat>		chats		= new ArrayList<>();
 | 
				
			||||||
	protected IDGenerator			idGenerator;
 | 
						protected IDGenerator		idGenerator;
 | 
				
			||||||
	protected CacheMap				cacheMap	= new CacheMap();
 | 
						protected CacheMap			cacheMap	= new CacheMap();
 | 
				
			||||||
 | 
						protected Instant			lastSync	= Instant.EPOCH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cacheMap.put(Message.class, new Cache<>());
 | 
							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
 | 
						 * 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.
 | 
						 * 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
 | 
						 * @throws Exception if the saving process failed
 | 
				
			||||||
	 * @since Envoy Client v0.3-alpha
 | 
						 * @since Envoy Client v0.3-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void save() throws Exception {}
 | 
						public void save(boolean isOnline) throws Exception {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Loads all user data.
 | 
						 * Loads all user data.
 | 
				
			||||||
@@ -77,7 +80,7 @@ public abstract class LocalDB {
 | 
				
			|||||||
	 * @since Envoy Client v0.1-beta
 | 
						 * @since Envoy Client v0.1-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void synchronize() {
 | 
						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);
 | 
							users.put(user.getName(), user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Synchronize user status data
 | 
							// Synchronize user status data
 | 
				
			||||||
@@ -98,7 +101,7 @@ public abstract class LocalDB {
 | 
				
			|||||||
	 *         user names as keys
 | 
						 *         user names as keys
 | 
				
			||||||
	 * @since Envoy Client v0.2-alpha
 | 
						 * @since Envoy Client v0.2-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public Map<String, Contact> getUsers() { return users; }
 | 
						public Map<String, User> getUsers() { return users; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return all saved {@link Chat} objects that list the client user as the
 | 
						 * @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; }
 | 
						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.
 | 
						 * Searches for a message by ID.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package envoy.client.data;
 | 
					package envoy.client.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.*;
 | 
				
			||||||
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.HashMap;
 | 
					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
 | 
						 * Constructs an empty local database. To serialize any user-specific data to
 | 
				
			||||||
	 * the file system, call {@link PersistentLocalDB#initializeUserStorage()} first
 | 
						 * 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
 | 
						 * @param dbDir the directory in which to persist data
 | 
				
			||||||
	 * @throws IOException if {@code dbDir} is a file (and not a directory)
 | 
						 * @throws IOException if {@code dbDir} is a file (and not a directory)
 | 
				
			||||||
@@ -57,12 +58,12 @@ public final class PersistentLocalDB extends LocalDB {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void save() throws IOException {
 | 
						public void save(boolean isOnline) throws IOException {
 | 
				
			||||||
		// Save users
 | 
							// Save users
 | 
				
			||||||
		SerializationUtils.write(usersFile, users);
 | 
							SerializationUtils.write(usersFile, users);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Save user data
 | 
							// Save user data and last sync time stamp
 | 
				
			||||||
		if (user != null) SerializationUtils.write(userFile, chats, cacheMap);
 | 
							if (user != null) SerializationUtils.write(userFile, chats, cacheMap, isOnline ? Instant.now() : lastSync);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Save id generator
 | 
							// Save id generator
 | 
				
			||||||
		if (hasIDGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
 | 
							if (hasIDGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
 | 
				
			||||||
@@ -76,6 +77,7 @@ public final class PersistentLocalDB extends LocalDB {
 | 
				
			|||||||
		try (var in = new ObjectInputStream(new FileInputStream(userFile))) {
 | 
							try (var in = new ObjectInputStream(new FileInputStream(userFile))) {
 | 
				
			||||||
			chats		= (ArrayList<Chat>) in.readObject();
 | 
								chats		= (ArrayList<Chat>) in.readObject();
 | 
				
			||||||
			cacheMap	= (CacheMap) in.readObject();
 | 
								cacheMap	= (CacheMap) in.readObject();
 | 
				
			||||||
 | 
								lastSync	= (Instant) in.readObject();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -121,12 +121,13 @@ public final class Startup extends Application {
 | 
				
			|||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void stop() {
 | 
						public void stop() {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
 | 
								logger.log(Level.INFO, "Saving local database and settings...");
 | 
				
			||||||
 | 
								localDB.save(client.isOnline());
 | 
				
			||||||
 | 
								Settings.getInstance().save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			logger.log(Level.INFO, "Closing connection...");
 | 
								logger.log(Level.INFO, "Closing connection...");
 | 
				
			||||||
			client.close();
 | 
								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");
 | 
								logger.log(Level.INFO, "Envoy was terminated by its user");
 | 
				
			||||||
		} catch (final Exception e) {
 | 
							} catch (final Exception e) {
 | 
				
			||||||
			logger.log(Level.SEVERE, "Unable to save local files: ", e);
 | 
								logger.log(Level.SEVERE, "Unable to save local files: ", e);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -183,12 +183,11 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
			final var contact = e.get();
 | 
								final var contact = e.get();
 | 
				
			||||||
			switch (e.getOperationType()) {
 | 
								switch (e.getOperationType()) {
 | 
				
			||||||
				case ADD:
 | 
									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);
 | 
										Chat chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact);
 | 
				
			||||||
					Platform.runLater(() -> chatList.getItems().add(chat));
 | 
										Platform.runLater(() -> chatList.getItems().add(chat));
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				case REMOVE:
 | 
									case REMOVE:
 | 
				
			||||||
					localDB.getUsers().remove(contact.getName());
 | 
					 | 
				
			||||||
					Platform.runLater(() -> chatList.getItems().removeIf(c -> c.getRecipient().equals(contact)));
 | 
										Platform.runLater(() -> chatList.getItems().removeIf(c -> c.getRecipient().equals(contact)));
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ package envoy.client.ui.controller;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import java.io.FileNotFoundException;
 | 
					import java.io.FileNotFoundException;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.concurrent.TimeoutException;
 | 
					import java.util.concurrent.TimeoutException;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
import java.util.logging.Logger;
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
@@ -94,7 +95,8 @@ public final class LoginScene {
 | 
				
			|||||||
		userTextField.requestFocus();
 | 
							userTextField.requestFocus();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Perform automatic login if configured
 | 
							// 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
 | 
						@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();
 | 
								new Alert(AlertType.ERROR, "The entered user name is not valid (" + Bounds.CONTACT_NAME_PATTERN + ")").showAndWait();
 | 
				
			||||||
			userTextField.getTextField().clear();
 | 
								userTextField.getTextField().clear();
 | 
				
			||||||
		} else performHandshake(new LoginCredentials(userTextField.getTextField().getText(), passwordField.getText(), registerCheckBox.isSelected(),
 | 
							} else performHandshake(new LoginCredentials(userTextField.getTextField().getText(), passwordField.getText(), registerCheckBox.isSelected(),
 | 
				
			||||||
				Startup.VERSION));
 | 
									Startup.VERSION, loadLastSync(userTextField.getTextField().getText())));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
	private void offlineModeButtonPressed() {
 | 
						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
 | 
						@FXML
 | 
				
			||||||
@@ -130,6 +133,18 @@ public final class LoginScene {
 | 
				
			|||||||
		System.exit(0);
 | 
							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) {
 | 
						private void performHandshake(LoginCredentials credentials) {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			client.performHandshake(credentials, cacheMap);
 | 
								client.performHandshake(credentials, cacheMap);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ package envoy.client.ui.listcell;
 | 
				
			|||||||
import java.awt.Toolkit;
 | 
					import java.awt.Toolkit;
 | 
				
			||||||
import java.awt.datatransfer.StringSelection;
 | 
					import java.awt.datatransfer.StringSelection;
 | 
				
			||||||
import java.io.ByteArrayInputStream;
 | 
					import java.io.ByteArrayInputStream;
 | 
				
			||||||
 | 
					import java.time.ZoneId;
 | 
				
			||||||
import java.time.format.DateTimeFormatter;
 | 
					import java.time.format.DateTimeFormatter;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
@@ -35,11 +36,12 @@ import envoy.util.EnvoyLog;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class MessageControl extends Label {
 | 
					public class MessageControl extends Label {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static User								client;
 | 
						private static User client;
 | 
				
			||||||
	private static final DateTimeFormatter			dateFormat		= DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
 | 
					 | 
				
			||||||
	private static final Map<MessageStatus, Image>	statusImages	= IconUtil.loadByEnum(MessageStatus.class, 16);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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<MessageStatus, Image>	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()) {
 | 
							if (message.hasAttachment()) {
 | 
				
			||||||
			switch (message.getAttachment().getType()) {
 | 
								switch (message.getAttachment().getType()) {
 | 
				
			||||||
				case PICTURE:
 | 
									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;
 | 
										break;
 | 
				
			||||||
				case VIDEO:
 | 
									case VIDEO:
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.data;
 | 
					package envoy.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,7 +16,7 @@ public final class GroupMessage extends Message {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	private final Map<Long, MessageStatus> memberStatuses;
 | 
						private final Map<Long, MessageStatus> 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
 | 
						 * 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 forwarded      whether this message was forwarded
 | 
				
			||||||
	 * @param memberStatuses a map of all members and their status according to this
 | 
						 * @param memberStatuses a map of all members and their status according to this
 | 
				
			||||||
	 *                       {@link GroupMessage}
 | 
						 *                       {@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<Long, MessageStatus> memberStatuses) {
 | 
								Attachment attachment, MessageStatus status, boolean forwarded, Map<Long, MessageStatus> memberStatuses) {
 | 
				
			||||||
		super(id, senderID, groupID, creationDate, receivedDate, readDate, text, attachment, status, forwarded);
 | 
							super(id, senderID, groupID, creationDate, receivedDate, readDate, text, attachment, status, forwarded);
 | 
				
			||||||
		this.memberStatuses = memberStatuses;
 | 
							this.memberStatuses = memberStatuses;
 | 
				
			||||||
@@ -55,10 +55,10 @@ public final class GroupMessage extends Message {
 | 
				
			|||||||
		setStatus(Collections.min(memberStatuses.values()));
 | 
							setStatus(Collections.min(memberStatuses.values()));
 | 
				
			||||||
		switch (getStatus()) {
 | 
							switch (getStatus()) {
 | 
				
			||||||
			case RECEIVED:
 | 
								case RECEIVED:
 | 
				
			||||||
				setReceivedDate(LocalDateTime.now());
 | 
									setReceivedDate(Instant.now());
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case READ:
 | 
								case READ:
 | 
				
			||||||
				setReadDate(LocalDateTime.now());
 | 
									setReadDate(Instant.now());
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package envoy.data;
 | 
					package envoy.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.Serializable;
 | 
					import java.io.Serializable;
 | 
				
			||||||
 | 
					import java.time.Instant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Contains a {@link User}'s login / registration information as well as the
 | 
					 * 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 String	identifier, password, clientVersion;
 | 
				
			||||||
	private final boolean	registration;
 | 
						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.
 | 
						 * 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
 | 
						 * @param registration  signifies that these credentials are used for user
 | 
				
			||||||
	 *                      registration instead of user login
 | 
						 *                      registration instead of user login
 | 
				
			||||||
	 * @param clientVersion the version of the client sending these credentials
 | 
						 * @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.identifier		= identifier;
 | 
				
			||||||
		this.password		= password;
 | 
							this.password		= password;
 | 
				
			||||||
		this.registration	= registration;
 | 
							this.registration	= registration;
 | 
				
			||||||
		this.clientVersion	= clientVersion;
 | 
							this.clientVersion	= clientVersion;
 | 
				
			||||||
 | 
							this.lastSync		= lastSync;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public String toString() {
 | 
						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
 | 
						 * @since Envoy Common v0.1-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public String getClientVersion() { return clientVersion; }
 | 
						public String getClientVersion() { return clientVersion; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @return the time stamp of the last synchronization
 | 
				
			||||||
 | 
						 * @since Envoy Common v0.2-beta
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public Instant getLastSync() { return lastSync; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,7 @@
 | 
				
			|||||||
package envoy.data;
 | 
					package envoy.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.Serializable;
 | 
					import java.io.Serializable;
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.time.format.DateTimeFormatter;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Represents a unique message with a unique, numeric ID. Further metadata
 | 
					 * 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 long			id, senderID, recipientID;
 | 
				
			||||||
	private final boolean		forwarded;
 | 
						private final boolean		forwarded;
 | 
				
			||||||
	private final LocalDateTime	creationDate;
 | 
						private final Instant		creationDate;
 | 
				
			||||||
	private final String		text;
 | 
						private final String		text;
 | 
				
			||||||
	private final Attachment	attachment;
 | 
						private final Attachment	attachment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private LocalDateTime	receivedDate, readDate;
 | 
						private Instant			receivedDate, readDate;
 | 
				
			||||||
	private MessageStatus	status;
 | 
						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
 | 
						 * 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 attachment   the attachment of the message, if present
 | 
				
			||||||
	 * @param status       the current {@link MessageStatus} of the message
 | 
						 * @param status       the current {@link MessageStatus} of the message
 | 
				
			||||||
	 * @param forwarded    whether this message was forwarded
 | 
						 * @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) {
 | 
								Attachment attachment, MessageStatus status, boolean forwarded) {
 | 
				
			||||||
		this.id				= id;
 | 
							this.id				= id;
 | 
				
			||||||
		this.senderID		= senderID;
 | 
							this.senderID		= senderID;
 | 
				
			||||||
@@ -115,7 +114,7 @@ public class Message implements Serializable {
 | 
				
			|||||||
				id,
 | 
									id,
 | 
				
			||||||
				senderID,
 | 
									senderID,
 | 
				
			||||||
				recipientID,
 | 
									recipientID,
 | 
				
			||||||
				DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss").format(creationDate),
 | 
									creationDate,
 | 
				
			||||||
				status,
 | 
									status,
 | 
				
			||||||
				text,
 | 
									text,
 | 
				
			||||||
				forwarded,
 | 
									forwarded,
 | 
				
			||||||
@@ -142,34 +141,34 @@ public class Message implements Serializable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the date at which this message was created
 | 
						 * @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
 | 
						 * @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
 | 
						 * @param receivedDate the date at which the message has been received by the
 | 
				
			||||||
	 *                     sender
 | 
						 *                     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
 | 
						 * @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
 | 
						 * @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
 | 
						 * @return the text content of this message
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.data;
 | 
					package envoy.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,7 +23,7 @@ public class MessageBuilder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Properties with default values
 | 
						// Properties with default values
 | 
				
			||||||
	private long					id;
 | 
						private long					id;
 | 
				
			||||||
	private LocalDateTime			creationDate, receivedDate, readDate;
 | 
						private Instant					creationDate, receivedDate, readDate;
 | 
				
			||||||
	private String					text;
 | 
						private String					text;
 | 
				
			||||||
	private Attachment				attachment;
 | 
						private Attachment				attachment;
 | 
				
			||||||
	private Message.MessageStatus	status;
 | 
						private Message.MessageStatus	status;
 | 
				
			||||||
@@ -70,7 +70,7 @@ public class MessageBuilder {
 | 
				
			|||||||
	public MessageBuilder(Message msg, long recipientID, IDGenerator iDGenerator) {
 | 
						public MessageBuilder(Message msg, long recipientID, IDGenerator iDGenerator) {
 | 
				
			||||||
		this(msg.getRecipientID(), recipientID, iDGenerator.next());
 | 
							this(msg.getRecipientID(), recipientID, iDGenerator.next());
 | 
				
			||||||
		this.attachment		= msg.getAttachment();
 | 
							this.attachment		= msg.getAttachment();
 | 
				
			||||||
		this.creationDate	= LocalDateTime.now();
 | 
							this.creationDate	= Instant.now();
 | 
				
			||||||
		this.forwarded		= true;
 | 
							this.forwarded		= true;
 | 
				
			||||||
		this.text			= msg.getText();
 | 
							this.text			= msg.getText();
 | 
				
			||||||
		this.status			= MessageStatus.WAITING;
 | 
							this.status			= MessageStatus.WAITING;
 | 
				
			||||||
@@ -83,7 +83,7 @@ public class MessageBuilder {
 | 
				
			|||||||
	 * <table border="1">
 | 
						 * <table border="1">
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
	 * <td>{@code date}</td>
 | 
						 * <td>{@code date}</td>
 | 
				
			||||||
	 * <td>{@code LocalDateTime.now()} and {@code null} for {@code receivedDate} and
 | 
						 * <td>{@code Instant.now()} and {@code null} for {@code receivedDate} and
 | 
				
			||||||
	 * {@code readDate}</td>
 | 
						 * {@code readDate}</td>
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
@@ -113,8 +113,8 @@ public class MessageBuilder {
 | 
				
			|||||||
	 * <br>
 | 
						 * <br>
 | 
				
			||||||
	 * <table border="1">
 | 
						 * <table border="1">
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
	 * <td>{@code date}</td>
 | 
						 * <td>{@code time stamp}</td>
 | 
				
			||||||
	 * <td>{@code new Date()}</td>
 | 
						 * <td>{@code Instant.now()}</td>
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
	 * <td>{@code text}</td>
 | 
						 * <td>{@code text}</td>
 | 
				
			||||||
@@ -140,8 +140,8 @@ public class MessageBuilder {
 | 
				
			|||||||
	 * <br>
 | 
						 * <br>
 | 
				
			||||||
	 * <table border="1">
 | 
						 * <table border="1">
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
	 * <td>{@code date}</td>
 | 
						 * <td>{@code time stamp}</td>
 | 
				
			||||||
	 * <td>{@code new Date()}</td>
 | 
						 * <td>{@code Instant.now()}</td>
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
	 * <tr>
 | 
						 * <tr>
 | 
				
			||||||
	 * <td>{@code text}</td>
 | 
						 * <td>{@code text}</td>
 | 
				
			||||||
@@ -162,7 +162,7 @@ public class MessageBuilder {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void supplyDefaults() {
 | 
						private void supplyDefaults() {
 | 
				
			||||||
		if (creationDate == null) creationDate = LocalDateTime.now();
 | 
							if (creationDate == null) creationDate = Instant.now();
 | 
				
			||||||
		if (text == null) text = "";
 | 
							if (text == null) text = "";
 | 
				
			||||||
		if (status == null) status = MessageStatus.WAITING;
 | 
							if (status == null) status = MessageStatus.WAITING;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -170,9 +170,9 @@ public class MessageBuilder {
 | 
				
			|||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @param creationDate the creation date of the {@link Message} to create
 | 
						 * @param creationDate the creation date of the {@link Message} to create
 | 
				
			||||||
	 * @return this {@link MessageBuilder}
 | 
						 * @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;
 | 
							this.creationDate = creationDate;
 | 
				
			||||||
		return this;
 | 
							return this;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -180,9 +180,9 @@ public class MessageBuilder {
 | 
				
			|||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @param receivedDate the received date of the {@link Message} to create
 | 
						 * @param receivedDate the received date of the {@link Message} to create
 | 
				
			||||||
	 * @return this {@link MessageBuilder}
 | 
						 * @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;
 | 
							this.receivedDate = receivedDate;
 | 
				
			||||||
		return this;
 | 
							return this;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -190,9 +190,9 @@ public class MessageBuilder {
 | 
				
			|||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @param readDate the read date of the {@link Message} to create
 | 
						 * @param readDate the read date of the {@link Message} to create
 | 
				
			||||||
	 * @return this {@link MessageBuilder}
 | 
						 * @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;
 | 
							this.readDate = readDate;
 | 
				
			||||||
		return this;
 | 
							return this;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.event;
 | 
					package envoy.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.data.GroupMessage;
 | 
					import envoy.data.GroupMessage;
 | 
				
			||||||
import envoy.data.Message.MessageStatus;
 | 
					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
 | 
						 * @param date     the date at which the MessageStatus change occurred for
 | 
				
			||||||
	 *                 this specific member
 | 
						 *                 this specific member
 | 
				
			||||||
	 * @param memberID the ID of the group member that caused the status change
 | 
						 * @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);
 | 
							super(id, status, date);
 | 
				
			||||||
		this.memberID = memberID;
 | 
							this.memberID = memberID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.event;
 | 
					package envoy.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.data.Message;
 | 
					import envoy.data.Message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,8 +14,8 @@ import envoy.data.Message;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class MessageStatusChange extends Event<Message.MessageStatus> {
 | 
					public class MessageStatusChange extends Event<Message.MessageStatus> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final long	id;
 | 
						private final long		id;
 | 
				
			||||||
	private final LocalDateTime	date;
 | 
						private final Instant	date;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static final long serialVersionUID = 0L;
 | 
						private static final long serialVersionUID = 0L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,9 +26,9 @@ public class MessageStatusChange extends Event<Message.MessageStatus> {
 | 
				
			|||||||
	 * @param status the status of the {@link Message} this event is related
 | 
						 * @param status the status of the {@link Message} this event is related
 | 
				
			||||||
	 *               to
 | 
						 *               to
 | 
				
			||||||
	 * @param date   the date at which the MessageStatus change occurred
 | 
						 * @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);
 | 
							super(status);
 | 
				
			||||||
		this.id		= id;
 | 
							this.id		= id;
 | 
				
			||||||
		this.date	= date;
 | 
							this.date	= date;
 | 
				
			||||||
@@ -40,7 +40,7 @@ public class MessageStatusChange extends Event<Message.MessageStatus> {
 | 
				
			|||||||
	 * @param message the message from which to build the event
 | 
						 * @param message the message from which to build the event
 | 
				
			||||||
	 * @since Envoy Common v0.2-alpha
 | 
						 * @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
 | 
						 * @return the ID of the {@link Message} this event is related to
 | 
				
			||||||
@@ -50,9 +50,9 @@ public class MessageStatusChange extends Event<Message.MessageStatus> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the date at which the status change occurred
 | 
						 * @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
 | 
						@Override
 | 
				
			||||||
	public String toString() { return String.format("MessageStatusChange[id=%d,status=%s,date=%s]", id, value, date); }
 | 
						public String toString() { return String.format("MessageStatusChange[id=%d,status=%s,date=%s]", id, value, date); }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.server.data;
 | 
					package envoy.server.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.persistence.*;
 | 
					import javax.persistence.*;
 | 
				
			||||||
@@ -28,7 +28,7 @@ public abstract class Contact {
 | 
				
			|||||||
	protected String	name;
 | 
						protected String	name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Column(name = "creation_date")
 | 
						@Column(name = "creation_date")
 | 
				
			||||||
	private LocalDateTime creationDate;
 | 
						private Instant creationDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@ManyToMany(fetch = FetchType.EAGER)
 | 
						@ManyToMany(fetch = FetchType.EAGER)
 | 
				
			||||||
	protected Set<Contact> contacts;
 | 
						protected Set<Contact> contacts;
 | 
				
			||||||
@@ -92,15 +92,15 @@ public abstract class Contact {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the creationDate
 | 
						 * @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
 | 
						 * @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
 | 
						@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()); }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.server.data;
 | 
					package envoy.server.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,7 +39,7 @@ public class GroupMessage extends Message {
 | 
				
			|||||||
	private Map<Long, envoy.data.Message.MessageStatus> memberMessageStatus;
 | 
						private Map<Long, envoy.data.Message.MessageStatus> memberMessageStatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Column(name = "last_status_change_date")
 | 
						@Column(name = "last_status_change_date")
 | 
				
			||||||
	protected LocalDateTime lastStatusChangeDate;
 | 
						protected Instant lastStatusChangeDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * The constructor for a database object.
 | 
						 * The constructor for a database object.
 | 
				
			||||||
@@ -55,9 +55,9 @@ public class GroupMessage extends Message {
 | 
				
			|||||||
	 *                             into a
 | 
						 *                             into a
 | 
				
			||||||
	 *                             database {@link GroupMessage}
 | 
						 *                             database {@link GroupMessage}
 | 
				
			||||||
	 * @param lastStatusChangeDate the time stamp to set
 | 
						 * @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);
 | 
							super(groupMessage);
 | 
				
			||||||
		memberMessageStatus			= groupMessage.getMemberStatuses();
 | 
							memberMessageStatus			= groupMessage.getMemberStatuses();
 | 
				
			||||||
		this.lastStatusChangeDate	= lastStatusChangeDate;
 | 
							this.lastStatusChangeDate	= lastStatusChangeDate;
 | 
				
			||||||
@@ -92,13 +92,13 @@ public class GroupMessage extends Message {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the date at which one of the member statuses changed last
 | 
						 * @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
 | 
						 * @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; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ package envoy.server.data;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import static envoy.data.Message.MessageStatus.*;
 | 
					import static envoy.data.Message.MessageStatus.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.persistence.*;
 | 
					import javax.persistence.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -55,13 +55,13 @@ public class Message {
 | 
				
			|||||||
	protected Contact recipient;
 | 
						protected Contact recipient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Column(name = "creation_date")
 | 
						@Column(name = "creation_date")
 | 
				
			||||||
	protected LocalDateTime creationDate;
 | 
						protected Instant creationDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Column(name = "received_date")
 | 
						@Column(name = "received_date")
 | 
				
			||||||
	protected LocalDateTime receivedDate;
 | 
						protected Instant receivedDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Column(name = "read_date")
 | 
						@Column(name = "read_date")
 | 
				
			||||||
	protected LocalDateTime readDate;
 | 
						protected Instant readDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected String							text;
 | 
						protected String							text;
 | 
				
			||||||
	protected envoy.data.Message.MessageStatus	status;
 | 
						protected envoy.data.Message.MessageStatus	status;
 | 
				
			||||||
@@ -134,7 +134,7 @@ public class Message {
 | 
				
			|||||||
	 * @since Envoy Server Standalone v0.1-beta
 | 
						 * @since Envoy Server Standalone v0.1-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void received() {
 | 
						public void received() {
 | 
				
			||||||
		receivedDate	= LocalDateTime.now();
 | 
							receivedDate	= Instant.now();
 | 
				
			||||||
		status			= RECEIVED;
 | 
							status			= RECEIVED;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -145,7 +145,7 @@ public class Message {
 | 
				
			|||||||
	 * @since Envoy Server Standalone v0.1-beta
 | 
						 * @since Envoy Server Standalone v0.1-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void read() {
 | 
						public void read() {
 | 
				
			||||||
		readDate	= LocalDateTime.now();
 | 
							readDate	= Instant.now();
 | 
				
			||||||
		status		= READ;
 | 
							status		= READ;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -190,43 +190,43 @@ public class Message {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the date at which a {link envoy.data.Message} has been created
 | 
						 * @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
 | 
						 * @param creationDate the creation date to set
 | 
				
			||||||
	 * @since Envoy Server Standalone v0.1-alpha
 | 
						 * @since Envoy Server Standalone v0.2-beta
 | 
				
			||||||
	 * @see Message#getCreationDate()
 | 
						 * @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
 | 
						 * @return the date at which a {link envoy.data.Message} has been received by
 | 
				
			||||||
	 *         the server
 | 
						 *         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
 | 
						 * @param receivedDate the received date to set
 | 
				
			||||||
	 * @since Envoy Server Standalone v0.1-alpha
 | 
						 * @since Envoy Server Standalone v0.2-beta
 | 
				
			||||||
	 * @see Message#getReceivedDate()
 | 
						 * @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
 | 
						 * @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
 | 
						 * @param readDate the read date to set
 | 
				
			||||||
	 * @since Envoy Server Standalone v0.1-alpha
 | 
						 * @since Envoy Server Standalone v0.2-beta
 | 
				
			||||||
	 * @see Message#getReadDate()
 | 
						 * @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}
 | 
						 * @return the status of a {link envoy.data.Message}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.server.data;
 | 
					package envoy.server.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.persistence.EntityManager;
 | 
					import javax.persistence.EntityManager;
 | 
				
			||||||
@@ -38,7 +38,7 @@ public class PersistenceManager {
 | 
				
			|||||||
				.getOnlineUsers()
 | 
									.getOnlineUsers()
 | 
				
			||||||
				.stream()
 | 
									.stream()
 | 
				
			||||||
				.map(this::getUserByID)
 | 
									.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();
 | 
								transaction.commit();
 | 
				
			||||||
		}));
 | 
							}));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -182,31 +182,29 @@ public class PersistenceManager {
 | 
				
			|||||||
	 * Returns all messages received while being offline or the ones that have
 | 
						 * Returns all messages received while being offline or the ones that have
 | 
				
			||||||
	 * changed.
 | 
						 * 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)
 | 
						 * @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<Message> getPendingMessages(User user) {
 | 
						public List<Message> getPendingMessages(User user, Instant lastSync) {
 | 
				
			||||||
		return entityManager
 | 
							return entityManager.createNamedQuery(Message.getPending).setParameter("user", user).setParameter("lastSeen", lastSync).getResultList();
 | 
				
			||||||
			.createNamedQuery(Message.getPending)
 | 
					 | 
				
			||||||
			.setParameter("user", user)
 | 
					 | 
				
			||||||
			.setParameter("lastSeen", user.getLastSeen())
 | 
					 | 
				
			||||||
			.getResultList();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Returns all groupMessages received while being offline or the ones that have
 | 
						 * Returns all groupMessages received while being offline or the ones that have
 | 
				
			||||||
	 * changed.
 | 
						 * 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
 | 
						 * @return all groupMessages that the client does not yet have (unread
 | 
				
			||||||
	 *         groupMessages)
 | 
						 *         groupMessages)
 | 
				
			||||||
	 * @since Envoy Server Standalone v0.1-alpha
 | 
						 * @since Envoy Server Standalone v0.2-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public List<GroupMessage> getPendingGroupMessages(User user) {
 | 
						public List<GroupMessage> getPendingGroupMessages(User user, Instant lastSync) {
 | 
				
			||||||
		return entityManager.createNamedQuery(GroupMessage.getPendingGroupMsg)
 | 
							return entityManager.createNamedQuery(GroupMessage.getPendingGroupMsg)
 | 
				
			||||||
			.setParameter("userId", user.getID())
 | 
								.setParameter("userId", user.getID())
 | 
				
			||||||
			.setParameter("lastSeen", user.getLastSeen())
 | 
								.setParameter("lastSeen", lastSync)
 | 
				
			||||||
			.getResultList();
 | 
								.getResultList();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -221,8 +219,7 @@ public class PersistenceManager {
 | 
				
			|||||||
	 * @since Envoy Server Standalone v0.1-alpha
 | 
						 * @since Envoy Server Standalone v0.1-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public List<User> searchUsers(String searchPhrase, long userId) {
 | 
						public List<User> searchUsers(String searchPhrase, long userId) {
 | 
				
			||||||
		return entityManager.createNamedQuery(
 | 
							return entityManager.createNamedQuery(User.searchByName)
 | 
				
			||||||
				User.searchByName)
 | 
					 | 
				
			||||||
			.setParameter("searchPhrase", searchPhrase + "%")
 | 
								.setParameter("searchPhrase", searchPhrase + "%")
 | 
				
			||||||
			.setParameter("context", getUserByID(userId))
 | 
								.setParameter("context", getUserByID(userId))
 | 
				
			||||||
			.getResultList();
 | 
								.getResultList();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.server.data;
 | 
					package envoy.server.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
import java.util.stream.Collectors;
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -66,7 +66,7 @@ public class User extends Contact {
 | 
				
			|||||||
	private String passwordHash;
 | 
						private String passwordHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Column(name = "last_seen")
 | 
						@Column(name = "last_seen")
 | 
				
			||||||
	private LocalDateTime lastSeen;
 | 
						private Instant lastSeen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private UserStatus status;
 | 
						private UserStatus status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -92,15 +92,15 @@ public class User extends Contact {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the last date the user has been online
 | 
						 * @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
 | 
						 * @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
 | 
						 * @return the status
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package envoy.server.net;
 | 
					package envoy.server.net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.*;
 | 
					import java.util.*;
 | 
				
			||||||
import java.util.stream.Collectors;
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,7 +52,7 @@ public class ConnectionManager implements ISocketIdListener {
 | 
				
			|||||||
			// Notify contacts of this users offline-going
 | 
								// Notify contacts of this users offline-going
 | 
				
			||||||
			envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
 | 
								envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID));
 | 
				
			||||||
			user.setStatus(UserStatus.OFFLINE);
 | 
								user.setStatus(UserStatus.OFFLINE);
 | 
				
			||||||
			user.setLastSeen(LocalDateTime.now());
 | 
								user.setLastSeen(Instant.now());
 | 
				
			||||||
			UserStatusChangeProcessor.updateUserStatus(user);
 | 
								UserStatusChangeProcessor.updateUserStatus(user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Remove the socket
 | 
								// Remove the socket
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ package envoy.server.processors;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import static envoy.data.Message.MessageStatus.*;
 | 
					import static envoy.data.Message.MessageStatus.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.logging.Logger;
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -56,7 +56,7 @@ public class GroupMessageProcessor implements ObjectProcessor<GroupMessage> {
 | 
				
			|||||||
				groupMessage);
 | 
									groupMessage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		try {
 | 
							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) {
 | 
							} catch (EntityExistsException e) {
 | 
				
			||||||
			logger.warning("Received a groupMessage with an ID that already exists");
 | 
								logger.warning("Received a groupMessage with an ID that already exists");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ package envoy.server.processors;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import static envoy.data.Message.MessageStatus.READ;
 | 
					import static envoy.data.Message.MessageStatus.READ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
import java.util.logging.Logger;
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
@@ -42,7 +42,7 @@ public class GroupMessageStatusChangeProcessor implements ObjectProcessor<GroupM
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// Apply the status change
 | 
							// Apply the status change
 | 
				
			||||||
		gmsg.getMemberMessageStatus().replace(statusChange.getMemberID(), statusChange.get());
 | 
							gmsg.getMemberMessageStatus().replace(statusChange.getMemberID(), statusChange.get());
 | 
				
			||||||
		gmsg.setLastStatusChangeDate(LocalDateTime.now());
 | 
							gmsg.setLastStatusChangeDate(Instant.now());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Notifying the other members about the status change
 | 
							// Notifying the other members about the status change
 | 
				
			||||||
		final var userID = connectionManager.getUserIDBySocketID(socketID);
 | 
							final var userID = connectionManager.getUserIDBySocketID(socketID);
 | 
				
			||||||
@@ -59,7 +59,7 @@ public class GroupMessageStatusChangeProcessor implements ObjectProcessor<GroupM
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			// Notify online members about the status change
 | 
								// Notify online members about the status change
 | 
				
			||||||
			writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
 | 
								writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
 | 
				
			||||||
					new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), LocalDateTime.now()));
 | 
										new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), Instant.now()));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		persistenceManager.updateMessage(gmsg);
 | 
							persistenceManager.updateMessage(gmsg);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import static envoy.data.Message.MessageStatus.*;
 | 
				
			|||||||
import static envoy.data.User.UserStatus.ONLINE;
 | 
					import static envoy.data.User.UserStatus.ONLINE;
 | 
				
			||||||
import static envoy.event.HandshakeRejection.*;
 | 
					import static envoy.event.HandshakeRejection.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.Instant;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.HashSet;
 | 
					import java.util.HashSet;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
@@ -47,7 +47,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
 | 
				
			|||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void process(LoginCredentials credentials, long socketID, ObjectWriteProxy writeProxy) {
 | 
						public void process(LoginCredentials credentials, long socketID, ObjectWriteProxy writeProxy) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Cache this write proxy for user-independant notifications
 | 
							// Cache this write proxy for user-independent notifications
 | 
				
			||||||
		UserStatusChangeProcessor.setWriteProxy(writeProxy);
 | 
							UserStatusChangeProcessor.setWriteProxy(writeProxy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!VersionUtil.verifyCompatibility(credentials.getClientVersion())) {
 | 
							if (!VersionUtil.verifyCompatibility(credentials.getClientVersion())) {
 | 
				
			||||||
@@ -98,7 +98,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
 | 
				
			|||||||
				// Creation of a new user
 | 
									// Creation of a new user
 | 
				
			||||||
				user = new User();
 | 
									user = new User();
 | 
				
			||||||
				user.setName(credentials.getIdentifier());
 | 
									user.setName(credentials.getIdentifier());
 | 
				
			||||||
				user.setLastSeen(LocalDateTime.now());
 | 
									user.setLastSeen(Instant.now());
 | 
				
			||||||
				user.setStatus(ONLINE);
 | 
									user.setStatus(ONLINE);
 | 
				
			||||||
				user.setPasswordHash(PasswordUtil.hash(credentials.getPassword()));
 | 
									user.setPasswordHash(PasswordUtil.hash(credentials.getPassword()));
 | 
				
			||||||
				user.setContacts(new HashSet<>());
 | 
									user.setContacts(new HashSet<>());
 | 
				
			||||||
@@ -117,7 +117,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
 | 
				
			|||||||
		// Complete the handshake
 | 
							// Complete the handshake
 | 
				
			||||||
		writeProxy.write(socketID, user.toCommon());
 | 
							writeProxy.write(socketID, user.toCommon());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		final var pendingMessages = PersistenceManager.getInstance().getPendingMessages(user);
 | 
							final var pendingMessages = PersistenceManager.getInstance().getPendingMessages(user, credentials.getLastSync());
 | 
				
			||||||
		pendingMessages.removeIf(GroupMessage.class::isInstance);
 | 
							pendingMessages.removeIf(GroupMessage.class::isInstance);
 | 
				
			||||||
		logger.fine("Sending " + pendingMessages.size() + " pending messages to " + user + "...");
 | 
							logger.fine("Sending " + pendingMessages.size() + " pending messages to " + user + "...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -138,7 +138,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
 | 
				
			|||||||
			} else writeProxy.write(socketID, new MessageStatusChange(msgCommon));
 | 
								} else writeProxy.write(socketID, new MessageStatusChange(msgCommon));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		List<GroupMessage> pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user);
 | 
							List<GroupMessage> pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user, credentials.getLastSync());
 | 
				
			||||||
		logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "...");
 | 
							logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (var gmsg : pendingGroupMessages) {
 | 
							for (var gmsg : pendingGroupMessages) {
 | 
				
			||||||
@@ -148,13 +148,13 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
 | 
				
			|||||||
			if (gmsg.getMemberMessageStatus().get(user.getID()) == SENT) {
 | 
								if (gmsg.getMemberMessageStatus().get(user.getID()) == SENT) {
 | 
				
			||||||
				gmsg.getMemberMessageStatus().replace(user.getID(), RECEIVED);
 | 
									gmsg.getMemberMessageStatus().replace(user.getID(), RECEIVED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				gmsg.setLastStatusChangeDate(LocalDateTime.now());
 | 
									gmsg.setLastStatusChangeDate(Instant.now());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				writeProxy.write(socketID, gmsgCommon);
 | 
									writeProxy.write(socketID, gmsgCommon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Notify all online group members about the status change
 | 
									// Notify all online group members about the status change
 | 
				
			||||||
				writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
 | 
									writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
 | 
				
			||||||
						new GroupMessageStatusChange(gmsg.getID(), RECEIVED, LocalDateTime
 | 
											new GroupMessageStatusChange(gmsg.getID(), RECEIVED, Instant
 | 
				
			||||||
							.now(),
 | 
												.now(),
 | 
				
			||||||
								connectionManager.getUserIDBySocketID(socketID)));
 | 
													connectionManager.getUserIDBySocketID(socketID)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -163,7 +163,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					// Notify online members about the status change
 | 
										// Notify online members about the status change
 | 
				
			||||||
					writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
 | 
										writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(),
 | 
				
			||||||
							new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), LocalDateTime.now()));
 | 
												new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), Instant.now()));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				PersistenceManager.getInstance().updateMessage(gmsg);
 | 
									PersistenceManager.getInstance().updateMessage(gmsg);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user