package com.ciandt.techgallery.service.impl; import com.google.api.server.spi.response.BadRequestException; import com.google.api.server.spi.response.InternalServerErrorException; import com.google.api.server.spi.response.NotFoundException; import com.google.appengine.api.users.User; import com.googlecode.objectify.Ref; import com.ciandt.techgallery.persistence.dao.TechnologyRecommendationDAO; import com.ciandt.techgallery.persistence.dao.impl.TechnologyRecommendationDAOImpl; import com.ciandt.techgallery.persistence.model.TechGalleryUser; import com.ciandt.techgallery.persistence.model.Technology; import com.ciandt.techgallery.persistence.model.TechnologyComment; import com.ciandt.techgallery.persistence.model.TechnologyRecommendation; import com.ciandt.techgallery.service.TechnologyRecommendationService; import com.ciandt.techgallery.service.TechnologyService; import com.ciandt.techgallery.service.UserServiceTG; import com.ciandt.techgallery.service.enums.ValidationMessageEnums; import com.ciandt.techgallery.service.impl.profile.UserProfileServiceImpl; import com.ciandt.techgallery.service.model.Response; import com.ciandt.techgallery.service.model.TechnologyRecommendationTO; import com.ciandt.techgallery.service.transformer.TechnologyRecommendationTransformer; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Logger; public class TechnologyRecommendationServiceImpl implements TechnologyRecommendationService { /* * Constants -------------------------------------------- */ private static final Logger log = Logger.getLogger(TechnologyRecommendationServiceImpl.class.getName()); /* * Attributes -------------------------------------------- */ private static TechnologyRecommendationServiceImpl instance; private final TechnologyRecommendationDAO technologyRecommendationDAO = TechnologyRecommendationDAOImpl.getInstance(); private final TechnologyService technologyService = TechnologyServiceImpl.getInstance(); private final TechnologyRecommendationTransformer techRecTransformer = new TechnologyRecommendationTransformer(); private final UserServiceTG userService = UserServiceTGImpl.getInstance(); /* * Constructors -------------------------------------------- */ private TechnologyRecommendationServiceImpl() {} /** * Singleton method for the service. * * @author <a href="mailto:joaom@ciandt.com"> João Felipe de Medeiros Moreira </a> * @since 07/10/2015 * * @return TechnologyRecommendationServiceImpl instance. */ public static TechnologyRecommendationServiceImpl getInstance() { if (instance == null) { instance = new TechnologyRecommendationServiceImpl(); } return instance; } /* * Methods -------------------------------------------- */ @Override public TechnologyRecommendation addRecommendation(TechnologyRecommendation recommendation, User user) throws BadRequestException { try { final TechGalleryUser tgUser = userService.getUserByEmail(user.getEmail()); recommendation.setRecommender(Ref.create(tgUser)); return addNewRecommendation(recommendation, tgUser); } catch (final NotFoundException e) { throw new BadRequestException(ValidationMessageEnums.USER_NOT_EXIST.message()); } } /** * Adds a new recommendation to the datastore, invalidates the previous one. * * @param recommendation the recommendation to be added * @param technology the technology for which the recommendation was made * @param tgUser the user who made the recommendation * @return the updated recommendation, with id */ private TechnologyRecommendation addNewRecommendation(TechnologyRecommendation recommendation, TechGalleryUser tgUser) { recommendation.setActive(true); recommendation.setRecommender(Ref.create(tgUser)); final TechnologyRecommendation previousRec = technologyRecommendationDAO .findActiveByRecommenderAndTechnology(tgUser, recommendation.getTechnology().get()); final Technology technology = recommendation.getTechnology().get(); // Inactivate previous recommendation if (previousRec != null) { previousRec.setActive(false); previousRec.setInactivatedDate(new Date()); technologyRecommendationDAO.update(previousRec); technologyService.removeRecomendationCounter(technology, previousRec.getScore()); } recommendation.setId(technologyRecommendationDAO.add(recommendation).getId()); technologyService.addRecomendationCounter(technology, recommendation.getScore()); UserProfileServiceImpl.getInstance().handleRecommendationChanges(recommendation); return recommendation; } @Override public List<Response> getRecommendations(String technologyId, User user) throws BadRequestException, InternalServerErrorException { Technology technology; try { technology = technologyService.getTechnologyById(technologyId, user); } catch (final NotFoundException e) { return null; } final List<TechnologyRecommendation> recommendations = technologyRecommendationDAO.findAllActivesByTechnology(technology); final List<Response> recommendationTOs = new ArrayList<Response>(); for (final TechnologyRecommendation recommendation : recommendations) { recommendationTOs.add(techRecTransformer.transformTo(recommendation)); } return recommendationTOs; } @Override public TechnologyRecommendation getRecommendationByComment(TechnologyComment comment) { return technologyRecommendationDAO.findByComment(comment); } @Override public List<Response> getRecommendationsUpByTechnologyAndUser(String technologyId, User user) throws BadRequestException, InternalServerErrorException { return getRecommendationsByTechnologyUserAndScore(technologyId, user, true); } @Override public List<Response> getRecommendationsDownByTechnologyAndUser(String technologyId, User user) throws BadRequestException, InternalServerErrorException { return getRecommendationsByTechnologyUserAndScore(technologyId, user, false); } /** * Method to search for recommendations that has the technology, user and score passed. * * @author <a href="mailto:joaom@ciandt.com"> João Felipe de Medeiros Moreira </a> * @since 25/09/2015 * * @param technologyId to find te recommendations * @param user to find the recommendations * @param score to filter the recommendations * * @return recommendationsUpTO * @throws InternalServerErrorException * @throws BadRequestException */ private List<Response> getRecommendationsByTechnologyUserAndScore(String technologyId, User user, Boolean score) throws BadRequestException, InternalServerErrorException { final List<Response> recommendationsUpTO = new ArrayList<Response>(); for (final Response recommendation : getRecommendations(technologyId, user)) { final TechnologyRecommendationTO recommendationTO = (TechnologyRecommendationTO) recommendation; if (recommendationTO.getScore().equals(score)) { recommendationsUpTO.add(recommendationTO); } } return recommendationsUpTO; } @Override public Response deleteRecommendById(Long recommendId, User user) throws BadRequestException, NotFoundException, InternalServerErrorException { final TechnologyRecommendation recommendation = technologyRecommendationDAO.findById(recommendId); final TechGalleryUser techUser = userService.getUserByEmail(user.getEmail()); validateDeletion(recommendId, recommendation, user, techUser); recommendation.setActive(false); technologyRecommendationDAO.update(recommendation); technologyService.removeRecomendationCounter(recommendation.getTechnology().get(), recommendation.getScore()); UserProfileServiceImpl.getInstance().handleRecommendationChanges(recommendation); return techRecTransformer.transformTo(recommendation); } /** * Responsable for validade the informations about the deletion. * * @author <a href="mailto:joaom@ciandt.com"> João Felipe de Medeiros Moreira </a> * @since 28/09/2015 * * @param recommendId to use by validation * @param recommendation to use by validation * @param user to use by validation * @param techUser to use by validation * * @throws BadRequestException in case the params are not correct * @throws InternalServerErrorException in case of internal error * @throws NotFoundException in case the information are not founded */ private void validateDeletion(Long recommendId, TechnologyRecommendation recommendation, User user, TechGalleryUser techUser) throws BadRequestException, NotFoundException, InternalServerErrorException { validateRecommend(recommendId, recommendation); validateUser(user, techUser); if (!recommendation.getRecommender().get().equals(techUser)) { throw new BadRequestException(ValidationMessageEnums.RECOMMEND_RECOMMENDER_ERROR.message()); } } /** * Validation for User. * * @author <a href="mailto:joaom@ciandt.com"> João Felipe de Medeiros Moreira </a> * @since 28/09/2015 * * @param user to be validated * @param techUser to be validated * * @throws BadRequestException in case the params are not correct * @throws InternalServerErrorException in case of internal error */ private void validateUser(User user, TechGalleryUser techUser) throws BadRequestException, InternalServerErrorException { log.info("Validating user to recommend"); if (user == null || user.getUserId() == null || user.getUserId().isEmpty()) { throw new BadRequestException(ValidationMessageEnums.USER_GOOGLE_ENDPOINT_NULL.message()); } if (techUser == null) { throw new BadRequestException(ValidationMessageEnums.USER_NOT_EXIST.message()); } } /** * Validation for Recommend. * * @author <a href="mailto:joaom@ciandt.com"> João Felipe de Medeiros Moreira </a> * @since 28/09/2015 * * @param recommendId to be validated * @param recommendation * * @throws BadRequestException in case the params are not correct */ private void validateRecommend(Long recommendId, TechnologyRecommendation recommendation) throws BadRequestException { log.info("Validating the recommend"); if (recommendId == null) { throw new BadRequestException(ValidationMessageEnums.RECOMMEND_ID_CANNOT_BLANK.message()); } if (recommendation == null) { throw new BadRequestException(ValidationMessageEnums.RECOMMEND_NOT_EXIST.message()); } } }