Added WriteProxy with creation method in Client, added caches to LocalDb
This commit is contained in:
		| @@ -20,8 +20,8 @@ import envoy.client.util.EnvoyLog; | ||||
|  */ | ||||
| public class Cache<T> implements Consumer<T> { | ||||
|  | ||||
| 	private final Queue<T>	elements	= new LinkedList<>(); | ||||
| 	private Consumer<T>		processor; | ||||
| 	private final Queue<T>			elements	= new LinkedList<>(); | ||||
| 	private transient Consumer<T>	processor; | ||||
|  | ||||
| 	private static final Logger logger = EnvoyLog.getLogger(Cache.class.getSimpleName()); | ||||
|  | ||||
| @@ -54,5 +54,6 @@ public class Cache<T> implements Consumer<T> { | ||||
| 	public void relay() { | ||||
| 		if (processor == null) throw new IllegalStateException("Processor is not defined"); | ||||
| 		elements.forEach(processor::accept); | ||||
| 		elements.clear(); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,9 @@ package envoy.client.data; | ||||
| import java.util.*; | ||||
|  | ||||
| import envoy.data.IdGenerator; | ||||
| import envoy.data.Message; | ||||
| import envoy.data.User; | ||||
| import envoy.event.MessageStatusChangeEvent; | ||||
|  | ||||
| /** | ||||
|  * Stores information about the current {@link User} and their {@link Chat}s. | ||||
| @@ -18,10 +20,12 @@ import envoy.data.User; | ||||
|  */ | ||||
| public abstract class LocalDb { | ||||
|  | ||||
| 	protected User				user; | ||||
| 	protected Map<String, User>	users	= new HashMap<>(); | ||||
| 	protected List<Chat>		chats	= new ArrayList<>(); | ||||
| 	protected IdGenerator		idGenerator; | ||||
| 	protected User								user; | ||||
| 	protected Map<String, User>					users	= new HashMap<>(); | ||||
| 	protected List<Chat>						chats	= new ArrayList<>(); | ||||
| 	protected IdGenerator						idGenerator; | ||||
| 	protected Cache<Message>					messageCache; | ||||
| 	protected Cache<MessageStatusChangeEvent>	statusCache; | ||||
|  | ||||
| 	/** | ||||
| 	 * Initializes a storage space for a user-specific list of chats. | ||||
| @@ -115,4 +119,28 @@ public abstract class LocalDb { | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public boolean hasIdGenerator() { return idGenerator != null; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the offline message cache | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public Cache<Message> getMessageCache() { return messageCache; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param messageCache the offline message cache to set | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void setMessageCache(Cache<Message> messageCache) { this.messageCache = messageCache; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the offline status cache | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public Cache<MessageStatusChangeEvent> getStatusCache() { return statusCache; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param statusCache the offline status cache to set | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void setStatusCache(Cache<MessageStatusChangeEvent> statusCache) { this.statusCache = statusCache; } | ||||
| } | ||||
|   | ||||
| @@ -40,18 +40,18 @@ public class PersistentLocalDb extends LocalDb { | ||||
| 	 * 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 | ||||
| 	 * @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; | ||||
| 	public PersistentLocalDb(File localDbDir) throws IOException { | ||||
| 		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"); | ||||
| 		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"); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|   | ||||
| @@ -118,6 +118,17 @@ public class Client implements Closeable { | ||||
| 		return cache; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates a new write proxy that uses this client to communicate with the | ||||
| 	 * server. | ||||
| 	 * | ||||
| 	 * @param localDb the local database that the write proxy will use to access | ||||
| 	 *                caches | ||||
| 	 * @return a new write proxy | ||||
| 	 * @since Envoy Client v0.3-alpha | ||||
| 	 */ | ||||
| 	public WriteProxy createWriteProxy(LocalDb localDb) { return new WriteProxy(this, localDb); } | ||||
|  | ||||
| 	/** | ||||
| 	 * Sends a message to the server. The message's status will be incremented once | ||||
| 	 * it was delivered successfully. | ||||
|   | ||||
							
								
								
									
										102
									
								
								src/main/java/envoy/client/net/WriteProxy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/main/java/envoy/client/net/WriteProxy.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| package envoy.client.net; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.util.logging.Level; | ||||
| import java.util.logging.Logger; | ||||
|  | ||||
| import envoy.client.data.LocalDb; | ||||
| import envoy.client.util.EnvoyLog; | ||||
| import envoy.data.Message; | ||||
| import envoy.event.MessageStatusChangeEvent; | ||||
|  | ||||
| /** | ||||
|  * Implements methods to send {@link Message}s and | ||||
|  * {@link MessageStatusChangeEvent}s to the server or cache them inside a | ||||
|  * {@link LocalDb} depending on the online status.<br> | ||||
|  * <br> | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>WriteProxy.java</strong><br> | ||||
|  * Created: <strong>6 Feb 2020</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since Envoy v0.3-alpha | ||||
|  */ | ||||
| public class WriteProxy { | ||||
|  | ||||
| 	private final Client	client; | ||||
| 	private final LocalDb	localDb; | ||||
|  | ||||
| 	private static final Logger logger = EnvoyLog.getLogger(WriteProxy.class.getSimpleName()); | ||||
|  | ||||
| 	/** | ||||
| 	 * Initializes a write proxy using a client and a local database. The | ||||
| 	 * corresponding cache processors are injected into the caches. | ||||
| 	 * | ||||
| 	 * @param client  the client used to send messages and message status change | ||||
| 	 *                events | ||||
| 	 * @param localDb the local database used to cache messages and message status | ||||
| 	 *                change events | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public WriteProxy(Client client, LocalDb localDb) { | ||||
| 		this.client		= client; | ||||
| 		this.localDb	= localDb; | ||||
|  | ||||
| 		// Initialize cache processors for messages and message status change events | ||||
| 		localDb.getMessageCache().setProcessor(msg -> { | ||||
| 			try { | ||||
| 				client.sendMessage(msg); | ||||
| 			} catch (IOException e) { | ||||
| 				logger.log(Level.SEVERE, "Could not send cached message", e); | ||||
| 			} | ||||
| 		}); | ||||
| 		localDb.getStatusCache().setProcessor(evt -> { | ||||
| 			try { | ||||
| 				client.sendEvent(evt); | ||||
| 			} catch (IOException e) { | ||||
| 				logger.log(Level.SEVERE, "Could not send cached message status change event", e); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Sends cached {@link Message}s and {@link MessageStatusChangeEvent}s to the | ||||
| 	 * server. | ||||
| 	 *  | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void flushCache() { | ||||
|  | ||||
| 		// Send messages | ||||
| 		localDb.getMessageCache().relay(); | ||||
|  | ||||
| 		// Send message status change events | ||||
| 		localDb.getStatusCache().relay(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Delivers a message to the server if online. Otherwise the message is cached | ||||
| 	 * inside the local database. | ||||
| 	 * | ||||
| 	 * @param message the message to send | ||||
| 	 * @throws IOException if the message could not be sent | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void writeMessage(Message message) throws IOException { | ||||
| 		if (client.isOnline()) client.sendMessage(message); | ||||
| 		else localDb.getMessageCache().accept(message); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Delivers a message status change event to the server if online. Otherwise the | ||||
| 	 * event is cached inside the local database. | ||||
| 	 * | ||||
| 	 * @param evt the event to send | ||||
| 	 * @throws IOException if the event could not be sent | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void writeMessageStatusChangeEvent(MessageStatusChangeEvent evt) throws IOException { | ||||
| 		if (client.isOnline()) client.sendEvent(evt); | ||||
| 		else localDb.getStatusCache().accept(evt); | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user