improvements + bookmarks
This commit is contained in:
parent
1fc18fdeb2
commit
d3f6c86db6
@ -8,15 +8,15 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spring-cachet-monitoring@champonthis.de
|
||||
*
|
||||
* The Class Application.
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class Application extends SpringBootServletInitializer {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
* The main method.
|
||||
*
|
||||
* @param args the arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
|
@ -13,8 +13,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class JPAConfig.
|
||||
*/
|
||||
@Configuration
|
||||
@EnableJpaAuditing()
|
||||
@ -23,6 +22,11 @@ public class JPAConfig {
|
||||
@Autowired
|
||||
private EntityManager em;
|
||||
|
||||
/**
|
||||
* Jpa query factory.
|
||||
*
|
||||
* @return the JPA query factory
|
||||
*/
|
||||
@Bean
|
||||
public JPAQueryFactory jpaQueryFactory() {
|
||||
return new JPAQueryFactory(em);
|
||||
|
@ -12,17 +12,22 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class MessageSourceConfig.
|
||||
*/
|
||||
@Configuration
|
||||
public class MessageSourceConfig {
|
||||
|
||||
@Value("${bstly.board.title:bstlboard}")
|
||||
private String title;
|
||||
|
||||
@Value("${bstly.board.url:http://localhost:8080}")
|
||||
private String baseUrl;
|
||||
|
||||
/**
|
||||
* Message source.
|
||||
*
|
||||
* @return the message source
|
||||
*/
|
||||
@Bean
|
||||
public MessageSource messageSource() {
|
||||
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
|
||||
|
@ -0,0 +1,97 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.board.businesslogic;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.bstly.board.model.Bookmarks;
|
||||
import de.bstly.board.model.QBookmarks;
|
||||
import de.bstly.board.repository.BookmarksRepository;
|
||||
import de.bstly.board.repository.EntryRepository;
|
||||
import de.bstly.board.repository.LocalUserRepository;
|
||||
|
||||
/**
|
||||
* The Class BookmarksManager.
|
||||
*/
|
||||
@Component
|
||||
public class BookmarksManager {
|
||||
|
||||
@Autowired
|
||||
private BookmarksRepository bookmarksRepository;
|
||||
@Autowired
|
||||
private EntryRepository entryRepository;
|
||||
@Autowired
|
||||
private LocalUserRepository localUserRepository;
|
||||
private QBookmarks qBookmarks = QBookmarks.bookmarks;
|
||||
|
||||
/**
|
||||
* Gets the.
|
||||
*
|
||||
* @param username the username
|
||||
* @return the bookmarks
|
||||
*/
|
||||
public Bookmarks get(String username) {
|
||||
return bookmarksRepository.findById(username).orElse(new Bookmarks(username));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for entry.
|
||||
*
|
||||
* @param username the username
|
||||
* @param entryId the entry id
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean hasEntry(String username, Long entryId) {
|
||||
return bookmarksRepository
|
||||
.exists(qBookmarks.username.eq(username).and(qBookmarks.entries.contains(entryId)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the entry.
|
||||
*
|
||||
* @param username the username
|
||||
* @param entryId the entry id
|
||||
*/
|
||||
public void addEntry(String username, Long entryId) {
|
||||
Assert.isTrue(entryRepository.existsById(entryId), "Invalid entryid");
|
||||
Assert.isTrue(localUserRepository.existsById(username), "Invalid username");
|
||||
Bookmarks bookmarks = get(username);
|
||||
|
||||
if (bookmarks.getEntries() == null) {
|
||||
bookmarks.setEntries(Lists.newArrayList());
|
||||
}
|
||||
|
||||
if (!hasEntry(username, entryId)) {
|
||||
bookmarks.getEntries().add(entryId);
|
||||
bookmarksRepository.save(bookmarks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the entry.
|
||||
*
|
||||
* @param username the username
|
||||
* @param entryId the entry id
|
||||
*/
|
||||
public void removeEntry(String username, Long entryId) {
|
||||
Assert.isTrue(entryRepository.existsById(entryId), "Invalid entryid");
|
||||
Assert.isTrue(localUserRepository.existsById(username), "Invalid username");
|
||||
|
||||
Bookmarks bookmarks = get(username);
|
||||
|
||||
if (bookmarks.getEntries() == null) {
|
||||
bookmarks.setEntries(Lists.newArrayList());
|
||||
}
|
||||
|
||||
if (hasEntry(username, entryId)) {
|
||||
bookmarks.getEntries().remove(entryId);
|
||||
bookmarksRepository.save(bookmarks);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -22,28 +22,34 @@ import de.bstly.board.repository.CommentRepository;
|
||||
import de.bstly.board.repository.VoteRepository;
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class CommentManager.
|
||||
*/
|
||||
@Component
|
||||
public class CommentManager {
|
||||
|
||||
@Autowired
|
||||
private CommentRepository commentRepository;
|
||||
|
||||
@Autowired
|
||||
private VoteRepository voteRepository;
|
||||
|
||||
@Autowired
|
||||
private VoteManager voteManager;
|
||||
|
||||
private QComment qComment = QComment.comment;
|
||||
|
||||
private QVote qVote = QVote.vote;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param parent
|
||||
* @param target
|
||||
* @param page
|
||||
* @param size
|
||||
* @return
|
||||
* Fetch by ranking.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @param date the date
|
||||
* @param gravity the gravity
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
|
||||
public Page<Comment> fetchByRanking(Long target, Long parent, Instant date, double gravity,
|
||||
@ -58,11 +64,14 @@ public class CommentManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @param order
|
||||
* @return
|
||||
* Fetch by date.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @param date the date
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<Comment> fetchByDate(Long target, Long parent, Instant date, int page, int size) {
|
||||
if (parent == null) {
|
||||
@ -79,10 +88,11 @@ public class CommentManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @param parent
|
||||
* @return
|
||||
* Count.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @return the long
|
||||
*/
|
||||
public Long count(Long target, Long parent) {
|
||||
if (parent == null) {
|
||||
@ -93,18 +103,20 @@ public class CommentManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @return
|
||||
* Count.
|
||||
*
|
||||
* @param target the target
|
||||
* @return the long
|
||||
*/
|
||||
public Long count(Long target) {
|
||||
return commentRepository.count(qComment.target.eq(target));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param username
|
||||
* @param comment
|
||||
* Apply metadata.
|
||||
*
|
||||
* @param username the username
|
||||
* @param comment the comment
|
||||
*/
|
||||
public void applyMetadata(String username, Comment comment) {
|
||||
if (!comment.getMetadata().containsKey("comments")) {
|
||||
@ -114,21 +126,21 @@ public class CommentManager {
|
||||
comment.getMetadata().put("points",
|
||||
voteManager.getPoints(comment.getId(), Types.comment));
|
||||
}
|
||||
|
||||
|
||||
if (!comment.getMetadata().containsKey("upvoted")) {
|
||||
comment.getMetadata().put("upvoted",
|
||||
voteRepository.exists(qVote.target.eq(comment.getId())
|
||||
.and(qVote.targetType.eq(Types.comment)).and(qVote.type.eq(VoteType.up))
|
||||
.and(qVote.author.eq(username))));
|
||||
}
|
||||
|
||||
|
||||
if (!comment.getMetadata().containsKey("downvoted")) {
|
||||
comment.getMetadata().put("downvoted",
|
||||
voteRepository.exists(qVote.target.eq(comment.getId())
|
||||
.and(qVote.targetType.eq(Types.comment))
|
||||
.and(qVote.type.eq(VoteType.down)).and(qVote.author.eq(username))));
|
||||
}
|
||||
|
||||
|
||||
if (!comment.getMetadata().containsKey("unvote")) {
|
||||
comment.getMetadata().put("unvote",
|
||||
voteRepository.exists(
|
||||
@ -138,8 +150,10 @@ public class CommentManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entries
|
||||
* Apply metadata.
|
||||
*
|
||||
* @param username the username
|
||||
* @param entries the entries
|
||||
*/
|
||||
public void applyMetadata(String username, List<Comment> entries) {
|
||||
for (Comment comment : entries) {
|
||||
@ -148,33 +162,40 @@ public class CommentManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
* Exists.
|
||||
*
|
||||
* @param id the id
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean exists(Long id) {
|
||||
return commentRepository.existsById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
* Gets the.
|
||||
*
|
||||
* @param id the id
|
||||
* @return the comment
|
||||
*/
|
||||
public Comment get(Long id) {
|
||||
return commentRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param comment
|
||||
* @return
|
||||
* Save.
|
||||
*
|
||||
* @param comment the comment
|
||||
* @return the comment
|
||||
*/
|
||||
public Comment save(Comment comment) {
|
||||
return commentRepository.save(comment);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param commentId
|
||||
* @return
|
||||
* Gets the points.
|
||||
*
|
||||
* @param commentId the comment id
|
||||
* @return the points
|
||||
*/
|
||||
public long getPoints(Long commentId) {
|
||||
long upvotes = voteRepository.count(qVote.targetType.eq(Types.comment)
|
||||
@ -185,8 +206,9 @@ public class CommentManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param comment
|
||||
* Delete.
|
||||
*
|
||||
* @param comment the comment
|
||||
*/
|
||||
public void delete(Comment comment) {
|
||||
for (Comment subcomment : commentRepository.findAll(qComment.parent.eq(comment.getId()))) {
|
||||
@ -199,8 +221,9 @@ public class CommentManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* Delete by target.
|
||||
*
|
||||
* @param target the target
|
||||
*/
|
||||
public void deleteByTarget(Long target) {
|
||||
for (Comment comment : commentRepository.findAll(qComment.target.eq(target))) {
|
||||
|
@ -14,6 +14,9 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.bstly.board.model.Bookmarks;
|
||||
import de.bstly.board.model.Entry;
|
||||
import de.bstly.board.model.QEntry;
|
||||
import de.bstly.board.model.QVote;
|
||||
@ -24,8 +27,7 @@ import de.bstly.board.repository.EntryRepository;
|
||||
import de.bstly.board.repository.VoteRepository;
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class EntryManager.
|
||||
*/
|
||||
@Component
|
||||
public class EntryManager {
|
||||
@ -38,29 +40,39 @@ public class EntryManager {
|
||||
private VoteManager voteManager;
|
||||
@Autowired
|
||||
private VoteRepository voteRepository;
|
||||
@Autowired
|
||||
private BookmarksManager bookmarksManager;
|
||||
|
||||
private QEntry qEntry = QEntry.entry;
|
||||
|
||||
private QVote qVote = QVote.vote;
|
||||
|
||||
@Value("${bstly.board.ranking.gravity:1.8}")
|
||||
private double GRAVITY;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @return
|
||||
* Direct fetch by ranking.
|
||||
*
|
||||
* @param date the date
|
||||
* @param gravity the gravity
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<Entry> fetchByRanking(int page, int size) {
|
||||
return entryRepository.findAll(
|
||||
PageRequest.of(page, size, Sort.by(Order.desc("ranking"), Order.desc("created"))));
|
||||
public Page<RankedEntry> fetchByRanking(Instant date, double gravity, int page,
|
||||
int size) {
|
||||
return entryRepository.findAllByRanking(date, gravity, PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @param order
|
||||
* @return
|
||||
* Fetch by date.
|
||||
*
|
||||
* @param date the date
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<Entry> fetchByDate(Instant date, int page, int size) {
|
||||
return entryRepository.findAll(qEntry.created.before(date),
|
||||
@ -68,53 +80,69 @@ public class EntryManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @return
|
||||
* Gets the entries.
|
||||
*
|
||||
* @param username the username
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the entries
|
||||
*/
|
||||
public Page<RankedEntry> directFetchByRanking(Instant date, double gravity, int page,
|
||||
int size) {
|
||||
return entryRepository.findAllByRanking(date, gravity, PageRequest.of(page, size));
|
||||
public Page<Entry> fetchByBookmarks(String username, int page, int size) {
|
||||
Bookmarks bookmarks = bookmarksManager.get(username);
|
||||
|
||||
if (bookmarks.getEntries() == null) {
|
||||
bookmarks.setEntries(Lists.newArrayList());
|
||||
}
|
||||
|
||||
return entryRepository.findAll(qEntry.id.in(bookmarks.getEntries()),
|
||||
PageRequest.of(page, size, Sort.by(Order.desc("created"))));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entry
|
||||
* Apply metadata.
|
||||
*
|
||||
* @param username the username
|
||||
* @param entry the entry
|
||||
*/
|
||||
public void applyMetadata(String username, Entry entry) {
|
||||
if (!entry.getMetadata().containsKey("comments")) {
|
||||
entry.getMetadata().put("comments", commentManager.count(entry.getId()));
|
||||
}
|
||||
|
||||
if (!entry.getMetadata().containsKey("points")) {
|
||||
entry.getMetadata().put("points", voteManager.getPoints(entry.getId(), Types.entry));
|
||||
}
|
||||
|
||||
|
||||
if (!entry.getMetadata().containsKey("bookmarked")) {
|
||||
entry.getMetadata().put("bookmarked",
|
||||
bookmarksManager.hasEntry(username, entry.getId()));
|
||||
}
|
||||
|
||||
if (!entry.getMetadata().containsKey("upvoted")) {
|
||||
entry.getMetadata().put("upvoted",
|
||||
voteRepository.exists(qVote.target.eq(entry.getId())
|
||||
.and(qVote.targetType.eq(Types.entry)).and(qVote.type.eq(VoteType.up))
|
||||
.and(qVote.author.eq(username))));
|
||||
}
|
||||
|
||||
|
||||
if (!entry.getMetadata().containsKey("downvoted")) {
|
||||
entry.getMetadata().put("downvoted",
|
||||
voteRepository.exists(qVote.target.eq(entry.getId())
|
||||
.and(qVote.targetType.eq(Types.entry))
|
||||
.and(qVote.type.eq(VoteType.down)).and(qVote.author.eq(username))));
|
||||
.and(qVote.targetType.eq(Types.entry)).and(qVote.type.eq(VoteType.down))
|
||||
.and(qVote.author.eq(username))));
|
||||
}
|
||||
|
||||
|
||||
if (!entry.getMetadata().containsKey("unvote")) {
|
||||
entry.getMetadata().put("unvote",
|
||||
voteRepository.exists(
|
||||
qVote.target.eq(entry.getId()).and(qVote.targetType.eq(Types.entry))
|
||||
.and(qVote.author.eq(username))));
|
||||
entry.getMetadata().put("unvote", voteRepository.exists(qVote.target.eq(entry.getId())
|
||||
.and(qVote.targetType.eq(Types.entry)).and(qVote.author.eq(username))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entries
|
||||
* Apply metadata.
|
||||
*
|
||||
* @param username the username
|
||||
* @param entries the entries
|
||||
*/
|
||||
public void applyMetadata(String username, List<Entry> entries) {
|
||||
for (Entry entry : entries) {
|
||||
@ -123,32 +151,39 @@ public class EntryManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
* Exists.
|
||||
*
|
||||
* @param id the id
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean exists(Long id) {
|
||||
return entryRepository.existsById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
* Gets the.
|
||||
*
|
||||
* @param id the id
|
||||
* @return the entry
|
||||
*/
|
||||
public Entry get(Long id) {
|
||||
return entryRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entry
|
||||
* @return
|
||||
* Save.
|
||||
*
|
||||
* @param entry the entry
|
||||
* @return the entry
|
||||
*/
|
||||
public Entry save(Entry entry) {
|
||||
return entryRepository.save(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entry
|
||||
* Delete.
|
||||
*
|
||||
* @param entry the entry
|
||||
*/
|
||||
public void delete(Entry entry) {
|
||||
commentManager.deleteByTarget(entry.getId());
|
||||
@ -157,9 +192,10 @@ public class EntryManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entryId
|
||||
* @return
|
||||
* Gets the points.
|
||||
*
|
||||
* @param entryId the entry id
|
||||
* @return the points
|
||||
*/
|
||||
public long getPoints(Long entryId) {
|
||||
long upvotes = voteRepository.count(qVote.targetType.eq(Types.entry)
|
||||
|
@ -12,48 +12,51 @@ import java.time.temporal.TemporalAmount;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class InstantHelper.
|
||||
*/
|
||||
public class InstantHelper {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param amount
|
||||
* @return
|
||||
* Plus.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param amount the amount
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant plus(Instant instant, TemporalAmount amount) {
|
||||
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amount).toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param amountToAdd
|
||||
* @param unit
|
||||
* @return
|
||||
* Plus.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param amountToAdd the amount to add
|
||||
* @param unit the unit
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant plus(Instant instant, long amountToAdd, TemporalUnit unit) {
|
||||
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amountToAdd, unit).toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param amount
|
||||
* @return
|
||||
* Minus.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param amount the amount
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant minus(Instant instant, TemporalAmount amount) {
|
||||
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amount).toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param amountToAdd
|
||||
* @param unit
|
||||
* @return
|
||||
* Minus.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param amountToAdd the amount to add
|
||||
* @param unit the unit
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant minus(Instant instant, long amountToAdd, TemporalUnit unit) {
|
||||
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amountToAdd, unit)
|
||||
@ -61,10 +64,11 @@ public class InstantHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param unit
|
||||
* @return
|
||||
* Truncate.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param unit the unit
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant truncate(Instant instant, TemporalUnit unit) {
|
||||
if (ChronoUnit.YEARS.equals(unit)) {
|
||||
|
@ -34,8 +34,7 @@ import de.bstly.board.repository.EntryRepository;
|
||||
import de.bstly.board.repository.LocalUserRepository;
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class UserManager.
|
||||
*/
|
||||
@Service
|
||||
public class UserManager implements UserDetailsService, SmartInitializingSingleton {
|
||||
@ -44,18 +43,27 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
|
||||
|
||||
@Autowired
|
||||
private LocalUserRepository localUserRepository;
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Autowired
|
||||
private EntryManager entryManager;
|
||||
|
||||
@Autowired
|
||||
private EntryRepository entryRepository;
|
||||
|
||||
private QLocalUser qLocalUser = QLocalUser.localUser;
|
||||
|
||||
private QEntry qEntry = QEntry.entry;
|
||||
|
||||
@Value("${admin.password:}")
|
||||
private String adminPassword;
|
||||
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#
|
||||
* loadUserByUsername(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see
|
||||
* de.bstly.board.businesslogic.LocalUserManager#loadUserByUsername(java.lang.
|
||||
@ -79,6 +87,10 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
|
||||
return new User(username, localUser.getPasswordHash(), authorities);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#
|
||||
* afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#
|
||||
@ -102,27 +114,30 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
* Gets the by username.
|
||||
*
|
||||
* @param username the username
|
||||
* @return the by username
|
||||
*/
|
||||
public LocalUser getByUsername(String username) {
|
||||
return localUserRepository.findById(username).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param externalId
|
||||
* @return
|
||||
* Gets the by external id.
|
||||
*
|
||||
* @param externalId the external id
|
||||
* @return the by external id
|
||||
*/
|
||||
public LocalUser getByExternalId(String externalId) {
|
||||
return localUserRepository.findOne(qLocalUser.externalId.eq(externalId)).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param authentication
|
||||
* @return
|
||||
* Gets the by auth.
|
||||
*
|
||||
* @param authentication the authentication
|
||||
* @return the by auth
|
||||
*/
|
||||
public LocalUser getByAuth(Authentication authentication) {
|
||||
if (authentication != null) {
|
||||
@ -181,8 +196,10 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param user
|
||||
* Apply metadata.
|
||||
*
|
||||
* @param username the username
|
||||
* @param user the user
|
||||
*/
|
||||
public void applyMetadata(String username, LocalUser user) {
|
||||
if (user.getUsername().equals(username) && !user.getMetadata().containsKey("self")) {
|
||||
@ -199,17 +216,20 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param localUser
|
||||
* @return
|
||||
* Save.
|
||||
*
|
||||
* @param localUser the local user
|
||||
* @return the local user
|
||||
*/
|
||||
public LocalUser save(LocalUser localUser) {
|
||||
return localUserRepository.save(localUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param username
|
||||
* @return
|
||||
* Exists.
|
||||
*
|
||||
* @param username the username
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean exists(String username) {
|
||||
return localUserRepository.existsById(username);
|
||||
|
@ -13,22 +13,23 @@ import de.bstly.board.model.VoteType;
|
||||
import de.bstly.board.repository.VoteRepository;
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class VoteManager.
|
||||
*/
|
||||
@Component
|
||||
public class VoteManager {
|
||||
|
||||
@Autowired
|
||||
private VoteRepository voteRepository;
|
||||
|
||||
private QVote qVote = QVote.vote;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param author
|
||||
* @param targetType
|
||||
* @param target
|
||||
* @return
|
||||
* Gets the.
|
||||
*
|
||||
* @param author the author
|
||||
* @param targetType the target type
|
||||
* @param target the target
|
||||
* @return the vote
|
||||
*/
|
||||
public Vote get(String author, Types targetType, Long target) {
|
||||
return voteRepository.findOne(qVote.author.eq(author).and(qVote.targetType.eq(targetType))
|
||||
@ -36,25 +37,29 @@ public class VoteManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param vote
|
||||
* @return
|
||||
* Save.
|
||||
*
|
||||
* @param vote the vote
|
||||
* @return the vote
|
||||
*/
|
||||
public Vote save(Vote vote) {
|
||||
return voteRepository.save(vote);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param vote
|
||||
* Delete.
|
||||
*
|
||||
* @param vote the vote
|
||||
*/
|
||||
public void delete(Vote vote) {
|
||||
voteRepository.delete(vote);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param vote
|
||||
* Delete by target.
|
||||
*
|
||||
* @param target the target
|
||||
* @param targetType the target type
|
||||
*/
|
||||
public void deleteByTarget(Long target, Types targetType) {
|
||||
for (Vote vote : voteRepository
|
||||
@ -64,10 +69,11 @@ public class VoteManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @param targetType
|
||||
* @return
|
||||
* Gets the points.
|
||||
*
|
||||
* @param target the target
|
||||
* @param targetType the target type
|
||||
* @return the points
|
||||
*/
|
||||
public Long getPoints(Long target, Types targetType) {
|
||||
return voteRepository
|
||||
|
@ -11,49 +11,53 @@ import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAmount;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class InstantHelper.
|
||||
*/
|
||||
public class InstantHelper {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param amount
|
||||
* @return
|
||||
* Plus.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param amount the amount
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant plus(Instant instant, TemporalAmount amount) {
|
||||
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amount).toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param amountToAdd
|
||||
* @param unit
|
||||
* @return
|
||||
* Plus.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param amountToAdd the amount to add
|
||||
* @param unit the unit
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant plus(Instant instant, long amountToAdd, TemporalUnit unit) {
|
||||
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amountToAdd, unit).toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param amount
|
||||
* @return
|
||||
* Minus.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param amount the amount
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant minus(Instant instant, TemporalAmount amount) {
|
||||
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amount).toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param amountToAdd
|
||||
* @param unit
|
||||
* @return
|
||||
* Minus.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param amountToAdd the amount to add
|
||||
* @param unit the unit
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant minus(Instant instant, long amountToAdd, TemporalUnit unit) {
|
||||
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amountToAdd, unit)
|
||||
@ -61,10 +65,11 @@ public class InstantHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instant
|
||||
* @param unit
|
||||
* @return
|
||||
* Truncate.
|
||||
*
|
||||
* @param instant the instant
|
||||
* @param unit the unit
|
||||
* @return the instant
|
||||
*/
|
||||
public static Instant truncate(Instant instant, TemporalUnit unit) {
|
||||
if (ChronoUnit.YEARS.equals(unit)) {
|
||||
|
@ -17,23 +17,25 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class AuthenticationController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/auth")
|
||||
public class AuthenticationController extends BaseController {
|
||||
|
||||
|
||||
private static String authorizationRequestBaseUri = "oauth2/authorization";
|
||||
|
||||
|
||||
@Autowired
|
||||
private ClientRegistrationRepository clientRegistrationRepository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Me.
|
||||
*
|
||||
* @return the authentication
|
||||
*/
|
||||
@GetMapping
|
||||
public Authentication me() {
|
||||
@ -42,8 +44,9 @@ public class AuthenticationController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Gets the external login urls.
|
||||
*
|
||||
* @return the external login urls
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@GetMapping("external")
|
||||
@ -66,14 +69,22 @@ public class AuthenticationController extends BaseController {
|
||||
return clients;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Class Client.
|
||||
*/
|
||||
protected static class Client {
|
||||
|
||||
|
||||
private String id;
|
||||
|
||||
|
||||
private String loginUrl;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param loginUrl
|
||||
* Instantiates a new client.
|
||||
*
|
||||
* @param id the id
|
||||
* @param loginUrl the login url
|
||||
*/
|
||||
public Client(String id, String loginUrl) {
|
||||
super();
|
||||
@ -82,6 +93,8 @@ public class AuthenticationController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
@ -89,21 +102,27 @@ public class AuthenticationController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
* Sets the id.
|
||||
*
|
||||
* @param id the new id
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the loginUrl
|
||||
* Gets the login url.
|
||||
*
|
||||
* @return the login url
|
||||
*/
|
||||
public String getLoginUrl() {
|
||||
return loginUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loginUrl the loginUrl to set
|
||||
* Sets the login url.
|
||||
*
|
||||
* @param loginUrl the new login url
|
||||
*/
|
||||
public void setLoginUrl(String loginUrl) {
|
||||
this.loginUrl = loginUrl;
|
||||
|
@ -10,18 +10,20 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import de.bstly.board.businesslogic.UserManager;
|
||||
import de.bstly.board.model.LocalUser;
|
||||
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class BaseController.
|
||||
*/
|
||||
public class BaseController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserManager localUserManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Authenticated.
|
||||
*
|
||||
* @return true, if successful
|
||||
*/
|
||||
protected boolean authenticated() {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
@ -29,8 +31,9 @@ public class BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Gets the current username.
|
||||
*
|
||||
* @return the current username
|
||||
*/
|
||||
protected String getCurrentUsername() {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
@ -38,8 +41,9 @@ public class BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Gets the local user.
|
||||
*
|
||||
* @return the local user
|
||||
*/
|
||||
protected LocalUser getLocalUser() {
|
||||
return localUserManager.getByAuth(SecurityContextHolder.getContext().getAuthentication());
|
||||
|
100
src/main/java/de/bstly/board/controller/BookmarksController.java
Normal file
100
src/main/java/de/bstly/board/controller/BookmarksController.java
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.board.controller;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
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.PutMapping;
|
||||
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.BookmarksManager;
|
||||
import de.bstly.board.businesslogic.EntryManager;
|
||||
import de.bstly.board.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.board.model.Entry;
|
||||
|
||||
/**
|
||||
* The Class BookmarksController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/b")
|
||||
public class BookmarksController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private BookmarksManager bookmarksManager;
|
||||
@Autowired
|
||||
private EntryManager entryManager;
|
||||
@Value("${bstly.board.size:30}")
|
||||
private int SIZE;
|
||||
|
||||
/**
|
||||
* Gets the entries.
|
||||
*
|
||||
* @param pageParameter the page parameter
|
||||
* @param sizeParameter the size parameter
|
||||
* @return the entries
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping()
|
||||
public Page<Entry> getEntries(@RequestParam("page") Optional<Integer> pageParameter,
|
||||
@RequestParam("size") Optional<Integer> sizeParameter) {
|
||||
|
||||
if (sizeParameter.isPresent() && sizeParameter.get() > 100) {
|
||||
sizeParameter = Optional.of(100);
|
||||
}
|
||||
|
||||
Page<Entry> entries = entryManager.fetchByBookmarks(getCurrentUsername(),
|
||||
pageParameter.orElse(0), sizeParameter.orElse(SIZE));
|
||||
|
||||
entryManager.applyMetadata(getCurrentUsername(), entries.getContent());
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the entry.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PutMapping("/{id}")
|
||||
public void addEntry(@PathVariable("id") Long id) {
|
||||
if (!entryManager.exists(id)) {
|
||||
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
if (bookmarksManager.hasEntry(getCurrentUsername(), id)) {
|
||||
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
bookmarksManager.addEntry(getCurrentUsername(), id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the entry.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@DeleteMapping("/{id}")
|
||||
public void removeEntry(@PathVariable("id") Long id) {
|
||||
|
||||
if (!entryManager.exists(id)) {
|
||||
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
if (!bookmarksManager.hasEntry(getCurrentUsername(), id)) {
|
||||
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
bookmarksManager.removeEntry(getCurrentUsername(), id);
|
||||
}
|
||||
|
||||
}
|
@ -29,26 +29,45 @@ import de.bstly.board.model.Types;
|
||||
import de.bstly.board.model.Vote;
|
||||
import de.bstly.board.model.VoteType;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class CommentController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/c")
|
||||
public class CommentController extends BaseController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private CommentManager commentManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
private CommentValidator commentValidator;
|
||||
|
||||
|
||||
@Autowired
|
||||
private VoteManager voteManager;
|
||||
|
||||
|
||||
@Value("${bstly.board.size:30}")
|
||||
private int SIZE;
|
||||
|
||||
|
||||
@Value("${bstly.board.ranking.gravity:1.8}")
|
||||
private double GRAVITY;
|
||||
|
||||
/**
|
||||
* Ranked comments.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @param pageParameter the page parameter
|
||||
* @param sizeParameter the size parameter
|
||||
* @param dateParameter the date parameter
|
||||
* @param gravityParameter the gravity parameter
|
||||
* @return the page
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping({ "/e/{target}", "/e/{target}/{parent}" })
|
||||
public Page<Comment> rankedComments(@PathVariable("target") Long target,
|
||||
@ -69,6 +88,13 @@ public class CommentController extends BaseController {
|
||||
// return comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count comments.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @return the long
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping({ "/c/{target}", "/c/{target}/{parent}" })
|
||||
public Long countComments(@PathVariable("target") Long target,
|
||||
@ -76,6 +102,16 @@ public class CommentController extends BaseController {
|
||||
return commentManager.count(target, parent.orElse(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* New comments.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @param pageParameter the page parameter
|
||||
* @param sizeParameter the size parameter
|
||||
* @param dateParameter the date parameter
|
||||
* @return the page
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping({ "/e/new/{target}", "/e/new/{target}/{parent}" })
|
||||
public Page<Comment> newComments(@PathVariable("target") Long target,
|
||||
@ -90,6 +126,12 @@ public class CommentController extends BaseController {
|
||||
return comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the comment.
|
||||
*
|
||||
* @param id the id
|
||||
* @return the comment
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping("/{id}")
|
||||
public Comment getComment(@PathVariable("id") Long id) {
|
||||
@ -104,6 +146,12 @@ public class CommentController extends BaseController {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the comment.
|
||||
*
|
||||
* @param comment the comment
|
||||
* @return the comment
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PostMapping()
|
||||
public Comment createComment(@RequestBody Comment comment) {
|
||||
|
@ -32,61 +32,91 @@ import de.bstly.board.repository.CommentRepository;
|
||||
import de.bstly.board.repository.LocalUserRepository;
|
||||
import de.bstly.board.repository.VoteRepository;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class DebugController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/debug")
|
||||
public class DebugController extends BaseController {
|
||||
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
|
||||
private Logger logger = LogManager.getLogger(DebugController.class);
|
||||
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
|
||||
@Autowired
|
||||
private LocalUserRepository localUserRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private CommentRepository commentRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private VoteRepository voteRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private EntryManager entryManager;
|
||||
|
||||
|
||||
@Value("${debug.random.users:0}")
|
||||
private int users;
|
||||
|
||||
|
||||
@Value("${debug.random.minEntries:0}")
|
||||
private int minEntries;
|
||||
|
||||
|
||||
@Value("${debug.random.maxEntries:10}")
|
||||
private int maxEntries;
|
||||
|
||||
|
||||
@Value("${debug.random.entryAge:63115200}")
|
||||
private long entryAge;
|
||||
|
||||
|
||||
@Value("${debug.random.minComments:0}")
|
||||
private int minComments;
|
||||
|
||||
|
||||
@Value("${debug.random.maxComments:10}")
|
||||
private int maxComments;
|
||||
|
||||
|
||||
@Value("${debug.random.subCommentsFactor:0.5}")
|
||||
private double subCommentsFactor;
|
||||
|
||||
|
||||
@Value("${debug.random.subCommentsThresh:0.3}")
|
||||
private double subCommentsThresh;
|
||||
|
||||
|
||||
@Value("${debug.random.subCommentsDepth:2}")
|
||||
private int subCommentsDepth;
|
||||
|
||||
|
||||
@Value("${debug.random.minUpvotes:5}")
|
||||
private int minUpvotes;
|
||||
|
||||
|
||||
@Value("${debug.random.maxUpvotes:10}")
|
||||
private int maxUpvotes;
|
||||
|
||||
|
||||
@Value("${debug.random.minDownvotes:0}")
|
||||
private int minDownvotes;
|
||||
|
||||
|
||||
@Value("${debug.random.maxDownvotes:10}")
|
||||
private int maxDownvotes;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Random.
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@GetMapping("/random")
|
||||
@ -120,6 +150,12 @@ public class DebugController extends BaseController {
|
||||
logger.warn("finished random generation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Entries.
|
||||
*
|
||||
* @param username the username
|
||||
* @param userCount the user count
|
||||
*/
|
||||
protected void entries(String username, long userCount) {
|
||||
long numEntries = RandomUtils.nextLong(minEntries, maxEntries);
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
@ -145,6 +181,13 @@ public class DebugController extends BaseController {
|
||||
+ "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Comments.
|
||||
*
|
||||
* @param target the target
|
||||
* @param date the date
|
||||
* @param userCount the user count
|
||||
*/
|
||||
protected void comments(Long target, Instant date, long userCount) {
|
||||
long numComments = RandomUtils.nextLong(minComments, maxComments);
|
||||
logger.debug("Create "
|
||||
@ -171,6 +214,17 @@ public class DebugController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub comments.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @param date the date
|
||||
* @param factor the factor
|
||||
* @param thresh the thresh
|
||||
* @param depth the depth
|
||||
* @param userCount the user count
|
||||
*/
|
||||
protected void subComments(Long target, Long parent, Instant date, double factor, double thresh,
|
||||
int depth, long userCount) {
|
||||
if (depth < subCommentsDepth && RandomUtils.nextDouble(0, 1) < thresh) {
|
||||
@ -201,6 +255,13 @@ public class DebugController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Votes.
|
||||
*
|
||||
* @param target the target
|
||||
* @param targetType the target type
|
||||
* @param userCount the user count
|
||||
*/
|
||||
protected void votes(Long target, Types targetType, long userCount) {
|
||||
long numUpvotes = RandomUtils.nextLong(minUpvotes, maxUpvotes);
|
||||
logger.debug("Create "
|
||||
|
@ -34,8 +34,7 @@ import de.bstly.board.model.Vote;
|
||||
import de.bstly.board.model.VoteType;
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class EntryController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/e")
|
||||
@ -43,16 +42,28 @@ public class EntryController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private EntryManager entryManager;
|
||||
|
||||
@Autowired
|
||||
private EntryValidator entryValidator;
|
||||
|
||||
@Autowired
|
||||
private VoteManager voteManager;
|
||||
|
||||
@Value("${bstly.board.size:30}")
|
||||
private int SIZE;
|
||||
|
||||
@Value("${bstly.board.ranking.gravity:1.8}")
|
||||
private double GRAVITY;
|
||||
|
||||
/**
|
||||
* Ranked entries.
|
||||
*
|
||||
* @param pageParameter the page parameter
|
||||
* @param sizeParameter the size parameter
|
||||
* @param dateParameter the date parameter
|
||||
* @param gravityParameter the gravity parameter
|
||||
* @return the page
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping()
|
||||
public Page<Entry> rankedEntries(@RequestParam("page") Optional<Integer> pageParameter,
|
||||
@ -64,9 +75,9 @@ public class EntryController extends BaseController {
|
||||
sizeParameter = Optional.of(100);
|
||||
}
|
||||
|
||||
Page<RankedEntry> entries = entryManager.directFetchByRanking(
|
||||
dateParameter.orElse(Instant.now()), gravityParameter.orElse(GRAVITY),
|
||||
pageParameter.orElse(0), sizeParameter.orElse(SIZE));
|
||||
Page<RankedEntry> entries = entryManager.fetchByRanking(dateParameter.orElse(Instant.now()),
|
||||
gravityParameter.orElse(GRAVITY), pageParameter.orElse(0),
|
||||
sizeParameter.orElse(SIZE));
|
||||
|
||||
Page<Entry> transformed = new PageImpl<Entry>(
|
||||
entries.getContent().stream().map(rankedEntry -> Entry.fromRankedEntry(rankedEntry))
|
||||
@ -77,22 +88,14 @@ public class EntryController extends BaseController {
|
||||
return transformed;
|
||||
}
|
||||
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping("ranked")
|
||||
public Page<Entry> rankedEntries(@RequestParam("page") Optional<Integer> pageParameter,
|
||||
@RequestParam("size") Optional<Integer> sizeParameter) {
|
||||
|
||||
if (sizeParameter.isPresent() && sizeParameter.get() > 100) {
|
||||
sizeParameter = Optional.of(100);
|
||||
}
|
||||
|
||||
Page<Entry> entries = entryManager.fetchByRanking(pageParameter.orElse(0),
|
||||
sizeParameter.orElse(SIZE));
|
||||
|
||||
entryManager.applyMetadata(getCurrentUsername(), entries.getContent());
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* New entries.
|
||||
*
|
||||
* @param pageParameter the page parameter
|
||||
* @param sizeParameter the size parameter
|
||||
* @param dateParameter the date parameter
|
||||
* @return the page
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping("/new")
|
||||
public Page<Entry> newEntries(@RequestParam("page") Optional<Integer> pageParameter,
|
||||
@ -109,6 +112,12 @@ public class EntryController extends BaseController {
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entry.
|
||||
*
|
||||
* @param id the id
|
||||
* @return the entry
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping("/{id}")
|
||||
public Entry getEntry(@PathVariable("id") Long id) {
|
||||
@ -119,10 +128,16 @@ public class EntryController extends BaseController {
|
||||
}
|
||||
|
||||
entryManager.applyMetadata(getCurrentUsername(), entry);
|
||||
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entry.
|
||||
*
|
||||
* @param entry the entry
|
||||
* @return the entry
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PostMapping()
|
||||
public Entry createEntry(@RequestBody Entry entry) {
|
||||
|
@ -8,26 +8,43 @@ 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.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.bstly.board.businesslogic.CommentManager;
|
||||
import de.bstly.board.businesslogic.EntryManager;
|
||||
import de.bstly.board.businesslogic.UserManager;
|
||||
import de.bstly.board.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.board.model.LocalUser;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class ModerationController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/m")
|
||||
public class ModerationController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private CommentManager commentManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
private EntryManager entryManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserManager userManager;
|
||||
|
||||
/**
|
||||
* Delete comment.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') || hasRole('ROLE_MOD')")
|
||||
@DeleteMapping("/c/{id}")
|
||||
public void deleteComment(@PathVariable("id") Long id) {
|
||||
@ -38,6 +55,11 @@ public class ModerationController {
|
||||
commentManager.delete(commentManager.get(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete entry.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') || hasRole('ROLE_MOD')")
|
||||
@DeleteMapping("/e/{id}")
|
||||
public void deleteEntry(@PathVariable("id") Long id) {
|
||||
@ -47,4 +69,58 @@ public class ModerationController {
|
||||
|
||||
entryManager.delete(entryManager.get(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make mod.
|
||||
*
|
||||
* @param username the username
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PutMapping("/u/{username}")
|
||||
public void makeMod(@PathVariable("username") String username) {
|
||||
LocalUser user = userManager.getByUsername(username);
|
||||
|
||||
if (user == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
if (user.getRoles() == null) {
|
||||
user.setRoles(Lists.newArrayList());
|
||||
}
|
||||
|
||||
if (user.getRoles().contains("ROLE_MOD")) {
|
||||
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
user.getRoles().add("ROLE_MOD");
|
||||
|
||||
userManager.save(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmake mode.
|
||||
*
|
||||
* @param username the username
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@DeleteMapping("/u/{username}")
|
||||
public void unmakeMode(@PathVariable("username") String username) {
|
||||
LocalUser user = userManager.getByUsername(username);
|
||||
|
||||
if (user == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
if (user.getRoles() == null) {
|
||||
user.setRoles(Lists.newArrayList());
|
||||
}
|
||||
|
||||
if (!user.getRoles().contains("ROLE_MOD")) {
|
||||
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
user.getRoles().remove("ROLE_MOD");
|
||||
|
||||
userManager.save(user);
|
||||
}
|
||||
}
|
||||
|
@ -19,17 +19,24 @@ import de.bstly.board.businesslogic.UserManager;
|
||||
import de.bstly.board.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.board.model.LocalUser;
|
||||
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class UserController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/u")
|
||||
public class UserController extends BaseController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserManager userManager;
|
||||
|
||||
/**
|
||||
* Gets the user.
|
||||
*
|
||||
* @param usernameParameter the username parameter
|
||||
* @return the user
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping({ "", "/{username}" })
|
||||
public LocalUser getUser(@PathVariable("username") Optional<String> usernameParameter) {
|
||||
@ -54,6 +61,12 @@ public class UserController extends BaseController {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user.
|
||||
*
|
||||
* @param user the user
|
||||
* @return the local user
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PostMapping()
|
||||
public LocalUser updateUser(@RequestBody LocalUser user) {
|
||||
|
@ -21,21 +21,32 @@ import de.bstly.board.model.Types;
|
||||
import de.bstly.board.model.Vote;
|
||||
import de.bstly.board.model.VoteType;
|
||||
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class VoteController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v")
|
||||
public class VoteController extends BaseController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private VoteManager voteManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
private EntryManager entryManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
private CommentManager commentManager;
|
||||
|
||||
/**
|
||||
* Gets the entry points.
|
||||
*
|
||||
* @param id the id
|
||||
* @return the entry points
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping("/e/{id}")
|
||||
public long getEntryPoints(@PathVariable("id") Long id) {
|
||||
@ -46,6 +57,11 @@ public class VoteController extends BaseController {
|
||||
return voteManager.getPoints(id, Types.entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vote entry up.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PutMapping("/e/{id}/up")
|
||||
public void voteEntryUp(@PathVariable("id") Long id) {
|
||||
@ -67,6 +83,11 @@ public class VoteController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Vote entry down.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PutMapping("/e/{id}/down")
|
||||
public void voteEntryDown(@PathVariable("id") Long id) {
|
||||
@ -88,6 +109,11 @@ public class VoteController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unvote entry.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@DeleteMapping("/e/{id}")
|
||||
public void unvoteEntry(@PathVariable("id") Long id) {
|
||||
@ -103,6 +129,12 @@ public class VoteController extends BaseController {
|
||||
voteManager.delete(vote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the comment points.
|
||||
*
|
||||
* @param id the id
|
||||
* @return the comment points
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping("/c/{id}")
|
||||
public long getCommentPoints(@PathVariable("id") Long id) {
|
||||
@ -113,6 +145,11 @@ public class VoteController extends BaseController {
|
||||
return voteManager.getPoints(id, Types.comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vote comment up.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PutMapping("/c/{id}/up")
|
||||
public void voteCommentUp(@PathVariable("id") Long id) {
|
||||
@ -134,6 +171,11 @@ public class VoteController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Vote comment down.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PutMapping("/c/{id}/down")
|
||||
public void voteCommentDown(@PathVariable("id") Long id) {
|
||||
@ -155,6 +197,11 @@ public class VoteController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unvote comment.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@DeleteMapping("/c/{id}")
|
||||
public void unvoteComment(@PathVariable("id") Long id) {
|
||||
|
@ -10,19 +10,19 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class ControllerExceptionHandler.
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param exception
|
||||
* @param request
|
||||
* @return
|
||||
* Handle response entity status exception.
|
||||
*
|
||||
* @param exception the exception
|
||||
* @param request the request
|
||||
* @return the response entity
|
||||
*/
|
||||
@ExceptionHandler(value = { EntityResponseStatusException.class })
|
||||
protected ResponseEntity<Object> handleResponseEntityStatusException(RuntimeException exception,
|
||||
|
@ -10,45 +10,47 @@ import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class EntityResponseStatusException.
|
||||
*/
|
||||
public class EntityResponseStatusException extends NestedRuntimeException {
|
||||
|
||||
/**
|
||||
* default serialVersionUID
|
||||
*/
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
private final HttpStatus status;
|
||||
|
||||
|
||||
@Nullable
|
||||
private final Object body;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param status
|
||||
* Instantiates a new entity response status exception.
|
||||
*
|
||||
* @param status the status
|
||||
*/
|
||||
public EntityResponseStatusException(HttpStatus status) {
|
||||
this(null, status);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param body
|
||||
* @param status
|
||||
* Instantiates a new entity response status exception.
|
||||
*
|
||||
* @param body the body
|
||||
* @param status the status
|
||||
*/
|
||||
public EntityResponseStatusException(@Nullable Object body, HttpStatus status) {
|
||||
this(body, status, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param body
|
||||
* @param status
|
||||
* @param cause
|
||||
* Instantiates a new entity response status exception.
|
||||
*
|
||||
* @param body the body
|
||||
* @param status the status
|
||||
* @param cause the cause
|
||||
*/
|
||||
public EntityResponseStatusException(@Nullable Object body, HttpStatus status, @Nullable Throwable cause) {
|
||||
super(null, cause);
|
||||
@ -58,25 +60,26 @@ public class EntityResponseStatusException extends NestedRuntimeException {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Gets the status.
|
||||
*
|
||||
* @return the status
|
||||
*/
|
||||
public HttpStatus getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Gets the body.
|
||||
*
|
||||
* @return the body
|
||||
*/
|
||||
@Nullable
|
||||
public Object getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
/*
|
||||
* @see org.springframework.core.NestedRuntimeException#getMessage()
|
||||
*/
|
||||
@Override
|
||||
public String getMessage() {
|
||||
|
@ -6,21 +6,21 @@ package de.bstly.board.controller.support;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.validation.AbstractBindingResult;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class RequestBodyErrors.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class RequestBodyErrors extends AbstractBindingResult {
|
||||
|
||||
|
||||
@Nullable
|
||||
private final Object target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param target
|
||||
* @param objectName
|
||||
* Instantiates a new request body errors.
|
||||
*
|
||||
* @param target the target
|
||||
*/
|
||||
public RequestBodyErrors(@Nullable Object target) {
|
||||
super("request-body");
|
||||
@ -35,6 +35,9 @@ public class RequestBodyErrors extends AbstractBindingResult {
|
||||
return target;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.validation.AbstractBindingResult#getActualFieldValue(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.validation.AbstractBindingResult#getActualFieldValue(java
|
||||
|
@ -13,15 +13,18 @@ import de.bstly.board.businesslogic.CommentManager;
|
||||
import de.bstly.board.businesslogic.EntryManager;
|
||||
import de.bstly.board.model.Comment;
|
||||
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class CommentValidator.
|
||||
*/
|
||||
@Component
|
||||
public class CommentValidator implements Validator {
|
||||
|
||||
|
||||
@Autowired
|
||||
private CommentManager commentManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
private EntryManager entryManager;
|
||||
|
||||
|
@ -12,13 +12,14 @@ import org.springframework.validation.Validator;
|
||||
import de.bstly.board.model.Entry;
|
||||
import de.bstly.board.model.EntryType;
|
||||
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class EntryValidator.
|
||||
*/
|
||||
@Component
|
||||
public class EntryValidator implements Validator {
|
||||
|
||||
|
||||
private UrlValidator urlValidator = new UrlValidator();
|
||||
|
||||
/*
|
||||
|
@ -7,19 +7,19 @@ import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import de.bstly.board.model.Vote;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class VotedEvent.
|
||||
*/
|
||||
public class VotedEvent extends ApplicationEvent {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* @param source
|
||||
* Instantiates a new voted event.
|
||||
*
|
||||
* @param vote the vote
|
||||
*/
|
||||
public VotedEvent(Vote vote) {
|
||||
super(vote);
|
||||
|
@ -28,34 +28,42 @@ import com.google.gson.JsonParser;
|
||||
import de.bstly.board.i18n.model.I18n;
|
||||
import de.bstly.board.i18n.repository.I18nRepository;
|
||||
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class I18nManager.
|
||||
*/
|
||||
@Component
|
||||
public class I18nManager implements SmartInitializingSingleton {
|
||||
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(I18nManager.class);
|
||||
|
||||
|
||||
@Autowired
|
||||
private I18nRepository i18nRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* @return
|
||||
* Gets the.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @return the i 18 n
|
||||
*/
|
||||
public I18n get(String locale) {
|
||||
return i18nRepository.findById(locale).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* @return
|
||||
* Gets the label.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @return the label
|
||||
*/
|
||||
public JsonObject getLabel(String locale) {
|
||||
I18n i18n = get(locale);
|
||||
@ -70,17 +78,19 @@ public class I18nManager implements SmartInitializingSingleton {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Gets the locales.
|
||||
*
|
||||
* @return the locales
|
||||
*/
|
||||
public List<String> getLocales() {
|
||||
return i18nRepository.findAll().stream().map(I18n::getLocale).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dest
|
||||
* @param src
|
||||
* Extend json object.
|
||||
*
|
||||
* @param dest the dest
|
||||
* @param src the src
|
||||
*/
|
||||
protected void extendJsonObject(JsonObject dest, JsonObject src) {
|
||||
for (Entry<String, JsonElement> srcEntry : src.entrySet()) {
|
||||
@ -100,10 +110,11 @@ public class I18nManager implements SmartInitializingSingleton {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* @param newLabel
|
||||
* @return
|
||||
* Adds the label.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @param newLabel the new label
|
||||
* @return the i 18 n
|
||||
*/
|
||||
public I18n addLabel(String locale, JsonObject newLabel) {
|
||||
JsonObject label = getLabel(locale);
|
||||
@ -122,10 +133,11 @@ public class I18nManager implements SmartInitializingSingleton {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* @param label
|
||||
* @return
|
||||
* Sets the label.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @param label the label
|
||||
* @return the i 18 n
|
||||
*/
|
||||
public I18n setLabel(String locale, JsonObject label) {
|
||||
I18n i18n = new I18n();
|
||||
@ -136,8 +148,9 @@ public class I18nManager implements SmartInitializingSingleton {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* Delete label.
|
||||
*
|
||||
* @param locale the locale
|
||||
*/
|
||||
public void deleteLabel(String locale) {
|
||||
if (i18nRepository.existsById(locale)) {
|
||||
@ -145,6 +158,9 @@ public class I18nManager implements SmartInitializingSingleton {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#
|
||||
* afterSingletonsInstantiated()
|
||||
|
@ -27,21 +27,25 @@ import com.google.gson.JsonObject;
|
||||
import de.bstly.board.controller.BaseController;
|
||||
import de.bstly.board.i18n.businesslogic.I18nManager;
|
||||
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class I18nController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/i18n")
|
||||
public class I18nController extends BaseController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private I18nManager i18nManager;
|
||||
|
||||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Gets the locales.
|
||||
*
|
||||
* @return the locales
|
||||
*/
|
||||
@GetMapping
|
||||
public List<String> getLocales() {
|
||||
@ -49,11 +53,13 @@ public class I18nController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* @param response
|
||||
* @throws JsonIOException
|
||||
* @throws IOException
|
||||
* Gets the label.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @param response the response
|
||||
* @return the label
|
||||
* @throws JsonIOException the json IO exception
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
@GetMapping("/{locale}")
|
||||
public void getLabel(@PathVariable("locale") String locale, HttpServletResponse response)
|
||||
@ -66,9 +72,10 @@ public class I18nController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* @param label
|
||||
* Sets the label.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @param label the label
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PostMapping("/{locale}")
|
||||
@ -81,9 +88,10 @@ public class I18nController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* @param label
|
||||
* Adds the label.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @param label the label
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PutMapping("/{locale}")
|
||||
@ -96,8 +104,9 @@ public class I18nController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
* Delete locale.
|
||||
*
|
||||
* @param locale the locale
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@DeleteMapping("/{locale}")
|
||||
|
@ -10,30 +10,27 @@ import javax.persistence.Lob;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class I18n.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "i18n", uniqueConstraints = @UniqueConstraint(columnNames = { "locale" }))
|
||||
public class I18n {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
@Id
|
||||
@Column(name = "locale", unique = true, nullable = false)
|
||||
private String locale;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
@Lob
|
||||
@Column(name = "label")
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* Gets the locale.
|
||||
*
|
||||
* @return the locale
|
||||
*/
|
||||
public String getLocale() {
|
||||
@ -41,13 +38,17 @@ public class I18n {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locale the locale to set
|
||||
* Sets the locale.
|
||||
*
|
||||
* @param locale the new locale
|
||||
*/
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the label.
|
||||
*
|
||||
* @return the label
|
||||
*/
|
||||
public String getLabel() {
|
||||
@ -55,7 +56,9 @@ public class I18n {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param label the label to set
|
||||
* Sets the label.
|
||||
*
|
||||
* @param label the new label
|
||||
*/
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
|
@ -10,9 +10,7 @@ import org.springframework.stereotype.Repository;
|
||||
import de.bstly.board.i18n.model.I18n;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Interface I18nRepository.
|
||||
*/
|
||||
@Repository
|
||||
public interface I18nRepository
|
||||
|
90
src/main/java/de/bstly/board/model/Bookmarks.java
Normal file
90
src/main/java/de/bstly/board/model/Bookmarks.java
Normal file
@ -0,0 +1,90 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* The Class Bookmarks.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "bookmarks")
|
||||
@EntityListeners({ AuditingEntityListener.class })
|
||||
public class Bookmarks {
|
||||
|
||||
@Id
|
||||
@Column(name = "username", nullable = false)
|
||||
private String username;
|
||||
@ElementCollection
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@CollectionTable(name = "bookmark_entries")
|
||||
private List<Long> entries;
|
||||
|
||||
/**
|
||||
* @param username
|
||||
*/
|
||||
public Bookmarks() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param username
|
||||
*/
|
||||
public Bookmarks(String username) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.entries = Lists.newArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 entries.
|
||||
*
|
||||
* @return the entries
|
||||
*/
|
||||
public List<Long> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entries.
|
||||
*
|
||||
* @param entries the new entries
|
||||
*/
|
||||
public void setEntries(List<Long> entries) {
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
}
|
@ -20,34 +20,49 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class Comment.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "comments")
|
||||
@EntityListeners({ AuditingEntityListener.class })
|
||||
public class Comment {
|
||||
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@Column(name = "id", nullable = false)
|
||||
private Long id;
|
||||
|
||||
|
||||
@Column(name = "author", nullable = false)
|
||||
private String author;
|
||||
|
||||
|
||||
@Column(name = "created", nullable = false)
|
||||
private Instant created;
|
||||
|
||||
|
||||
@Column(name = "target", nullable = false)
|
||||
private Long target;
|
||||
|
||||
|
||||
@Column(name = "parent", nullable = true)
|
||||
private Long parent;
|
||||
|
||||
|
||||
@Lob
|
||||
@Column(name = "text", nullable = false)
|
||||
private String text;
|
||||
|
||||
|
||||
@Transient
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public Long getId() {
|
||||
@ -55,13 +70,17 @@ public class Comment {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
* Sets the id.
|
||||
*
|
||||
* @param id the new id
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
public String getAuthor() {
|
||||
@ -69,13 +88,17 @@ public class Comment {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param author the author to set
|
||||
* Sets the author.
|
||||
*
|
||||
* @param author the new author
|
||||
*/
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the created.
|
||||
*
|
||||
* @return the created
|
||||
*/
|
||||
public Instant getCreated() {
|
||||
@ -83,13 +106,17 @@ public class Comment {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param created the created to set
|
||||
* Sets the created.
|
||||
*
|
||||
* @param created the new created
|
||||
*/
|
||||
public void setCreated(Instant created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the target.
|
||||
*
|
||||
* @return the target
|
||||
*/
|
||||
public Long getTarget() {
|
||||
@ -97,13 +124,17 @@ public class Comment {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target the target to set
|
||||
* Sets the target.
|
||||
*
|
||||
* @param target the new target
|
||||
*/
|
||||
public void setTarget(Long target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent.
|
||||
*
|
||||
* @return the parent
|
||||
*/
|
||||
public Long getParent() {
|
||||
@ -111,13 +142,17 @@ public class Comment {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parent the parent to set
|
||||
* Sets the parent.
|
||||
*
|
||||
* @param parent the new parent
|
||||
*/
|
||||
public void setParent(Long parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text.
|
||||
*
|
||||
* @return the text
|
||||
*/
|
||||
public String getText() {
|
||||
@ -125,13 +160,17 @@ public class Comment {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param text the text to set
|
||||
* Sets the text.
|
||||
*
|
||||
* @param text the new text
|
||||
*/
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata.
|
||||
*
|
||||
* @return the metadata
|
||||
*/
|
||||
public Map<String, Object> getMetadata() {
|
||||
@ -143,7 +182,9 @@ public class Comment {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param metadata the metadata to set
|
||||
* Sets the metadata.
|
||||
*
|
||||
* @param metadata the metadata
|
||||
*/
|
||||
public void setMetadata(Map<String, Object> metadata) {
|
||||
this.metadata = metadata;
|
||||
|
@ -22,42 +22,63 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class Entry.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "entries")
|
||||
@EntityListeners({ AuditingEntityListener.class })
|
||||
public class Entry {
|
||||
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@Column(name = "id", nullable = false)
|
||||
private Long id;
|
||||
|
||||
|
||||
@Column(name = "author", nullable = false)
|
||||
private String author;
|
||||
|
||||
|
||||
@Column(name = "created", nullable = false)
|
||||
private Instant created;
|
||||
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "entry_type", nullable = false)
|
||||
private EntryType entryType;
|
||||
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "entry_status", nullable = false, columnDefinition = "varchar(255) default 'NORMAL'")
|
||||
private EntryStatus entryStatus;
|
||||
|
||||
|
||||
@Column(name = "url")
|
||||
private String url;
|
||||
|
||||
|
||||
@Column(name = "title", nullable = false)
|
||||
private String title;
|
||||
|
||||
|
||||
@Lob
|
||||
@Column(name = "text")
|
||||
private String text;
|
||||
|
||||
|
||||
@Transient
|
||||
private Double ranking;
|
||||
|
||||
|
||||
@Transient
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public Long getId() {
|
||||
@ -65,13 +86,17 @@ public class Entry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
* Sets the id.
|
||||
*
|
||||
* @param id the new id
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
public String getAuthor() {
|
||||
@ -79,13 +104,17 @@ public class Entry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param author the author to set
|
||||
* Sets the author.
|
||||
*
|
||||
* @param author the new author
|
||||
*/
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the created.
|
||||
*
|
||||
* @return the created
|
||||
*/
|
||||
public Instant getCreated() {
|
||||
@ -93,41 +122,53 @@ public class Entry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param created the created to set
|
||||
* Sets the created.
|
||||
*
|
||||
* @param created the new created
|
||||
*/
|
||||
public void setCreated(Instant created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entryType
|
||||
* Gets the entry type.
|
||||
*
|
||||
* @return the entry type
|
||||
*/
|
||||
public EntryType getEntryType() {
|
||||
return entryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entryType the entryType to set
|
||||
* Sets the entry type.
|
||||
*
|
||||
* @param entryType the new entry type
|
||||
*/
|
||||
public void setEntryType(EntryType entryType) {
|
||||
this.entryType = entryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entryStatus
|
||||
* Gets the entry status.
|
||||
*
|
||||
* @return the entry status
|
||||
*/
|
||||
public EntryStatus getEntryStatus() {
|
||||
return entryStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entryStatus the entryStatus to set
|
||||
* Sets the entry status.
|
||||
*
|
||||
* @param entryStatus the new entry status
|
||||
*/
|
||||
public void setEntryStatus(EntryStatus entryStatus) {
|
||||
this.entryStatus = entryStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
public String getUrl() {
|
||||
@ -135,13 +176,17 @@ public class Entry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param url the url to set
|
||||
* Sets the url.
|
||||
*
|
||||
* @param url the new url
|
||||
*/
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title.
|
||||
*
|
||||
* @return the title
|
||||
*/
|
||||
public String getTitle() {
|
||||
@ -149,13 +194,17 @@ public class Entry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param title the title to set
|
||||
* Sets the title.
|
||||
*
|
||||
* @param title the new title
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text.
|
||||
*
|
||||
* @return the text
|
||||
*/
|
||||
public String getText() {
|
||||
@ -163,13 +212,17 @@ public class Entry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param text the text to set
|
||||
* Sets the text.
|
||||
*
|
||||
* @param text the new text
|
||||
*/
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ranking.
|
||||
*
|
||||
* @return the ranking
|
||||
*/
|
||||
public Double getRanking() {
|
||||
@ -177,13 +230,17 @@ public class Entry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ranking the ranking to set
|
||||
* Sets the ranking.
|
||||
*
|
||||
* @param ranking the new ranking
|
||||
*/
|
||||
public void setRanking(Double ranking) {
|
||||
this.ranking = ranking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata.
|
||||
*
|
||||
* @return the metadata
|
||||
*/
|
||||
public Map<String, Object> getMetadata() {
|
||||
@ -194,16 +251,19 @@ public class Entry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param metadata the metadata to set
|
||||
* Sets the metadata.
|
||||
*
|
||||
* @param metadata the metadata
|
||||
*/
|
||||
public void setMetadata(Map<String, Object> metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rankedEntry
|
||||
* @return
|
||||
* From ranked entry.
|
||||
*
|
||||
* @param rankedEntry the ranked entry
|
||||
* @return the entry
|
||||
*/
|
||||
public static Entry fromRankedEntry(RankedEntry rankedEntry) {
|
||||
Entry entry = new Entry();
|
||||
|
@ -3,12 +3,17 @@
|
||||
*/
|
||||
package de.bstly.board.model;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Enum EntryStatus.
|
||||
*/
|
||||
public enum EntryStatus {
|
||||
|
||||
NORMAL, ARCHIVED, PINNED
|
||||
|
||||
NORMAL,
|
||||
|
||||
ARCHIVED,
|
||||
|
||||
PINNED
|
||||
|
||||
}
|
||||
|
@ -3,12 +3,19 @@
|
||||
*/
|
||||
package de.bstly.board.model;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Enum EntryType.
|
||||
*/
|
||||
public enum EntryType {
|
||||
|
||||
DISCUSSION, INTERN, LINK, QUESTION
|
||||
|
||||
DISCUSSION,
|
||||
|
||||
INTERN,
|
||||
|
||||
LINK,
|
||||
|
||||
QUESTION
|
||||
|
||||
}
|
||||
|
@ -23,44 +23,65 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class LocalUser.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
@JsonInclude(Include.NON_EMPTY)
|
||||
public class LocalUser {
|
||||
|
||||
|
||||
@Id
|
||||
@Column(name = "username", nullable = false)
|
||||
private String username;
|
||||
|
||||
|
||||
@Column(name = "external_id", nullable = true)
|
||||
private String externalId;
|
||||
|
||||
|
||||
@JsonIgnore
|
||||
@Column(name = "password_hash", nullable = true)
|
||||
private String passwordHash;
|
||||
|
||||
|
||||
@ElementCollection
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@CollectionTable(name = "users_roles")
|
||||
private List<String> roles;
|
||||
|
||||
|
||||
@Lob
|
||||
@Column(name = "about", nullable = true)
|
||||
private String about;
|
||||
|
||||
|
||||
@Column(name = "email", nullable = true)
|
||||
private String email;
|
||||
|
||||
|
||||
@Column(name = "locale", nullable = false, columnDefinition = "varchar(255) default 'en'")
|
||||
private String locale;
|
||||
|
||||
|
||||
@Column(name = "dark_theme", columnDefinition = "boolean default false")
|
||||
private boolean darkTheme;
|
||||
|
||||
|
||||
@ElementCollection
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@CollectionTable(name = "users_settings")
|
||||
private Map<String, String> settings;
|
||||
|
||||
|
||||
@Transient
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
/**
|
||||
* Gets the username.
|
||||
*
|
||||
* @return the username
|
||||
*/
|
||||
public String getUsername() {
|
||||
@ -68,41 +89,53 @@ public class LocalUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param username the username to set
|
||||
* Sets the username.
|
||||
*
|
||||
* @param username the new username
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the externalId
|
||||
* Gets the external id.
|
||||
*
|
||||
* @return the external id
|
||||
*/
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param externalId the externalId to set
|
||||
* Sets the external id.
|
||||
*
|
||||
* @param externalId the new external id
|
||||
*/
|
||||
public void setExternalId(String externalId) {
|
||||
this.externalId = externalId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the passwordHash
|
||||
* Gets the password hash.
|
||||
*
|
||||
* @return the password hash
|
||||
*/
|
||||
public String getPasswordHash() {
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param passwordHash the passwordHash to set
|
||||
* Sets the password hash.
|
||||
*
|
||||
* @param passwordHash the new password hash
|
||||
*/
|
||||
public void setPasswordHash(String passwordHash) {
|
||||
this.passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the roles.
|
||||
*
|
||||
* @return the roles
|
||||
*/
|
||||
public List<String> getRoles() {
|
||||
@ -110,13 +143,17 @@ public class LocalUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param roles the roles to set
|
||||
* Sets the roles.
|
||||
*
|
||||
* @param roles the new roles
|
||||
*/
|
||||
public void setRoles(List<String> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the about.
|
||||
*
|
||||
* @return the about
|
||||
*/
|
||||
public String getAbout() {
|
||||
@ -124,13 +161,17 @@ public class LocalUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param about the about to set
|
||||
* Sets the about.
|
||||
*
|
||||
* @param about the new about
|
||||
*/
|
||||
public void setAbout(String about) {
|
||||
this.about = about;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the email.
|
||||
*
|
||||
* @return the email
|
||||
*/
|
||||
public String getEmail() {
|
||||
@ -138,13 +179,17 @@ public class LocalUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param email the email to set
|
||||
* Sets the email.
|
||||
*
|
||||
* @param email the new email
|
||||
*/
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the locale.
|
||||
*
|
||||
* @return the locale
|
||||
*/
|
||||
public String getLocale() {
|
||||
@ -152,27 +197,35 @@ public class LocalUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locale the locale to set
|
||||
* Sets the locale.
|
||||
*
|
||||
* @param locale the new locale
|
||||
*/
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the darkTheme
|
||||
* Checks if is dark theme.
|
||||
*
|
||||
* @return true, if is dark theme
|
||||
*/
|
||||
public boolean isDarkTheme() {
|
||||
return darkTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param darkTheme the darkTheme to set
|
||||
* Sets the dark theme.
|
||||
*
|
||||
* @param darkTheme the new dark theme
|
||||
*/
|
||||
public void setDarkTheme(boolean darkTheme) {
|
||||
this.darkTheme = darkTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the settings.
|
||||
*
|
||||
* @return the settings
|
||||
*/
|
||||
public Map<String, String> getSettings() {
|
||||
@ -180,13 +233,17 @@ public class LocalUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param settings the settings to set
|
||||
* Sets the settings.
|
||||
*
|
||||
* @param settings the settings
|
||||
*/
|
||||
public void setSettings(Map<String, String> settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata.
|
||||
*
|
||||
* @return the metadata
|
||||
*/
|
||||
public Map<String, Object> getMetadata() {
|
||||
@ -197,7 +254,9 @@ public class LocalUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param metadata the metadata to set
|
||||
* Sets the metadata.
|
||||
*
|
||||
* @param metadata the metadata
|
||||
*/
|
||||
public void setMetadata(Map<String, Object> metadata) {
|
||||
this.metadata = metadata;
|
||||
|
@ -10,25 +10,34 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
|
||||
/**
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class PersistentLogin.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "persistent_logins")
|
||||
public class PersistentLogin {
|
||||
|
||||
|
||||
@Column(name = "username", length = 64, nullable = false)
|
||||
private String username;
|
||||
|
||||
|
||||
@Id
|
||||
@Column(name = "series", length = 64)
|
||||
private String series;
|
||||
|
||||
|
||||
@Column(name = "token", length = 64, nullable = false)
|
||||
private String token;
|
||||
|
||||
|
||||
@Column(name = "last_used", nullable = false)
|
||||
private Instant last_used;
|
||||
|
||||
/**
|
||||
* Gets the username.
|
||||
*
|
||||
* @return the username
|
||||
*/
|
||||
public String getUsername() {
|
||||
@ -36,13 +45,17 @@ public class PersistentLogin {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param username the username to set
|
||||
* Sets the username.
|
||||
*
|
||||
* @param username the new username
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the series.
|
||||
*
|
||||
* @return the series
|
||||
*/
|
||||
public String getSeries() {
|
||||
@ -50,13 +63,17 @@ public class PersistentLogin {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param series the series to set
|
||||
* Sets the series.
|
||||
*
|
||||
* @param series the new series
|
||||
*/
|
||||
public void setSeries(String series) {
|
||||
this.series = series;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token.
|
||||
*
|
||||
* @return the token
|
||||
*/
|
||||
public String getToken() {
|
||||
@ -64,21 +81,27 @@ public class PersistentLogin {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param token the token to set
|
||||
* Sets the token.
|
||||
*
|
||||
* @param token the new token
|
||||
*/
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last_used
|
||||
* Gets the last used.
|
||||
*
|
||||
* @return the last used
|
||||
*/
|
||||
public Instant getLast_used() {
|
||||
return last_used;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param last_used the last_used to set
|
||||
* Sets the last used.
|
||||
*
|
||||
* @param last_used the new last used
|
||||
*/
|
||||
public void setLast_used(Instant last_used) {
|
||||
this.last_used = last_used;
|
||||
|
@ -5,27 +5,72 @@ package de.bstly.board.model;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Interface RankedEntry.
|
||||
*/
|
||||
public interface RankedEntry {
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
Long getId();
|
||||
|
||||
/**
|
||||
* Gets the author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
String getAuthor();
|
||||
|
||||
/**
|
||||
* Gets the created.
|
||||
*
|
||||
* @return the created
|
||||
*/
|
||||
Instant getCreated();
|
||||
|
||||
/**
|
||||
* Gets the entry type.
|
||||
*
|
||||
* @return the entry type
|
||||
*/
|
||||
EntryType getEntry_Type();
|
||||
|
||||
/**
|
||||
* Gets the url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
String getUrl();
|
||||
|
||||
/**
|
||||
* Gets the title.
|
||||
*
|
||||
* @return the title
|
||||
*/
|
||||
String getTitle();
|
||||
|
||||
/**
|
||||
* Gets the text.
|
||||
*
|
||||
* @return the text
|
||||
*/
|
||||
String getText();
|
||||
|
||||
/**
|
||||
* Gets the ranking.
|
||||
*
|
||||
* @return the ranking
|
||||
*/
|
||||
Double getRanking();
|
||||
|
||||
/**
|
||||
* Gets the points.
|
||||
*
|
||||
* @return the points
|
||||
*/
|
||||
Long getPoints();
|
||||
}
|
||||
|
@ -3,11 +3,16 @@
|
||||
*/
|
||||
package de.bstly.board.model;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Enum Types.
|
||||
*/
|
||||
public enum Types {
|
||||
|
||||
comment, entry, user
|
||||
|
||||
comment,
|
||||
|
||||
entry,
|
||||
|
||||
user
|
||||
}
|
||||
|
@ -13,29 +13,40 @@ import javax.persistence.Table;
|
||||
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class Vote.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "votes")
|
||||
@EntityListeners({ AuditingEntityListener.class })
|
||||
public class Vote {
|
||||
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
|
||||
@Column(name = "target", nullable = false)
|
||||
private Long target;
|
||||
|
||||
|
||||
@Column(name = "target_type", nullable = false)
|
||||
private Types targetType;
|
||||
|
||||
|
||||
@Column(name = "author", nullable = false)
|
||||
private String author;
|
||||
|
||||
|
||||
@Column(name = "type", nullable = false)
|
||||
private VoteType type;
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public Long getId() {
|
||||
@ -43,13 +54,17 @@ public class Vote {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
* Sets the id.
|
||||
*
|
||||
* @param id the new id
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the target.
|
||||
*
|
||||
* @return the target
|
||||
*/
|
||||
public Long getTarget() {
|
||||
@ -57,27 +72,35 @@ public class Vote {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target the target to set
|
||||
* Sets the target.
|
||||
*
|
||||
* @param target the new target
|
||||
*/
|
||||
public void setTarget(Long target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the targetType
|
||||
* Gets the target type.
|
||||
*
|
||||
* @return the target type
|
||||
*/
|
||||
public Types getTargetType() {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param targetType the targetType to set
|
||||
* Sets the target type.
|
||||
*
|
||||
* @param targetType the new target type
|
||||
*/
|
||||
public void setTargetType(Types targetType) {
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
public String getAuthor() {
|
||||
@ -85,13 +108,17 @@ public class Vote {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param author the author to set
|
||||
* Sets the author.
|
||||
*
|
||||
* @param author the new author
|
||||
*/
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public VoteType getType() {
|
||||
@ -99,7 +126,9 @@ public class Vote {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type the type to set
|
||||
* Sets the type.
|
||||
*
|
||||
* @param type the new type
|
||||
*/
|
||||
public void setType(VoteType type) {
|
||||
this.type = type;
|
||||
|
@ -3,10 +3,15 @@
|
||||
*/
|
||||
package de.bstly.board.model;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Enum VoteType.
|
||||
*/
|
||||
public enum VoteType {
|
||||
up, down
|
||||
|
||||
|
||||
up,
|
||||
|
||||
|
||||
down
|
||||
}
|
||||
|
@ -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.Bookmarks;
|
||||
|
||||
/**
|
||||
* The Interface BookmarksRepository.
|
||||
*/
|
||||
@Repository
|
||||
public interface BookmarksRepository
|
||||
extends JpaRepository<Bookmarks, String>, QuerydslPredicateExecutor<Bookmarks> {
|
||||
|
||||
}
|
@ -16,28 +16,63 @@ import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.bstly.board.model.Comment;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Interface CommentRepository.
|
||||
*/
|
||||
@Repository
|
||||
public interface CommentRepository
|
||||
extends JpaRepository<Comment, Long>, QuerydslPredicateExecutor<Comment> {
|
||||
|
||||
/**
|
||||
* Find all by ranking and parent.
|
||||
*
|
||||
* @param target the target
|
||||
* @param date the date
|
||||
* @param gravity the gravity
|
||||
* @return the list
|
||||
*/
|
||||
@Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent IS NULL AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent IS NULL AND comment.created < :date", nativeQuery = true)
|
||||
List<Comment> findAllByRankingAndParent(@Param("target") Long target,
|
||||
@Param("date") Instant date, @Param("gravity") double gravity);
|
||||
|
||||
/**
|
||||
* Find all by ranking and parent.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @param date the date
|
||||
* @param gravity the gravity
|
||||
* @return the list
|
||||
*/
|
||||
@Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent = :parent AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent = :parent AND comment.created < :date", nativeQuery = true)
|
||||
List<Comment> findAllByRankingAndParent(@Param("target") Long target,
|
||||
@Param("parent") Long parent, @Param("date") Instant date,
|
||||
@Param("gravity") double gravity);
|
||||
|
||||
/**
|
||||
* Find all by ranking and parent.
|
||||
*
|
||||
* @param target the target
|
||||
* @param date the date
|
||||
* @param gravity the gravity
|
||||
* @param pageable the pageable
|
||||
* @return the page
|
||||
*/
|
||||
@Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent IS NULL AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent IS NULL AND comment.created < :date", nativeQuery = true)
|
||||
Page<Comment> findAllByRankingAndParent(@Param("target") Long target,
|
||||
@Param("date") Instant date, @Param("gravity") double gravity, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Find all by ranking and parent.
|
||||
*
|
||||
* @param target the target
|
||||
* @param parent the parent
|
||||
* @param date the date
|
||||
* @param gravity the gravity
|
||||
* @param pageable the pageable
|
||||
* @return the page
|
||||
*/
|
||||
@Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent = :parent AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent = :parent AND comment.created < :date", nativeQuery = true)
|
||||
Page<Comment> findAllByRankingAndParent(@Param("target") Long target,
|
||||
@Param("parent") Long parent, @Param("date") Instant date,
|
||||
|
@ -16,41 +16,62 @@ import org.springframework.stereotype.Repository;
|
||||
import de.bstly.board.model.Entry;
|
||||
import de.bstly.board.model.RankedEntry;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Interface EntryRepository.
|
||||
*/
|
||||
@Repository
|
||||
public interface EntryRepository
|
||||
extends JpaRepository<Entry, Long>, QuerydslPredicateExecutor<Entry> {
|
||||
|
||||
|
||||
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 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 CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity) AS ranking FROM entries AS entry LEFT JOIN ("
|
||||
+ UPVOTES_QUERY
|
||||
+ ") AS upvote ON upvote.target = entry.id LEFT JOIN ("
|
||||
+ DOWNVOTES_QUERY
|
||||
+ ") AS downvote ON downvote.target = entry.id WHERE entry.created < :before AND entry.entry_status = 'NORMAL' ORDER BY ranking DESC, entry.created DESC";
|
||||
|
||||
|
||||
static final String ARCHIVE_CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity) AS ranking FROM entries AS entry LEFT JOIN ("
|
||||
+ UPVOTES_QUERY
|
||||
+ ") AS upvote ON upvote.target = entry.id LEFT JOIN ("
|
||||
+ DOWNVOTES_QUERY
|
||||
+ ") AS downvote ON downvote.target = entry.id WHERE entry.created < :before ORDER BY ranking DESC, entry.created DESC";
|
||||
|
||||
|
||||
static final String ADDITIONAL_QUERY = "SELECT entry.*, calculation.ranking, calculation.points FROM entries AS entry LEFT JOIN ("
|
||||
+ CALCULATION_QUERY
|
||||
+ ") as calculation on calculation.id = entry.id WHERE entry.created < :before ORDER BY calculation.ranking DESC, entry.created DESC";
|
||||
|
||||
|
||||
static final String COUNT_QUERY = "SELECT count(*) FROM entries as entry WHERE entry.created < :before";
|
||||
|
||||
/**
|
||||
* Find all by ranking.
|
||||
*
|
||||
* @param before the before
|
||||
* @param gravity the gravity
|
||||
* @param pageable the pageable
|
||||
* @return the page
|
||||
*/
|
||||
@Query(value = CALCULATION_QUERY, countQuery = COUNT_QUERY, nativeQuery = true)
|
||||
Page<RankedEntry> findAllByRanking(@Param("before") Instant before,
|
||||
@Param("gravity") double gravity, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Find all by ranking archive.
|
||||
*
|
||||
* @param before the before
|
||||
* @param gravity the gravity
|
||||
* @param pageable the pageable
|
||||
* @return the page
|
||||
*/
|
||||
@Query(value = ARCHIVE_CALCULATION_QUERY, countQuery = COUNT_QUERY, nativeQuery = true)
|
||||
Page<RankedEntry> findAllByRankingArchive(@Param("before") Instant before,
|
||||
@Param("gravity") double gravity, Pageable pageable);
|
||||
|
@ -10,9 +10,7 @@ import org.springframework.stereotype.Repository;
|
||||
import de.bstly.board.model.LocalUser;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Interface LocalUserRepository.
|
||||
*/
|
||||
@Repository
|
||||
public interface LocalUserRepository
|
||||
|
@ -10,9 +10,7 @@ import org.springframework.stereotype.Repository;
|
||||
import de.bstly.board.model.Vote;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Interface VoteRepository.
|
||||
*/
|
||||
@Repository
|
||||
public interface VoteRepository extends JpaRepository<Vote, Long>, QuerydslPredicateExecutor<Vote> {
|
||||
|
@ -9,23 +9,27 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
|
||||
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
* The Class LocalRememberMeServices.
|
||||
*/
|
||||
public class LocalRememberMeServices extends PersistentTokenBasedRememberMeServices {
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param userDetailsService
|
||||
* @param tokenRepository
|
||||
* Instantiates a new local remember me services.
|
||||
*
|
||||
* @param key the key
|
||||
* @param userDetailsService the user details service
|
||||
* @param tokenRepository the token repository
|
||||
*/
|
||||
public LocalRememberMeServices(String key, UserDetailsService userDetailsService,
|
||||
PersistentTokenRepository tokenRepository) {
|
||||
super(key, userDetailsService, tokenRepository);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices#rememberMeRequested(javax.servlet.http.HttpServletRequest, java.lang.String)
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* @see org.springframework.security.web.authentication.rememberme.
|
||||
|
@ -4,6 +4,7 @@
|
||||
package de.bstly.board.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@ -12,36 +13,55 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.web.authentication.RememberMeServices;
|
||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.bstly.board.businesslogic.UserManager;
|
||||
import de.bstly.board.model.LocalUser;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lurkars
|
||||
*
|
||||
* The Class OAuth2AuthenticationSuccessHandler.
|
||||
*/
|
||||
@Component
|
||||
public class OAuth2AuthenticationSuccessHandler
|
||||
extends SavedRequestAwareAuthenticationSuccessHandler {
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserManager localUserManager;
|
||||
|
||||
|
||||
private RememberMeServices rememberMeServices;
|
||||
|
||||
/*
|
||||
* @see org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.Authentication)
|
||||
*/
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication authentication) throws IOException, ServletException {
|
||||
LocalUser localUser = localUserManager.getByAuth(authentication);
|
||||
|
||||
User user = new User(localUser.getUsername(), "", authentication.getAuthorities());
|
||||
List<GrantedAuthority> authorities = Lists.newArrayList();
|
||||
authorities.addAll(authentication.getAuthorities());
|
||||
|
||||
if (localUser.getRoles() != null) {
|
||||
for (String role : localUser.getRoles()) {
|
||||
authorities.add(new SimpleGrantedAuthority(role));
|
||||
}
|
||||
}
|
||||
|
||||
User user = new User(localUser.getUsername(), "", authorities);
|
||||
|
||||
UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(
|
||||
user, null, authentication.getAuthorities());
|
||||
user, null, authorities);
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(newAuthentication);
|
||||
|
||||
@ -54,6 +74,11 @@ public class OAuth2AuthenticationSuccessHandler
|
||||
clearAuthenticationAttributes(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the remember me services.
|
||||
*
|
||||
* @param rememberMeServices the new remember me services
|
||||
*/
|
||||
public void setRememberMeServices(RememberMeServices rememberMeServices) {
|
||||
this.rememberMeServices = rememberMeServices;
|
||||
}
|
||||
|
@ -25,26 +25,37 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
import de.bstly.board.businesslogic.UserManager;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author monitoring@bstly.de
|
||||
*
|
||||
* The Class SecurityConfig.
|
||||
*/
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserManager localUserManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;
|
||||
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
|
||||
@Value("${loginUrl:/login}")
|
||||
private String loginUrl;
|
||||
|
||||
|
||||
@Value("${loginTargetUrl:/}")
|
||||
private String loginTargetUrl;
|
||||
|
||||
/*
|
||||
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* @see org.springframework.security.config.annotation.web.configuration.
|
||||
@ -87,14 +98,20 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* Password encoder.
|
||||
*
|
||||
* @return the argon 2 password encoder
|
||||
*/
|
||||
@Bean(name = "passwordEncoder")
|
||||
public Argon2PasswordEncoder passwordEncoder() {
|
||||
return new Argon2PasswordEncoder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Persistent token repository.
|
||||
*
|
||||
* @return the persistent token repository
|
||||
*/
|
||||
@Bean
|
||||
public PersistentTokenRepository persistentTokenRepository() {
|
||||
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
|
||||
@ -102,6 +119,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
return tokenRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remember me services.
|
||||
*
|
||||
* @return the remember me services
|
||||
*/
|
||||
@Bean
|
||||
public RememberMeServices rememberMeServices() {
|
||||
PersistentTokenBasedRememberMeServices rememberMeServices = new LocalRememberMeServices(
|
||||
|
Loading…
Reference in New Issue
Block a user