added tags + filtering

This commit is contained in:
_Bastler 2021-12-01 19:00:50 +01:00
parent b9211d2178
commit 39369a7cf8
9 changed files with 642 additions and 204 deletions

View File

@ -17,6 +17,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order; import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.OrderSpecifier;
@ -43,6 +44,8 @@ public class EntryManager {
@Autowired @Autowired
private EntryRepository entryRepository; private EntryRepository entryRepository;
@Autowired @Autowired
private TagManager tagManager;
@Autowired
private CommentManager commentManager; private CommentManager commentManager;
@Autowired @Autowired
private VoteManager voteManager; private VoteManager voteManager;
@ -73,19 +76,21 @@ public class EntryManager {
+ 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 WHERE %s ORDER BY ranking DESC, entry.created DESC"; + ") AS downvote ON downvote.target = entry.id %s";
static final String DATE_QUERY = "SELECT entry.*FROM entries AS entry WHERE %s ORDER BY entry.created DESC"; static final String DATE_QUERY = "SELECT 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 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 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 WHERE %s ORDER BY ranking DESC, entry.created DESC"; + ") 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 entry.* FROM entries AS entry LEFT JOIN ("
+ COMMENTS_QUERY + COMMENTS_QUERY
+ ") AS comment ON comment.target = entry.id WHERE %s ORDER BY comment.last DESC, entry.created DESC"; + ") AS comment ON comment.target = entry.id %s ";
static final String COUNT_QUERY = "SELECT count(entry.id) FROM entries as entry WHERE %s"; static final String COUNT_QUERY = "SELECT count(entry.id) FROM entries as entry %s";
/** /**
* Fetch by ranking. * Fetch by ranking.
@ -93,20 +98,23 @@ public class EntryManager {
* @param username the username * @param username the username
* @param date the date * @param date the date
* @param flaggedStatus the flagged status * @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
* @return the page * @return the page
*/ */
public Page<Entry> fetchByRanking(String username, Instant date, FlaggedStatus flaggedStatus, public Page<Entry> fetchByRanking(String username, Instant date, FlaggedStatus flaggedStatus,
double gravity, int page, int size) { String tag, double gravity, int page, int size, boolean asc) {
Query query = createEntryQuery(RANK_CALCULATION_QUERY, username, date, flaggedStatus); Query query = createEntryQuery(RANK_CALCULATION_QUERY, username, date, flaggedStatus, tag,
null, 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); Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, null);
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);
} }
@ -117,18 +125,21 @@ public class EntryManager {
* @param username the username * @param username the username
* @param date the date * @param date the date
* @param flaggedStatus the flagged status * @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
* @return the page * @return the page
*/ */
public Page<Entry> fetchByDate(String username, Instant date, FlaggedStatus flaggedStatus, public Page<Entry> fetchByDate(String username, Instant date, FlaggedStatus flaggedStatus,
int page, int size) { String tag, int page, int size, boolean asc) {
Query query = createEntryQuery(DATE_QUERY, username, date, flaggedStatus); Query query = createEntryQuery(DATE_QUERY, username, date, flaggedStatus, tag, null,
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); Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, null);
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);
} }
@ -139,20 +150,24 @@ public class EntryManager {
* @param username the username * @param username the username
* @param date the date * @param date the date
* @param flaggedStatus the flagged status * @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
* @return the page * @return the page
*/ */
public Page<Entry> fetchByComments(String username, Instant date, FlaggedStatus flaggedStatus, public Page<Entry> fetchByComments(String username, Instant date, FlaggedStatus flaggedStatus,
double gravity, int page, int size) { String tag, double gravity, int page, int size, boolean asc) {
Query query = createEntryQuery(COMMENT_CALCULATION_QUERY, username, date, flaggedStatus); Query query = createEntryQuery(COMMENT_CALCULATION_QUERY, username, date, flaggedStatus,
tag, null,
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); Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, null);
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);
} }
@ -163,18 +178,51 @@ public class EntryManager {
* @param username the username * @param username the username
* @param date the date * @param date the date
* @param flaggedStatus the flagged status * @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
* @return the page * @return the page
*/ */
public Page<Entry> fetchByLastComment(String username, Instant date, public Page<Entry> fetchByLastComment(String username, Instant date,
FlaggedStatus flaggedStatus, int page, int size) { FlaggedStatus flaggedStatus, String tag, int page, int size, boolean asc) {
Query query = createEntryQuery(LAST_COMMENT_QUERY, username, date, flaggedStatus); Query query = createEntryQuery(LAST_COMMENT_QUERY, username, date, flaggedStatus, tag, null,
asc ? "comment.last ASC, entry.created ASC"
: "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); Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag, null);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
}
/**
* Fetch by user.
*
* @param fromUser the from user
* @param username the username
* @param date the date
* @param flaggedStatus the flagged status
* @param tag the tag
* @param page the page
* @param size the size
* @param asc the asc
* @return the page
*/
public Page<Entry> fetchByUser(String fromUser, String username, Instant date,
FlaggedStatus flaggedStatus, String tag, int page, int size, boolean asc) {
Query query = createEntryQuery(DATE_QUERY, username, date, flaggedStatus, tag,
"AND entry.author = :username", asc ? "entry.created ASC" : "entry.created DESC");
query.setParameter("username", username);
query.setFirstResult((page) * size);
query.setMaxResults(size);
@SuppressWarnings("unchecked")
List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus, tag,
"AND entry.author = :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);
} }
@ -186,28 +234,48 @@ public class EntryManager {
* @param username the username * @param username the username
* @param date the date * @param date the date
* @param flaggedStatus the flagged status * @param flaggedStatus the flagged status
* @param tag the tag
* @param additional the additional
* @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, Instant date,
FlaggedStatus flaggedStatus) { FlaggedStatus flaggedStatus, String tag, String additional, String orderBy) {
String filterString = ""; String filterString = "";
if (StringUtils.hasText(tag)) {
filterString += " INNER JOIN tags as tag ON entry.id = tag.target AND tag.tag = '"
+ tag
+ "'";
}
boolean author = false; boolean author = false;
if (date != null) { if (date != null) {
filterString = "entry.created < :before"; filterString += " WHERE entry.created < :before";
} else { } else {
date = Instant.now(); date = Instant.now();
author = true; author = true;
filterString = "(entry.created < :before OR entry.author = :author)"; filterString += " WHERE (entry.created < :before OR entry.author = :author)";
} }
filterString += " AND entry.flagged_status = :flag"; filterString += " AND entry.flagged_status = :flag";
if (StringUtils.hasText(additional)) {
filterString += " "
+ additional;
}
if (StringUtils.hasText(orderBy)) {
filterString += " ORDER BY "
+ orderBy;
}
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", date);
if (author) { if (author) {
query.setParameter("author", username); query.setParameter("author", username);
} }
query.setParameter("flag", flaggedStatus.toString()); query.setParameter("flag", flaggedStatus.toString());
return query; return query;
@ -220,23 +288,36 @@ public class EntryManager {
* @param username the username * @param username the username
* @param date the date * @param date the date
* @param flaggedStatus the flagged status * @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, Instant date,
FlaggedStatus flaggedStatus) { FlaggedStatus flaggedStatus, String tag, String additional) {
String filterString = ""; String filterString = "";
if (StringUtils.hasText(tag)) {
filterString += " INNER JOIN tags as tag ON entry.id = tag.target AND tag.tag = '"
+ tag
+ "'";
}
boolean author = false; boolean author = false;
if (date != null) { if (date != null) {
filterString = "entry.created < :before"; filterString += "WHERE entry.created < :before";
} else { } else {
date = Instant.now(); date = Instant.now();
author = true; author = true;
filterString = "(entry.created < :before OR entry.author = :author)"; filterString += "WHERE (entry.created < :before OR entry.author = :author)";
} }
filterString += " AND entry.flagged_status = :flag"; filterString += " AND entry.flagged_status = :flag";
if (StringUtils.hasText(additional)) {
filterString += " "
+ additional;
}
Query query = em.createNativeQuery(String.format(rawQuery, filterString)); Query query = em.createNativeQuery(String.format(rawQuery, filterString));
query.setParameter("before", date); query.setParameter("before", date);
if (author) { if (author) {
@ -267,23 +348,6 @@ public class EntryManager {
query.fetchCount()); 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. * Fetch by bookmarks.
* *
@ -313,8 +377,19 @@ public class EntryManager {
*/ */
public void applyMetadata(String username, long karma, Entry entry, List<String> ignore) { public void applyMetadata(String username, long karma, Entry entry, List<String> ignore) {
entry.setTags(tagManager.getForTarget(entry.getId()));
ignore.addAll(entry.getMetadata().keySet()); ignore.addAll(entry.getMetadata().keySet());
if (!ignore.contains("author")) {
entry.getMetadata().put("author", entry.getAuthor().equals(username));
}
if (!ignore.contains("edit")) {
entry.getMetadata().put("edit", entry.getAuthor().equals(username)
&& entry.getCreated().isAfter(Instant.now()));
}
if (!ignore.contains("comments")) { if (!ignore.contains("comments")) {
entry.getMetadata().put("comments", commentManager.count(entry.getId())); entry.getMetadata().put("comments", commentManager.count(entry.getId()));
} }
@ -421,7 +496,10 @@ public class EntryManager {
* @return the entry * @return the entry
*/ */
public Entry save(Entry entry) { public Entry save(Entry entry) {
return entryRepository.save(entry); List<String> tags = Lists.newArrayList(entry.getTags());
entry = entryRepository.save(entry);
tagManager.setForTarget(entry.getId(), tags);
return entry;
} }
/** /**
@ -430,6 +508,7 @@ public class EntryManager {
* @param entry the entry * @param entry the entry
*/ */
public void delete(Entry entry) { public void delete(Entry entry) {
tagManager.deleteByTarget(entry.getId());
commentManager.deleteByTarget(entry.getId()); commentManager.deleteByTarget(entry.getId());
voteManager.deleteByTarget(entry.getId(), Types.entry); voteManager.deleteByTarget(entry.getId(), Types.entry);
bookmarksManager.removeEntry(entry.getId()); bookmarksManager.removeEntry(entry.getId());

View File

@ -0,0 +1,96 @@
/**
*
*/
package de.bstly.board.businesslogic;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.querydsl.jpa.impl.JPAQueryFactory;
import de.bstly.board.model.QTag;
import de.bstly.board.model.Tag;
import de.bstly.board.repository.TagRepository;
/**
* The Class TagManager.
*/
@Component
public class TagManager {
@Autowired
private JPAQueryFactory jpaQueryFactory;
@Autowired
private TagRepository tagRepository;
private QTag qTag = QTag.tag1;
/**
* Creates the.
*
* @param tag the tag
* @param target the target
* @return the tag
*/
public Tag create(String tag, Long target) {
return tagRepository.save(new Tag(tag, target));
}
/**
* Delete.
*
* @param tag the tag
* @param target the target
*/
public void delete(String tag, Long target) {
tagRepository.deleteById(new Tag(tag, target));
}
/**
* Gets the for target.
*
* @param target the target
* @return the for target
*/
public List<String> getForTarget(Long target) {
return jpaQueryFactory.selectFrom(qTag).where(qTag.target.eq(target)).select(qTag.tag)
.fetch();
}
/**
* Sets the for target.
*
* @param target the target
* @param tags the tags
*/
public void setForTarget(Long target, List<String> tags) {
deleteByTarget(target);
if (tags != null) {
for (String tag : tags) {
create(tag, target);
}
}
}
/**
* Delete by target.
*
* @param target the target
*/
public void deleteByTarget(Long target) {
tagRepository.deleteAll(tagRepository.findAll(qTag.target.eq(target)));
}
/**
* Search.
*
* @param search the search
* @return the list
*/
public List<String> search(String search) {
return jpaQueryFactory.selectFrom(qTag).where(qTag.tag.containsIgnoreCase(search))
.distinct().limit(10).select(qTag.tag).fetch();
}
}

View File

@ -125,6 +125,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)
@ -224,6 +230,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()

View File

@ -67,7 +67,9 @@ public class EntryController extends BaseController {
* @param pageParameter the page parameter * @param pageParameter the page parameter
* @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 gravityParameter the gravity parameter * @param gravityParameter the gravity parameter
* @param ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
* @return the page * @return the page
*/ */
@ -76,7 +78,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("gravity") Optional<Double> gravityParameter, @RequestParam("gravity") Optional<Double> gravityParameter,
@RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
if (sizeParameter.isPresent() && sizeParameter.get() > 100) { if (sizeParameter.isPresent() && sizeParameter.get() > 100) {
@ -92,9 +96,9 @@ public class EntryController extends BaseController {
} }
Page<Entry> entries = entryManager.fetchByRanking(getCurrentUsername(), Page<Entry> entries = entryManager.fetchByRanking(getCurrentUsername(),
dateParameter.orElse(null), FlaggedStatus.NORMAL, dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null),
gravityParameter.orElse(getGravity()), pageParameter.orElse(0), gravityParameter.orElse(getGravity()), pageParameter.orElse(0),
sizeParameter.orElse(settingsManager.getPageSize())); sizeParameter.orElse(settingsManager.getPageSize()), ascParameter.orElse(false));
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList()); List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()), entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
@ -108,6 +112,8 @@ public class EntryController extends BaseController {
* @param pageParameter the page parameter * @param pageParameter the page parameter
* @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 ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
* @return the page * @return the page
*/ */
@ -116,6 +122,8 @@ 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("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
if (sizeParameter.isPresent() && sizeParameter.get() > 100) { if (sizeParameter.isPresent() && sizeParameter.get() > 100) {
@ -127,8 +135,9 @@ public class EntryController extends BaseController {
} }
Page<Entry> entries = entryManager.fetchByDate(getCurrentUsername(), Page<Entry> entries = entryManager.fetchByDate(getCurrentUsername(),
dateParameter.orElse(null), FlaggedStatus.NORMAL, pageParameter.orElse(0), dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null),
sizeParameter.orElse(settingsManager.getPageSize())); pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false));
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList()); List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()), entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
entries.getContent(), ignore); entries.getContent(), ignore);
@ -141,7 +150,9 @@ public class EntryController extends BaseController {
* @param pageParameter the page parameter * @param pageParameter the page parameter
* @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 gravityParameter the gravity parameter * @param gravityParameter the gravity parameter
* @param ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
* @return the page * @return the page
*/ */
@ -150,7 +161,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("gravity") Optional<Double> gravityParameter, @RequestParam("gravity") Optional<Double> gravityParameter,
@RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
if (sizeParameter.isPresent() && sizeParameter.get() > 100) { if (sizeParameter.isPresent() && sizeParameter.get() > 100) {
@ -162,9 +175,9 @@ public class EntryController extends BaseController {
} }
Page<Entry> entries = entryManager.fetchByComments(getCurrentUsername(), Page<Entry> entries = entryManager.fetchByComments(getCurrentUsername(),
dateParameter.orElse(null), FlaggedStatus.NORMAL, dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null),
gravityParameter.orElse(getGravity()), pageParameter.orElse(0), gravityParameter.orElse(getGravity()), pageParameter.orElse(0),
sizeParameter.orElse(settingsManager.getPageSize())); sizeParameter.orElse(settingsManager.getPageSize()), ascParameter.orElse(false));
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList()); List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()), entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
@ -178,6 +191,8 @@ public class EntryController extends BaseController {
* @param pageParameter the page parameter * @param pageParameter the page parameter
* @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 ascParameter the asc parameter
* @param ignoreParameter the ignore parameter * @param ignoreParameter the ignore parameter
* @return the page * @return the page
*/ */
@ -186,6 +201,8 @@ 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("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
if (sizeParameter.isPresent() && sizeParameter.get() > 100) { if (sizeParameter.isPresent() && sizeParameter.get() > 100) {
@ -197,8 +214,9 @@ public class EntryController extends BaseController {
} }
Page<Entry> entries = entryManager.fetchByLastComment(getCurrentUsername(), Page<Entry> entries = entryManager.fetchByLastComment(getCurrentUsername(),
dateParameter.orElse(null), FlaggedStatus.NORMAL, pageParameter.orElse(0), dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null),
sizeParameter.orElse(settingsManager.getPageSize())); pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false));
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList()); List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()), entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
@ -213,6 +231,7 @@ public class EntryController extends BaseController {
* @param pageParameter the page parameter * @param pageParameter the page parameter
* @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 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
@ -223,6 +242,7 @@ 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("asc") Optional<Boolean> ascParameter, @RequestParam("asc") Optional<Boolean> ascParameter,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
@ -234,9 +254,10 @@ public class EntryController extends BaseController {
dateParameter = Optional.of(Instant.now()); dateParameter = Optional.of(Instant.now());
} }
Page<Entry> entries = entryManager.fetchByUser(username, Page<Entry> entries = entryManager.fetchByUser(getCurrentUsername(), username,
dateParameter.orElse(Instant.now()), pageParameter.orElse(0), dateParameter.orElse(null), FlaggedStatus.NORMAL, tagParameter.orElse(null),
sizeParameter.orElse(settingsManager.getPageSize()), ascParameter.orElse(false)); pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()),
ascParameter.orElse(false));
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList()); List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()), entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
entries.getContent(), ignore); entries.getContent(), ignore);
@ -319,8 +340,8 @@ public class EntryController extends BaseController {
@PatchMapping @PatchMapping
public Entry updateEntry(@RequestBody Entry entry, public Entry updateEntry(@RequestBody Entry entry,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) { @RequestParam("ignore") Optional<List<String>> ignoreParameter) {
Entry orgEnry = entryManager.get(entry.getId()); Entry orgEntry = entryManager.get(entry.getId());
if (orgEnry == null || !orgEnry.getAuthor().equals(getCurrentUsername()) || orgEnry if (orgEntry == null || !orgEntry.getAuthor().equals(getCurrentUsername()) || orgEntry
.getCreated().plus(getEntryDelay(), ChronoUnit.MINUTES).isBefore(Instant.now())) { .getCreated().plus(getEntryDelay(), ChronoUnit.MINUTES).isBefore(Instant.now())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN); throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
} }
@ -333,15 +354,16 @@ public class EntryController extends BaseController {
HttpStatus.UNPROCESSABLE_ENTITY); HttpStatus.UNPROCESSABLE_ENTITY);
} }
orgEnry.setUrl(entry.getUrl()); orgEntry.setUrl(entry.getUrl());
orgEnry.setTitle(entry.getTitle().trim()); orgEntry.setTitle(entry.getTitle().trim());
orgEnry.setText(entry.getText().trim()); orgEntry.setText(entry.getText().trim());
orgEnry = entryManager.save(orgEnry); orgEntry.setTags(entry.getTags());
orgEntry = entryManager.save(orgEntry);
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList()); List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()), entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
entry, ignore); orgEntry, ignore);
return entry; return orgEntry;
} }
/** /**

View File

@ -0,0 +1,93 @@
/**
*
*/
package de.bstly.board.controller;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
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 com.google.common.collect.Lists;
import de.bstly.board.businesslogic.EntryManager;
import de.bstly.board.businesslogic.TagManager;
import de.bstly.board.businesslogic.UserManager;
import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.controller.support.RequestBodyErrors;
import de.bstly.board.controller.validation.EntryValidator;
import de.bstly.board.model.Entry;
/**
* The Class TagController.
*/
@RestController
@RequestMapping("/tags")
public class TagController extends BaseController {
@Autowired
private TagManager tagManager;
@Autowired
private EntryManager entryManager;
@Autowired
private UserManager userManager;
@Autowired
private EntryValidator entryValidator;
/**
* Search.
*
* @param query the query
* @return the list
*/
@PreAuthorize("isAuthenticated()")
@GetMapping
public List<String> search(@RequestParam("q") String query) {
return tagManager.search(query);
}
/**
* Sets the tags.
*
* @param id the id
* @param tags the tags
* @param ignoreParameter the ignore parameter
* @return the entry
*/
@PreAuthorize("isAuthenticated()")
@PatchMapping("/entry/{id}")
public Entry setTags(@PathVariable("id") Long id, @RequestBody List<String> tags,
@RequestParam("ignore") Optional<List<String>> ignoreParameter) {
Entry entry = entryManager.get(id);
if (entry == null || !entry.getAuthor().equals(getCurrentUsername())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
}
entry.setTags(tags);
RequestBodyErrors bindingResult = new RequestBodyErrors(entry);
entryValidator.validate(entry, bindingResult);
if (bindingResult.hasErrors()) {
throw new EntityResponseStatusException(bindingResult.getAllErrors(),
HttpStatus.UNPROCESSABLE_ENTITY);
}
entry = entryManager.save(entry);
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
entry, ignore);
return entry;
}
}

View File

@ -52,6 +52,14 @@ public class EntryValidator implements Validator {
if (StringUtils.hasText(entry.getUrl()) && !urlValidator.isValid(entry.getUrl())) { if (StringUtils.hasText(entry.getUrl()) && !urlValidator.isValid(entry.getUrl())) {
errors.rejectValue("url", "INVALID"); errors.rejectValue("url", "INVALID");
} }
if (entry.getTags() != null) {
for (String tag : entry.getTags()) {
if (tag.contains("#")) {
errors.rejectValue("tags", "INVALID", tag);
}
}
}
} }
} }

View File

@ -4,6 +4,7 @@
package de.bstly.board.model; package de.bstly.board.model;
import java.time.Instant; import java.time.Instant;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.Column; import javax.persistence.Column;
@ -55,6 +56,8 @@ public class Entry {
@Column(name = "text") @Column(name = "text")
private String text; private String text;
@Transient @Transient
private List<String> tags;
@Transient
private Double ranking; private Double ranking;
@Transient @Transient
private Long points; private Long points;
@ -223,6 +226,24 @@ public class Entry {
this.text = text; this.text = text;
} }
/**
* 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 ranking. * Gets the ranking.
* *

View File

@ -0,0 +1,89 @@
/**
*
*/
package de.bstly.board.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
/**
* The Class Tag.
*/
@Entity
@Table(name = "tags")
@IdClass(Tag.class)
public class Tag implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name = "tag", nullable = false)
private String tag;
@Id
@Column(name = "target", nullable = false)
private Long target;
/**
* Instantiates a new tag.
*/
public Tag() {
super();
}
/**
* Instantiates a new tag.
*
* @param tag the tag
* @param target the target
*/
public Tag(String tag, Long target) {
super();
this.tag = tag;
this.target = target;
}
/**
* Gets the tag.
*
* @return the tag
*/
public String getTag() {
return tag;
}
/**
* Sets the tag.
*
* @param tag the new tag
*/
public void setTag(String tag) {
this.tag = tag;
}
/**
* Gets the target.
*
* @return the target
*/
public Long getTarget() {
return target;
}
/**
* Sets the target.
*
* @param target the new target
*/
public void setTarget(Long target) {
this.target = target;
}
}

View File

@ -0,0 +1,18 @@
/**
*
*/
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.Tag;
/**
* The Interface TagRepository.
*/
@Repository
public interface TagRepository extends JpaRepository<Tag, Tag>, QuerydslPredicateExecutor<Tag> {
}