package managers; import akka.actor.ActorSystem; import models.*; import models.enums.GroupType; import models.enums.LinkType; import models.services.ElasticsearchService; import play.db.jpa.DefaultJPAApi; import play.db.jpa.JPA; import play.db.jpa.JPAApi; import scala.concurrent.duration.Duration; import javax.inject.Inject; import javax.persistence.NoResultException; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; /** * Created by Iven on 16.12.2015. */ public class GroupAccountManager implements BaseManager { @Inject ElasticsearchService elasticsearchService; @Inject NotificationManager notificationManager; @Inject PostManager postManager; @Inject MediaManager mediaManager; @Inject JPAApi jpaApi; @Override public void create(Object model) { jpaApi.em().persist(model); reIndex(((GroupAccount) model).group); } @Override public void update(Object model) { jpaApi.em().merge(model); reIndex(((GroupAccount) model).group); } @Override public void delete(Object model) { GroupAccount groupAccount = (GroupAccount) model; jpaApi.em().remove(groupAccount); reIndex(groupAccount.group); notificationManager.deleteReferencesForAccountId(groupAccount.group, groupAccount.account.id); } public GroupAccount findById(Long id) { return jpaApi.em().find(GroupAccount.class, id); } /** * Find all groups and courses where given account is owner or member */ public List<Group> findEstablished(Account account) { @SuppressWarnings("unchecked") List<Group> groupAccounts = jpaApi .em() .createQuery( "SELECT ga.group FROM GroupAccount ga WHERE ga.account.id = ?1 AND ga.linkType = ?2") .setParameter(1, account.id) .setParameter(2, LinkType.establish).getResultList(); return groupAccounts; } /** * Find all groups where given account is owner or member */ public List<Group> findGroupsEstablished(Account account) { @SuppressWarnings("unchecked") List<Group> groupAccounts = jpaApi .em() .createQuery( "SELECT ga.group FROM GroupAccount ga WHERE ga.account.id = ?1 AND ga.linkType = ?2 AND ga.group.groupType != ?3 ORDER BY ga.group.title ASC") .setParameter(1, account.id) .setParameter(2, LinkType.establish) .setParameter(3, GroupType.course).getResultList(); return groupAccounts; } /** * Find all courses where given account is owner or member. */ public List<Group> findCoursesEstablished(final Account account) { @SuppressWarnings("unchecked") List<Group> courseAccounts = jpaApi .em() .createQuery( "SELECT ga.group FROM GroupAccount ga WHERE ga.account.id = ?1 AND ga.linkType = ?2 AND ga.group.groupType = ?3 ORDER BY ga.group.title ASC") .setParameter(1, account.id) .setParameter(2, LinkType.establish) .setParameter(3, GroupType.course).getResultList(); return courseAccounts; } /** * Find all open groups where given account is owner or member */ @SuppressWarnings("unchecked") public List<Group> findPublicEstablished(final Account account) { return jpaApi .em() .createQuery( "SELECT ga.group FROM GroupAccount ga WHERE ga.account.id = ?1 AND ga.linkType = ?2 AND ga.group.groupType = ?3") .setParameter(1, account.id) .setParameter(2, LinkType.establish) .setParameter(3, GroupType.open).getResultList(); } /** * Find all requests and rejects for summarization under "Offene Anfragen" * for given Account * * @param account Account instance * @return List of group accounts */ public List<GroupAccount> findRequests(Account account) { @SuppressWarnings("unchecked") List<GroupAccount> groupAccounts = jpaApi .em() .createQuery( "SELECT ga FROM GroupAccount ga WHERE ((ga.group.owner.id = ?1 OR ga.account.id = ?1) AND ga.linkType = ?2) OR (ga.account.id = ?1 AND ga.linkType = ?3) OR (ga.account.id = ?1 AND ga.linkType = ?4)") .setParameter(1, account.id).setParameter(2, LinkType.request) .setParameter(3, LinkType.reject).setParameter(4, LinkType.invite).getResultList(); return groupAccounts; } /** * Has account any link-types to given group? * * @param account Account instance * @param group Group instance * @return True, if an account has a link type for a group */ public boolean hasLinkTypes(Account account, Group group) { try { jpaApi.em().createQuery("SELECT ga FROM GroupAccount ga WHERE ga.account.id = ?1 AND ga.group.id = ?2") .setParameter(1, account.id).setParameter(2, group.id).getSingleResult(); } catch (NoResultException exp) { return false; } return true; } /** * Retrieve Accounts from Group with given LinkType. */ public List<Account> findAccountsByGroup(final Group group, final LinkType type) { @SuppressWarnings("unchecked") List<Account> accounts = (List<Account>) jpaApi .em() .createQuery( "SELECT ga.account FROM GroupAccount ga WHERE ga.group.id = ?1 AND ga.linkType = ?2") .setParameter(1, group.id).setParameter(2, type) .getResultList(); return accounts; } /** * Retrieve Accounts from Group with given LinkType. */ @SuppressWarnings("unchecked") public static List<Account> staticFindAccountsByGroup(final Group group, final LinkType type) { return JPA.createFor("defaultPersistenceUnit").withTransaction(() -> { return (List<Account>) JPA .em() .createQuery( "SELECT ga.account FROM GroupAccount ga WHERE ga.group.id = ?1 AND ga.linkType = ?2") .setParameter(1, group.id).setParameter(2, type) .getResultList(); }); } public List<Long> findAccountIdsByGroup(final Group group, final LinkType type) { @SuppressWarnings("unchecked") List<Long> accounts = (List<Long>) jpaApi .em() .createQuery( "SELECT ga.account.id FROM GroupAccount ga WHERE ga.group.id = ?1 AND ga.linkType = ?2") .setParameter(1, group.id).setParameter(2, type) .getResultList(); return accounts; } /** * Returns a groupAccount by account and group. * * @param account Account instance * @param group Group instance * @return Group account instance */ public GroupAccount find(Account account, Group group) { try { return (GroupAccount) jpaApi .em() .createQuery( "SELECT ga FROM GroupAccount ga WHERE ga.account.id = ?1 AND ga.group.id = ?2") .setParameter(1, account.id).setParameter(2, group.id) .getSingleResult(); } catch (NoResultException exp) { return null; } } /** * each group document contains information about their member * if a user gets access to this group -> (re)index group document * and (re)index all containing post documents * * @param group group which should be indexed */ private void reIndex(Group group) { new Thread(() -> { jpaApi.withTransaction(() -> { try { elasticsearchService.index(group); for (Post post : postManager.getPostsForGroup(group, 0, 0)) { elasticsearchService.index(post); } for (Media medium : mediaManager.findByFolder(group.rootFolder.id)) { elasticsearchService.index(medium); } } catch (IOException e) { e.printStackTrace(); } }); }).start(); } /** * filter GroupAccounts by LinkType * @param groupAccountList list of groupAccounts * @param linkType to filter * @return Accounts */ public static List<Account> filterGroupAccountsByLinkType(Set<GroupAccount> groupAccountList, LinkType linkType) { List<Account> accountList = new ArrayList<>(); for (GroupAccount groupAccount : groupAccountList) { if (groupAccount.linkType.equals(linkType)) { accountList.add(groupAccount.account); } } return accountList; } }