package hu.sch.ejb; import hu.sch.domain.Group; import hu.sch.domain.Membership; import hu.sch.domain.Post; import hu.sch.domain.PostType; import hu.sch.domain.enums.SvieStatus; import hu.sch.domain.user.User; import hu.sch.services.GroupManagerLocal; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.NonUniqueResultException; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TypedQuery; import org.hibernate.Hibernate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author tomi */ @Stateless public class GroupManagerBean implements GroupManagerLocal { private static final Logger logger = LoggerFactory.getLogger(GroupManagerBean.class); @PersistenceContext private EntityManager em; public GroupManagerBean() { } /** * For testing purposes. */ public GroupManagerBean(EntityManager em) { this.em = em; } @Override public List<Group> getAllGroups() { return getAllGroups(false); } @Override public List<Group> getAllGroups(boolean includeMemberCount) { if (!includeMemberCount) { return em.createNamedQuery(Group.findAll).getResultList(); } // TODO: make constant values constant and/or enums Query q = em.createQuery("SELECT g, " + "(SELECT COUNT(*) FROM Membership ms WHERE ms.user.sviePrimaryMembership = ms " + "AND ms.group.id = g.id AND ms.user.svieStatus = 'ELFOGADVA' " + "AND ms.user.svieMembershipType = 'RENDESTAG') " + "FROM Group g WHERE g.status='akt'"); List<Object[]> groupsAndCount = q.getResultList(); List<Group> groups = new ArrayList<>(groupsAndCount.size()); for (Object[] results : groupsAndCount) { Group g = (Group) results[0]; g.setNumberOfPrimaryMembers((Long) results[1]); groups.add(g); } return groups; } @Override public List<Group> getGroupTree() { Query q = em.createNamedQuery(Group.groupHierarchy); List<Group> groups = q.getResultList(); List<Group> rootGroups = new ArrayList<>(); for (Group cs : groups) { if (cs.getParent() != null) { if (cs.getParent().getSubGroups() == null) { cs.getParent().setSubGroups(new ArrayList<Group>()); } cs.getParent().getSubGroups().add(cs); } else { rootGroups.add(cs); } } return rootGroups; } @Override public Group findGroupById(Long id) { return findGroupById(id, false); } @Override public Group findGroupById(Long id, boolean fetchMemberships) { final Group group = em.find(Group.class, id); if (fetchMemberships && group != null) { Hibernate.initialize(group.getMemberships()); } return group; } @Override public Group findGroupByName(String name) { try { return em.createNamedQuery(Group.findByName, Group.class) .setParameter("name", name) .getSingleResult(); } catch (NonUniqueResultException ex) { logger.warn("Group name is not unique: " + name, ex); } catch (Exception ex) { logger.warn("Could not retrieve group with name: " + name, ex); } return null; } @Override public List<User> findMembersByGroupAndPost(Long groupId, String post) { Query q = em.createNamedQuery(Group.findMembersByGroupAndPost); q.setParameter("groupId", groupId); q.setParameter("post", post); return q.getResultList(); } @Override public List<User> findMembersWithPrimaryMembership(Long groupId) { Query q = em.createQuery("SELECT ms.user FROM Membership ms " + "WHERE ms.group.id=:groupId AND ms.user.sviePrimaryMembership = ms " + "AND ms.user.svieStatus = :svieStatus " + "ORDER BY ms.user.lastName, ms.user.firstName"); q.setParameter("groupId", groupId); q.setParameter("svieStatus", SvieStatus.ELFOGADVA); return q.getResultList(); } @Override public List<User> findActiveMembers(long groupId) { Query q = em.createQuery("SELECT ms.user FROM Membership ms JOIN " + "ms.user WHERE ms.group.id = :groupId AND ms.end = NULL " + "ORDER BY ms.user.lastName ASC, ms.user.firstName ASC"); q.setParameter("groupId", groupId); return q.getResultList(); } @Override public Group updateGroupInfo(Long id, Group group) { Group groupToUpdate = findGroupById(id); groupToUpdate.setName(group.getName()); groupToUpdate.setFounded(group.getFounded()); groupToUpdate.setIntroduction(group.getIntroduction()); groupToUpdate.setMailingList(group.getMailingList()); groupToUpdate.setUsersCanApply(group.getUsersCanApply()); groupToUpdate.setWebPage(group.getWebPage()); return groupToUpdate; } @Override public User findLeaderForGroup(Long groupId) { final String queryString = "SELECT p.membership.user FROM Post p " + "WHERE p.postType.postName = :postname AND p.membership.group.id = :id"; TypedQuery<User> q = em.createQuery(queryString, User.class) .setParameter("id", groupId) .setParameter("postname", PostType.KORVEZETO); try { User ret = q.getSingleResult(); return ret; } catch (NoResultException nre) { logger.error(String.format("No group was found with id: %d", groupId), nre); } return null; } @Override public void createGroup(Group group, User leader) { Membership ms = new Membership(); ms.setGroup(group); ms.setStart(new Date()); ms.setUser(leader); Post post = new Post(); post.setMembership(ms); PostType leaderPost = em.createNamedQuery(PostType.searchForPostType, PostType.class) .setParameter("pn", PostType.KORVEZETO) .getSingleResult(); post.setPostType(leaderPost); em.persist(group); em.persist(ms); em.persist(post); } @Override public List<Group> getSubGroups(Long groupId) { return em.createQuery("SELECT g FROM Group g WHERE g.parent.id =:id") .setParameter("id", groupId) .getResultList(); } }