Merge pull request 'Remove TransientLocalDB and no-db Config Value' (#24) from remove-transient-localdb into develop
Reviewed-on: https://git.kske.dev/zdm/envoy/pulls/24 Reviewed-by: delvh <leon@kske.dev>
This commit is contained in:
commit
8a01229855
@ -35,7 +35,6 @@ public final class ClientConfig extends Config {
|
|||||||
put("server", "s", identity());
|
put("server", "s", identity());
|
||||||
put("port", "p", Integer::parseInt);
|
put("port", "p", Integer::parseInt);
|
||||||
put("localDB", "db", File::new);
|
put("localDB", "db", File::new);
|
||||||
put("ignoreLocalDB", "nodb", Boolean::parseBoolean);
|
|
||||||
put("user", "u", identity());
|
put("user", "u", identity());
|
||||||
put("password", "pw", identity());
|
put("password", "pw", identity());
|
||||||
}
|
}
|
||||||
@ -58,12 +57,6 @@ public final class ClientConfig extends Config {
|
|||||||
*/
|
*/
|
||||||
public File getLocalDB() { return (File) items.get("localDB").get(); }
|
public File getLocalDB() { return (File) items.get("localDB").get(); }
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {@code true} if the local database is to be ignored
|
|
||||||
* @since Envoy Client v0.3-alpha
|
|
||||||
*/
|
|
||||||
public Boolean isIgnoreLocalDB() { return (Boolean) items.get("ignoreLocalDB").get(); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the user name
|
* @return the user name
|
||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.3-alpha
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
package envoy.client.data;
|
package envoy.client.data;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import envoy.data.*;
|
import envoy.data.*;
|
||||||
import envoy.event.GroupResize;
|
import envoy.event.*;
|
||||||
import envoy.event.MessageStatusChange;
|
import envoy.util.SerializationUtils;
|
||||||
import envoy.event.NameChange;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores information about the current {@link User} and their {@link Chat}s.
|
* Stores information about the current {@link User} and their {@link Chat}s.
|
||||||
* For message ID generation a {@link IDGenerator} is stored as well.
|
* For message ID generation a {@link IDGenerator} is stored as well.
|
||||||
* <p>
|
* <p>
|
||||||
|
* The managed objects are stored inside a folder in the local file system.
|
||||||
|
* <p>
|
||||||
* Project: <strong>envoy-client</strong><br>
|
* Project: <strong>envoy-client</strong><br>
|
||||||
* File: <strong>LocalDB.java</strong><br>
|
* File: <strong>LocalDB.java</strong><br>
|
||||||
* Created: <strong>3 Feb 2020</strong><br>
|
* Created: <strong>3 Feb 2020</strong><br>
|
||||||
@ -19,60 +21,105 @@ import envoy.event.NameChange;
|
|||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public abstract class LocalDB {
|
public final class LocalDB {
|
||||||
|
|
||||||
protected User user;
|
private User user;
|
||||||
protected Map<String, User> users = new HashMap<>();
|
private Map<String, User> users = new HashMap<>();
|
||||||
protected List<Chat> chats = new ArrayList<>();
|
private List<Chat> chats = new ArrayList<>();
|
||||||
protected IDGenerator idGenerator;
|
private IDGenerator idGenerator;
|
||||||
protected CacheMap cacheMap = new CacheMap();
|
private CacheMap cacheMap = new CacheMap();
|
||||||
protected Instant lastSync = Instant.EPOCH;
|
private Instant lastSync = Instant.EPOCH;
|
||||||
|
private File dbDir, userFile, idGeneratorFile, usersFile;
|
||||||
|
|
||||||
{
|
/**
|
||||||
|
* Constructs an empty local database. To serialize any user-specific data to
|
||||||
|
* the file system, call {@link LocalDB#initializeUserStorage()} first
|
||||||
|
* and then {@link LocalDB#save(boolean)}.
|
||||||
|
*
|
||||||
|
* @param dbDir the directory in which to persist data
|
||||||
|
* @throws IOException if {@code dbDir} is a file (and not a directory)
|
||||||
|
* @since Envoy Client v0.2-beta
|
||||||
|
*/
|
||||||
|
public LocalDB(File dbDir) throws IOException {
|
||||||
|
this.dbDir = dbDir;
|
||||||
|
|
||||||
|
// Test if the database directory is actually a directory
|
||||||
|
if (dbDir.exists() && !dbDir.isDirectory())
|
||||||
|
throw new IOException(String.format("LocalDBDir '%s' is not a directory!", dbDir.getAbsolutePath()));
|
||||||
|
|
||||||
|
// Initialize global files
|
||||||
|
idGeneratorFile = new File(dbDir, "id_gen.db");
|
||||||
|
usersFile = new File(dbDir, "users.db");
|
||||||
|
|
||||||
|
// Initialize offline caches
|
||||||
cacheMap.put(Message.class, new Cache<>());
|
cacheMap.put(Message.class, new Cache<>());
|
||||||
cacheMap.put(MessageStatusChange.class, new Cache<>());
|
cacheMap.put(MessageStatusChange.class, new Cache<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a storage space for a user-specific list of chats.
|
* Creates a database file for a user-specific list of chats.
|
||||||
*
|
*
|
||||||
* @since Envoy Client v0.3-alpha
|
* @throws IllegalStateException if the client user is not specified
|
||||||
|
* @since Envoy Client v0.1-alpha
|
||||||
*/
|
*/
|
||||||
public void initializeUserStorage() {}
|
public void initializeUserStorage() {
|
||||||
|
if (user == null) throw new IllegalStateException("Client user is null, cannot initialize user storage");
|
||||||
|
userFile = new File(dbDir, user.getID() + ".db");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
* @param isOnline determines which {@code lastSync} time stamp is saved
|
||||||
* @throws Exception if the saving process failed
|
* @throws IOException if the saving process failed
|
||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public void save(boolean isOnline) throws Exception {}
|
public void save(boolean isOnline) throws IOException {
|
||||||
|
// Save users
|
||||||
|
SerializationUtils.write(usersFile, users);
|
||||||
|
|
||||||
|
// Save user data and last sync time stamp
|
||||||
|
if (user != null) SerializationUtils.write(userFile, chats, cacheMap, isOnline ? Instant.now() : lastSync);
|
||||||
|
|
||||||
|
// Save id generator
|
||||||
|
if (hasIDGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all user data.
|
* Loads all user data.
|
||||||
*
|
*
|
||||||
* @throws Exception if the loading process failed
|
* @throws ClassNotFoundException if the loading process failed
|
||||||
|
* @throws IOException if the loading process failed
|
||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public void loadUsers() throws Exception {}
|
public void loadUsers() throws ClassNotFoundException, IOException { users = SerializationUtils.read(usersFile, HashMap.class); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all data of the client user.
|
* Loads all data of the client user.
|
||||||
*
|
*
|
||||||
* @throws Exception if the loading process failed
|
* @throws ClassNotFoundException if the loading process failed
|
||||||
|
* @throws IOException if the loading process failed
|
||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public void loadUserData() throws Exception {}
|
public void loadUserData() throws ClassNotFoundException, IOException {
|
||||||
|
try (var in = new ObjectInputStream(new FileInputStream(userFile))) {
|
||||||
|
chats = (ArrayList<Chat>) in.readObject();
|
||||||
|
cacheMap = (CacheMap) in.readObject();
|
||||||
|
lastSync = (Instant) in.readObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the ID generator. Any exception thrown during this process is ignored.
|
* Loads the ID generator. Any exception thrown during this process is ignored.
|
||||||
*
|
*
|
||||||
* @since Envoy Client v0.3-alpha
|
* @since Envoy Client v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public void loadIDGenerator() {}
|
public void loadIDGenerator() {
|
||||||
|
try {
|
||||||
|
idGenerator = SerializationUtils.read(idGeneratorFile, IDGenerator.class);
|
||||||
|
} catch (ClassNotFoundException | IOException e) {}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Synchronizes the contact list of the client user with the chat and user
|
* Synchronizes the contact list of the client user with the chat and user
|
||||||
* storage.
|
* storage.
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
package envoy.client.data;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
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.
|
|
||||||
* <p>
|
|
||||||
* 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 Client v0.1-alpha
|
|
||||||
*/
|
|
||||||
public final class PersistentLocalDB extends LocalDB {
|
|
||||||
|
|
||||||
private File dbDir, userFile, idGeneratorFile, usersFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an empty local database. To serialize any user-specific data to
|
|
||||||
* the file system, call {@link PersistentLocalDB#initializeUserStorage()} first
|
|
||||||
* and then {@link PersistentLocalDB#save(boolean)}.
|
|
||||||
*
|
|
||||||
* @param dbDir the directory in which to persist data
|
|
||||||
* @throws IOException if {@code dbDir} is a file (and not a directory)
|
|
||||||
* @since Envoy Client v0.1-alpha
|
|
||||||
*/
|
|
||||||
public PersistentLocalDB(File dbDir) throws IOException {
|
|
||||||
this.dbDir = dbDir;
|
|
||||||
|
|
||||||
// Test if the database directory is actually a directory
|
|
||||||
if (dbDir.exists() && !dbDir.isDirectory())
|
|
||||||
throw new IOException(String.format("LocalDBDir '%s' is not a directory!", dbDir.getAbsolutePath()));
|
|
||||||
|
|
||||||
// Initialize global files
|
|
||||||
idGeneratorFile = new File(dbDir, "id_gen.db");
|
|
||||||
usersFile = new File(dbDir, "users.db");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a database file for a user-specific list of chats.
|
|
||||||
*
|
|
||||||
* @throws IllegalStateException if the client user is not specified
|
|
||||||
* @since Envoy Client v0.1-alpha
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void initializeUserStorage() {
|
|
||||||
if (user == null) throw new IllegalStateException("Client user is null, cannot initialize user storage");
|
|
||||||
userFile = new File(dbDir, user.getID() + ".db");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(boolean isOnline) throws IOException {
|
|
||||||
// Save users
|
|
||||||
SerializationUtils.write(usersFile, users);
|
|
||||||
|
|
||||||
// Save user data and last sync time stamp
|
|
||||||
if (user != null) SerializationUtils.write(userFile, chats, cacheMap, isOnline ? Instant.now() : lastSync);
|
|
||||||
|
|
||||||
// Save id generator
|
|
||||||
if (hasIDGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadUsers() throws ClassNotFoundException, IOException { users = SerializationUtils.read(usersFile, HashMap.class); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadUserData() throws ClassNotFoundException, IOException {
|
|
||||||
try (var in = new ObjectInputStream(new FileInputStream(userFile))) {
|
|
||||||
chats = (ArrayList<Chat>) in.readObject();
|
|
||||||
cacheMap = (CacheMap) in.readObject();
|
|
||||||
lastSync = (Instant) in.readObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadIDGenerator() {
|
|
||||||
try {
|
|
||||||
idGenerator = SerializationUtils.read(idGeneratorFile, IDGenerator.class);
|
|
||||||
} catch (ClassNotFoundException | IOException e) {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package envoy.client.data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements a {@link LocalDB} in a way that does not persist any information
|
|
||||||
* after application shutdown.
|
|
||||||
* <p>
|
|
||||||
* 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 Client v0.3-alpha
|
|
||||||
*/
|
|
||||||
public final class TransientLocalDB extends LocalDB {
|
|
||||||
}
|
|
@ -1,12 +1,9 @@
|
|||||||
package envoy.client.ui;
|
package envoy.client.ui;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.*;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
@ -19,8 +16,7 @@ import envoy.client.ui.SceneContext.SceneInfo;
|
|||||||
import envoy.client.ui.controller.LoginScene;
|
import envoy.client.ui.controller.LoginScene;
|
||||||
import envoy.data.*;
|
import envoy.data.*;
|
||||||
import envoy.data.User.UserStatus;
|
import envoy.data.User.UserStatus;
|
||||||
import envoy.event.GroupMessageStatusChange;
|
import envoy.event.*;
|
||||||
import envoy.event.MessageStatusChange;
|
|
||||||
import envoy.exception.EnvoyException;
|
import envoy.exception.EnvoyException;
|
||||||
import envoy.util.EnvoyLog;
|
import envoy.util.EnvoyLog;
|
||||||
|
|
||||||
@ -70,11 +66,8 @@ public final class Startup extends Application {
|
|||||||
logger.log(Level.INFO, "Envoy starting...");
|
logger.log(Level.INFO, "Envoy starting...");
|
||||||
|
|
||||||
// Initialize the local database
|
// Initialize the local database
|
||||||
if (config.isIgnoreLocalDB()) {
|
try {
|
||||||
localDB = new TransientLocalDB();
|
localDB = new LocalDB(new File(config.getHomeDirectory(), config.getLocalDB().getPath()));
|
||||||
new Alert(AlertType.WARNING, "Ignoring local database.\nMessages will not be saved!").showAndWait();
|
|
||||||
} else try {
|
|
||||||
localDB = new PersistentLocalDB(new File(config.getHomeDirectory(), config.getLocalDB().getPath()));
|
|
||||||
} catch (final IOException e3) {
|
} catch (final IOException e3) {
|
||||||
logger.log(Level.SEVERE, "Could not initialize local database: ", e3);
|
logger.log(Level.SEVERE, "Could not initialize local database: ", e3);
|
||||||
new Alert(AlertType.ERROR, "Could not initialize local database!\n" + e3).showAndWait();
|
new Alert(AlertType.ERROR, "Could not initialize local database!\n" + e3).showAndWait();
|
||||||
|
Reference in New Issue
Block a user