Simplify cache storage with a CacheMap class
This commit is contained in:
parent
4f654cc2a5
commit
9c19d544d6
46
src/main/java/envoy/client/data/CacheMap.java
Normal file
46
src/main/java/envoy/client/data/CacheMap.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package envoy.client.data;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a heterogeneous map of {@link Cache} objects with different type
|
||||||
|
* parameters.
|
||||||
|
* <p>
|
||||||
|
* Project: <strong>envoy-client</strong><br>
|
||||||
|
* File: <strong>CacheMap.java</strong><br>
|
||||||
|
* Created: <strong>09.07.2020</strong><br>
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
* @since Envoy Client v0.1-beta
|
||||||
|
*/
|
||||||
|
public final class CacheMap {
|
||||||
|
|
||||||
|
private final Map<Class<?>, Cache<?>> map = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a cache to the map.
|
||||||
|
*
|
||||||
|
* @param <T> the type accepted by the cache
|
||||||
|
* @param key the class that maps to the cache
|
||||||
|
* @param cache the cache to store
|
||||||
|
* @since Envoy Client v0.1-beta
|
||||||
|
*/
|
||||||
|
public <T> void put(Class<T> key, Cache<T> cache) { map.put(key, cache); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a cache mapped by a class.
|
||||||
|
*
|
||||||
|
* @param <T> the type accepted by the cache
|
||||||
|
* @param key the class that maps to the cache
|
||||||
|
* @return the cache
|
||||||
|
* @since Envoy Client v0.1-beta
|
||||||
|
*/
|
||||||
|
public <T> Cache<T> get(Class<T> key) { return (Cache<T>) map.get(key); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the map in which the caches are stored
|
||||||
|
* @since Envoy Client v0.1-beta
|
||||||
|
*/
|
||||||
|
public Map<Class<?>, Cache<?>> getMap() { return map; }
|
||||||
|
}
|
@ -3,13 +3,11 @@ package envoy.client.net;
|
|||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import envoy.client.data.Cache;
|
import envoy.client.data.CacheMap;
|
||||||
import envoy.client.data.ClientConfig;
|
import envoy.client.data.ClientConfig;
|
||||||
import envoy.client.data.LocalDB;
|
import envoy.client.data.LocalDB;
|
||||||
import envoy.client.event.SendEvent;
|
import envoy.client.event.SendEvent;
|
||||||
@ -40,8 +38,6 @@ public class Client implements Closeable {
|
|||||||
private Receiver receiver;
|
private Receiver receiver;
|
||||||
private boolean online;
|
private boolean online;
|
||||||
|
|
||||||
private Map<Class<?>, Cache<?>> cacheMap;
|
|
||||||
|
|
||||||
// Asynchronously initialized during handshake
|
// Asynchronously initialized during handshake
|
||||||
private volatile User sender;
|
private volatile User sender;
|
||||||
private volatile boolean rejected;
|
private volatile boolean rejected;
|
||||||
@ -64,7 +60,8 @@ public class Client implements Closeable {
|
|||||||
* @throws InterruptedException if the current thread is interrupted while
|
* @throws InterruptedException if the current thread is interrupted while
|
||||||
* waiting for the handshake response
|
* waiting for the handshake response
|
||||||
*/
|
*/
|
||||||
public void performHandshake(LoginCredentials credentials, Map<Class<?>, Cache<?>> cacheMap)
|
public void performHandshake(LoginCredentials credentials,
|
||||||
|
CacheMap cacheMap)
|
||||||
throws TimeoutException, IOException, InterruptedException {
|
throws TimeoutException, IOException, InterruptedException {
|
||||||
if (online) throw new IllegalStateException("Handshake has already been performed successfully");
|
if (online) throw new IllegalStateException("Handshake has already been performed successfully");
|
||||||
|
|
||||||
@ -78,7 +75,7 @@ public class Client implements Closeable {
|
|||||||
|
|
||||||
// Register user creation processor, contact list processor and message cache
|
// Register user creation processor, contact list processor and message cache
|
||||||
receiver.registerProcessor(User.class, sender -> this.sender = sender);
|
receiver.registerProcessor(User.class, sender -> this.sender = sender);
|
||||||
cacheMap.forEach((inputclass, cache) -> receiver.registerProcessor(inputclass, cache));
|
receiver.registerProcessors(cacheMap.getMap());
|
||||||
receiver.registerProcessor(HandshakeRejection.class, evt -> { rejected = true; eventBus.dispatch(evt); });
|
receiver.registerProcessor(HandshakeRejection.class, evt -> { rejected = true; eventBus.dispatch(evt); });
|
||||||
|
|
||||||
rejected = false;
|
rejected = false;
|
||||||
@ -124,7 +121,7 @@ public class Client implements Closeable {
|
|||||||
* requested from the server
|
* requested from the server
|
||||||
* @since Envoy Client v0.2-alpha
|
* @since Envoy Client v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public void initReceiver(LocalDB localDB, Map<Class<?>, Cache<?>> cacheMap) throws IOException {
|
public void initReceiver(LocalDB localDB, CacheMap cacheMap) throws IOException {
|
||||||
checkOnline();
|
checkOnline();
|
||||||
|
|
||||||
// Process incoming messages
|
// Process incoming messages
|
||||||
@ -134,18 +131,17 @@ public class Client implements Closeable {
|
|||||||
final GroupMessageStatusChangeProcessor groupMessageStatusChangeProcessor = new GroupMessageStatusChangeProcessor();
|
final GroupMessageStatusChangeProcessor groupMessageStatusChangeProcessor = new GroupMessageStatusChangeProcessor();
|
||||||
|
|
||||||
receiver.registerProcessor(GroupMessage.class, receivedGroupMessageProcessor);
|
receiver.registerProcessor(GroupMessage.class, receivedGroupMessageProcessor);
|
||||||
|
|
||||||
receiver.registerProcessor(Message.class, receivedMessageProcessor);
|
receiver.registerProcessor(Message.class, receivedMessageProcessor);
|
||||||
|
|
||||||
receiver.registerProcessor(MessageStatusChange.class, messageStatusChangeProcessor);
|
receiver.registerProcessor(MessageStatusChange.class, messageStatusChangeProcessor);
|
||||||
|
|
||||||
receiver.registerProcessor(GroupMessageStatusChange.class, groupMessageStatusChangeProcessor);
|
receiver.registerProcessor(GroupMessageStatusChange.class, groupMessageStatusChangeProcessor);
|
||||||
|
|
||||||
// Relay cached unread messages and unread groupMessages
|
// Relay cached unread messages and unread groupMessages
|
||||||
cacheMap.get(Message.class).setProcessor((Consumer<?>) receivedMessageProcessor);
|
cacheMap.get(Message.class).setProcessor(receivedMessageProcessor);
|
||||||
cacheMap.get(GroupMessage.class).setProcessor((Consumer<?>) receivedGroupMessageProcessor);
|
cacheMap.get(GroupMessage.class).setProcessor(receivedGroupMessageProcessor);
|
||||||
// Process message status changes
|
|
||||||
cacheMap.get(MessageStatusChange.class).setProcessor((Consumer<?>) messageStatusChangeProcessor);
|
// Relay cached status changes
|
||||||
cacheMap.get(GroupMessageStatusChange.class).setProcessor((Consumer<?>) groupMessageStatusChangeProcessor);
|
cacheMap.get(MessageStatusChange.class).setProcessor(messageStatusChangeProcessor);
|
||||||
|
cacheMap.get(GroupMessageStatusChange.class).setProcessor(groupMessageStatusChangeProcessor);
|
||||||
|
|
||||||
// Process user status changes
|
// Process user status changes
|
||||||
receiver.registerProcessor(UserStatusChange.class, eventBus::dispatch);
|
receiver.registerProcessor(UserStatusChange.class, eventBus::dispatch);
|
||||||
|
@ -79,9 +79,7 @@ public class Receiver extends Thread {
|
|||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
final Consumer processor = processors.get(obj.getClass());
|
final Consumer processor = processors.get(obj.getClass());
|
||||||
if (processor == null)
|
if (processor == null)
|
||||||
logger.log(Level.WARNING, String.format(
|
logger.log(Level.WARNING, String.format("The received object has the %s for which no processor is defined.", obj.getClass()));
|
||||||
"The received object has the %s for which no processor is defined.",
|
|
||||||
obj.getClass()));
|
|
||||||
else processor.accept(obj);
|
else processor.accept(obj);
|
||||||
}
|
}
|
||||||
} catch (final SocketException e) {
|
} catch (final SocketException e) {
|
||||||
@ -103,6 +101,14 @@ public class Receiver extends Thread {
|
|||||||
*/
|
*/
|
||||||
public <T> void registerProcessor(Class<T> processorClass, Consumer<T> processor) { processors.put(processorClass, processor); }
|
public <T> void registerProcessor(Class<T> processorClass, Consumer<T> processor) { processors.put(processorClass, processor); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a map of object processors to this {@link Receiver}.
|
||||||
|
*
|
||||||
|
* @param processors the processors to add the processors to add
|
||||||
|
* @since Envoy Client v0.1-beta
|
||||||
|
*/
|
||||||
|
public void registerProcessors(Map<Class<?>, ? extends Consumer<?>> processors) { this.processors.putAll(processors); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all object processors registered at this {@link Receiver}.
|
* Removes all object processors registered at this {@link Receiver}.
|
||||||
*
|
*
|
||||||
|
@ -2,7 +2,6 @@ package envoy.client.ui;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -100,7 +99,7 @@ public final class Startup extends Application {
|
|||||||
// Initialize client and unread message cache
|
// Initialize client and unread message cache
|
||||||
client = new Client();
|
client = new Client();
|
||||||
|
|
||||||
final var cacheMap = new HashMap<Class<?>, Cache<?>>();
|
final var cacheMap = new CacheMap();
|
||||||
cacheMap.put(Message.class, new Cache<Message>());
|
cacheMap.put(Message.class, new Cache<Message>());
|
||||||
cacheMap.put(GroupMessage.class, new Cache<GroupMessage>());
|
cacheMap.put(GroupMessage.class, new Cache<GroupMessage>());
|
||||||
cacheMap.put(MessageStatusChange.class, new Cache<MessageStatusChange>());
|
cacheMap.put(MessageStatusChange.class, new Cache<MessageStatusChange>());
|
||||||
|
@ -2,7 +2,6 @@ package envoy.client.ui.controller;
|
|||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
|
||||||
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;
|
||||||
@ -55,10 +54,10 @@ public final class LoginScene {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label connectionLabel;
|
private Label connectionLabel;
|
||||||
|
|
||||||
private Client client;
|
private Client client;
|
||||||
private LocalDB localDB;
|
private LocalDB localDB;
|
||||||
private Map<Class<?>, Cache<?>> cacheMap;
|
private CacheMap cacheMap;
|
||||||
private SceneContext sceneContext;
|
private SceneContext sceneContext;
|
||||||
|
|
||||||
private static final Logger logger = EnvoyLog.getLogger(LoginScene.class);
|
private static final Logger logger = EnvoyLog.getLogger(LoginScene.class);
|
||||||
private static final EventBus eventBus = EventBus.getInstance();
|
private static final EventBus eventBus = EventBus.getInstance();
|
||||||
@ -81,7 +80,7 @@ public final class LoginScene {
|
|||||||
* @param sceneContext the scene context used to initialize the chat scene
|
* @param sceneContext the scene context used to initialize the chat scene
|
||||||
* @since Envoy Client v0.1-beta
|
* @since Envoy Client v0.1-beta
|
||||||
*/
|
*/
|
||||||
public void initializeData(Client client, LocalDB localDB, Map<Class<?>, Cache<?>> cacheMap, SceneContext sceneContext) {
|
public void initializeData(Client client, LocalDB localDB, CacheMap cacheMap, SceneContext sceneContext) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.localDB = localDB;
|
this.localDB = localDB;
|
||||||
this.cacheMap = cacheMap;
|
this.cacheMap = cacheMap;
|
||||||
@ -198,6 +197,6 @@ public final class LoginScene {
|
|||||||
sceneContext.<ChatScene>getController().initializeData(sceneContext, localDB, client, writeProxy);
|
sceneContext.<ChatScene>getController().initializeData(sceneContext, localDB, client, writeProxy);
|
||||||
|
|
||||||
// Relay unread messages from cache
|
// Relay unread messages from cache
|
||||||
if (client.isOnline()) cacheMap.values().forEach(cache -> { if (cache != null) cache.relay(); });
|
if (client.isOnline()) cacheMap.getMap().values().forEach(cache -> { if (cache != null) cache.relay(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user