/** * */ package de.bstly.board.businesslogic; import java.time.Instant; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.stereotype.Component; import com.querydsl.jpa.impl.JPAQueryFactory; import de.bstly.board.model.Comment; import de.bstly.board.model.QComment; import de.bstly.board.model.QEntry; import de.bstly.board.model.QVote; import de.bstly.board.model.Types; import de.bstly.board.model.VoteType; import de.bstly.board.repository.CommentRepository; import de.bstly.board.repository.VoteRepository; /** * The Class CommentManager. */ @Component public class CommentManager { @Autowired private CommentRepository commentRepository; @Autowired private JPAQueryFactory jpaQueryFactory; @Autowired private VoteRepository voteRepository; @Autowired private VoteManager voteManager; private QComment qComment = QComment.comment; private QVote qVote = QVote.vote; private QEntry qEntry = QEntry.entry; /** * Fetch by ranking. * * @param target the target * @param parent the parent * @param date the date * @param gravity the gravity * @param page the page * @param size the size * @return the page */ public Page fetchByRanking(Long target, Long parent, Instant date, double gravity, int page, int size) { if (parent == null) { return commentRepository.findAllByRankingAndParent(target, date, gravity, PageRequest.of(page, size)); } return commentRepository.findAllByRankingAndParent(target, parent, date, gravity, PageRequest.of(page, size)); } /** * Fetch by date. * * @param target the target * @param parent the parent * @param date the date * @param page the page * @param size the size * @param desc the desc * @return the page */ public Page fetchByDate(Long target, Long parent, Instant date, int page, int size, boolean desc) { Sort sort = Sort.by(desc ? Order.desc("created") : Order.asc("created")); if (parent == null) { return commentRepository .findAll( qComment.target.eq(target).and(qComment.parent.isNull()) .and(qComment.created.before(date)), PageRequest.of(page, size, sort)); } return commentRepository.findAll(qComment.target.eq(target).and(qComment.parent.eq(parent)) .and(qComment.created.before(date)), PageRequest.of(page, size, sort)); } /** * Fetch by username. * * @param username the username * @param orElse the or else * @param date the date * @param page the page * @param size the size * @param asc the asc * @return the page */ public Page fetchByUsername(String username, Long orElse, Instant date, int page, int size, boolean asc) { Sort sort = Sort.by(asc ? Order.asc("created") : Order.desc("created")); return commentRepository.findAll(qComment.author.eq(username).and(qComment.parent.isNull()) .and(qComment.created.before(date)), PageRequest.of(page, size, sort)); } /** * Count. * * @param target the target * @param parent the parent * @return the long */ public Long count(Long target, Long parent) { if (parent == null) { return count(target); } return commentRepository.count(qComment.target.eq(target).and(qComment.parent.eq(parent))); } /** * Count. * * @param target the target * @return the long */ public Long count(Long target) { return commentRepository.count(qComment.target.eq(target)); } /** * Apply metadata. * * @param username the username * @param comment the comment */ public void applyMetadata(String username, Comment comment, List ignore) { ignore.addAll(comment.getMetadata().keySet()); if (!ignore.contains("comments")) { comment.getMetadata().put("comments", count(comment.getTarget(), comment.getId())); } if (!ignore.contains("points")) { comment.getMetadata().put("points", voteManager.getPoints(comment.getId(), Types.comment)); } if (!ignore.contains("upvoted")) { comment.getMetadata().put("upvoted", voteRepository.exists(qVote.target.eq(comment.getId()) .and(qVote.targetType.eq(Types.comment)).and(qVote.type.eq(VoteType.up)) .and(qVote.author.eq(username)))); } if (!ignore.contains("downvoted")) { comment.getMetadata().put("downvoted", voteRepository.exists(qVote.target.eq(comment.getId()) .and(qVote.targetType.eq(Types.comment)) .and(qVote.type.eq(VoteType.down)).and(qVote.author.eq(username)))); } if (!ignore.contains("unvote")) { comment.getMetadata().put("unvote", voteRepository.exists( qVote.target.eq(comment.getId()).and(qVote.targetType.eq(Types.comment)) .and(qVote.author.eq(username)))); } if (!ignore.contains("entry")) { comment.getMetadata().put("entry", jpaQueryFactory.selectFrom(qEntry) .where(qEntry.id.eq(comment.getTarget())).select(qEntry.title).fetchOne()); } } /** * Apply metadata. * * @param username the username * @param entries the entries */ public void applyMetadata(String username, List entries, List ignore) { for (Comment comment : entries) { applyMetadata(username, comment, ignore); } } /** * Exists. * * @param id the id * @return true, if successful */ public boolean exists(Long id) { return commentRepository.existsById(id); } /** * Gets the. * * @param id the id * @return the comment */ public Comment get(Long id) { return commentRepository.findById(id).orElse(null); } /** * Save. * * @param comment the comment * @return the comment */ public Comment save(Comment comment) { return commentRepository.save(comment); } /** * Gets the points. * * @param commentId the comment id * @return the points */ public long getPoints(Long commentId) { long upvotes = voteRepository.count(qVote.targetType.eq(Types.comment) .and(qVote.type.eq(VoteType.up)).and(qVote.target.eq(commentId))); long downvotes = voteRepository.count(qVote.targetType.eq(Types.comment) .and(qVote.type.eq(VoteType.down)).and(qVote.target.eq(commentId))); return upvotes - downvotes; } /** * Delete. * * @param comment the comment */ public void delete(Comment comment) { for (Comment subcomment : commentRepository.findAll(qComment.parent.eq(comment.getId()))) { delete(subcomment); } voteManager.deleteByTarget(comment.getId(), Types.comment); commentRepository.delete(comment); } /** * Delete by target. * * @param target the target */ public void deleteByTarget(Long target) { for (Comment comment : commentRepository.findAll(qComment.target.eq(target))) { delete(comment); } } }