Made local database persistence optional
* Split LocalDB into abstract class LocalDb and PersistentLocalDb and TransientLocalDb * Moved LocalDb to database package * Added ignoreLocalDb option to Config
This commit is contained in:
		| @@ -9,6 +9,7 @@ import java.util.logging.Logger; | ||||
|  | ||||
| import javax.naming.TimeLimitExceededException; | ||||
|  | ||||
| import envoy.client.database.LocalDb; | ||||
| import envoy.client.net.ReceivedMessageProcessor; | ||||
| import envoy.client.net.Receiver; | ||||
| import envoy.client.util.EnvoyLog; | ||||
| @@ -47,14 +48,14 @@ public class Client implements Closeable { | ||||
| 	 * will block for up to 5 seconds. If the handshake does exceed this time limit, | ||||
| 	 * an exception is thrown. | ||||
| 	 * | ||||
| 	 * @param credentials the login credentials of the user | ||||
| 	 * @param localDB     the local database used to persist the current | ||||
| 	 *                    {@link IdGenerator} | ||||
| 	 * @param credentials       the login credentials of the user | ||||
| 	 * @param localDb the local database used to persist the current | ||||
| 	 *                          {@link IdGenerator} | ||||
| 	 * @throws Exception if the online mode could not be entered or the request | ||||
| 	 *                   failed for some other reason | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void onlineInit(LoginCredentials credentials, LocalDB localDB) throws Exception { | ||||
| 	public void onlineInit(LoginCredentials credentials, LocalDb localDb) throws Exception { | ||||
| 		// Establish TCP connection | ||||
| 		logger.info(String.format("Attempting connection to server %s:%d...", config.getServer(), config.getPort())); | ||||
| 		socket = new Socket(config.getServer(), config.getPort()); | ||||
| @@ -92,10 +93,10 @@ public class Client implements Closeable { | ||||
| 		// TODO: Status handling | ||||
|  | ||||
| 		// Process message ID generation | ||||
| 		receiver.registerProcessor(IdGenerator.class, localDB::setIdGenerator); | ||||
| 		receiver.registerProcessor(IdGenerator.class, localDb::setIdGenerator); | ||||
|  | ||||
| 		// Request a generator if none is present | ||||
| 		if (!localDB.hasIdGenerator() || !localDB.getIdGenerator().hasNext()) requestIdGenerator(); | ||||
| 		if (!localDb.hasIdGenerator() || !localDb.getIdGenerator().hasNext()) requestIdGenerator(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| package envoy.client; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.Properties; | ||||
| import java.util.*; | ||||
| import java.util.logging.Level; | ||||
|  | ||||
| import envoy.exception.EnvoyException; | ||||
| @@ -31,6 +29,7 @@ public class Config { | ||||
| 		items.put("server", new ConfigItem<>("server", "s", (input) -> input, null)); | ||||
| 		items.put("port", new ConfigItem<>("port", "p", (input) -> Integer.parseInt(input), null)); | ||||
| 		items.put("localDB", new ConfigItem<>("localDB", "db", (input) -> new File(input), new File("localDB"))); | ||||
| 		items.put("ignoreLocalDB", new ConfigItem<>("ignoreLocalDB", "nodb", (input) -> Boolean.parseBoolean(input), false)); | ||||
| 		items.put("homeDirectory", | ||||
| 				new ConfigItem<>("homeDirectory", "h", (input) -> new File(input), new File(System.getProperty("user.home"), ".envoy"))); | ||||
| 		items.put("fileLevelBarrier", new ConfigItem<>("fileLevelBarrier", "fb", (input) -> Level.parse(input), Level.CONFIG)); | ||||
| @@ -99,7 +98,7 @@ public class Config { | ||||
| 	 * @return {@code true} if server, port and localDB directory are known. | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public boolean isInitialized() { return items.values().stream().noneMatch(item -> item.get() == null); } | ||||
| 	public boolean isInitialized() { return items.values().stream().map(ConfigItem::get).noneMatch(Objects::isNull); } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the host name of the Envoy server | ||||
| @@ -119,6 +118,12 @@ public class Config { | ||||
| 	 */ | ||||
| 	public File getLocalDB() { return (File) items.get("localDB").get(); } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return {@code true} if the local database is to be ignored | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public Boolean isIgnoreLocalDB() { return (Boolean) items.get("ignoreLocalDB").get(); } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the directory in which all local files are saves | ||||
| 	 * @since Envoy v0.2-alpha | ||||
|   | ||||
| @@ -1,163 +0,0 @@ | ||||
| package envoy.client; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.*; | ||||
|  | ||||
| import envoy.data.IdGenerator; | ||||
| import envoy.data.User; | ||||
| import envoy.util.SerializationUtils; | ||||
|  | ||||
| /** | ||||
|  * Stored information about the current {@link User} and their {@link Chat}s. | ||||
|  * For message ID generation a {@link IdGenerator} is stored as well. | ||||
|  * These object are persisted inside a folder of the local file system.<br> | ||||
|  * <br> | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>LocalDB.java</strong><br> | ||||
|  * Created: <strong>27.10.2019</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @since Envoy v0.1-alpha | ||||
|  */ | ||||
| public class LocalDB { | ||||
|  | ||||
| 	private File				localDBDir, localDBFile, usersFile, idGeneratorFile; | ||||
| 	private User				user; | ||||
| 	private Map<String, User>	users	= new HashMap<>(); | ||||
| 	private List<Chat>			chats	= new ArrayList<>(); | ||||
| 	private IdGenerator			idGenerator; | ||||
|  | ||||
| 	/** | ||||
| 	 * Constructs an empty local database. To serialize any chats to the file | ||||
| 	 * system, call {@link LocalDB#initializeDBFile()}. | ||||
| 	 * | ||||
| 	 * @param localDBDir the directory in which to store users and chats | ||||
| 	 * @throws IOException if the LocalDB could not be initialized | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public LocalDB(File localDBDir) throws IOException { | ||||
| 		this.localDBDir = localDBDir; | ||||
|  | ||||
| 		// Initialize local database directory | ||||
| 		if (localDBDir.exists() && !localDBDir.isDirectory()) | ||||
| 			throw new IOException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); | ||||
| 		usersFile		= new File(localDBDir, "users.db"); | ||||
| 		idGeneratorFile	= new File(localDBDir, "id_generator.db"); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates a database file for a user-specific list of chats. | ||||
| 	 * | ||||
| 	 * @throws NullPointerException if the client user is not yet specified | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void initializeDBFile() { | ||||
| 		if (user == null) throw new NullPointerException("Client user is null"); | ||||
| 		localDBFile = new File(localDBDir, user.getId() + ".db"); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Stores all users to the local database. If the client user is specified, the | ||||
| 	 * chats related to this user are stored as well. The message id generator will | ||||
| 	 * also be saved if present. | ||||
| 	 * | ||||
| 	 * @throws IOException if something went wrong during saving | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void save() throws IOException { | ||||
| 		// Save users | ||||
| 		SerializationUtils.write(usersFile, users); | ||||
|  | ||||
| 		// Save chats | ||||
| 		if (user != null) SerializationUtils.write(localDBFile, chats); | ||||
|  | ||||
| 		// Save id generator | ||||
| 		if (hasIdGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Loads all users that are stored in the local database. | ||||
| 	 * | ||||
| 	 * @throws IOException            if the loading process failed | ||||
| 	 * @throws ClassNotFoundException if the loading process failed | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void loadUsers() throws ClassNotFoundException, IOException { users = SerializationUtils.read(usersFile, HashMap.class); } | ||||
|  | ||||
| 	/** | ||||
| 	 * Loads all chats saved by Envoy for the client user. | ||||
| 	 * | ||||
| 	 * @throws IOException            if the loading process failed | ||||
| 	 * @throws ClassNotFoundException if the loading process failed | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void loadChats() throws ClassNotFoundException, IOException { chats = SerializationUtils.read(localDBFile, ArrayList.class); } | ||||
|  | ||||
| 	/** | ||||
| 	 * Loads the message ID generator that is stored in the local database. If the | ||||
| 	 * file is not found, the exception is ignored. | ||||
| 	 * | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void loadIdGenerator() { | ||||
| 		try { | ||||
| 			idGenerator = SerializationUtils.read(idGeneratorFile, IdGenerator.class); | ||||
| 		} catch (ClassNotFoundException | IOException e) {} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return a {@code Map<String, User>} of all users stored locally with their | ||||
| 	 *         user names as keys | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Map<String, User> getUsers() { return users; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param users the users to set | ||||
| 	 */ | ||||
| 	public void setUsers(Map<String, User> users) { this.users = users; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return all saved {@link Chat} objects that list the client user as the | ||||
| 	 *         sender | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 **/ | ||||
| 	public List<Chat> getChats() { return chats; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param chats the chats to set | ||||
| 	 */ | ||||
| 	public void setChats(List<Chat> chats) { this.chats = chats; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the {@link User} who initialized the local database | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public User getUser() { return user; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param user the user to set | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void setUser(User user) { this.user = user; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the message ID generator | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public IdGenerator getIdGenerator() { return idGenerator; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param idGenerator the message ID generator to set | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void setIdGenerator(IdGenerator idGenerator) { this.idGenerator = idGenerator; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return {@code true} if an {@link IdGenerator} is present | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public boolean hasIdGenerator() { return idGenerator != null; } | ||||
| } | ||||
							
								
								
									
										119
									
								
								src/main/java/envoy/client/database/LocalDb.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/main/java/envoy/client/database/LocalDb.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| package envoy.client.database; | ||||
|  | ||||
| import java.util.*; | ||||
|  | ||||
| import envoy.client.Chat; | ||||
| import envoy.data.IdGenerator; | ||||
| import envoy.data.User; | ||||
|  | ||||
| /** | ||||
|  * Stores information about the current {@link User} and their {@link Chat}s. | ||||
|  * For message ID generation a {@link IdGenerator} is stored as well.<br> | ||||
|  * <br> | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>LocalDb.java</strong><br> | ||||
|  * Created: <strong>3 Feb 2020</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since Envoy v0.3-alpha | ||||
|  */ | ||||
| public abstract class LocalDb { | ||||
|  | ||||
| 	protected User				user; | ||||
| 	protected Map<String, User>	users	= new HashMap<>(); | ||||
| 	protected List<Chat>		chats	= new ArrayList<>(); | ||||
| 	protected IdGenerator		idGenerator; | ||||
|  | ||||
| 	/** | ||||
| 	 * Initializes a storage space for a user-specific list of chats. | ||||
| 	 * | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void initializeUserStorage() {} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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. | ||||
| 	 * | ||||
| 	 * @throws Exception if the saving process failed | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void save() throws Exception {} | ||||
|  | ||||
| 	/** | ||||
| 	 * Loads all user data. | ||||
| 	 * | ||||
| 	 * @throws Exception if the loading process failed | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void loadUsers() throws Exception {} | ||||
|  | ||||
| 	/** | ||||
| 	 * Loads all chat data of the client user. | ||||
| 	 * | ||||
| 	 * @throws Exception if the loading process failed | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void loadChats() throws Exception {} | ||||
|  | ||||
| 	/** | ||||
| 	 * Loads the ID generator. Any exception thrown during this process is ignored. | ||||
| 	 * | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void loadIdGenerator() {} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return a {@code Map<String, User>} of all users stored locally with their | ||||
| 	 *         user names as keys | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Map<String, User> getUsers() { return users; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param users the users to set | ||||
| 	 */ | ||||
| 	public void setUsers(Map<String, User> users) { this.users = users; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return all saved {@link Chat} objects that list the client user as the | ||||
| 	 *         sender | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 **/ | ||||
| 	public List<Chat> getChats() { return chats; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param chats the chats to set | ||||
| 	 */ | ||||
| 	public void setChats(List<Chat> chats) { this.chats = chats; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the {@link User} who initialized the local database | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public User getUser() { return user; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param user the user to set | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void setUser(User user) { this.user = user; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the message ID generator | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public IdGenerator getIdGenerator() { return idGenerator; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param idGenerator the message ID generator to set | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void setIdGenerator(IdGenerator idGenerator) { this.idGenerator = idGenerator; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return {@code true} if an {@link IdGenerator} is present | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public boolean hasIdGenerator() { return idGenerator != null; } | ||||
| } | ||||
							
								
								
									
										93
									
								
								src/main/java/envoy/client/database/PersistentLocalDb.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/main/java/envoy/client/database/PersistentLocalDb.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| package envoy.client.database; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
|  | ||||
| import envoy.client.ConfigItem; | ||||
| import envoy.data.IdGenerator; | ||||
| import envoy.util.SerializationUtils; | ||||
|  | ||||
| /** | ||||
|  * Implements a {@link LocalDb} in a way that stores all information inside a | ||||
|  * folder on the local file system.<br> | ||||
|  * <br> | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>PersistentLocalDb.java</strong><br> | ||||
|  * Created: <strong>27.10.2019</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @since Envoy v0.1-alpha | ||||
|  */ | ||||
| public class PersistentLocalDb extends LocalDb { | ||||
|  | ||||
| 	private File localDBDir, localDBFile, usersFile, idGeneratorFile; | ||||
|  | ||||
| 	/** | ||||
| 	 * Initializes an empty local database without a directory. All changes made to | ||||
| 	 * this instance cannot be saved to the file system.<br> | ||||
| 	 * <br> | ||||
| 	 * This constructor shall be used in conjunction with the {@code ignoreLocalDB} | ||||
| 	 * {@link ConfigItem}. | ||||
| 	 * | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public PersistentLocalDb() {} | ||||
|  | ||||
| 	/** | ||||
| 	 * Constructs an empty local database. To serialize any chats to the file | ||||
| 	 * system, call {@link PersistentLocalDb#initializeUserStorage()}. | ||||
| 	 * | ||||
| 	 * @param localDBDir the directory in which to store users and chats | ||||
| 	 * @throws IOException if the PersistentLocalDb could not be initialized | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public PersistentLocalDb(File localDBDir) throws IOException { | ||||
| 		this.localDBDir = localDBDir; | ||||
|  | ||||
| 		// Initialize local database directory | ||||
| 		if (localDBDir.exists() && !localDBDir.isDirectory()) | ||||
| 			throw new IOException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); | ||||
| 		usersFile		= new File(localDBDir, "users.db"); | ||||
| 		idGeneratorFile	= new File(localDBDir, "id_generator.db"); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates a database file for a user-specific list of chats. | ||||
| 	 * | ||||
| 	 * @throws NullPointerException if the client user is not yet specified | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public void initializeUserStorage() { | ||||
| 		if (user == null) throw new NullPointerException("Client user is null"); | ||||
| 		localDBFile = new File(localDBDir, user.getId() + ".db"); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void save() throws IOException { | ||||
| 		// Save users | ||||
| 		SerializationUtils.write(usersFile, users); | ||||
|  | ||||
| 		// Save chats | ||||
| 		if (user != null) SerializationUtils.write(localDBFile, chats); | ||||
|  | ||||
| 		// Save id generator | ||||
| 		if (hasIdGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void loadUsers() throws ClassNotFoundException, IOException { users = SerializationUtils.read(usersFile, HashMap.class); } | ||||
|  | ||||
| 	@Override | ||||
| 	public void loadChats() throws ClassNotFoundException, IOException { chats = SerializationUtils.read(localDBFile, ArrayList.class); } | ||||
|  | ||||
| 	@Override | ||||
| 	public void loadIdGenerator() { | ||||
| 		try { | ||||
| 			idGenerator = SerializationUtils.read(idGeneratorFile, IdGenerator.class); | ||||
| 		} catch (ClassNotFoundException | IOException e) {} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/main/java/envoy/client/database/TransientLocalDb.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/main/java/envoy/client/database/TransientLocalDb.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| package envoy.client.database; | ||||
|  | ||||
| /** | ||||
|  * Implements a {@link LocalDb} in a way that does not persist any information | ||||
|  * after application shutdown.<br> | ||||
|  * <br> | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>TransientLocalDb.java</strong><br> | ||||
|  * Created: <strong>3 Feb 2020</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since Envoy v0.3-alpha | ||||
|  */ | ||||
| public class TransientLocalDb extends LocalDb { | ||||
| } | ||||
| @@ -9,7 +9,10 @@ import java.util.logging.Logger; | ||||
| import javax.swing.*; | ||||
| import javax.swing.border.EmptyBorder; | ||||
|  | ||||
| import envoy.client.*; | ||||
| import envoy.client.Chat; | ||||
| import envoy.client.Client; | ||||
| import envoy.client.Settings; | ||||
| import envoy.client.database.LocalDb; | ||||
| import envoy.client.event.MessageCreationEvent; | ||||
| import envoy.client.event.ThemeChangeEvent; | ||||
| import envoy.client.ui.list.ComponentList; | ||||
| @@ -34,7 +37,7 @@ public class ChatWindow extends JFrame { | ||||
|  | ||||
| 	// User specific objects | ||||
| 	private Client	client; | ||||
| 	private LocalDB	localDB; | ||||
| 	private LocalDb	localDb; | ||||
|  | ||||
| 	// GUI components | ||||
| 	private JPanel					contentPane				= new JPanel(); | ||||
| @@ -161,13 +164,13 @@ public class ChatWindow extends JFrame { | ||||
| 		userList.setCellRenderer(new UserListRenderer()); | ||||
| 		userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); | ||||
| 		userList.addListSelectionListener((listSelectionEvent) -> { | ||||
| 			if (client != null && localDB != null && !listSelectionEvent.getValueIsAdjusting()) { | ||||
| 			if (client != null && localDb != null && !listSelectionEvent.getValueIsAdjusting()) { | ||||
| 				@SuppressWarnings("unchecked") | ||||
| 				final JList<User>	selectedUserList	= (JList<User>) listSelectionEvent.getSource(); | ||||
| 				final User			user				= selectedUserList.getSelectedValue(); | ||||
|  | ||||
| 				// Select current chat | ||||
| 				currentChat = localDB.getChats().stream().filter(chat -> chat.getRecipient().getId() == user.getId()).findFirst().get(); | ||||
| 				currentChat = localDb.getChats().stream().filter(chat -> chat.getRecipient().getId() == user.getId()).findFirst().get(); | ||||
|  | ||||
| 				// Read current Chat | ||||
| 				currentChat.read(); | ||||
| @@ -206,7 +209,7 @@ public class ChatWindow extends JFrame { | ||||
| 		// Listen to received messages | ||||
| 		EventBus.getInstance().register(MessageCreationEvent.class, (evt) -> { | ||||
| 			Message message = ((MessageCreationEvent) evt).get(); | ||||
| 			localDB.getChats().stream().filter(c -> c.getRecipient().getId() == message.getSenderId()).findFirst().get().appendMessage(message); | ||||
| 			localDb.getChats().stream().filter(c -> c.getRecipient().getId() == message.getSenderId()).findFirst().get().appendMessage(message); | ||||
| 			revalidate(); | ||||
| 			repaint(); | ||||
| 		}); | ||||
| @@ -262,7 +265,7 @@ public class ChatWindow extends JFrame { | ||||
| 		if (!messageEnterTextArea.getText().isEmpty()) try { | ||||
|  | ||||
| 			// Create message | ||||
| 			final Message message = new MessageBuilder(localDB.getUser().getId(), currentChat.getRecipient().getId(), localDB.getIdGenerator()) | ||||
| 			final Message message = new MessageBuilder(localDb.getUser().getId(), currentChat.getRecipient().getId(), localDb.getIdGenerator()) | ||||
| 				.setText(messageEnterTextArea.getText()) | ||||
| 				.build(); | ||||
|  | ||||
| @@ -270,7 +273,7 @@ public class ChatWindow extends JFrame { | ||||
| 			// TODO: Store offline messages | ||||
| 			client.sendMessage(message); | ||||
|  | ||||
| 			// Add message to LocalDB and update UI | ||||
| 			// Add message to PersistentLocalDb and update UI | ||||
| 			currentChat.appendMessage(message); | ||||
| 			// messageList.setModel(currentChat.getModel()); | ||||
|  | ||||
| @@ -281,8 +284,8 @@ public class ChatWindow extends JFrame { | ||||
| 			revalidate(); | ||||
| 			repaint(); | ||||
|  | ||||
| 			// Request a new id generator if all ids were used | ||||
| 			if (!localDB.getIdGenerator().hasNext()) client.requestIdGenerator(); | ||||
| 			// Request a new id generator if all IDs were used | ||||
| 			if (!localDb.getIdGenerator().hasNext()) client.requestIdGenerator(); | ||||
|  | ||||
| 		} catch (Exception e) { | ||||
| 			JOptionPane.showMessageDialog(this, | ||||
| @@ -302,12 +305,12 @@ public class ChatWindow extends JFrame { | ||||
| 	private void loadUsersAndChats() { | ||||
| 		new Thread(() -> { | ||||
| 			DefaultListModel<User> userListModel = new DefaultListModel<>(); | ||||
| 			localDB.getUsers().values().forEach(user -> { | ||||
| 			localDb.getUsers().values().forEach(user -> { | ||||
| 				userListModel.addElement(user); | ||||
|  | ||||
| 				// Check if user exists in local DB | ||||
| 				if (localDB.getChats().stream().filter(c -> c.getRecipient().getId() == user.getId()).count() == 0) | ||||
| 					localDB.getChats().add(new Chat(user)); | ||||
| 				if (localDb.getChats().stream().filter(c -> c.getRecipient().getId() == user.getId()).count() == 0) | ||||
| 					localDb.getChats().add(new Chat(user)); | ||||
| 			}); | ||||
| 			SwingUtilities.invokeLater(() -> userList.setModel(userListModel)); | ||||
| 		}).start(); | ||||
| @@ -324,14 +327,16 @@ public class ChatWindow extends JFrame { | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Sets the {@link LocalDB} used by this {@link ChatWindow}. After invoking this | ||||
| 	 * Sets the {@link LocalDb} used by this {@link ChatWindow}. After | ||||
| 	 * invoking this | ||||
| 	 * method, users and chats will be loaded from the database into the GUI. | ||||
| 	 * | ||||
| 	 * @param localDB the {@link LocalDB} used to manage stored messages and users | ||||
| 	 * @param localDb the {@link LocalDb} used to manage stored messages | ||||
| 	 *                and users | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void setLocalDB(LocalDB localDB) { | ||||
| 		this.localDB = localDB; | ||||
| 	public void setLocalDB(LocalDb localDb) { | ||||
| 		this.localDb = localDb; | ||||
| 		loadUsersAndChats(); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -11,7 +11,12 @@ import javax.swing.JFrame; | ||||
| import javax.swing.JOptionPane; | ||||
| import javax.swing.SwingUtilities; | ||||
|  | ||||
| import envoy.client.*; | ||||
| import envoy.client.Client; | ||||
| import envoy.client.Config; | ||||
| import envoy.client.Settings; | ||||
| import envoy.client.database.LocalDb; | ||||
| import envoy.client.database.PersistentLocalDb; | ||||
| import envoy.client.database.TransientLocalDb; | ||||
| import envoy.client.util.EnvoyLog; | ||||
| import envoy.data.LoginCredentials; | ||||
| import envoy.data.User; | ||||
| @@ -63,8 +68,8 @@ public class Startup { | ||||
| 		} catch (Exception e) { | ||||
| 			JOptionPane | ||||
| 				.showMessageDialog(null, "Error loading configuration values:\n" + e.toString(), "Configuration error", JOptionPane.ERROR_MESSAGE); | ||||
| 			System.exit(1); | ||||
| 			e.printStackTrace(); | ||||
| 			System.exit(1); | ||||
| 		} | ||||
|  | ||||
| 		// Set new logger levels loaded from config | ||||
| @@ -80,12 +85,19 @@ public class Startup { | ||||
| 		} | ||||
|  | ||||
| 		// Initialize the local database | ||||
| 		LocalDB localDB; | ||||
| 		try { | ||||
| 			localDB = new LocalDB(new File(config.getHomeDirectory(), config.getLocalDB().getPath())); | ||||
| 		LocalDb localDb; | ||||
| 		if (config.isIgnoreLocalDB()) { | ||||
| 			localDb = new TransientLocalDb(); | ||||
| 			JOptionPane.showMessageDialog(null, | ||||
| 					"Ignoring local database.\nMessages will not be saved!", | ||||
| 					"Local database warning", | ||||
| 					JOptionPane.WARNING_MESSAGE); | ||||
| 		} else try { | ||||
| 			localDb = new PersistentLocalDb(new File(config.getHomeDirectory(), config.getLocalDB().getPath())); | ||||
| 		} catch (IOException e3) { | ||||
| 			logger.log(Level.SEVERE, "Could not initialize local database", e3); | ||||
| 			JOptionPane.showMessageDialog(null, "Could not initialize local database!\n" + e3.toString()); | ||||
| 			JOptionPane | ||||
| 				.showMessageDialog(null, "Could not initialize local database!\n" + e3.toString(), "Local database error", JOptionPane.ERROR_MESSAGE); | ||||
| 			System.exit(1); | ||||
| 			return; | ||||
| 		} | ||||
| @@ -97,15 +109,15 @@ public class Startup { | ||||
| 		Client client = new Client(); | ||||
| 		try { | ||||
| 			// Try entering online mode first | ||||
| 			localDB.loadIdGenerator(); | ||||
| 			client.onlineInit(credentials, localDB); | ||||
| 			localDb.loadIdGenerator(); | ||||
| 			client.onlineInit(credentials, localDb); | ||||
| 		} catch (Exception e1) { | ||||
| 			logger.warning("Could not connect to server. Trying offline mode..."); | ||||
| 			e1.printStackTrace(); | ||||
| 			try { | ||||
| 				// Try entering offline mode | ||||
| 				localDB.loadUsers(); | ||||
| 				User clientUser = localDB.getUsers().get(credentials.getName()); | ||||
| 				localDb.loadUsers(); | ||||
| 				User clientUser = localDb.getUsers().get(credentials.getName()); | ||||
| 				if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown"); | ||||
| 				client.setSender(clientUser); | ||||
| 				JOptionPane.showMessageDialog(null, | ||||
| @@ -120,12 +132,12 @@ public class Startup { | ||||
| 		} | ||||
|  | ||||
| 		// Set client user in local database | ||||
| 		localDB.setUser(client.getSender()); | ||||
| 		localDb.setUser(client.getSender()); | ||||
|  | ||||
| 		// Initialize chats in local database | ||||
| 		try { | ||||
| 			localDB.initializeDBFile(); | ||||
| 			localDB.loadChats(); | ||||
| 			localDb.initializeUserStorage(); | ||||
| 			localDb.loadChats(); | ||||
| 		} catch (FileNotFoundException e) { | ||||
| 			// The local database file has not yet been created, probably first login | ||||
| 		} catch (Exception e) { | ||||
| @@ -137,12 +149,12 @@ public class Startup { | ||||
| 		} | ||||
|  | ||||
| 		// Save all users to the local database | ||||
| 		if (client.isOnline()) localDB.setUsers(client.getUsers()); | ||||
| 		if (client.isOnline()) localDb.setUsers(client.getUsers()); | ||||
|  | ||||
| 		EventQueue.invokeLater(() -> { | ||||
| 			try { | ||||
| 				chatWindow.setClient(client); | ||||
| 				chatWindow.setLocalDB(localDB); | ||||
| 				chatWindow.setLocalDB(localDb); | ||||
|  | ||||
| 				try { | ||||
| 					new StatusTrayIcon(chatWindow).show(); | ||||
| @@ -162,16 +174,16 @@ public class Startup { | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		// Save Settings and LocalDB on shutdown | ||||
| 		// Save Settings and PersistentLocalDb on shutdown | ||||
| 		Runtime.getRuntime().addShutdownHook(new Thread(() -> { | ||||
| 			try { | ||||
| 				logger.info("Closing connection..."); | ||||
| 				client.close(); | ||||
|  | ||||
| 				logger.info("Saving local database and settings..."); | ||||
| 				localDB.save(); | ||||
| 				localDb.save(); | ||||
| 				Settings.getInstance().save(); | ||||
| 			} catch (IOException e) { | ||||
| 			} catch (Exception e) { | ||||
| 				logger.log(Level.SEVERE, "Unable to save local files", e); | ||||
| 			} | ||||
| 		})); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user