From db209f2c0acf35f673262a650e68e908ffa672ec Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt <code@dgerhardt.net> Date: Tue, 18 Jul 2017 17:21:11 +0200 Subject: [PATCH] Split up ContentService Added new service for comments. --- .../arsnova/controller/CommentController.java | 16 +- .../arsnova/controller/LegacyController.java | 6 +- .../thm/arsnova/services/CommentService.java | 25 +++ .../arsnova/services/CommentServiceImpl.java | 159 ++++++++++++++++++ .../thm/arsnova/services/ContentService.java | 17 -- .../arsnova/services/ContentServiceImpl.java | 116 +------------ .../websocket/ArsnovaSocketioServerImpl.java | 6 +- 7 files changed, 203 insertions(+), 142 deletions(-) create mode 100644 src/main/java/de/thm/arsnova/services/CommentService.java create mode 100644 src/main/java/de/thm/arsnova/services/CommentServiceImpl.java diff --git a/src/main/java/de/thm/arsnova/controller/CommentController.java b/src/main/java/de/thm/arsnova/controller/CommentController.java index c2d792f36..0fc96762b 100644 --- a/src/main/java/de/thm/arsnova/controller/CommentController.java +++ b/src/main/java/de/thm/arsnova/controller/CommentController.java @@ -20,7 +20,7 @@ package de.thm.arsnova.controller; import de.thm.arsnova.entities.CommentReadingCount; import de.thm.arsnova.entities.transport.Comment; import de.thm.arsnova.exceptions.BadRequestException; -import de.thm.arsnova.services.ContentService; +import de.thm.arsnova.services.CommentService; import de.thm.arsnova.web.DeprecatedApi; import de.thm.arsnova.web.Pagination; import io.swagger.annotations.Api; @@ -49,7 +49,7 @@ import java.util.List; public class CommentController extends PaginationController { @Autowired - private ContentService contentService; + private CommentService commentService; @ApiOperation(value = "Count all the comments in current session", nickname = "getAudienceQuestionCount") @@ -57,7 +57,7 @@ public class CommentController extends PaginationController { @DeprecatedApi @Deprecated public int getInterposedCount(@ApiParam(value = "Session-Key from current session", required = true) @RequestParam final String sessionkey) { - return contentService.getInterposedCount(sessionkey); + return commentService.getInterposedCount(sessionkey); } @ApiOperation(value = "count all unread comments", @@ -66,7 +66,7 @@ public class CommentController extends PaginationController { @DeprecatedApi @Deprecated public CommentReadingCount getUnreadInterposedCount(@ApiParam(value = "Session-Key from current session", required = true) @RequestParam("sessionkey") final String sessionkey, String user) { - return contentService.getInterposedReadingCount(sessionkey, user); + return commentService.getInterposedReadingCount(sessionkey, user); } @ApiOperation(value = "Retrieves all Comments for a Session", @@ -74,14 +74,14 @@ public class CommentController extends PaginationController { @RequestMapping(value = "/", method = RequestMethod.GET) @Pagination public List<Comment> getInterposedQuestions(@ApiParam(value = "Session-Key from current session", required = true) @RequestParam final String sessionkey) { - return Comment.fromList(contentService.getInterposedQuestions(sessionkey, offset, limit)); + return Comment.fromList(commentService.getInterposedQuestions(sessionkey, offset, limit)); } @ApiOperation(value = "Retrieves an Comment", nickname = "getInterposedQuestion") @RequestMapping(value = "/{questionId}", method = RequestMethod.GET) public Comment getInterposedQuestion(@ApiParam(value = "ID of the Comment that needs to be deleted", required = true) @PathVariable final String questionId) { - return new Comment(contentService.readInterposedQuestion(questionId)); + return new Comment(commentService.readInterposedQuestion(questionId)); } @ApiOperation(value = "Creates a new Comment for a Session and returns the Comment's data", @@ -95,7 +95,7 @@ public class CommentController extends PaginationController { @ApiParam(value = "Session-Key from current session", required = true) @RequestParam final String sessionkey, @ApiParam(value = "the body from the new comment", required = true) @RequestBody final de.thm.arsnova.entities.Comment comment ) { - if (contentService.saveQuestion(comment)) { + if (commentService.saveQuestion(comment)) { return; } @@ -106,6 +106,6 @@ public class CommentController extends PaginationController { nickname = "deleteInterposedQuestion") @RequestMapping(value = "/{questionId}", method = RequestMethod.DELETE) public void deleteInterposedQuestion(@ApiParam(value = "ID of the comment that needs to be deleted", required = true) @PathVariable final String questionId) { - contentService.deleteInterposedQuestion(questionId); + commentService.deleteInterposedQuestion(questionId); } } diff --git a/src/main/java/de/thm/arsnova/controller/LegacyController.java b/src/main/java/de/thm/arsnova/controller/LegacyController.java index f1966160e..d58adad0a 100644 --- a/src/main/java/de/thm/arsnova/controller/LegacyController.java +++ b/src/main/java/de/thm/arsnova/controller/LegacyController.java @@ -17,6 +17,7 @@ */ package de.thm.arsnova.controller; +import de.thm.arsnova.services.CommentService; import de.thm.arsnova.services.ContentService; import de.thm.arsnova.web.DeprecatedApi; import org.springframework.beans.factory.annotation.Autowired; @@ -35,6 +36,9 @@ public class LegacyController extends AbstractController { @Autowired private ContentService contentService; + @Autowired + private CommentService commentService; + /* specific routes */ @DeprecatedApi @@ -95,7 +99,7 @@ public class LegacyController extends AbstractController { @RequestMapping(value = "/session/{sessionKey}/interposed", method = RequestMethod.DELETE) @ResponseBody public void deleteAllInterposedQuestions(@PathVariable final String sessionKey) { - contentService.deleteAllInterposedQuestions(sessionKey); + commentService.deleteAllInterposedQuestions(sessionKey); } @DeprecatedApi diff --git a/src/main/java/de/thm/arsnova/services/CommentService.java b/src/main/java/de/thm/arsnova/services/CommentService.java new file mode 100644 index 000000000..e255011ad --- /dev/null +++ b/src/main/java/de/thm/arsnova/services/CommentService.java @@ -0,0 +1,25 @@ +package de.thm.arsnova.services; + +import de.thm.arsnova.entities.Comment; +import de.thm.arsnova.entities.CommentReadingCount; +import de.thm.arsnova.entities.User; + +import java.util.List; + +public interface CommentService { + boolean saveQuestion(Comment comment); + + int getInterposedCount(String sessionKey); + + CommentReadingCount getInterposedReadingCount(String sessionKey, String username); + + List<Comment> getInterposedQuestions(String sessionKey, int offset, int limit); + + Comment readInterposedQuestion(String commentId); + + Comment readInterposedQuestionInternal(String commentId, User user); + + void deleteInterposedQuestion(String commentId); + + void deleteAllInterposedQuestions(String sessionKeyword); +} diff --git a/src/main/java/de/thm/arsnova/services/CommentServiceImpl.java b/src/main/java/de/thm/arsnova/services/CommentServiceImpl.java new file mode 100644 index 000000000..9a15135d3 --- /dev/null +++ b/src/main/java/de/thm/arsnova/services/CommentServiceImpl.java @@ -0,0 +1,159 @@ +package de.thm.arsnova.services; + +import de.thm.arsnova.entities.Comment; +import de.thm.arsnova.entities.CommentReadingCount; +import de.thm.arsnova.entities.Session; +import de.thm.arsnova.entities.User; +import de.thm.arsnova.events.DeleteCommentEvent; +import de.thm.arsnova.events.NewCommentEvent; +import de.thm.arsnova.exceptions.ForbiddenException; +import de.thm.arsnova.exceptions.NotFoundException; +import de.thm.arsnova.exceptions.UnauthorizedException; +import de.thm.arsnova.persistance.CommentRepository; +import de.thm.arsnova.persistance.SessionRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * Performs all comment related operations. + */ +@Service +public class CommentServiceImpl implements CommentService { + @Autowired + private UserService userService; + + @Autowired + private CommentRepository commentRepository; + + @Autowired + private SessionRepository sessionRepository; + + private ApplicationEventPublisher publisher; + + @Override + @PreAuthorize("isAuthenticated()") + public boolean saveQuestion(final Comment comment) { + final Session session = sessionRepository.getSessionFromKeyword(comment.getSessionId()); + final Comment result = commentRepository.saveQuestion(session, comment, userService.getCurrentUser()); + + if (null != result) { + final NewCommentEvent event = new NewCommentEvent(this, session, result); + this.publisher.publishEvent(event); + return true; + } + return false; + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(#commentId, 'comment', 'owner')") + public void deleteInterposedQuestion(final String commentId) { + final Comment comment = commentRepository.getInterposedQuestion(commentId); + if (comment == null) { + throw new NotFoundException(); + } + commentRepository.deleteInterposedQuestion(comment); + + final Session session = sessionRepository.getSessionFromKeyword(comment.getSessionId()); + final DeleteCommentEvent event = new DeleteCommentEvent(this, session, comment); + this.publisher.publishEvent(event); + } + + @Override + @PreAuthorize("isAuthenticated()") + public void deleteAllInterposedQuestions(final String sessionKeyword) { + final Session session = sessionRepository.getSessionFromKeyword(sessionKeyword); + if (session == null) { + throw new UnauthorizedException(); + } + final User user = getCurrentUser(); + if (session.isCreator(user)) { + commentRepository.deleteAllInterposedQuestions(session); + } else { + commentRepository.deleteAllInterposedQuestions(session, user); + } + } + + @Override + @PreAuthorize("isAuthenticated()") + public int getInterposedCount(final String sessionKey) { + return commentRepository.getInterposedCount(sessionKey); + } + + @Override + @PreAuthorize("isAuthenticated()") + public CommentReadingCount getInterposedReadingCount(final String sessionKey, String username) { + final Session session = sessionRepository.getSessionFromKeyword(sessionKey); + if (session == null) { + throw new NotFoundException(); + } + if (username == null) { + return commentRepository.getInterposedReadingCount(session); + } else { + User currentUser = userService.getCurrentUser(); + if (!currentUser.getUsername().equals(username)) { + throw new ForbiddenException(); + } + + return commentRepository.getInterposedReadingCount(session, currentUser); + } + } + + @Override + @PreAuthorize("isAuthenticated()") + public List<Comment> getInterposedQuestions(final String sessionKey, final int offset, final int limit) { + final Session session = this.getSession(sessionKey); + final User user = getCurrentUser(); + if (session.isCreator(user)) { + return commentRepository.getInterposedQuestions(session, offset, limit); + } else { + return commentRepository.getInterposedQuestions(session, user, offset, limit); + } + } + + @Override + @PreAuthorize("isAuthenticated()") + public Comment readInterposedQuestion(final String commentId) { + final User user = userService.getCurrentUser(); + return this.readInterposedQuestionInternal(commentId, user); + } + + /* + * The "internal" suffix means it is called by internal services that have no authentication! + * TODO: Find a better way of doing this... + */ + @Override + public Comment readInterposedQuestionInternal(final String commentId, User user) { + final Comment comment = commentRepository.getInterposedQuestion(commentId); + if (comment == null) { + throw new NotFoundException(); + } + final Session session = sessionRepository.getSessionFromId(comment.getSessionId()); + if (!comment.isCreator(user) && !session.isCreator(user)) { + throw new UnauthorizedException(); + } + if (session.isCreator(user)) { + commentRepository.markInterposedQuestionAsRead(comment); + } + return comment; + } + + private User getCurrentUser() { + final User user = userService.getCurrentUser(); + if (user == null) { + throw new UnauthorizedException(); + } + return user; + } + + private Session getSession(final String sessionkey) { + final Session session = sessionRepository.getSessionFromKeyword(sessionkey); + if (session == null) { + throw new NotFoundException(); + } + return session; + } +} diff --git a/src/main/java/de/thm/arsnova/services/ContentService.java b/src/main/java/de/thm/arsnova/services/ContentService.java index 9e861af00..9fae2e8ac 100644 --- a/src/main/java/de/thm/arsnova/services/ContentService.java +++ b/src/main/java/de/thm/arsnova/services/ContentService.java @@ -32,8 +32,6 @@ import java.util.Map; public interface ContentService { Content saveQuestion(Content content); - boolean saveQuestion(Comment comment); - Content getQuestion(String id); List<Content> getSkillQuestions(String sessionkey); @@ -78,16 +76,6 @@ public interface ContentService { int getTotalAnswerCountByQuestion(String questionId); - int getInterposedCount(String sessionKey); - - CommentReadingCount getInterposedReadingCount(String sessionKey, String username); - - List<Comment> getInterposedQuestions(String sessionKey, int offset, int limit); - - Comment readInterposedQuestion(String commentId); - - Comment readInterposedQuestionInternal(String commentId, User user); - Content update(Content content); Content update(Content content, User user); @@ -100,8 +88,6 @@ public interface ContentService { void deleteAnswer(String questionId, String answerId); - void deleteInterposedQuestion(String commentId); - List<Content> getLectureQuestions(String sessionkey); List<Content> getFlashcards(String sessionkey); @@ -140,8 +126,6 @@ public interface ContentService { List<String> getUnAnsweredPreparationQuestionIds(String sessionKey, User user); - void deleteAllInterposedQuestions(String sessionKeyword); - void publishAll(String sessionkey, boolean publish); void publishQuestions(String sessionkey, boolean publish, List<Content> contents); @@ -167,5 +151,4 @@ public interface ContentService { String getQuestionFcImage(String questionId); List<Content> replaceImageData(List<Content> contents); - } diff --git a/src/main/java/de/thm/arsnova/services/ContentServiceImpl.java b/src/main/java/de/thm/arsnova/services/ContentServiceImpl.java index 62580548f..aa03b62e6 100644 --- a/src/main/java/de/thm/arsnova/services/ContentServiceImpl.java +++ b/src/main/java/de/thm/arsnova/services/ContentServiceImpl.java @@ -19,18 +19,14 @@ package de.thm.arsnova.services; import de.thm.arsnova.util.ImageUtils; import de.thm.arsnova.entities.Answer; -import de.thm.arsnova.entities.Comment; -import de.thm.arsnova.entities.CommentReadingCount; import de.thm.arsnova.entities.Content; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; import de.thm.arsnova.events.*; import de.thm.arsnova.exceptions.BadRequestException; -import de.thm.arsnova.exceptions.ForbiddenException; import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.exceptions.UnauthorizedException; import de.thm.arsnova.persistance.AnswerRepository; -import de.thm.arsnova.persistance.CommentRepository; import de.thm.arsnova.persistance.ContentRepository; import de.thm.arsnova.persistance.SessionRepository; import org.slf4j.Logger; @@ -51,7 +47,7 @@ import java.util.Timer; import java.util.TimerTask; /** - * Performs all question, comment, and answer related operations. + * Performs all content and answer related operations. */ @Service public class ContentServiceImpl implements ContentService, ApplicationEventPublisherAware { @@ -61,9 +57,6 @@ public class ContentServiceImpl implements ContentService, ApplicationEventPubli @Autowired private SessionRepository sessionRepository; - @Autowired - private CommentRepository commentRepository; - @Autowired private ContentRepository contentRepository; @@ -133,20 +126,6 @@ public class ContentServiceImpl implements ContentService, ApplicationEventPubli return result; } - @Override - @PreAuthorize("isAuthenticated()") - public boolean saveQuestion(final Comment comment) { - final Session session = sessionRepository.getSessionFromKeyword(comment.getSessionId()); - final Comment result = commentRepository.saveQuestion(session, comment, userService.getCurrentUser()); - - if (null != result) { - final NewCommentEvent event = new NewCommentEvent(this, session, result); - this.publisher.publishEvent(event); - return true; - } - return false; - } - @Override @PreAuthorize("isAuthenticated()") public Content getQuestion(final String id) { @@ -352,35 +331,6 @@ public class ContentServiceImpl implements ContentService, ApplicationEventPubli return session; } - @Override - @PreAuthorize("isAuthenticated() and hasPermission(#commentId, 'comment', 'owner')") - public void deleteInterposedQuestion(final String commentId) { - final Comment comment = commentRepository.getInterposedQuestion(commentId); - if (comment == null) { - throw new NotFoundException(); - } - commentRepository.deleteInterposedQuestion(comment); - - final Session session = sessionRepository.getSessionFromKeyword(comment.getSessionId()); - final DeleteCommentEvent event = new DeleteCommentEvent(this, session, comment); - this.publisher.publishEvent(event); - } - - @Override - @PreAuthorize("isAuthenticated()") - public void deleteAllInterposedQuestions(final String sessionKeyword) { - final Session session = sessionRepository.getSessionFromKeyword(sessionKeyword); - if (session == null) { - throw new UnauthorizedException(); - } - final User user = getCurrentUser(); - if (session.isCreator(user)) { - commentRepository.deleteAllInterposedQuestions(session); - } else { - commentRepository.deleteAllInterposedQuestions(session, user); - } - } - @Override @PreAuthorize("isAuthenticated() and hasPermission(#questionId, 'content', 'owner')") public void deleteAnswers(final String questionId) { @@ -575,70 +525,6 @@ public class ContentServiceImpl implements ContentService, ApplicationEventPubli return answerRepository.getTotalAnswerCount(sessionKey); } - @Override - @PreAuthorize("isAuthenticated()") - public int getInterposedCount(final String sessionKey) { - return commentRepository.getInterposedCount(sessionKey); - } - - @Override - @PreAuthorize("isAuthenticated()") - public CommentReadingCount getInterposedReadingCount(final String sessionKey, String username) { - final Session session = sessionRepository.getSessionFromKeyword(sessionKey); - if (session == null) { - throw new NotFoundException(); - } - if (username == null) { - return commentRepository.getInterposedReadingCount(session); - } else { - User currentUser = userService.getCurrentUser(); - if (!currentUser.getUsername().equals(username)) { - throw new ForbiddenException(); - } - - return commentRepository.getInterposedReadingCount(session, currentUser); - } - } - - @Override - @PreAuthorize("isAuthenticated()") - public List<Comment> getInterposedQuestions(final String sessionKey, final int offset, final int limit) { - final Session session = this.getSession(sessionKey); - final User user = getCurrentUser(); - if (session.isCreator(user)) { - return commentRepository.getInterposedQuestions(session, offset, limit); - } else { - return commentRepository.getInterposedQuestions(session, user, offset, limit); - } - } - - @Override - @PreAuthorize("isAuthenticated()") - public Comment readInterposedQuestion(final String commentId) { - final User user = userService.getCurrentUser(); - return this.readInterposedQuestionInternal(commentId, user); - } - - /* - * The "internal" suffix means it is called by internal services that have no authentication! - * TODO: Find a better way of doing this... - */ - @Override - public Comment readInterposedQuestionInternal(final String commentId, User user) { - final Comment comment = commentRepository.getInterposedQuestion(commentId); - if (comment == null) { - throw new NotFoundException(); - } - final Session session = sessionRepository.getSessionFromId(comment.getSessionId()); - if (!comment.isCreator(user) && !session.isCreator(user)) { - throw new UnauthorizedException(); - } - if (session.isCreator(user)) { - commentRepository.markInterposedQuestionAsRead(comment); - } - return comment; - } - @Override @PreAuthorize("isAuthenticated()") public Content update(final Content content) { diff --git a/src/main/java/de/thm/arsnova/websocket/ArsnovaSocketioServerImpl.java b/src/main/java/de/thm/arsnova/websocket/ArsnovaSocketioServerImpl.java index 6cd3bf2a8..3fad4fc48 100644 --- a/src/main/java/de/thm/arsnova/websocket/ArsnovaSocketioServerImpl.java +++ b/src/main/java/de/thm/arsnova/websocket/ArsnovaSocketioServerImpl.java @@ -35,6 +35,7 @@ import de.thm.arsnova.events.*; import de.thm.arsnova.exceptions.NoContentException; import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.exceptions.UnauthorizedException; +import de.thm.arsnova.services.CommentService; import de.thm.arsnova.services.FeedbackService; import de.thm.arsnova.services.ContentService; import de.thm.arsnova.services.SessionService; @@ -78,6 +79,9 @@ public class ArsnovaSocketioServerImpl implements ArsnovaSocketioServer, Arsnova @Autowired private ContentService contentService; + @Autowired + private CommentService commentService; + private static final Logger logger = LoggerFactory.getLogger(ArsnovaSocketioServerImpl.class); private int portNumber; @@ -191,7 +195,7 @@ public class ArsnovaSocketioServerImpl implements ArsnovaSocketioServer, Arsnova AckRequest ackRequest) { final User user = userService.getUser2SocketId(client.getSessionId()); try { - contentService.readInterposedQuestionInternal(comment.getId(), user); + commentService.readInterposedQuestionInternal(comment.getId(), user); } catch (NotFoundException | UnauthorizedException e) { logger.error("Loading of comment {} failed for user {} with exception {}", comment.getId(), user, e.getMessage()); } -- GitLab