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