This repository has been archived on 2021-12-05. You can view files and clone it, but cannot push or open issues or pull requests.
envoy/src/main/java/envoy/client/data/LocalDB.java

220 lines
6.2 KiB
Java
Raw Normal View History

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.
* <p>
* Project: <strong>envoy-client</strong><br>
* File: <strong>LocalDB.java</strong><br>
* Created: <strong>3 Feb 2020</strong><br>
*
* @author Kai S. K. Engelbart
* @since Envoy Client v0.3-alpha
*/
public abstract class LocalDB {
protected User user;
protected Map<String, Contact> users = new HashMap<>();
protected List<Chat> chats = new ArrayList<>();
protected IDGenerator idGenerator;
protected Cache<Message> messageCache = new Cache<>();
protected Cache<MessageStatusChange> statusCache = 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 {}
/**
2020-02-06 21:42:17 +01:00
* Loads all data of the client user.
*
* @throws Exception if the loading process failed
* @since Envoy Client v0.3-alpha
*/
2020-02-06 21:42:17 +01:00
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<String, User>} of all users stored locally with their
* user names as keys
* @since Envoy Client v0.2-alpha
*/
public Map<String, Contact> 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<Chat> getChats() { return chats; }
/**
* @param chats the chats to set
*/
public void setChats(List<Chat> 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 offline message cache
* @since Envoy Client v0.3-alpha
*/
public Cache<Message> getMessageCache() { return messageCache; }
/**
* @param messageCache the offline message cache to set
* @since Envoy Client v0.3-alpha
*/
public void setMessageCache(Cache<Message> messageCache) { this.messageCache = messageCache; }
/**
* @return the offline status cache
* @since Envoy Client v0.3-alpha
*/
public Cache<MessageStatusChange> getStatusCache() { return statusCache; }
/**
* @param statusCache the offline status cache to set
* @since Envoy Client v0.3-alpha
*/
public void setStatusCache(Cache<MessageStatusChange> statusCache) { this.statusCache = statusCache; }
/**
* Searches for a message by ID.
*
* @param id the ID of the message to search for
2020-06-10 13:05:44 +02:00
* @return an optional containing the message
* @since Envoy Client v0.1-beta
*/
2020-06-10 13:05:44 +02:00
public Optional<Message> getMessage(long id) {
return chats.stream().map(Chat::getMessages).flatMap(List::stream).filter(m -> m.getID() == id).findAny();
}
2020-06-10 13:05:44 +02:00
/**
* 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<Chat> 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;
}
});
}
}