userpages, filter improvments

This commit is contained in:
2021-12-02 19:30:54 +01:00
parent 922cf5597e
commit 428f13afbb
14 changed files with 1097 additions and 172 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version> <java.version>11</java.version>
<revision>1.1.0</revision> <revision>1.2.0</revision>
</properties> </properties>
<parent> <parent>
@@ -24,6 +24,7 @@ import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import de.bstly.board.controller.model.EntryFilter;
import de.bstly.board.model.Bookmarks; import de.bstly.board.model.Bookmarks;
import de.bstly.board.model.Entry; import de.bstly.board.model.Entry;
import de.bstly.board.model.FlaggedStatus; import de.bstly.board.model.FlaggedStatus;
@@ -66,27 +67,27 @@ public class EntryManager {
private QVote qVote = QVote.vote; private QVote qVote = QVote.vote;
private QFlag qFlag = QFlag.flag; private QFlag qFlag = QFlag.flag;
static final String UPVOTES_QUERY = "SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 1 GROUP BY upvote.target"; static final String UPVOTES_QUERY = "SELECT DISTINCT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 1 GROUP BY upvote.target";
static final String DOWNVOTES_QUERY = "SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 AND downvote.target_type = 1 GROUP BY downvote.target"; static final String DOWNVOTES_QUERY = "SELECT DISTINCT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 AND downvote.target_type = 1 GROUP BY downvote.target";
static final String COMMENTS_QUERY = "SELECT comment.target,MAX(comment.created) as last,COUNT(comment.id) AS count FROM comments as comment WHERE comment.flagged_status = :flag GROUP BY comment.target"; static final String COMMENTS_QUERY = "SELECT DISTINCT comment.target,MAX(comment.created) as last,COUNT(comment.id) AS count FROM comments as comment WHERE comment.flagged_status = :flag GROUP BY comment.target";
static final String RANK_CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / IF(:gravity > 0, POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity), 1) AS ranking FROM entries AS entry LEFT JOIN (" static final String RANK_CALCULATION_QUERY = "SELECT DISTINCT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / IF(:gravity > 0, POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity), 1) AS ranking FROM entries AS entry LEFT JOIN ("
+ UPVOTES_QUERY + UPVOTES_QUERY
+ ") AS upvote ON upvote.target = entry.id LEFT JOIN (" + ") AS upvote ON upvote.target = entry.id LEFT JOIN ("
+ DOWNVOTES_QUERY + DOWNVOTES_QUERY
+ ") AS downvote ON downvote.target = entry.id %s"; + ") AS downvote ON downvote.target = entry.id %s";
static final String DATE_QUERY = "SELECT entry.* FROM entries AS entry %s"; static final String DATE_QUERY = "SELECT DISTINCT entry.* FROM entries AS entry %s";
static final String USER_QUERY = "SELECT entry.* FROM entries AS entry %s ORDER BY entry.created :order"; static final String USER_QUERY = "SELECT DISTINCT entry.* FROM entries AS entry %s ORDER BY entry.created :order";
static final String COMMENT_CALCULATION_QUERY = "SELECT entry.*, IFNULL(comment.count,0) as comments, IFNULL(comment.count,0) / IF(:gravity > 0, POW(TIMESTAMPDIFF(HOUR, comment.last, :before)+2,:gravity), 1) AS ranking FROM entries AS entry LEFT JOIN (" static final String COMMENT_CALCULATION_QUERY = "SELECT DISTINCT entry.*, IFNULL(comment.count,0) as comments, IFNULL(comment.count,0) / IF(:gravity > 0, POW(TIMESTAMPDIFF(HOUR, comment.last, :before)+2,:gravity), 1) AS ranking FROM entries AS entry LEFT JOIN ("
+ COMMENTS_QUERY + COMMENTS_QUERY
+ ") AS comment ON comment.target = entry.id %s"; + ") AS comment ON comment.target = entry.id %s";
static final String LAST_COMMENT_QUERY = "SELECT entry.* FROM entries AS entry LEFT JOIN (" static final String LAST_COMMENT_QUERY = "SELECT DISTINCT entry.* FROM entries AS entry LEFT JOIN ("
+ COMMENTS_QUERY + COMMENTS_QUERY
+ ") AS comment ON comment.target = entry.id %s "; + ") AS comment ON comment.target = entry.id %s ";
@@ -96,25 +97,23 @@ public class EntryManager {
* Fetch by ranking. * Fetch by ranking.
* *
* @param username the username * @param username the username
* @param date the date * @param filter the filter
* @param flaggedStatus the flagged status
* @param tag the tag
* @param gravity the gravity * @param gravity the gravity
* @param page the page * @param page the page
* @param size the size * @param size the size
* @param asc the asc * @param asc the asc
* @return the page * @return the page
*/ */
public Page<Entry> fetchByRanking(String username, Instant date, FlaggedStatus flaggedStatus, public Page<Entry> fetchByRanking(String username, EntryFilter filter, double gravity, int page,
String tag, double gravity, int page, int size, boolean asc) { int size, boolean asc) {
Query query = createEntryQuery(RANK_CALCULATION_QUERY, username, date, flaggedStatus, tag, Query query = createEntryQuery(RANK_CALCULATION_QUERY, username, filter,
null, asc ? "ranking ASC, entry.created ASC" : "ranking DESC, entry.created DESC"); asc ? "ranking ASC, entry.created ASC" : "ranking DESC, entry.created DESC");
query.setParameter("gravity", gravity); query.setParameter("gravity", gravity);
query.setFirstResult((page) * size); query.setFirstResult((page) * size);
query.setMaxResults(size); query.setMaxResults(size);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, null); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }
@@ -123,23 +122,21 @@ public class EntryManager {
* Fetch by date. * Fetch by date.
* *
* @param username the username * @param username the username
* @param date the date * @param filter the filter
* @param flaggedStatus the flagged status
* @param tag the tag
* @param page the page * @param page the page
* @param size the size * @param size the size
* @param asc the asc * @param asc the asc
* @return the page * @return the page
*/ */
public Page<Entry> fetchByDate(String username, Instant date, FlaggedStatus flaggedStatus, public Page<Entry> fetchByDate(String username, EntryFilter filter, int page, int size,
String tag, int page, int size, boolean asc) { boolean asc) {
Query query = createEntryQuery(DATE_QUERY, username, date, flaggedStatus, tag, null, Query query = createEntryQuery(DATE_QUERY, username, filter,
asc ? "entry.created ASC" : "entry.created DESC"); asc ? "entry.created ASC" : "entry.created DESC");
query.setFirstResult((page) * size); query.setFirstResult((page) * size);
query.setMaxResults(size); query.setMaxResults(size);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, null); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }
@@ -148,26 +145,23 @@ public class EntryManager {
* Fetch by comments. * Fetch by comments.
* *
* @param username the username * @param username the username
* @param date the date * @param filter the filter
* @param flaggedStatus the flagged status
* @param tag the tag
* @param gravity the gravity * @param gravity the gravity
* @param page the page * @param page the page
* @param size the size * @param size the size
* @param asc the asc * @param asc the asc
* @return the page * @return the page
*/ */
public Page<Entry> fetchByComments(String username, Instant date, FlaggedStatus flaggedStatus, public Page<Entry> fetchByComments(String username, EntryFilter filter, double gravity,
String tag, double gravity, int page, int size, boolean asc) { int page, int size, boolean asc) {
Query query = createEntryQuery(COMMENT_CALCULATION_QUERY, username, date, flaggedStatus, Query query = createEntryQuery(COMMENT_CALCULATION_QUERY, username, filter,
tag, null,
asc ? "ranking ASC, entry.created ASC" : "ranking DESC, entry.created DESC"); asc ? "ranking ASC, entry.created ASC" : "ranking DESC, entry.created DESC");
query.setParameter("gravity", gravity); query.setParameter("gravity", gravity);
query.setFirstResult((page) * size); query.setFirstResult((page) * size);
query.setMaxResults(size); query.setMaxResults(size);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, null); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }
@@ -176,24 +170,22 @@ public class EntryManager {
* Fetch by last comment. * Fetch by last comment.
* *
* @param username the username * @param username the username
* @param date the date * @param filter the filter
* @param flaggedStatus the flagged status
* @param tag the tag
* @param page the page * @param page the page
* @param size the size * @param size the size
* @param asc the asc * @param asc the asc
* @return the page * @return the page
*/ */
public Page<Entry> fetchByLastComment(String username, Instant date, public Page<Entry> fetchByLastComment(String username, EntryFilter filter, int page, int size,
FlaggedStatus flaggedStatus, String tag, int page, int size, boolean asc) { boolean asc) {
Query query = createEntryQuery(LAST_COMMENT_QUERY, username, date, flaggedStatus, tag, null, Query query = createEntryQuery(LAST_COMMENT_QUERY, username, filter,
asc ? "comment.last ASC, entry.created ASC" asc ? "comment.last ASC, entry.created ASC"
: "comment.last DESC, entry.created DESC"); : "comment.last DESC, entry.created DESC");
query.setFirstResult((page) * size); query.setFirstResult((page) * size);
query.setMaxResults(size); query.setMaxResults(size);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, null); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }
@@ -203,25 +195,23 @@ public class EntryManager {
* *
* @param fromUser the from user * @param fromUser the from user
* @param username the username * @param username the username
* @param date the date * @param filter the filter
* @param flaggedStatus the flagged status
* @param tag the tag
* @param page the page * @param page the page
* @param size the size * @param size the size
* @param asc the asc * @param asc the asc
* @return the page * @return the page
*/ */
public Page<Entry> fetchByUser(String fromUser, String username, Instant date, public Page<Entry> fetchByUser(String fromUser, String username, EntryFilter filter, int page,
FlaggedStatus flaggedStatus, String tag, int page, int size, boolean asc) { int size, boolean asc) {
Query query = createEntryQuery(DATE_QUERY, username, date, flaggedStatus, tag, filter.setAdditional("AND entry.author = :username");
"AND entry.author = :username", asc ? "entry.created ASC" : "entry.created DESC"); Query query = createEntryQuery(DATE_QUERY, username, filter,
asc ? "entry.created ASC" : "entry.created DESC");
query.setParameter("username", username); query.setParameter("username", username);
query.setFirstResult((page) * size); query.setFirstResult((page) * size);
query.setMaxResults(size); query.setMaxResults(size);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
"AND entry.author = :username");
queryTotal.setParameter("username", username); queryTotal.setParameter("username", username);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
@@ -232,37 +222,72 @@ public class EntryManager {
* *
* @param rawQuery the raw query * @param rawQuery the raw query
* @param username the username * @param username the username
* @param date the date * @param filter the filter
* @param flaggedStatus the flagged status
* @param tag the tag
* @param additional the additional
* @param orderBy the order by * @param orderBy the order by
* @return the query * @return the query
*/ */
protected Query createEntryQuery(String rawQuery, String username, Instant date, protected Query createEntryQuery(String rawQuery, String username, EntryFilter filter,
FlaggedStatus flaggedStatus, String tag, String additional, String orderBy) { String orderBy) {
String filterString = ""; String filterString = "";
if (StringUtils.hasText(tag)) { String tagsString = "";
filterString += " INNER JOIN tags as tag ON entry.id = tag.target AND tag.tag = '" if (filter.getTags() != null && !filter.getTags().isEmpty()) {
+ tag for (int index = 0; index < filter.getTags().size(); index++) {
tagsString += "'"
+ filter.getTags().get(index)
+ "'"; + "'";
if (index < filter.getTags().size() - 1) {
tagsString += ",";
}
}
}
if (StringUtils.hasText(tagsString)) {
filterString += " INNER JOIN tags as tag ON entry.id = tag.target AND tag.tag IN ("
+ tagsString
+ ")";
} }
boolean author = false; boolean author = false;
if (date != null) { if (filter.getDate() != null) {
filterString += " WHERE entry.created < :before"; filterString += " WHERE entry.created < :before";
} else { } else {
date = Instant.now(); filter.setDate(Instant.now());
author = true; author = true;
filterString += " WHERE (entry.created < :before OR entry.author = :author)"; filterString += " WHERE (entry.created < :before OR entry.author = :author)";
} }
if (filter.getFlaggedStatus() == null) {
filter.setFlaggedStatus(FlaggedStatus.NORMAL);
}
filterString += " AND entry.flagged_status = :flag"; filterString += " AND entry.flagged_status = :flag";
if (StringUtils.hasText(additional)) { if (filter.getEntryType() != null) {
filterString += " AND entry.entry_type = :type";
}
if (StringUtils.hasText(filter.getAdditional())) {
filterString += " " filterString += " "
+ additional; + filter.getAdditional();
}
String excludedTagsString = "";
if (filter.getExcludedTags() != null && !filter.getExcludedTags().isEmpty()) {
for (int index = 0; index < filter.getExcludedTags().size(); index++) {
excludedTagsString += "'"
+ filter.getExcludedTags().get(index)
+ "'";
if (index < filter.getExcludedTags().size() - 1) {
excludedTagsString += ",";
}
}
}
if (StringUtils.hasText(excludedTagsString)) {
filterString += " AND NOT EXISTS (SELECT * FROM tags as excludedTag WHERE entry.id = excludedTag.target AND excludedTag.tag IN ("
+ excludedTagsString
+ "))";
} }
if (StringUtils.hasText(orderBy)) { if (StringUtils.hasText(orderBy)) {
@@ -271,12 +296,16 @@ public class EntryManager {
} }
Query query = em.createNativeQuery(String.format(rawQuery, filterString), Entry.class); Query query = em.createNativeQuery(String.format(rawQuery, filterString), Entry.class);
query.setParameter("before", date); query.setParameter("before", filter.getDate());
if (author) { if (author) {
query.setParameter("author", username); query.setParameter("author", username);
} }
query.setParameter("flag", flaggedStatus.toString()); if (filter.getEntryType() != null) {
query.setParameter("type", filter.getEntryType().toString());
}
query.setParameter("flag", filter.getFlaggedStatus().toString());
return query; return query;
} }
@@ -286,44 +315,83 @@ public class EntryManager {
* *
* @param rawQuery the raw query * @param rawQuery the raw query
* @param username the username * @param username the username
* @param date the date * @param filter the filter
* @param flaggedStatus the flagged status
* @param tag the tag
* @param additional the additional
* @return the query * @return the query
*/ */
protected Query createCountQuery(String rawQuery, String username, Instant date, protected Query createCountQuery(String rawQuery, String username, EntryFilter filter) {
FlaggedStatus flaggedStatus, String tag, String additional) {
String filterString = ""; String filterString = "";
if (StringUtils.hasText(tag)) { String tagsString = "";
filterString += " INNER JOIN tags as tag ON entry.id = tag.target AND tag.tag = '" if (filter.getTags() != null && !filter.getTags().isEmpty()) {
+ tag for (int index = 0; index < filter.getTags().size(); index++) {
tagsString += "'"
+ filter.getTags().get(index)
+ "'"; + "'";
if (index < filter.getTags().size() - 1) {
tagsString += ",";
}
}
}
if (StringUtils.hasText(tagsString)) {
filterString += " INNER JOIN tags as tag ON entry.id = tag.target AND tag.tag IN ("
+ tagsString
+ ")";
} }
boolean author = false; boolean author = false;
if (date != null) { if (filter.getDate() != null) {
filterString += " WHERE entry.created < :before"; filterString += " WHERE entry.created < :before";
} else { } else {
date = Instant.now(); filter.setDate(Instant.now());
author = true; author = true;
filterString += " WHERE (entry.created < :before OR entry.author = :author)"; filterString += " WHERE (entry.created < :before OR entry.author = :author)";
} }
if (filter.getFlaggedStatus() == null) {
filter.setFlaggedStatus(FlaggedStatus.NORMAL);
}
filterString += " AND entry.flagged_status = :flag"; filterString += " AND entry.flagged_status = :flag";
if (StringUtils.hasText(additional)) { if (filter.getEntryType() != null) {
filterString += " AND entry.entry_type = :type";
}
if (StringUtils.hasText(filter.getAdditional())) {
filterString += " " filterString += " "
+ additional; + filter.getAdditional();
}
String excludedTagsString = "";
if (filter.getExcludedTags() != null && !filter.getExcludedTags().isEmpty()) {
for (int index = 0; index < filter.getExcludedTags().size(); index++) {
excludedTagsString += "'"
+ filter.getExcludedTags().get(index)
+ "'";
if (index < filter.getExcludedTags().size() - 1) {
excludedTagsString += ",";
}
}
}
if (StringUtils.hasText(excludedTagsString)) {
filterString += " AND NOT EXISTS (SELECT * FROM tags as excludedTag WHERE entry.id = excludedTag.target AND excludedTag.tag IN ("
+ excludedTagsString
+ "))";
} }
Query query = em.createNativeQuery(String.format(rawQuery, filterString)); Query query = em.createNativeQuery(String.format(rawQuery, filterString));
query.setParameter("before", date); query.setParameter("before", filter.getDate());
if (author) { if (author) {
query.setParameter("author", username); query.setParameter("author", username);
} }
query.setParameter("flag", flaggedStatus.toString());
if (filter.getEntryType() != null) {
query.setParameter("type", filter.getEntryType().toString());
}
query.setParameter("flag", filter.getFlaggedStatus().toString());
return query; return query;
} }
@@ -496,11 +564,14 @@ public class EntryManager {
* @return the entry * @return the entry
*/ */
public Entry save(Entry entry) { public Entry save(Entry entry) {
List<String> tags = Lists.newArrayList(entry.getTags()); List<String> tags = Lists.newArrayList();
if (entry.getTags() != null) {
tags = Lists.newArrayList(entry.getTags());
if (tags.size() > settingsManager.getMaxTags()) { if (tags.size() > settingsManager.getMaxTags()) {
tags = tags.subList(0, settingsManager.getMaxTags() - 1); tags = tags.subList(0, settingsManager.getMaxTags() - 1);
} }
}
entry = entryRepository.save(entry); entry = entryRepository.save(entry);
tagManager.setForTarget(entry.getId(), tags); tagManager.setForTarget(entry.getId(), tags);
@@ -26,6 +26,8 @@ public class SettingsManager {
private long FLAG_THRESH; private long FLAG_THRESH;
@Value("${bstly.board.maxTags:3}") @Value("${bstly.board.maxTags:3}")
private int MAX_TAGS; private int MAX_TAGS;
@Value("${bstly.board.maxUserPage:5}")
private long MAX_USER_PAGES;
/** /**
* Gets the gravity. * Gets the gravity.
@@ -82,9 +84,20 @@ public class SettingsManager {
} }
/** /**
* @return * Gets the max tags.
*
* @return the max tags
*/ */
public int getMaxTags() { public int getMaxTags() {
return MAX_TAGS; return MAX_TAGS;
} }
/**
* Gets the max user pages.
*
* @return the max user pages
*/
public long getMaxUserPages() {
return MAX_USER_PAGES;
}
} }
@@ -131,6 +131,12 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
/* /*
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String) * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
*/ */
/*
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
*/
/*
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
*/
/* /*
* @see org.springframework.security.core.userdetails.UserDetailsService# * @see org.springframework.security.core.userdetails.UserDetailsService#
* loadUserByUsername(java.lang.String) * loadUserByUsername(java.lang.String)
@@ -236,6 +242,12 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
/* /*
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated() * @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
*/ */
/*
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
*/
/*
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
*/
/* /*
* @see org.springframework.beans.factory.SmartInitializingSingleton# * @see org.springframework.beans.factory.SmartInitializingSingleton#
* afterSingletonsInstantiated() * afterSingletonsInstantiated()
@@ -0,0 +1,126 @@
/**
*
*/
package de.bstly.board.businesslogic;
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.Direction;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import de.bstly.board.model.QUserPage;
import de.bstly.board.model.UserPage;
import de.bstly.board.repository.UserPageRepository;
/**
* The Class UserPageManager.
*/
@Component
public class UserPageManager {
@Autowired
private UserPageRepository userPageRepository;
private QUserPage qUserPage = QUserPage.userPage;
/**
* Exists.
*
* @param username the username
* @param name the name
* @return true, if successful
*/
public boolean exists(String username, String name) {
return userPageRepository
.exists(qUserPage.username.equalsIgnoreCase(username).and(qUserPage.name.eq(name)));
}
/**
* Gets the.
*
* @param id the id
* @return the user page
*/
public UserPage get(Long id) {
return userPageRepository.findById(id).orElse(null);
}
/**
* Gets the.
*
* @param username the username
* @param name the name
* @return the user page
*/
public UserPage get(String username, String name) {
return userPageRepository
.findOne(qUserPage.username.equalsIgnoreCase(username).and(qUserPage.name.eq(name)))
.orElse(null);
}
/**
* Save.
*
* @param userPage the user page
* @return the user page
*/
public UserPage save(UserPage userPage) {
return userPageRepository.save(userPage);
}
/**
* Gets the by user.
*
* @param username the username
* @param page the page
* @param size the size
* @param sortBy the sort by
* @param asc the asc
* @return the by user
*/
public Page<UserPage> getByUser(String username, int page, int size, String sortBy,
boolean desc) {
return userPageRepository.findAll(qUserPage.username.equalsIgnoreCase(username),
PageRequest.of(page, size, Sort.by(desc ? Direction.DESC : Direction.ASC, sortBy)));
}
/**
* Count by user.
*
* @param username the username
* @return the long
*/
public long countByUser(String username) {
return userPageRepository.count(qUserPage.username.equalsIgnoreCase(username));
}
/**
* Gets the public.
*
* @param username the username
* @param page the page
* @param size the size
* @param sortBy the sort by
* @param asc the asc
* @return the public
*/
public Page<UserPage> getPublic(String username, int page, int size, String sortBy,
boolean desc) {
return userPageRepository.findAll(
qUserPage.username.notEqualsIgnoreCase(username).and(qUserPage.publicPage.isTrue()),
PageRequest.of(page, size, Sort.by(desc ? Direction.DESC : Direction.ASC, sortBy)));
}
/**
* Delete.
*
* @param username the username
* @param name the name
*/
public void delete(String username, String name) {
Assert.isTrue(exists(username, name), "UserPage not found!");
userPageRepository.delete(get(username, name));
}
}
@@ -32,14 +32,18 @@ import com.google.common.collect.Lists;
import de.bstly.board.businesslogic.EntryManager; import de.bstly.board.businesslogic.EntryManager;
import de.bstly.board.businesslogic.SettingsManager; import de.bstly.board.businesslogic.SettingsManager;
import de.bstly.board.businesslogic.UserManager; import de.bstly.board.businesslogic.UserManager;
import de.bstly.board.businesslogic.UserPageManager;
import de.bstly.board.businesslogic.VoteManager; import de.bstly.board.businesslogic.VoteManager;
import de.bstly.board.controller.model.EntryFilter;
import de.bstly.board.controller.support.EntityResponseStatusException; import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.controller.support.RequestBodyErrors; import de.bstly.board.controller.support.RequestBodyErrors;
import de.bstly.board.controller.validation.EntryValidator; import de.bstly.board.controller.validation.EntryValidator;
import de.bstly.board.model.Entry; import de.bstly.board.model.Entry;
import de.bstly.board.model.EntryStatus; import de.bstly.board.model.EntryStatus;
import de.bstly.board.model.EntryType;
import de.bstly.board.model.FlaggedStatus; import de.bstly.board.model.FlaggedStatus;
import de.bstly.board.model.Types; import de.bstly.board.model.Types;
import de.bstly.board.model.UserPage;
import de.bstly.board.model.Vote; import de.bstly.board.model.Vote;
import de.bstly.board.model.VoteType; import de.bstly.board.model.VoteType;
@@ -60,6 +64,8 @@ public class EntryController extends BaseController {
private VoteManager voteManager; private VoteManager voteManager;
@Autowired @Autowired
private SettingsManager settingsManager; private SettingsManager settingsManager;
@Autowired
private UserPageManager userPageManager;
/** /**
* Fetch by ranking. * Fetch by ranking.
@@ -68,6 +74,7 @@ public class EntryController extends BaseController {
* @param sizeParameter the size parameter * @param sizeParameter the size parameter
* @param dateParameter the date parameter * @param dateParameter the date parameter
* @param tagParameter the tag parameter * @param tagParameter the tag parameter
* @param typeParameter the type parameter
* @param gravityParameter the gravity parameter * @param gravityParameter the gravity parameter
* @param ascParameter the asc parameter * @param ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
@@ -78,7 +85,9 @@ public class EntryController extends BaseController {
public Page<Entry> fetchByRanking(@RequestParam("page") Optional<Integer> pageParameter, public Page<Entry> fetchByRanking(@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter, @RequestParam("size") Optional<Integer> sizeParameter,
@RequestParam("date") Optional<Instant> dateParameter, @RequestParam("date") Optional<Instant> dateParameter,
@RequestParam("tag") Optional<String> tagParameter, @RequestParam("tags") Optional<List<String>> tagsParameter,
@RequestParam("excludedTags") Optional<List<String>> excludedTagsParameter,
@RequestParam("type") Optional<EntryType> typeParameter,
@RequestParam("gravity") Optional<Double> gravityParameter, @RequestParam("gravity") Optional<Double> gravityParameter,
@RequestParam("asc") Optional<Boolean> ascParameter, @RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
@@ -95,8 +104,11 @@ public class EntryController extends BaseController {
gravityParameter = Optional.of(2.0); gravityParameter = Optional.of(2.0);
} }
Page<Entry> entries = entryManager.fetchByRanking(getCurrentUsername(), EntryFilter filter = buildFilter(dateParameter.orElse(null), FlaggedStatus.NORMAL,
dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null), tagsParameter.orElse(null), excludedTagsParameter.orElse(null),
typeParameter.orElse(null));
Page<Entry> entries = entryManager.fetchByRanking(getCurrentUsername(), filter,
gravityParameter.orElse(getGravity()), pageParameter.orElse(0), gravityParameter.orElse(getGravity()), pageParameter.orElse(0),
sizeParameter.orElse(settingsManager.getPageSize()), ascParameter.orElse(false)); sizeParameter.orElse(settingsManager.getPageSize()), ascParameter.orElse(false));
@@ -113,6 +125,7 @@ public class EntryController extends BaseController {
* @param sizeParameter the size parameter * @param sizeParameter the size parameter
* @param dateParameter the date parameter * @param dateParameter the date parameter
* @param tagParameter the tag parameter * @param tagParameter the tag parameter
* @param typeParameter the type parameter
* @param ascParameter the asc parameter * @param ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
* @return the page * @return the page
@@ -122,7 +135,9 @@ public class EntryController extends BaseController {
public Page<Entry> fetchByDate(@RequestParam("page") Optional<Integer> pageParameter, public Page<Entry> fetchByDate(@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter, @RequestParam("size") Optional<Integer> sizeParameter,
@RequestParam("date") Optional<Instant> dateParameter, @RequestParam("date") Optional<Instant> dateParameter,
@RequestParam("tag") Optional<String> tagParameter, @RequestParam("tags") Optional<List<String>> tagsParameter,
@RequestParam("excludedTags") Optional<List<String>> excludedTagsParameter,
@RequestParam("type") Optional<EntryType> typeParameter,
@RequestParam("asc") Optional<Boolean> ascParameter, @RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
@@ -134,8 +149,11 @@ public class EntryController extends BaseController {
dateParameter = Optional.of(Instant.now()); dateParameter = Optional.of(Instant.now());
} }
Page<Entry> entries = entryManager.fetchByDate(getCurrentUsername(), EntryFilter filter = buildFilter(dateParameter.orElse(null), FlaggedStatus.NORMAL,
dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null), tagsParameter.orElse(null), excludedTagsParameter.orElse(null),
typeParameter.orElse(null));
Page<Entry> entries = entryManager.fetchByDate(getCurrentUsername(), filter,
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()), pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false)); ascParameter.orElse(false));
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList()); List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
@@ -151,6 +169,7 @@ public class EntryController extends BaseController {
* @param sizeParameter the size parameter * @param sizeParameter the size parameter
* @param dateParameter the date parameter * @param dateParameter the date parameter
* @param tagParameter the tag parameter * @param tagParameter the tag parameter
* @param typeParameter the type parameter
* @param gravityParameter the gravity parameter * @param gravityParameter the gravity parameter
* @param ascParameter the asc parameter * @param ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
@@ -161,7 +180,9 @@ public class EntryController extends BaseController {
public Page<Entry> fetchByComments(@RequestParam("page") Optional<Integer> pageParameter, public Page<Entry> fetchByComments(@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter, @RequestParam("size") Optional<Integer> sizeParameter,
@RequestParam("date") Optional<Instant> dateParameter, @RequestParam("date") Optional<Instant> dateParameter,
@RequestParam("tag") Optional<String> tagParameter, @RequestParam("tags") Optional<List<String>> tagsParameter,
@RequestParam("excludedTags") Optional<List<String>> excludedTagsParameter,
@RequestParam("type") Optional<EntryType> typeParameter,
@RequestParam("gravity") Optional<Double> gravityParameter, @RequestParam("gravity") Optional<Double> gravityParameter,
@RequestParam("asc") Optional<Boolean> ascParameter, @RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
@@ -174,8 +195,11 @@ public class EntryController extends BaseController {
dateParameter = Optional.of(Instant.now()); dateParameter = Optional.of(Instant.now());
} }
Page<Entry> entries = entryManager.fetchByComments(getCurrentUsername(), EntryFilter filter = buildFilter(dateParameter.orElse(null), FlaggedStatus.NORMAL,
dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null), tagsParameter.orElse(null), excludedTagsParameter.orElse(null),
typeParameter.orElse(null));
Page<Entry> entries = entryManager.fetchByComments(getCurrentUsername(), filter,
gravityParameter.orElse(getGravity()), pageParameter.orElse(0), gravityParameter.orElse(getGravity()), pageParameter.orElse(0),
sizeParameter.orElse(settingsManager.getPageSize()), ascParameter.orElse(false)); sizeParameter.orElse(settingsManager.getPageSize()), ascParameter.orElse(false));
@@ -192,6 +216,7 @@ public class EntryController extends BaseController {
* @param sizeParameter the size parameter * @param sizeParameter the size parameter
* @param dateParameter the date parameter * @param dateParameter the date parameter
* @param tagParameter the tag parameter * @param tagParameter the tag parameter
* @param typeParameter the type parameter
* @param ascParameter the asc parameter * @param ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
* @return the page * @return the page
@@ -201,7 +226,9 @@ public class EntryController extends BaseController {
public Page<Entry> fetchByLast(@RequestParam("page") Optional<Integer> pageParameter, public Page<Entry> fetchByLast(@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter, @RequestParam("size") Optional<Integer> sizeParameter,
@RequestParam("date") Optional<Instant> dateParameter, @RequestParam("date") Optional<Instant> dateParameter,
@RequestParam("tag") Optional<String> tagParameter, @RequestParam("tags") Optional<List<String>> tagsParameter,
@RequestParam("excludedTags") Optional<List<String>> excludedTagsParameter,
@RequestParam("type") Optional<EntryType> typeParameter,
@RequestParam("asc") Optional<Boolean> ascParameter, @RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
@@ -213,8 +240,11 @@ public class EntryController extends BaseController {
dateParameter = Optional.of(Instant.now()); dateParameter = Optional.of(Instant.now());
} }
Page<Entry> entries = entryManager.fetchByLastComment(getCurrentUsername(), EntryFilter filter = buildFilter(dateParameter.orElse(null), FlaggedStatus.NORMAL,
dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null), tagsParameter.orElse(null), excludedTagsParameter.orElse(null),
typeParameter.orElse(null));
Page<Entry> entries = entryManager.fetchByLastComment(getCurrentUsername(), filter,
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()), pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false)); ascParameter.orElse(false));
@@ -232,6 +262,7 @@ public class EntryController extends BaseController {
* @param sizeParameter the size parameter * @param sizeParameter the size parameter
* @param dateParameter the date parameter * @param dateParameter the date parameter
* @param tagParameter the tag parameter * @param tagParameter the tag parameter
* @param typeParameter the type parameter
* @param ascParameter the asc parameter * @param ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
* @return the page * @return the page
@@ -242,7 +273,9 @@ public class EntryController extends BaseController {
@RequestParam("page") Optional<Integer> pageParameter, @RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter, @RequestParam("size") Optional<Integer> sizeParameter,
@RequestParam("date") Optional<Instant> dateParameter, @RequestParam("date") Optional<Instant> dateParameter,
@RequestParam("tag") Optional<String> tagParameter, @RequestParam("tags") Optional<List<String>> tagsParameter,
@RequestParam("excludedTags") Optional<List<String>> excludedTagsParameter,
@RequestParam("type") Optional<EntryType> typeParameter,
@RequestParam("asc") Optional<Boolean> ascParameter, @RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
@@ -254,8 +287,11 @@ public class EntryController extends BaseController {
dateParameter = Optional.of(Instant.now()); dateParameter = Optional.of(Instant.now());
} }
Page<Entry> entries = entryManager.fetchByUser(getCurrentUsername(), username, EntryFilter filter = buildFilter(dateParameter.orElse(null), FlaggedStatus.NORMAL,
dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null), tagsParameter.orElse(null), excludedTagsParameter.orElse(null),
typeParameter.orElse(null));
Page<Entry> entries = entryManager.fetchByUser(getCurrentUsername(), username, filter,
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()), pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false)); ascParameter.orElse(false));
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList()); List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
@@ -264,6 +300,98 @@ public class EntryController extends BaseController {
return entries; return entries;
} }
/**
* Fetch by user page.
*
* @param name the name
* @param usernameParameter the username parameter
* @param pageParameter the page parameter
* @param sizeParameter the size parameter
* @param ascParameter the asc parameter
* @param ignoreParameter the ignore parameter
* @return the page
*/
@PreAuthorize("isAuthenticated()")
@GetMapping("/userpage/{name}")
public Page<Entry> fetchByUserPage(@PathVariable("name") String name,
@RequestParam("user") Optional<String> usernameParameter,
@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter,
@RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) {
UserPage userPage = userPageManager.get(usernameParameter.orElse(getCurrentUsername()),
name);
if (userPage == null || usernameParameter.isPresent() && !userPage.isPublicPage()) {
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
}
if (sizeParameter.isPresent() && sizeParameter.get() > 100) {
sizeParameter = Optional.of(100);
}
EntryFilter filter = new EntryFilter();
filter.setEntryType(userPage.getEntryType());
filter.setTags(userPage.getTags());
filter.setExcludedTags(userPage.getExcludedTags());
Page<Entry> entries = null;
switch (userPage.getSorting()) {
case TOP:
entries = entryManager.fetchByRanking(getCurrentUsername(), filter, getGravity(),
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false));
break;
case NEW:
entries = entryManager.fetchByDate(getCurrentUsername(), filter,
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false));
break;
case HOT:
entries = entryManager.fetchByComments(getCurrentUsername(), filter, getGravity(),
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false));
break;
case LAST:
entries = entryManager.fetchByLastComment(getCurrentUsername(), filter,
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false));
break;
}
if (entries == null) {
throw new EntityResponseStatusException(HttpStatus.BAD_REQUEST);
}
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
entries.getContent(), ignore);
return entries;
}
/**
* Builds the filter.
*
* @param date the date
* @param flaggedStatus the flagged status
* @param tag the tag
* @param type the type
* @return the entry filter
*/
protected EntryFilter buildFilter(Instant date, FlaggedStatus flaggedStatus, List<String> tags,
List<String> excludedTags, EntryType type) {
EntryFilter filter = new EntryFilter();
filter.setDate(date);
filter.setFlaggedStatus(flaggedStatus);
filter.setEntryType(type);
filter.setTags(tags);
filter.setExcludedTags(excludedTags);
return filter;
}
/** /**
* Gets the entry. * Gets the entry.
* *
@@ -37,6 +37,7 @@ public class SettingsController extends BaseController {
settings.put("entryDelay", getEntryDelay()); settings.put("entryDelay", getEntryDelay());
settings.put("commentDelay", getCommentDelay()); settings.put("commentDelay", getCommentDelay());
settings.put("maxTags", settingsManager.getMaxTags()); settings.put("maxTags", settingsManager.getMaxTags());
settings.put("maxUserPages", settingsManager.getMaxUserPages());
settings.put("defaultGravity", settingsManager.getGravity()); settings.put("defaultGravity", settingsManager.getGravity());
settings.put("defaultPageSize", settingsManager.getPageSize()); settings.put("defaultPageSize", settingsManager.getPageSize());
settings.put("defaultEntryDelay", settingsManager.getEntryDelay()); settings.put("defaultEntryDelay", settingsManager.getEntryDelay());
@@ -0,0 +1,138 @@
/**
*
*/
package de.bstly.board.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import de.bstly.board.businesslogic.SettingsManager;
import de.bstly.board.businesslogic.UserPageManager;
import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.controller.support.RequestBodyErrors;
import de.bstly.board.controller.validation.UserPageValidator;
import de.bstly.board.model.UserPage;
/**
* The Class UserPageController.
*/
@RestController
@RequestMapping("/userpages")
public class UserPageController extends BaseController {
@Autowired
private UserPageManager userPageManager;
@Autowired
private SettingsManager settingsManager;
@Autowired
private UserPageValidator userPageValidator;
/**
* Gets the user pages.
*
* @param pageParameter the page parameter
* @param sizeParameter the size parameter
* @param ascParameter the asc parameter
* @return the user pages
*/
@PreAuthorize("isAuthenticated()")
@GetMapping()
public Page<UserPage> getUserPages(@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter,
@RequestParam("desc") Optional<Boolean> descParameter) {
return userPageManager.getByUser(getCurrentUsername(), pageParameter.orElse(0),
sizeParameter.orElse(settingsManager.getPageSize()), "name",
descParameter.orElse(false));
}
/**
* Gets the public user pages.
*
* @param pageParameter the page parameter
* @param sizeParameter the size parameter
* @param ascParameter the asc parameter
* @return the public user pages
*/
@PreAuthorize("isAuthenticated()")
@GetMapping("/public")
public Page<UserPage> getPublicUserPages(@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter,
@RequestParam("desc") Optional<Boolean> descParameter) {
return userPageManager.getPublic(getCurrentUsername(), pageParameter.orElse(0),
sizeParameter.orElse(settingsManager.getPageSize()), "name",
descParameter.orElse(false));
}
/**
* Gets the user page.
*
* @param name the name
* @return the user page
*/
@PreAuthorize("isAuthenticated()")
@GetMapping("/userpage/{name}")
public UserPage getUserPage(@PathVariable("name") String name) {
UserPage userPage = userPageManager.get(getCurrentUsername(), name);
if (userPage == null) {
throw new EntityResponseStatusException(HttpStatus.NOT_FOUND);
}
return userPage;
}
/**
* Creates the or update.
*
* @param userPage the user page
* @return the user page
*/
@PreAuthorize("isAuthenticated()")
@PostMapping("/userpage")
public UserPage createOrUpdate(@RequestBody UserPage userPage) {
userPage.setUsername(getCurrentUsername());
RequestBodyErrors bindingResult = new RequestBodyErrors(userPage);
userPageValidator.validate(userPage, bindingResult);
if (bindingResult.hasErrors()) {
throw new EntityResponseStatusException(bindingResult.getAllErrors(),
HttpStatus.UNPROCESSABLE_ENTITY);
}
if (!userPageManager.exists(getCurrentUsername(), userPage.getName()) && userPageManager
.countByUser(getCurrentUsername()) >= settingsManager.getMaxUserPages()) {
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
}
return userPageManager.save(userPage);
}
/**
* Delete user page.
*
* @param name the name
*/
@PreAuthorize("isAuthenticated()")
@DeleteMapping("/userpage/{name}")
public void deleteUserPage(@PathVariable("name") String name) {
if (!userPageManager.exists(getCurrentUsername(), name)) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
}
userPageManager.delete(getCurrentUsername(), name);
}
}
@@ -0,0 +1,132 @@
/**
*
*/
package de.bstly.board.controller.model;
import java.time.Instant;
import java.util.List;
import de.bstly.board.model.EntryType;
import de.bstly.board.model.FlaggedStatus;
/**
* The Class EntryFilter.
*/
public class EntryFilter {
private Instant date;
private FlaggedStatus flaggedStatus;
private List<String> tags;
private List<String> excludedTags;
private EntryType entryType;
private String additional;
/**
* Gets the date.
*
* @return the date
*/
public Instant getDate() {
return date;
}
/**
* Sets the date.
*
* @param date the new date
*/
public void setDate(Instant date) {
this.date = date;
}
/**
* Gets the flagged status.
*
* @return the flagged status
*/
public FlaggedStatus getFlaggedStatus() {
return flaggedStatus;
}
/**
* Sets the flagged status.
*
* @param flaggedStatus the new flagged status
*/
public void setFlaggedStatus(FlaggedStatus flaggedStatus) {
this.flaggedStatus = flaggedStatus;
}
/**
* Gets the tags.
*
* @return the tags
*/
public List<String> getTags() {
return tags;
}
/**
* Sets the tags.
*
* @param tags the new tags
*/
public void setTags(List<String> tags) {
this.tags = tags;
}
/**
* Gets the excluded tags.
*
* @return the excluded tags
*/
public List<String> getExcludedTags() {
return excludedTags;
}
/**
* Sets the excluded tags.
*
* @param excludedTags the new excluded tags
*/
public void setExcludedTags(List<String> excludedTags) {
this.excludedTags = excludedTags;
}
/**
* Gets the entry type.
*
* @return the entry type
*/
public EntryType getEntryType() {
return entryType;
}
/**
* Sets the entry type.
*
* @param entryType the new entry type
*/
public void setEntryType(EntryType entryType) {
this.entryType = entryType;
}
/**
* Gets the additional.
*
* @return the additional
*/
public String getAdditional() {
return additional;
}
/**
* Sets the additional.
*
* @param additional the new additional
*/
public void setAdditional(String additional) {
this.additional = additional;
}
}
@@ -0,0 +1,73 @@
/**
*
*/
package de.bstly.board.controller.validation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import de.bstly.board.businesslogic.UserPageManager;
import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.model.UserPage;
/**
* The Class UserPageValidator.
*/
@Component
public class UserPageValidator implements Validator {
@Autowired
private UserPageManager userPageManager;
/*
* @see org.springframework.validation.Validator#supports(java.lang.Class)
*/
@Override
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(UserPage.class);
}
/*
* @see org.springframework.validation.Validator#validate(java.lang.Object,
* org.springframework.validation.Errors)
*/
@Override
public void validate(Object target, Errors errors) {
UserPage userPage = (UserPage) target;
if (!StringUtils.hasText(userPage.getName())) {
errors.rejectValue("name", "required");
}
if ((userPage.getId() == null || userPage.getId().equals(0L))
&& userPageManager.exists(userPage.getUsername(), userPage.getName())) {
errors.rejectValue("name", "ALREADY_EXISTS");
}
if (userPage.getId() != null) {
UserPage origUserPage = userPageManager.get(userPage.getId());
if (origUserPage == null) {
errors.rejectValue("id", "INVALID");
}
if (!origUserPage.getUsername().equals(userPage.getUsername())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
}
UserPage other = userPageManager.get(userPage.getUsername(), userPage.getName());
if (other != null && !other.getId().equals(userPage.getId())) {
errors.rejectValue("name", "ALREADY_EXISTS");
}
}
if (userPage.getSorting() == null) {
errors.rejectValue("sorting", "REQUIRED");
}
}
}
@@ -0,0 +1,200 @@
/**
*
*/
package de.bstly.board.model;
import java.util.List;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
* The Class UserPage.
*/
@Entity
@Table(name = "user_pages")
@EntityListeners({ AuditingEntityListener.class })
public class UserPage {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "username", nullable = false)
private String username;
@Enumerated(EnumType.STRING)
@Column(name = "sorting", nullable = false)
private UserPageSorting sorting;
@ElementCollection
@LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "users_page_tags")
private List<String> tags;
@ElementCollection
@LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "user_pages_excluded_tags")
private List<String> excludedTags;
@Column(name = "entry_type", nullable = true)
private EntryType entryType;
@Column(name = "public", columnDefinition = "boolean default false")
private boolean publicPage;
/**
* Gets the id.
*
* @return the id
*/
public Long getId() {
return id;
}
/**
* Sets the id.
*
* @param id the new id
*/
public void setId(Long id) {
this.id = id;
}
/**
* Gets the name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Sets the name.
*
* @param name the new name
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets the username.
*
* @return the username
*/
public String getUsername() {
return username;
}
/**
* Sets the username.
*
* @param username the new username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Gets the sorting.
*
* @return the sorting
*/
public UserPageSorting getSorting() {
return sorting;
}
/**
* Sets the sorting.
*
* @param sorting the new sorting
*/
public void setSorting(UserPageSorting sorting) {
this.sorting = sorting;
}
/**
* Gets the tags.
*
* @return the tags
*/
public List<String> getTags() {
return tags;
}
/**
* Sets the tags.
*
* @param tags the new tags
*/
public void setTags(List<String> tags) {
this.tags = tags;
}
/**
* Gets the excluded tags.
*
* @return the excluded tags
*/
public List<String> getExcludedTags() {
return excludedTags;
}
/**
* Sets the excluded tags.
*
* @param excludedTags the new excluded tags
*/
public void setExcludedTags(List<String> excludedTags) {
this.excludedTags = excludedTags;
}
/**
* Gets the entry type.
*
* @return the entry type
*/
public EntryType getEntryType() {
return entryType;
}
/**
* Sets the entry type.
*
* @param entryType the new entry type
*/
public void setEntryType(EntryType entryType) {
this.entryType = entryType;
}
/**
* Checks if is public page.
*
* @return true, if is public page
*/
public boolean isPublicPage() {
return publicPage;
}
/**
* Sets the public page.
*
* @param publicPage the new public page
*/
public void setPublicPage(boolean publicPage) {
this.publicPage = publicPage;
}
}
@@ -0,0 +1,12 @@
/**
*
*/
package de.bstly.board.model;
/**
* The Enum UserPageSorting.
*/
public enum UserPageSorting {
TOP, NEW, HOT, LAST
}
@@ -0,0 +1,19 @@
/**
*
*/
package de.bstly.board.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;
import de.bstly.board.model.UserPage;
/**
* The Interface UserPageRepository.
*/
@Repository
public interface UserPageRepository
extends JpaRepository<UserPage, Long>, QuerydslPredicateExecutor<UserPage> {
}