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. *

* Project: envoy-client
* File: PersistentLocalDB.java
* Created: 27.10.2019
* * @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) 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) {} } }