package envoy.client.data; import java.util.*; import envoy.data.*; import envoy.event.GroupResize; import envoy.event.MessageStatusChange; import envoy.event.NameChange; /** * Stores information about the current {@link User} and their {@link Chat}s. * For message ID generation a {@link IDGenerator} is stored as well. *

* Project: envoy-client
* File: LocalDB.java
* Created: 3 Feb 2020
* * @author Kai S. K. Engelbart * @since Envoy Client v0.3-alpha */ public abstract class LocalDB { protected User user; protected Map users = new HashMap<>(); protected List chats = new ArrayList<>(); protected IDGenerator idGenerator; protected CacheMap cacheMap = new CacheMap(); { cacheMap.put(Message.class, new Cache<>()); cacheMap.put(MessageStatusChange.class, new Cache<>()); } /** * Initializes a storage space for a user-specific list of chats. * * @since Envoy Client 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 Client v0.3-alpha */ public void save() throws Exception {} /** * Loads all user data. * * @throws Exception if the loading process failed * @since Envoy Client v0.3-alpha */ public void loadUsers() throws Exception {} /** * Loads all data of the client user. * * @throws Exception if the loading process failed * @since Envoy Client v0.3-alpha */ public void loadUserData() throws Exception {} /** * Loads the ID generator. Any exception thrown during this process is ignored. * * @since Envoy Client v0.3-alpha */ public void loadIDGenerator() {} /** * Synchronizes the contact list of the client user with the chat and user * storage. * * @since Envoy Client v0.1-beta */ public void synchronize() { user.getContacts().stream().filter(u -> u instanceof User && !users.containsKey(u.getName())).forEach(u -> users.put(u.getName(), u)); users.put(user.getName(), user); // Synchronize user status data for (Contact contact : users.values()) if (contact instanceof User) getChat(contact.getID()).ifPresent(chat -> { ((User) chat.getRecipient()).setStatus(((User) contact).getStatus()); }); // Create missing chats user.getContacts() .stream() .filter(c -> !c.equals(user) && getChat(c.getID()).isEmpty()) .map(c -> c instanceof User ? new Chat(c) : new GroupChat(user, c)) .forEach(chats::add); } /** * @return a {@code Map} of all users stored locally with their * user names as keys * @since Envoy Client v0.2-alpha */ public Map getUsers() { return users; } /** * @return all saved {@link Chat} objects that list the client user as the * sender * @since Envoy Client v0.1-alpha **/ public List getChats() { return chats; } /** * @param chats the chats to set */ public void setChats(List chats) { this.chats = chats; } /** * @return the {@link User} who initialized the local database * @since Envoy Client v0.2-alpha */ public User getUser() { return user; } /** * @param user the user to set * @since Envoy Client v0.2-alpha */ public void setUser(User user) { this.user = user; } /** * @return the message ID generator * @since Envoy Client v0.3-alpha */ public IDGenerator getIDGenerator() { return idGenerator; } /** * @param idGenerator the message ID generator to set * @since Envoy Client v0.3-alpha */ public void setIDGenerator(IDGenerator idGenerator) { this.idGenerator = idGenerator; } /** * @return {@code true} if an {@link IDGenerator} is present * @since Envoy Client v0.3-alpha */ public boolean hasIDGenerator() { return idGenerator != null; } /** * @return the cache map for messages and message status changes * @since Envoy Client v0.1-beta */ public CacheMap getCacheMap() { return cacheMap; } /** * Searches for a message by ID. * * @param id the ID of the message to search for * @return an optional containing the message * @since Envoy Client v0.1-beta */ public Optional getMessage(long id) { return chats.stream().map(Chat::getMessages).flatMap(List::stream).filter(m -> m.getID() == id).findAny(); } /** * Searches for a chat by recipient ID. * * @param recipientID the ID of the chat's recipient * @return an optional containing the chat * @since Envoy Client v0.1-beta */ public Optional getChat(long recipientID) { return chats.stream().filter(c -> c.getRecipient().getID() == recipientID).findAny(); } /** * Performs a contact name change if the corresponding contact is present. * * @param event the {@link NameChange} to process * @since Envoy Client v0.1-beta */ public void replaceContactName(NameChange event) { chats.stream().map(Chat::getRecipient).filter(c -> c.getID() == event.getID()).findAny().ifPresent(c -> c.setName(event.get())); } /** * Performs a group resize operation if the corresponding group is present. * * @param event the {@link GroupResize} to process * @since Envoy Client v0.1-beta */ public void updateGroup(GroupResize event) { chats.stream() .map(Chat::getRecipient) .filter(Group.class::isInstance) .filter(g -> g.getID() == event.getGroupID() && g.getID() != user.getID()) .map(Group.class::cast) .findAny() .ifPresent(group -> { switch (event.getOperation()) { case ADD: group.getContacts().add(event.get()); break; case REMOVE: group.getContacts().remove(event.get()); break; } }); } }