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

333 lines
9.1 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.google.common.collect.Lists;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import de.bstly.board.model.Bookmarks;
import de.bstly.board.model.Entry;
import de.bstly.board.model.EntryStatus;
import de.bstly.board.model.QEntry;
import de.bstly.board.model.QFlag;
import de.bstly.board.model.QVote;
import de.bstly.board.model.RankedEntry;
import de.bstly.board.model.Types;
import de.bstly.board.model.VoteType;
import de.bstly.board.repository.EntryRepository;
import de.bstly.board.repository.VoteRepository;
/**
* The Class EntryManager.
*/
@Component
public class EntryManager {
@Autowired
private EntryRepository entryRepository;
@Autowired
private CommentManager commentManager;
@Autowired
private VoteManager voteManager;
@Autowired
private VoteRepository voteRepository;
@Autowired
private BookmarksManager bookmarksManager;
@Autowired
private SettingsManager settingsManager;
@Autowired
private FlagManager flagManager;
@Autowired
private JPAQueryFactory jpaQueryFactory;
private QEntry qEntry = QEntry.entry;
private QVote qVote = QVote.vote;
private QFlag qFlag = QFlag.flag;
/**
* Fetch by ranking.
*
* @param date the date
* @param gravity the gravity
* @param page the page
* @param size the size
* @return the page
*/
public Page<RankedEntry> fetchByRanking(Instant date, double gravity, int page, int size) {
return entryRepository.findAllByRanking(date, gravity, PageRequest.of(page, size));
}
/**
* Fetch by comments.
*
* @param date the date
* @param gravity the gravity
* @param page the page
* @param size the size
* @return the page
*/
public Page<RankedEntry> fetchByComments(Instant date, double gravity, int page, int size) {
return entryRepository.findAllByComments(date, gravity, PageRequest.of(page, size));
}
/**
* Fetch by last comment.
*
* @param date the date
* @param page the page
* @param size the size
* @return the page
*/
public Page<Entry> fetchByLastComment(Instant date, int page, int size) {
return entryRepository.findAllByLastComment(date, PageRequest.of(page, size));
}
/**
* Fetch by date.
*
* @param date the date
* @param page the page
* @param size the size
* @return the page
*/
public Page<Entry> fetchByDate(Instant date, int page, int size) {
return entryRepository.findAll(
qEntry.created.before(date).and(qEntry.entryStatus.eq(EntryStatus.NORMAL)),
PageRequest.of(page, size, Sort.by(Order.desc("created"))));
}
/**
* Fetch flagged.
*
* @param page the page
* @param size the size
* @param asc the asc
* @return the page
*/
public Page<Entry> fetchFlagged(int page, int size, boolean asc) {
Sort sort = Sort.by(asc ? Order.asc("created") : Order.desc("created"));
JPAQuery<Entry> query = jpaQueryFactory.selectFrom(qEntry).leftJoin(qFlag)
.on(qEntry.id.eq(qFlag.target)).where(qFlag.targetType.eq(Types.entry))
.groupBy(qFlag.target);
return new PageImpl<Entry>(query
.orderBy(new OrderSpecifier<>(asc ? com.querydsl.core.types.Order.ASC
: com.querydsl.core.types.Order.DESC, qEntry.created))
.limit(size).offset(page * size).fetch(), PageRequest.of(page, size, sort),
query.fetchCount());
}
/**
* Fetch by user.
*
* @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<Entry> fetchByUser(String username, Instant date, int page, int size, boolean asc) {
Sort sort = Sort.by(asc ? Order.asc("created") : Order.desc("created"));
return entryRepository.findAll(
qEntry.author.equalsIgnoreCase(username).and(qEntry.created.before(date)),
PageRequest.of(page, size, sort));
}
/**
* Fetch by bookmarks.
*
* @param username the username
* @param page the page
* @param size the size
* @return the page
*/
public Page<Entry> fetchByBookmarks(String username, int page, int size) {
Bookmarks bookmarks = bookmarksManager.get(username);
if (bookmarks.getEntries() == null) {
bookmarks.setEntries(Lists.newArrayList());
}
return entryRepository.findAll(qEntry.id.in(bookmarks.getEntries()),
PageRequest.of(page, size, Sort.by(Order.desc("created"))));
}
/**
* Apply metadata.
*
* @param username the username
* @param karma the karma
* @param entry the entry
* @param ignore the ignore
*/
public void applyMetadata(String username, long karma, Entry entry, List<String> ignore) {
ignore.addAll(entry.getMetadata().keySet());
if (!ignore.contains("comments")) {
entry.getMetadata().put("comments", commentManager.count(entry.getId()));
}
if (!ignore.contains("points")) {
entry.getMetadata().put("points", voteManager.getPoints(entry.getId(), Types.entry));
}
if (!ignore.contains("bookmark")) {
entry.getMetadata().put("bookmark",
!bookmarksManager.hasEntry(username, entry.getId()));
}
if (!ignore.contains("removeBookmark")) {
entry.getMetadata().put("removeBookmark",
bookmarksManager.hasEntry(username, entry.getId()));
}
if (!ignore.contains("upvoted")) {
entry.getMetadata().put("upvoted",
voteRepository.exists(qVote.target.eq(entry.getId())
.and(qVote.targetType.eq(Types.entry)).and(qVote.type.eq(VoteType.up))
.and(qVote.author.equalsIgnoreCase(username))));
}
if (!ignore.contains("downvoted")) {
entry.getMetadata().put("downvoted",
voteRepository.exists(qVote.target.eq(entry.getId())
.and(qVote.targetType.eq(Types.entry)).and(qVote.type.eq(VoteType.down))
.and(qVote.author.equalsIgnoreCase(username))));
}
if (!username.equals(entry.getAuthor()) && !ignore.contains("flag")) {
entry.getMetadata().put("flag",
flagManager.get(username, entry.getId(), Types.entry) == null);
}
if (!username.equals(entry.getAuthor()) && !ignore.contains("unflag")) {
entry.getMetadata().put("unflag",
flagManager.get(username, entry.getId(), Types.entry) != null);
}
if (!ignore.contains("flagged")) {
entry.getMetadata().put("flagged",
flagManager.getFlags(entry.getId(), Types.entry) > 0);
}
if (voteRepository
.exists(qVote.target.eq(entry.getId()).and(qVote.targetType.eq(Types.entry))
.and(qVote.author.equalsIgnoreCase(username)))) {
if (!ignore.contains("unvote")) {
entry.getMetadata().put("unvote", true);
}
} else {
if (!ignore.contains("vote")) {
entry.getMetadata().put("vote", true);
}
if (!ignore.contains("downvote") && karma >= settingsManager.getUnvoteThresh()) {
entry.getMetadata().put("downvote", true);
}
}
}
/**
* Apply metadata.
*
* @param username the username
* @param karma the karma
* @param entries the entries
* @param ignore the ignore
*/
public void applyMetadata(String username, long karma, List<Entry> entries,
List<String> ignore) {
for (Entry entry : entries) {
applyMetadata(username, karma, entry, ignore);
}
}
/**
* Exists.
*
* @param id the id
* @return true, if successful
*/
public boolean exists(Long id) {
return entryRepository.existsById(id);
}
/**
* Gets the.
*
* @param id the id
* @return the entry
*/
public Entry get(Long id) {
return entryRepository.findById(id).orElse(null);
}
/**
* Save.
*
* @param entry the entry
* @return the entry
*/
public Entry save(Entry entry) {
return entryRepository.save(entry);
}
/**
* Delete.
*
* @param entry the entry
*/
public void delete(Entry entry) {
commentManager.deleteByTarget(entry.getId());
voteManager.deleteByTarget(entry.getId(), Types.entry);
entryRepository.delete(entry);
}
/**
* Gets the points.
*
* @param entryId the entry id
* @return the points
*/
public long getPoints(Long entryId) {
long upvotes = voteRepository.count(qVote.targetType.eq(Types.entry)
.and(qVote.type.eq(VoteType.up)).and(qVote.target.eq(entryId)));
long downvotes = voteRepository.count(qVote.targetType.eq(Types.entry)
.and(qVote.type.eq(VoteType.down)).and(qVote.target.eq(entryId)));
return upvotes - downvotes;
}
/**
* Gets the user points.
*
* @param entryId the entry id
* @param username the username
* @return the user points
*/
public long getUserPoints(Long entryId, String username) {
long upvotes = voteRepository.count(qVote.targetType.eq(Types.entry)
.and(qVote.type.eq(VoteType.up).and(qVote.author.notEqualsIgnoreCase(username)))
.and(qVote.target.eq(entryId)));
long downvotes = voteRepository.count(qVote.targetType.eq(Types.entry)
.and(qVote.type.eq(VoteType.down).and(qVote.author.notEqualsIgnoreCase(username)))
.and(qVote.target.eq(entryId)));
return upvotes - downvotes;
}
}