package envoy.server.database; import java.util.Date; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import envoy.data.User.UserStatus; import envoy.server.data.ConfigItem; import envoy.server.data.Message; import envoy.server.data.User; import envoy.server.net.ConnectionManager; /** * Project: envoy-server-standalone
* File: PersistenceManager.java
* Created: 1 Jan 2020
* * @author Leon Hofmeister * @since Envoy Server Standalone v0.1-alpha */ public class PersistenceManager { private final EntityManager entityManager = Persistence.createEntityManagerFactory("envoy").createEntityManager(); private final EntityTransaction transaction = entityManager.getTransaction(); private static final PersistenceManager persistenceManager = new PersistenceManager(); /** * Creates the singleton instance of the @link{PersistenceManager}. * * @since Envoy Server Standalone v0.1-alpha */ private PersistenceManager() { transaction.begin(); Runtime.getRuntime().addShutdownHook(new Thread(() -> { ConnectionManager.getInstance() .getOnlineUsers() .stream() .map(this::getUserById) .forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(new Date()); updateUser(user); }); transaction.commit(); })); } /** * @return the {@link PersistenceManager} singleton * @since Envoy Server Standalone v0.1-alpha */ public static PersistenceManager getInstance() { return persistenceManager; } /** * Adds a {@link User} to the database. * * @param User the {@link User} to add to the database * @since Envoy Server Standalone v0.1-alpha */ public void addUser(User User) { entityManager.persist(User); entityManager.flush(); } /** * Adds a {@link Message} to the database. * * @param message the {@link Message} to add to the database * @since Envoy Server Standalone v0.1-alpha */ public void addMessage(Message message) { entityManager.persist(message); entityManager.flush(); } /** * Adds a {@link ConfigItem} to the database. * * @param configItem the {@link ConfigItem} to add to the database * @since Envoy Server Standalone v0.1-alpha */ public void addConfigItem(ConfigItem configItem) { entityManager.persist(configItem); entityManager.flush(); } /** * Updates a {@link User} in the database * * @param user the {@link User} to add to the database * @since Envoy Server Standalone v0.1-alpha */ public void updateUser(User user) { entityManager.merge(user); entityManager.flush(); } /** * Updates a {@link Message} in the database. * * @param message the message to update * @since Envoy Server Standalone v0.1-alpha */ public void updateMessage(Message message) { entityManager.merge(message); entityManager.flush(); } /** * Updates a {@link ConfigItem} in the database. * * @param configItem the configItem to update * @since Envoy Server Standalone v0.1-alpha */ public void updateConfigItem(ConfigItem configItem) { entityManager.merge(configItem); entityManager.flush(); } /** * Deletes a {@link User} in the database. * * @param user the {@link User} to delete * @since Envoy Server Standalone v0.1-alpha */ public void deleteUser(User user) { entityManager.remove(user); entityManager.flush(); } /** * Deletes a {@link Message} in the database. * * @param message the {@link Message} to delete * @since Envoy Server Standalone v0.1-alpha */ public void deleteMessage(Message message) { entityManager.remove(message); entityManager.flush(); } /** * Searches for a {@link User} with a specific id. * * @param id the id to search for * @return the user with the specified id * @since Envoy Server Standalone v0.1-alpha */ public User getUserById(long id) { return entityManager.find(User.class, id); } /** * Searched for a {@link User} with a specific name. * * @param name the name of the user * @return the user with the specified name * @since Envoy Server Standalone v0.1-alpha */ public User getUserByName(String name) { return (User) entityManager.createNamedQuery("getUserByName").setParameter("name", name).getSingleResult(); } /** * Searches for a {@link Message} with a specific id. * * @param id the id to search for * @return the message with the specified id * @since Envoy Server Standalone v0.1-alpha */ public Message getMessageById(long id) { return entityManager.find(Message.class, id); } /** * @param key the name of this {@link ConfigItem} * @return the {@link ConfigItem} with the given name * @since Envoy Server Standalone v0.1-alpha */ public ConfigItem getConfigItemById(String key) { return entityManager.find(ConfigItem.class, key); } /** * Returns all messages received while being offline. * * @param user - the user who wants to receive his unread messages * @return all messages that the client does not yet have (unread messages) * @since Envoy Server Standalone v0.1-alpha */ public List getUnreadMessages(User user) { return entityManager.createNamedQuery("getUnreadMessages").setParameter("recipient", user).getResultList(); } /** * Searches for users matching a search phrase. Contacts of the attached user * and the attached user is ignored. * * @param searchPhrase the search phrase * @param userId the ID of the user in whose context the search is * performed * @return a list of all users who matched the criteria * @since Envoy Server Standalone v0.1-alpha */ public List searchUsers(String searchPhrase, long userId) { return entityManager.createNamedQuery("searchUsers") .setParameter("searchPhrase", searchPhrase + "%") .setParameter("context", getUserById(userId)) .getResultList(); } /** * Adds a user to the contact list of another user and vice versa. * * @param userId1 the ID of the first user * @param userId2 the ID of the second user * @since Envoy Server Standalone v0.1-alpha */ public void addContact(long userId1, long userId2) { User u1 = getUserById(userId1); User u2 = getUserById(userId2); u1.getContacts().add(u2); u2.getContacts().add(u1); updateUser(u1); updateUser(u2); } /** * @param user the User whose contacts should be retrieved * @return the contacts of this User * @since Envoy Server Standalone v0.1-alpha */ public List getContacts(User user) { return entityManager.createNamedQuery("getContactsOfUser").setParameter("user", user).getResultList(); } }