package org.codiki.posts; import java.io.IOException; import java.security.Principal; import java.util.Collections; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.codiki.core.entities.business.SearchEntity; import org.codiki.core.entities.dto.PostDTO; import org.codiki.core.entities.persistence.Category; import org.codiki.core.entities.persistence.Post; import org.codiki.core.entities.persistence.User; import org.codiki.core.repositories.CategoryRepository; import org.codiki.core.repositories.PostRepository; import org.codiki.core.services.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PostService { static final int SCORE_TITLE = 50; static final int SCORE_DESCRIPTION = 5; static final int SCORE_TEXT = 1; static final int SCORE_CATEGORY = 30; static final int SCORE_AUTHOR_NAME = 40; static final int SCORE_AUTHOR_EMAIL = 40; @Autowired private PostRepository postRepository; @Autowired private CategoryRepository categoryRepository; @Autowired private UserService userService; public Optional insert(final PostDTO pPost, final HttpServletRequest pRequest, final HttpServletResponse pResponse, final Principal pPrincipal) { Optional result = Optional.empty(); final Optional user = userService.getUserByPrincipal(pPrincipal); if(user.isPresent()) { final Post postToSave = new Post(pPost); postToSave.setAuthor(user.get()); postRepository.save(postToSave); result = Optional.of(postToSave); } else { pResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } return result; } public void update(final Post pPost, final HttpServletRequest pRequest, final HttpServletResponse pResponse, final Principal pPrincipal) throws IOException { final Optional connectedUser = userService.getUserByPrincipal(pPrincipal); if(connectedUser.isPresent() && connectedUser.get().getKey().equals(pPost.getAuthor().getKey())) { final Optional postOpt = postRepository.getByKey(pPost.getKey()); if(postOpt.isPresent()) { final Optional category = categoryRepository.findById(pPost.getCategory().getId()); if(category.isPresent()) { final Post post = postOpt.get(); post.setTitle(pPost.getTitle()); post.setImage(pPost.getImage()); post.setDescription(pPost.getDescription()); post.setCreationDate(new Date()); post.setText(pPost.getText()); post.setCategory(category.get()); postRepository.save(post); } else { pResponse.sendError(HttpServletResponse.SC_BAD_REQUEST); } } else { pResponse.sendError(HttpServletResponse.SC_NOT_FOUND); } } else { pResponse.sendError(HttpServletResponse.SC_FORBIDDEN); } } public void delete(final String pPostKey, final HttpServletRequest pRequest, final HttpServletResponse pResponse, final Principal pPrincipal) throws IOException { final Optional postToDelete = postRepository.getByKey(pPostKey); if(postToDelete.isPresent()) { final Optional connectedUser = userService.getUserByPrincipal(pPrincipal); if(connectedUser.isPresent()) { if(connectedUser.get().getKey().equals(postToDelete.get().getAuthor().getKey())) { postRepository.delete(postToDelete.get()); } else { pResponse.sendError(HttpServletResponse.SC_FORBIDDEN); } } else { pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } else { pResponse.sendError(HttpServletResponse.SC_NOT_FOUND); } } public List search(String pSearchCriteria) { final String[] criteriasArray = pSearchCriteria.split(" "); final List listSearchEntities = new LinkedList<>(); postRepository.search(criteriasArray).stream().map(SearchEntity::new).forEach(e -> { calculateScore(e, criteriasArray); listSearchEntities.add(e); }); Collections.sort(listSearchEntities, (e1, e2) -> e2.getScore() - e1.getScore()); return listSearchEntities.stream().map(SearchEntity::getPost).collect(Collectors.toList()); } void calculateScore(final SearchEntity searchPost, final String[] pCriteriasArray) { for(final String criteria : pCriteriasArray) { String formattedCriteria = formatForComp(criteria); calculateScoreForTitle(searchPost, formattedCriteria); calculateScoreForDescription(searchPost, formattedCriteria); calculateScoreForText(searchPost, formattedCriteria); calculateScoreForCategory(searchPost, formattedCriteria); calculateScoreForAuthorName(searchPost, formattedCriteria); calculateScoreForAuthorEmail(searchPost, formattedCriteria); } } String formatForComp(final String pElem) { return StringUtils.stripAccents(pElem.toLowerCase()); } void calculateScoreForTitle(final SearchEntity pSearchPost, final String pCriteria) { if(formatForComp(pSearchPost.getPost().getTitle()).contains(pCriteria)) { pSearchPost.increaseScore(SCORE_TITLE); } } void calculateScoreForDescription(final SearchEntity pSearchPost, final String pCriteria) { final int criteriaOccurence = StringUtils.countMatches(formatForComp(pSearchPost.getPost().getDescription()), pCriteria); pSearchPost.increaseScore(criteriaOccurence * SCORE_DESCRIPTION); } void calculateScoreForText(final SearchEntity pSearchPost, final String pCriteria) { final int criteriaOccurence = StringUtils.countMatches(formatForComp(pSearchPost.getPost().getText()), pCriteria); pSearchPost.increaseScore(criteriaOccurence * SCORE_TEXT); } void calculateScoreForCategory(final SearchEntity pSearchPost, final String pCriteria) { if(formatForComp(pSearchPost.getPost().getCategory().getName()).contains(pCriteria)) { pSearchPost.increaseScore(SCORE_CATEGORY); } } void calculateScoreForAuthorName(final SearchEntity pSearchPost, final String pCriteria) { if(formatForComp(pSearchPost.getPost().getAuthor().getName()).contains(pCriteria)) { pSearchPost.increaseScore(SCORE_AUTHOR_NAME); } } void calculateScoreForAuthorEmail(final SearchEntity pSearchPost, final String pCriteria) { if(formatForComp(pSearchPost.getPost().getAuthor().getEmail()).contains(pCriteria)) { pSearchPost.increaseScore(SCORE_AUTHOR_EMAIL); } } }