package managers; import models.*; import models.enums.LinkType; import models.services.ElasticsearchService; import play.db.jpa.JPA; import play.db.jpa.JPAApi; import javax.inject.Inject; import javax.persistence.NoResultException; import java.io.IOException; import java.util.Iterator; import java.util.List; /** * Created by Iven on 17.12.2015. */ public class FriendshipManager implements BaseManager { @Inject ElasticsearchService elasticsearchService; @Inject NotificationManager notificationManager; @Inject GroupAccountManager groupAccountManager; @Inject JPAApi jpaApi; @Override public void create(Object model) { Friendship friendship = ((Friendship) model); jpaApi.em().persist(model); reIndex(friendship); } @Override public void update(Object model) { Friendship friendship = ((Friendship) model); jpaApi.em().merge(model); reIndex(friendship); } @Override public void delete(Object model) { Friendship friendship = ((Friendship) model); jpaApi.em().remove(friendship); notificationManager.deleteReferences(friendship); reIndex(friendship); } public Friendship findById(Long id) { return jpaApi.em().find(Friendship.class, id); } public Friendship findRequest(Account me, Account potentialFriend) { try{ return (Friendship) jpaApi.em().createQuery("SELECT fs FROM Friendship fs WHERE fs.account.id = ?1 AND fs.friend.id = ?2 AND fs.linkType = ?3") .setParameter(1, me.id).setParameter(2, potentialFriend.id).setParameter(3, LinkType.request).getSingleResult(); } catch (NoResultException exp) { return null; } } public Friendship findReverseRequest(Account me, Account potentialFriend) { try{ return (Friendship) jpaApi.em().createQuery("SELECT fs FROM Friendship fs WHERE fs.friend.id = ?1 AND fs.account.id = ?2 AND fs.linkType = ?3") .setParameter(1, me.id).setParameter(2, potentialFriend.id).setParameter(3, LinkType.request).getSingleResult(); } catch (NoResultException exp) { return null; } } public Friendship findFriendLink(Account account, Account target) { try{ return (Friendship) jpaApi.em().createQuery("SELECT fs FROM Friendship fs WHERE fs.account.id = ?1 and fs.friend.id = ?2 AND fs.linkType = ?3") .setParameter(1, account.id).setParameter(2, target.id).setParameter(3, LinkType.establish).getSingleResult(); } catch (NoResultException exp) { return null; } } /** * Returns true, if two accounts have a friendly relationship. * * @param me Account instance * @param potentialFriend Account instance * @return True, if both accounts are friends */ public boolean alreadyFriendly(Account me, Account potentialFriend) { try { jpaApi.em().createQuery("SELECT fs FROM Friendship fs WHERE fs.account.id = ?1 and fs.friend.id = ?2 AND fs.linkType = ?3") .setParameter(1, me.id).setParameter(2, potentialFriend.id).setParameter(3, LinkType.establish).getSingleResult(); } catch (NoResultException exp) { return false; } return true; } public static boolean alreadyFriendly2(Account me, Account potentialFriend) { try { JPA.em().createQuery("SELECT fs FROM Friendship fs WHERE fs.account.id = ?1 and fs.friend.id = ?2 AND fs.linkType = ?3") .setParameter(1, me.id).setParameter(2, potentialFriend.id).setParameter(3, LinkType.establish).getSingleResult(); } catch (NoResultException exp) { return false; } return true; } public boolean alreadyRejected(Account me, Account potentialFriend) { try { jpaApi.em().createQuery("SELECT fs FROM Friendship fs WHERE fs.account.id = ?1 and fs.friend.id = ?2 AND fs.linkType = ?3") .setParameter(1, me.id).setParameter(2, potentialFriend.id).setParameter(3, LinkType.reject).getSingleResult(); } catch (NoResultException exp) { return false; } return true; } @SuppressWarnings("unchecked") public List<Account> findFriends(final Account account){ return (List<Account>) jpaApi.em().createQuery("SELECT fs.friend FROM Friendship fs WHERE fs.account.id = ?1 AND fs.linkType = ?2 ORDER BY fs.friend.firstname ASC") .setParameter(1, account.id).setParameter(2, LinkType.establish).getResultList(); } /** * Lists all friendships of the specified account (in both directions and of all LinkTypes) * @param accountId the account id * @return the list of Friendships */ @SuppressWarnings("unchecked") public List<Friendship> listAllFriendships(Long accountId){ return jpaApi.em().createQuery("SELECT fs FROM Friendship fs WHERE fs.account.id = ?1 OR fs.friend.id = ?1") .setParameter(1, accountId).getResultList(); } @SuppressWarnings("unchecked") public List<Long> findFriendsId(final Account account){ return (List<Long>) jpaApi.em().createQuery("SELECT fs.friend.id FROM Friendship fs WHERE fs.account.id = ?1 AND fs.linkType = ?2") .setParameter(1, account.id).setParameter(2, LinkType.establish).getResultList(); } @SuppressWarnings("unchecked") public List<Friendship> findRequests(final Account account) { return (List<Friendship>) jpaApi.em().createQuery("SELECT fs FROM Friendship fs WHERE (fs.friend.id = ?1 OR fs.account.id = ?1) AND fs.linkType = ?2") .setParameter(1, account.id).setParameter(2, LinkType.request).getResultList(); } @SuppressWarnings("unchecked") public List<Friendship> findRejects(final Account account) { return (List<Friendship>) jpaApi.em().createQuery("SELECT fs FROM Friendship fs WHERE fs.account.id = ?1 AND fs.linkType = ?2") .setParameter(1, account.id).setParameter(2, LinkType.reject).getResultList(); } public List<Account> friendsToInvite(Account account, Group group) { List<Account> inevitableFriends = findFriends(account); if (inevitableFriends != null) { Iterator<Account> it = inevitableFriends.iterator(); Account friend; while(it.hasNext()) { friend = it.next(); //remove account from list if there is any type of link (requests, invite, already member) if (groupAccountManager.hasLinkTypes(friend, group)) { it.remove(); } } } return inevitableFriends; } private void reIndex(Friendship friendship) { // each account document contains information about their friends // if a user accepts or deletes a friendship -> (re)index both user documents try { elasticsearchService.index(friendship.account); elasticsearchService.index(friendship.friend); } catch (IOException e) { e.printStackTrace(); } } }