package hu.sch.ejb; import hu.sch.domain.user.User; import hu.sch.domain.*; import hu.sch.util.config.Configuration; import hu.sch.domain.user.ProfileImage; import hu.sch.ejb.image.ImageProcessor; import hu.sch.ejb.image.ImageRemoverService; import hu.sch.ejb.image.ImageSaver; import hu.sch.services.*; import hu.sch.services.exceptions.DuplicatedUserException; import hu.sch.services.exceptions.PekException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; import javax.ejb.Stateless; import javax.inject.Inject; 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 hege * @author messo * @author tomi * @author ksisu */ @Stateless public class UserManagerBean implements UserManagerLocal { private static Logger logger = LoggerFactory.getLogger(UserManagerBean.class); @PersistenceContext private EntityManager em; private SystemManagerLocal systemManager; private Configuration config; public UserManagerBean() { } public UserManagerBean(EntityManager em) { this.em = em; } @Inject public void setSystemManager(SystemManagerLocal systemManager) { this.systemManager = systemManager; } @Inject public void setConfig(Configuration config) { this.config = config; } @Override public User findUserById(Long userId) { if (userId == null || userId.equals(0L)) { // TODO: github/#41: introduce exception instead of silent null return null; } return em.find(User.class, userId); } @Override public User findUserByIdWithMemberships(Long userId) { if (userId == null || userId.equals(0L)) { // ha nincs használható userId, akkor ne menjünk el a DB-hez. return null; } TypedQuery<User> q = em.createNamedQuery(User.findWithMemberships, User.class); q.setParameter("id", userId); try { return q.getSingleResult(); } catch (Exception ex) { logger.warn("Can't find user with memberships for this id: " + userId); // TODO: github/#41: rethrow exception with wrapper return null; } } @Override public User findUserByIdWithIMAccounts(Long userId) { try { return em.createNamedQuery(User.findWithIMAccounts, User.class) .setParameter("id", userId) .getSingleResult(); } catch (NoResultException ex) { logger.warn("Could not find user with id {}", userId); } return null; } @Override public User findUserByScreenName(String screenName) { try { return em.createNamedQuery(User.findByScreenName, User.class) .setParameter("screenName", screenName) .getSingleResult(); } catch (NoResultException ex) { logger.info("User with {} screenname was not found.", screenName); } return null; } @Override public User findUserByNeptun(final String neptun) { return findUserByNeptun(neptun, false); } @Override public User findUserByNeptun(final String neptun, boolean includeMemberships) { try { final User user = em.createNamedQuery(User.findUserByNeptunCode, User.class) .setParameter("neptun", neptun) .getSingleResult(); if (includeMemberships) { Hibernate.initialize(user.getMemberships()); } return user; } catch (NoResultException ex) { logger.info("User not found with {} neptun.", neptun); } return null; } @Override public User findUserByEmail(final String email) throws DuplicatedUserException { try { return em.createQuery("SELECT u FROM User u WHERE u.emailAddress = :email", User.class) .setParameter("email", email) .getSingleResult(); } catch (NoResultException ex) { logger.info("Could not find user with email: {}", email); } catch (NonUniqueResultException ex) { throw new DuplicatedUserException(String.format("Duplicate user with %s email", email), ex); } return null; } @Override public User findUserByConfirmationCode(final String code) { TypedQuery<User> q = em.createQuery("SELECT u FROM User u WHERE u.confirmationCode = :code", User.class); q.setParameter("code", code); logger.debug("Find user with confirmation code=" + code); User result = null; try { result = q.getSingleResult(); } catch (NoResultException ex) { logger.info("No user was found with {} confirmation code.", code); } catch (NonUniqueResultException ex) { logger.error("Multiple users were found for the same {} confirmation code.", code); } return result; } @Override public List<EntrantRequest> getEntrantRequestsForUser(User felhasznalo) { Query q = em.createQuery("SELECT e FROM EntrantRequest e " + "WHERE e.user=:user " + "ORDER BY e.valuation.semester DESC, e.entrantType ASC"); q.setParameter("user", felhasznalo); return q.getResultList(); } @Override public void updateUser(User user) { updateUser(user, null); } @Override public User updateUser(User user, ProfileImage image) { // process image if (image != null) { ImageProcessor proc = new ImageProcessor(user, image, config.getImageUploadConfig()); String imagePath = proc.process(); user.setPhotoPath(imagePath); } // save user return em.merge(user); } @Override public List<User> findUsersByName(String name) { Query q = em.createQuery("SELECT u FROM User u WHERE UPPER(concat(concat(u.lastName, ' '), " + "u.firstName)) LIKE UPPER(:name) " + "ORDER BY u.lastName ASC, u.firstName ASC"); q.setParameter("name", "%" + name + "%"); return q.getResultList(); } /** * {@inheritDoc} */ @Override public List<PointHistory> getCommunityPointsForUser(User user) { TypedQuery<PointHistory> q = em.createNamedQuery(PointHistory.findByUser, PointHistory.class); q.setParameter("user", user); return q.getResultList(); } @Override public SpotImage getSpotImage(User user) { TypedQuery<SpotImage> q = em.createNamedQuery(SpotImage.findByNeptun, SpotImage.class); q.setParameter("neptunCode", user.getNeptunCode()); try { return q.getSingleResult(); } catch (NoResultException ex) { return null; } } @Override public boolean acceptRecommendedPhoto(String screenName) { User user = findUserByScreenName(screenName); TypedQuery<SpotImage> q = em.createNamedQuery(SpotImage.findByNeptun, SpotImage.class); q.setParameter("neptunCode", user.getNeptunCode()); try { SpotImage si = q.getSingleResult(); ImageSaver imageSaver = new ImageSaver(user, config.getImageUploadConfig()); String imgPath = imageSaver.copy(si.getImageFullPath(config.getImageUploadConfig().getBasePath())).getRelativePath(); user.setPhotoPath(imgPath); removeSpotImage(user, si); return true; } catch (NoResultException ex) { logger.error("No user with {} screen name.", screenName); } catch (PekException ex) { logger.error("Could not copy image. Error code: {}", ex.getErrorCode()); } return false; } @Override public void declineRecommendedPhoto(User user) { TypedQuery<SpotImage> q = em.createNamedQuery(SpotImage.findByNeptun, SpotImage.class); q.setParameter("neptunCode", user.getNeptunCode()); SpotImage img = q.getSingleResult(); removeSpotImage(user, img); } /** * Deletes the spot image from the file system and db. * * @param img the image to delete */ private void removeSpotImage(User user, SpotImage img) { try { Files.deleteIfExists(Paths.get(img.getImageFullPath(config.getImageUploadConfig().getBasePath()))); } catch (IOException ex) { logger.warn("IO Error while deleting file.", ex); // nothing to do. } em.remove(img); // update user to not show recommended photo user.setShowRecommendedPhoto(false); } @Override public void removeProfileImage(User user) { new ImageRemoverService(config).removeProfileImage(user); user.setPhotoPath(null); updateUser(user); } }