bstlboard-back/src/main/java/de/bstly/board/businesslogic/CommentManager.java

291 lines
8.4 KiB
Java

/**
*
*/
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.PageImpl;
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.core.types.OrderSpecifier;
import com.querydsl.jpa.impl.JPAQuery;
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.QFlag;
import de.bstly.board.model.QVote;
import de.bstly.board.model.support.FlaggedStatus;
import de.bstly.board.model.support.Types;
import de.bstly.board.model.support.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;
@Autowired
private FlagManager flagManager;
private QComment qComment = QComment.comment;
private QVote qVote = QVote.vote;
private QFlag qFlag = QFlag.flag;
private QEntry qEntry = QEntry.entry;
/**
* Fetch by date.
*
* @param username the username
* @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<Comment> fetchByDate(String username, 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.flaggedStatus.eq(FlaggedStatus.NORMAL))
.and(qComment.created.before(date).or(qComment.author.eq(username))),
PageRequest.of(page, size, sort));
}
return commentRepository.findAll(
qComment.target.eq(target).and(qComment.parent.eq(parent))
.and(qComment.flaggedStatus.eq(FlaggedStatus.NORMAL)).and(qComment.created.before(date)),
PageRequest.of(page, size, sort));
}
/**
* Fetch flagged.
*
* @param page the page
* @param size the size
* @param asc the asc
* @return the page
*/
public Page<Comment> fetchFlagged(int page, int size, boolean asc) {
Sort sort = Sort.by(asc ? Order.asc("created") : Order.desc("created"));
JPAQuery<Comment> query = jpaQueryFactory.selectFrom(qComment).leftJoin(qFlag).on(qComment.id.eq(qFlag.target))
.where(qFlag.targetType.eq(Types.comment)).groupBy(qFlag.target);
JPAQuery<Long> countQuery = query.clone().select(qComment.id.countDistinct());
return new PageImpl<Comment>(query
.orderBy(new OrderSpecifier<>(
asc ? com.querydsl.core.types.Order.ASC : com.querydsl.core.types.Order.DESC, qComment.created))
.limit(size).offset(page * size).fetch(), PageRequest.of(page, size, sort), countQuery.fetchOne());
}
/**
* Fetch by username.
*
* @param username the username
* @param date the date
* @param page the page
* @param size the size
* @param asc the asc
* @return the page
*/
public Page<Comment> fetchByUsername(String username, Instant date, int page, int size, boolean asc) {
Sort sort = Sort.by(asc ? Order.asc("created") : Order.desc("created"));
return commentRepository.findAll(qComment.author.equalsIgnoreCase(username)
.and(qComment.flaggedStatus.eq(FlaggedStatus.NORMAL)).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))
.and(qComment.flaggedStatus.eq(FlaggedStatus.NORMAL)).and(qComment.created.before(Instant.now())));
}
/**
* Count.
*
* @param target the target
* @return the long
*/
public Long count(Long target) {
return commentRepository.count(qComment.target.eq(target).and(qComment.flaggedStatus.eq(FlaggedStatus.NORMAL))
.and(qComment.created.before(Instant.now())));
}
/**
* Apply metadata.
*
* @param username the username
* @param comment the comment
* @param ignore the ignore
*/
public void applyMetadata(String username, Comment comment, List<String> ignore) {
ignore.addAll(comment.getMetadata().keySet());
if (!ignore.contains("author")) {
comment.getMetadata().put("author", comment.getAuthor());
}
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.equalsIgnoreCase(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.equalsIgnoreCase(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.equalsIgnoreCase(username))));
}
if (!username.equals(comment.getAuthor()) && !ignore.contains("flag")) {
comment.getMetadata().put("flag", flagManager.get(username, comment.getId(), Types.comment) == null);
}
if (!username.equals(comment.getAuthor()) && !ignore.contains("unflag")) {
comment.getMetadata().put("unflag", flagManager.get(username, comment.getId(), Types.comment) != null);
}
if (!ignore.contains("flagged")) {
comment.getMetadata().put("flagged", flagManager.getFlags(comment.getId(), Types.comment) > 0);
}
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
* @param ignore the ignore
*/
public void applyMetadata(String username, List<Comment> entries, List<String> 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);
flagManager.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);
}
}
}