diff --git a/src/main/java/de/thm/arsnova/controller/v2/CommentController.java b/src/main/java/de/thm/arsnova/controller/v2/CommentController.java index dab81e01c66ac7c6fe96c0cd3319224892597779..83811330c90e535f838e0e9d9aaed2b6991b624d 100644 --- a/src/main/java/de/thm/arsnova/controller/v2/CommentController.java +++ b/src/main/java/de/thm/arsnova/controller/v2/CommentController.java @@ -126,6 +126,6 @@ public class CommentController extends PaginationController { nickname = "deleteComment") @RequestMapping(value = "/{commentId}", method = RequestMethod.DELETE) public void deleteComment(@ApiParam(value = "ID of the comment that needs to be deleted", required = true) @PathVariable final String commentId) { - commentService.delete(commentId); + commentService.delete(commentService.get(commentId)); } } diff --git a/src/main/java/de/thm/arsnova/controller/v2/ContentController.java b/src/main/java/de/thm/arsnova/controller/v2/ContentController.java index e097c27a0b0d01e9360269dd8bca8e10f2e96681..cc1a20422db636341d4fe152722291151a183262 100644 --- a/src/main/java/de/thm/arsnova/controller/v2/ContentController.java +++ b/src/main/java/de/thm/arsnova/controller/v2/ContentController.java @@ -53,6 +53,7 @@ import org.springframework.web.bind.annotation.RestController; import javax.naming.OperationNotSupportedException; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -250,7 +251,7 @@ public class ContentController extends PaginationController { @RequestParam(required = false) final Boolean publish, @RequestParam(value = "lecturequestionsonly", defaultValue = "false", required = false) boolean lectureContentsOnly, @RequestParam(value = "preparationquestionsonly", defaultValue = "false", required = false) boolean preparationContentsOnly - ) { + ) throws IOException { String roomId = roomService.getIdByShortId(roomShortId); boolean p = publish == null || publish; Iterable<de.thm.arsnova.model.Content> contents; @@ -555,7 +556,7 @@ public class ContentController extends PaginationController { @PathVariable final String answerId, final HttpServletResponse response ) { - answerService.deleteAnswer(contentId, answerId); + answerService.delete(answerService.get(answerId)); } @ApiOperation(value = "Delete answers from a content, identified by content ID", diff --git a/src/main/java/de/thm/arsnova/controller/v2/MotdController.java b/src/main/java/de/thm/arsnova/controller/v2/MotdController.java index 812f9ab18d95fa03b4171c5449ede78204e45267..7e65c4400a55610e6aa4acdb8dbb5962465ad796 100644 --- a/src/main/java/de/thm/arsnova/controller/v2/MotdController.java +++ b/src/main/java/de/thm/arsnova/controller/v2/MotdController.java @@ -148,11 +148,7 @@ public class MotdController extends AbstractController { @RequestMapping(value = "/{motdId}", method = RequestMethod.DELETE) public void deleteMotd(@ApiParam(value = "Motd-key from the message that shall be deleted", required = true) @PathVariable final String motdId) { de.thm.arsnova.model.Motd motd = motdService.get(motdId); - if (motd.getAudience() == de.thm.arsnova.model.Motd.Audience.ROOM) { - motdService.deleteByRoomId(motd.getRoomId(), motd); - } else { - motdService.delete(motd); - } + motdService.delete(motd); } @RequestMapping(value = "/userlist", method = RequestMethod.GET) diff --git a/src/main/java/de/thm/arsnova/controller/v2/RoomController.java b/src/main/java/de/thm/arsnova/controller/v2/RoomController.java index baef51c6f0e9d3b30b0c8cc427dee350291183c4..981d13b73791a773cfa1b4821bf096ac7e88bbd1 100644 --- a/src/main/java/de/thm/arsnova/controller/v2/RoomController.java +++ b/src/main/java/de/thm/arsnova/controller/v2/RoomController.java @@ -51,6 +51,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -307,7 +308,7 @@ public class RoomController extends PaginationController { @ApiParam(value = "wether statistics shall be exported", required = true) @RequestParam(value = "withAnswerStatistics", defaultValue = "false") final Boolean withAnswerStatistics, @ApiParam(value = "wether comments shall be exported", required = true) @RequestParam(value = "withFeedbackQuestions", defaultValue = "false") final Boolean withFeedbackQuestions, final HttpServletResponse response - ) { + ) throws IOException { List<ImportExportContainer> rooms = new ArrayList<>(); ImportExportContainer temp; for (String shortId : shortIds) { @@ -327,7 +328,7 @@ public class RoomController extends PaginationController { public Room copyToPublicPool( @ApiParam(value = "Room-Key from current Room", required = true) @PathVariable final String shortId, @ApiParam(value = "public pool attributes for Room", required = true) @RequestBody final ImportExportContainer.PublicPool publicPool - ) { + ) throws IOException { String id = roomService.getIdByShortId(shortId); roomService.setActive(id, false); de.thm.arsnova.model.Room roomInfo = roomService.copyRoomToPublicPool(shortId, publicPool); @@ -347,7 +348,7 @@ public class RoomController extends PaginationController { @ApiParam(value = "Room-Key from current Room", required = true) @PathVariable final String shortId, @ApiParam(value = "lock", required = true) @RequestParam(required = false) final Boolean lock, final HttpServletResponse response - ) { + ) throws IOException { if (lock != null) { return toV2Migrator.migrate(roomService.setActive(roomService.getIdByShortId(shortId), lock)); } @@ -412,7 +413,7 @@ public class RoomController extends PaginationController { @ApiParam(value = "Room-Key from current Room", required = true) @PathVariable final String shortId, @ApiParam(value = "lock", required = true) @RequestParam(required = true) final Boolean lock, final HttpServletResponse response - ) { + ) throws IOException { return String.valueOf(roomService.lockFeedbackInput(roomService.getIdByShortId(shortId), lock)); } diff --git a/src/main/java/de/thm/arsnova/event/DeleteAllLectureAnswersEvent.java b/src/main/java/de/thm/arsnova/event/DeleteAllLectureAnswersEvent.java deleted file mode 100644 index 0ad169a83f106857f86abfcde7e31bceed8600ab..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/DeleteAllLectureAnswersEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -/** - * Fires whenever all answers of all lecture questions of a session are deleted. - */ -public class DeleteAllLectureAnswersEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - public DeleteAllLectureAnswersEvent(Object source, String roomId) { - super(source, roomId); - } - -} diff --git a/src/main/java/de/thm/arsnova/event/DeleteAllPreparationAnswersEvent.java b/src/main/java/de/thm/arsnova/event/DeleteAllPreparationAnswersEvent.java deleted file mode 100644 index 49a8d9342797071f7ebd37b6c75afcdcb9f47f78..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/DeleteAllPreparationAnswersEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -/** - * Fires whenever all answers of all preparation questions of a session are deleted. - */ -public class DeleteAllPreparationAnswersEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - public DeleteAllPreparationAnswersEvent(Object source, String roomId) { - super(source, roomId); - } -} diff --git a/src/main/java/de/thm/arsnova/event/DeleteAllQuestionsAnswersEvent.java b/src/main/java/de/thm/arsnova/event/DeleteAllQuestionsAnswersEvent.java deleted file mode 100644 index aa671783fd1f776fa34607ad8827a497102149b7..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/DeleteAllQuestionsAnswersEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -/** - * Fires whenever all answers of all questions of a session are deleted. - */ -public class DeleteAllQuestionsAnswersEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - public DeleteAllQuestionsAnswersEvent(Object source, String roomId) { - super(source, roomId); - } -} diff --git a/src/main/java/de/thm/arsnova/event/DeleteAllQuestionsEvent.java b/src/main/java/de/thm/arsnova/event/DeleteAllQuestionsEvent.java deleted file mode 100644 index 2bf5bac225a909d0076af155c12c37a03123e581..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/DeleteAllQuestionsEvent.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -/** - * Fires whenever all questions of a session are deleted. Note that this implies that all answers are deleted as well, - * even though the specific answer events are not fired. - */ -public class DeleteAllQuestionsEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - public DeleteAllQuestionsEvent(Object source, String roomId) { - super(source, roomId); - } - -} diff --git a/src/main/java/de/thm/arsnova/event/FeatureChangeEvent.java b/src/main/java/de/thm/arsnova/event/FeatureChangeEvent.java deleted file mode 100644 index 790eaea277ef8862e588493afcf92f45d842c5ac..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/FeatureChangeEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -/** - * Fires whenever a new session is created. - */ -public class FeatureChangeEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - public FeatureChangeEvent(Object source, String roomId) { - super(source, roomId); - } - -} diff --git a/src/main/java/de/thm/arsnova/event/LockFeedbackEvent.java b/src/main/java/de/thm/arsnova/event/LockFeedbackEvent.java deleted file mode 100644 index 6c50fc4b8cad526d36ed7f5c30b68390515c7a2b..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/LockFeedbackEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -/** - * Fires whenever voting on a question is disabled. - */ -public class LockFeedbackEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - public LockFeedbackEvent(Object source, String roomId) { - super(source, roomId); - } -} diff --git a/src/main/java/de/thm/arsnova/event/LockQuestionEvent.java b/src/main/java/de/thm/arsnova/event/LockQuestionEvent.java deleted file mode 100644 index 58d5b6fbf60e9fc0dd3d53591e1f36c2bc6c4f4a..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/LockQuestionEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -/** - * Fires whenever a content is disabled, i.e., it is hidden from students. - */ -public class LockQuestionEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private final Content content; - - public LockQuestionEvent(Object source, String roomId, Content content) { - super(source, roomId); - this.content = content; - } - - public Content getQuestion() { - return this.content; - } - -} diff --git a/src/main/java/de/thm/arsnova/event/LockQuestionsEvent.java b/src/main/java/de/thm/arsnova/event/LockQuestionsEvent.java deleted file mode 100644 index 869d0c1a0071a765140c5b277ecbb0e8947c5cbb..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/LockQuestionsEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.List; - -/** - * Fires whenever a set of contents are disabled, i.e., they are hidden from students. - */ -public class LockQuestionsEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private List<Content> contents; - - public LockQuestionsEvent(Object source, String roomId, List<Content> contents) { - super(source, roomId); - this.contents = contents; - } - - public List<Content> getQuestions() { - return this.contents; - } - -} diff --git a/src/main/java/de/thm/arsnova/event/LockVoteEvent.java b/src/main/java/de/thm/arsnova/event/LockVoteEvent.java deleted file mode 100644 index bf3ba29733e2fde71e0da5b6b701ef34f5847721..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/LockVoteEvent.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.HashMap; -import java.util.Map; - -/** - * Fires whenever voting on a content is disabled. - */ -public class LockVoteEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private final Content content; - - public LockVoteEvent(Object source, String roomId, Content content) { - super(source, roomId); - this.content = content; - } - - public String getQuestionId() { - return this.content.getId(); - } - - public String getGroup() { - /* FIXME: Event does not support content with multiple groups */ - return content.getGroups().toArray(new String[1])[0]; - } - - public Boolean getVotingDisabled() { - /* FIXME: migrate */ - return false; - //return this.content.isVotingDisabled(); - } - - public Map<String, Object> getVotingAdmission() { - Map<String, Object> map = new HashMap<>(); - - map.put("_id", getQuestionId()); - map.put("variant", getGroup()); - return map; - } -} diff --git a/src/main/java/de/thm/arsnova/event/LockVotesEvent.java b/src/main/java/de/thm/arsnova/event/LockVotesEvent.java deleted file mode 100644 index 7595c19a2ebc14b46bdb4429fd7e011548e9dc04..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/LockVotesEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.List; - -/** - * Fires whenever voting of multiple contents is disabled. - */ -public class LockVotesEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private List<Content> contents; - - public LockVotesEvent(Object source, String roomId, List<Content> contents) { - super(source, roomId); - this.contents = contents; - } - - public List<Content> getQuestions() { - return this.contents; - } - -} diff --git a/src/main/java/de/thm/arsnova/event/PiRoundCancelEvent.java b/src/main/java/de/thm/arsnova/event/PiRoundCancelEvent.java deleted file mode 100644 index 73fadca6db1e3a9379dea4ebc691cbb59097d01b..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/PiRoundCancelEvent.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -/** - * Fires whenever a peer instruction round is canceled. - */ -public class PiRoundCancelEvent extends PiRoundEndEvent { - - private static final long serialVersionUID = 1L; - - public PiRoundCancelEvent(Object source, String roomId, Content content) { - super(source, roomId, content); - } - -} diff --git a/src/main/java/de/thm/arsnova/event/PiRoundDelayedStartEvent.java b/src/main/java/de/thm/arsnova/event/PiRoundDelayedStartEvent.java deleted file mode 100644 index c12cc8782616ad96191c46ab3fe592a2b06f79cd..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/PiRoundDelayedStartEvent.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -/** - * Fires whenever a delayed peer instruction round is initiated. The delayed part denotes that this round might not - * have been started yet. - */ -public class PiRoundDelayedStartEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - private final String questionId; - private final Date startTime; - private final Date endTime; - private final String group; - private int piRound; - - public PiRoundDelayedStartEvent(Object source, String roomId, Content content) { - super(source, roomId); - this.questionId = content.getId(); - /* FIXME: Event does not support content with multiple groups */ - this.group = content.getGroups().toArray(new String[1])[0]; - this.piRound = content.getState().getRound(); - this.endTime = content.getState().getRoundEndTimestamp(); - this.startTime = new Date(); - } - - public String getQuestionId() { - return questionId; - } - - public Date getStartTime() { - return startTime; - } - - public Date getEndTime() { - return endTime; - } - - public String getGroup() { - return group; - } - - public Integer getPiRound() { - return piRound; - } - - public Map<String, Object> getPiRoundInformations() { - Map<String, Object> map = new HashMap<>(); - - map.put("_id", getQuestionId()); - map.put("endTime", getEndTime().getTime()); - map.put("startTime", getStartTime().getTime()); - map.put("variant", getGroup()); - map.put("round", getPiRound()); - - return map; - } -} diff --git a/src/main/java/de/thm/arsnova/event/PiRoundEndEvent.java b/src/main/java/de/thm/arsnova/event/PiRoundEndEvent.java deleted file mode 100644 index 8d56a813950b1292eff2818bb6b5a54b2cc6d024..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/PiRoundEndEvent.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.HashMap; -import java.util.Map; - -/** - * Fires whenever a peer instruction round has ended. - */ -public class PiRoundEndEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private final String contentId; - private final String group; - - public PiRoundEndEvent(Object source, String roomId, Content content) { - super(source, roomId); - contentId = content.getId(); - /* FIXME: Event does not support content with multiple groups */ - this.group = content.getGroups().toArray(new String[1])[0]; - } - - public String getContentId() { - return contentId; - } - - public String getGroup() { - return group; - } - - public Map<String, String> getPiRoundEndInformations() { - Map<String, String> map = new HashMap<>(); - - map.put("_id", getContentId()); - map.put("variant", getGroup()); - - return map; - } - -} diff --git a/src/main/java/de/thm/arsnova/event/PiRoundResetEvent.java b/src/main/java/de/thm/arsnova/event/PiRoundResetEvent.java deleted file mode 100644 index 2b4cd53254f022f33241402c0e13cf595b455eb5..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/PiRoundResetEvent.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.HashMap; -import java.util.Map; - -/** - * Fires whenever a peer instruction round is reset. - */ -public class PiRoundResetEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private final String contentId; - private final String group; - - public PiRoundResetEvent(Object source, String roomId, Content content) { - super(source, roomId); - contentId = content.getId(); - /* FIXME: Event does not support content with multiple groups */ - this.group = content.getGroups().toArray(new String[1])[0]; - } - - public String getContentId() { - return contentId; - } - - public String getGroup() { - return group; - } - - public Map<String, String> getPiRoundResetInformations() { - Map<String, String> map = new HashMap<>(); - - map.put("_id", getContentId()); - map.put("variant", getGroup()); - - return map; - } - -} diff --git a/src/main/java/de/thm/arsnova/event/StatusRoomEvent.java b/src/main/java/de/thm/arsnova/event/StatusRoomEvent.java deleted file mode 100644 index d7307cd7919c8fd161e5e1fd3522dc31b101338b..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/StatusRoomEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -/** - * Fires whenever the status of a session changes, i.e., it is enabled or disabled. - */ -public class StatusRoomEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - public StatusRoomEvent(Object source, String roomId) { - super(source, roomId); - } - -} diff --git a/src/main/java/de/thm/arsnova/event/UnlockQuestionEvent.java b/src/main/java/de/thm/arsnova/event/UnlockQuestionEvent.java deleted file mode 100644 index deddf45f1f18a762ae3650fd6e8ebd817d967db3..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/UnlockQuestionEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -/** - * Fires whenever a content is enabled, i.e., it becomes visible to students. - */ -public class UnlockQuestionEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private final Content content; - - public UnlockQuestionEvent(Object source, String roomId, Content content) { - super(source, roomId); - this.content = content; - } - - public Content getQuestion() { - return this.content; - } - -} diff --git a/src/main/java/de/thm/arsnova/event/UnlockQuestionsEvent.java b/src/main/java/de/thm/arsnova/event/UnlockQuestionsEvent.java deleted file mode 100644 index 81f38cc60c40641ccd22223e26d0f4a6b80fdc47..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/UnlockQuestionsEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.List; - -/** - * Fires whenever a set of contents are enabled, i.e., they become visible to students. - */ -public class UnlockQuestionsEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private List<Content> contents; - - public UnlockQuestionsEvent(Object source, String roomId, List<Content> contents) { - super(source, roomId); - this.contents = contents; - } - - public List<Content> getQuestions() { - return this.contents; - } - -} diff --git a/src/main/java/de/thm/arsnova/event/UnlockVoteEvent.java b/src/main/java/de/thm/arsnova/event/UnlockVoteEvent.java deleted file mode 100644 index 3dd6996e3fd8cad2810ce3fd887088864d4a056f..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/UnlockVoteEvent.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.HashMap; -import java.util.Map; - -/** - * Fires whenever voting on a content is enabled. - */ -public class UnlockVoteEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private final Content content; - - public UnlockVoteEvent(Object source, String roomId, Content content) { - super(source, roomId); - this.content = content; - } - - public String getQuestionId() { - return this.content.getId(); - } - - public String getGroup() { - /* FIXME: Event does not support content with multiple groups */ - return content.getGroups().toArray(new String[1])[0]; - } - - public Boolean getVotingDisabled() { - return !this.content.getState().isResponsesEnabled(); - } - - public Map<String, Object> getVotingAdmission() { - Map<String, Object> map = new HashMap<>(); - - map.put("_id", getQuestionId()); - map.put("variant", getGroup()); - return map; - } -} diff --git a/src/main/java/de/thm/arsnova/event/UnlockVotesEvent.java b/src/main/java/de/thm/arsnova/event/UnlockVotesEvent.java deleted file mode 100644 index 85cf1d06f9a8ce5b55c3fd48b9cc6a0c4dc005bf..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/event/UnlockVotesEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of ARSnova Backend. - * Copyright (C) 2012-2018 The ARSnova Team and Contributors - * - * ARSnova Backend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ARSnova Backend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.thm.arsnova.event; - -import de.thm.arsnova.model.Content; - -import java.util.List; - -/** - * Fires whenever voting of multiple contents is enabled. - */ -public class UnlockVotesEvent extends RoomEvent { - - private static final long serialVersionUID = 1L; - - private List<Content> contents; - - public UnlockVotesEvent(Object source, String roomId, List<Content> contents) { - super(source, roomId); - this.contents = contents; - } - - public List<Content> getQuestions() { - return this.contents; - } - -} diff --git a/src/main/java/de/thm/arsnova/service/AnswerService.java b/src/main/java/de/thm/arsnova/service/AnswerService.java index 759815ccf0dd77f8afccf504940dc9c6c2794c6d..01a1a6fc37fdfa5cffd3875ab94a9bff4983168f 100644 --- a/src/main/java/de/thm/arsnova/service/AnswerService.java +++ b/src/main/java/de/thm/arsnova/service/AnswerService.java @@ -42,8 +42,6 @@ public interface AnswerService extends EntityService<Answer> { Answer updateAnswer(Answer answer); - void deleteAnswer(String contentId, String answerId); - Map<String, Object> countAnswersAndAbstentionsInternal(String contentId); int countLectureContentAnswers(String roomId); diff --git a/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java b/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java index bc0b146cb937bee6a1dca389b4c634e046b42a5c..8bf36e4fccaa8d8c390a02ed6a59b3e429831164 100644 --- a/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java @@ -27,8 +27,6 @@ import de.thm.arsnova.model.Room; import de.thm.arsnova.model.TextAnswer; import de.thm.arsnova.model.transport.AnswerQueueElement; import de.thm.arsnova.persistence.AnswerRepository; -import de.thm.arsnova.persistence.ContentRepository; -import de.thm.arsnova.persistence.RoomRepository; import de.thm.arsnova.security.User; import de.thm.arsnova.web.exceptions.NotFoundException; import de.thm.arsnova.web.exceptions.UnauthorizedException; @@ -58,23 +56,21 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen private final Queue<AnswerQueueElement> answerQueue = new ConcurrentLinkedQueue<>(); - private RoomRepository roomRepository; - private ContentRepository contentRepository; - private AnswerRepository answerRepository; + private RoomService roomService; private ContentService contentService; + private AnswerRepository answerRepository; private UserService userService; public AnswerServiceImpl( AnswerRepository repository, - ContentRepository contentRepository, - RoomRepository roomRepository, + RoomService roomService, ContentService contentService, UserService userService, @Qualifier("defaultJsonMessageConverter") MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) { super(Answer.class, repository, jackson2HttpMessageConverter.getObjectMapper()); this.answerRepository = repository; - this.contentRepository = contentRepository; - this.roomRepository = roomRepository; + this.roomService = roomService; + this.contentService = contentService; this.contentService = contentService; this.userService = userService; } @@ -110,7 +106,7 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen @Override @PreAuthorize("hasPermission(#contentId, 'content', 'owner')") public void deleteAnswers(final String contentId) { - final Content content = contentRepository.findOne(contentId); + final Content content = contentService.get(contentId); content.resetState(); /* FIXME: cancel timer */ contentService.update(content); @@ -129,7 +125,7 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen @Override public void getFreetextAnswerAndMarkRead(final String answerId, final String userId) { - final Answer answer = answerRepository.findOne(answerId); + final Answer answer = get(answerId); if (!(answer instanceof TextAnswer)) { throw new NotFoundException(); } @@ -137,17 +133,17 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen if (textAnswer.isRead()) { return; } - final Room room = roomRepository.findOne(textAnswer.getRoomId()); + final Room room = roomService.get(textAnswer.getRoomId()); if (room.getOwnerId().equals(userId)) { textAnswer.setRead(true); - answerRepository.save(textAnswer); + update(textAnswer); } } @Override @PreAuthorize("isAuthenticated()") public AnswerStatistics getStatistics(final String contentId, final int round) { - final ChoiceQuestionContent content = (ChoiceQuestionContent) contentRepository.findOne(contentId); + final ChoiceQuestionContent content = (ChoiceQuestionContent) contentService.get(contentId); if (content == null) { throw new NotFoundException(); } @@ -191,7 +187,7 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen @PreAuthorize("isAuthenticated()") public List<TextAnswer> getTextAnswers(final String contentId, final int piRound, final int offset, final int limit) { /* FIXME: round support not implemented */ - final Content content = contentRepository.findOne(contentId); + final Content content = contentService.get(contentId); if (content == null) { throw new NotFoundException(); } @@ -320,7 +316,7 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen if (content == null) { throw new NotFoundException(); } - final Room room = roomRepository.findOne(content.getRoomId()); + final Room room = roomService.get(content.getRoomId()); answer.setCreatorId(user.getId()); answer.setContentId(content.getId()); @@ -371,43 +367,22 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen content.checkTextStrictOptions(realAnswer); } */ - final Room room = roomRepository.findOne(content.getRoomId()); + final Room room = roomService.get(content.getRoomId()); answer.setCreatorId(user.getId()); answer.setContentId(content.getId()); answer.setRoomId(room.getId()); - this.eventPublisher.publishEvent(new BeforeCreationEvent<>(this, realAnswer)); - answerRepository.save(realAnswer); - this.eventPublisher.publishEvent(new AfterCreationEvent<>(this, realAnswer)); + update(realAnswer); return answer; } - /* FIXME: Remove, this should be handled by EntityService! */ - @Override - @PreAuthorize("isAuthenticated()") - @CacheEvict(value = "answerlists", allEntries = true) - public void deleteAnswer(final String contentId, final String answerId) { - final Content content = contentRepository.findOne(contentId); - if (content == null) { - throw new NotFoundException(); - } - final User user = userService.getCurrentUser(); - final Room room = roomRepository.findOne(content.getRoomId()); - if (user == null || room == null || !room.getOwnerId().equals(user.getId())) { - throw new UnauthorizedException(); - } - //this.eventPublisher.publishEvent(new BeforeDeletionEvent<>(answer)); - answerRepository.deleteById(answerId); - //this.eventPublisher.publishEvent(new AfterDeletionEvent<>(answer)); - } - /* * The "internal" suffix means it is called by internal services that have no authentication! * TODO: Find a better way of doing this... */ @Override public int countLectureQuestionAnswersInternal(final String roomId) { - return answerRepository.countByRoomIdOnlyLectureVariant(roomRepository.findOne(roomId).getId()); + return answerRepository.countByRoomIdOnlyLectureVariant(roomService.get(roomId).getId()); } @Override @@ -444,6 +419,6 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen */ @Override public int countPreparationQuestionAnswersInternal(final String roomId) { - return answerRepository.countByRoomIdOnlyPreparationVariant(roomRepository.findOne(roomId).getId()); + return answerRepository.countByRoomIdOnlyPreparationVariant(roomService.get(roomId).getId()); } } diff --git a/src/main/java/de/thm/arsnova/service/CommentService.java b/src/main/java/de/thm/arsnova/service/CommentService.java index a359bf881312b0c1f99846ade9140444c125e1be..5c0202e3210517b5349185075ce7431fc1498995 100644 --- a/src/main/java/de/thm/arsnova/service/CommentService.java +++ b/src/main/java/de/thm/arsnova/service/CommentService.java @@ -15,7 +15,5 @@ public interface CommentService extends EntityService<Comment> { Comment getAndMarkRead(String commentId) throws IOException; - void delete(String commentId); - void deleteByRoomId(String roomId); } diff --git a/src/main/java/de/thm/arsnova/service/CommentServiceImpl.java b/src/main/java/de/thm/arsnova/service/CommentServiceImpl.java index 91e7708ef82922b67b44d8a33183f1af1c6d83f8..69c1241f46d801983ed2bf70d58793a6605cb6ab 100644 --- a/src/main/java/de/thm/arsnova/service/CommentServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/CommentServiceImpl.java @@ -1,12 +1,9 @@ package de.thm.arsnova.service; -import de.thm.arsnova.event.AfterDeletionEvent; -import de.thm.arsnova.event.BeforeDeletionEvent; import de.thm.arsnova.model.Comment; import de.thm.arsnova.model.Room; import de.thm.arsnova.model.migration.v2.CommentReadingCount; import de.thm.arsnova.persistence.CommentRepository; -import de.thm.arsnova.persistence.RoomRepository; import de.thm.arsnova.security.User; import de.thm.arsnova.web.exceptions.ForbiddenException; import de.thm.arsnova.web.exceptions.NotFoundException; @@ -29,25 +26,25 @@ import java.util.Map; public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implements CommentService { private UserService userService; - private CommentRepository commentRepository; + private RoomService roomService; - private RoomRepository roomRepository; + private CommentRepository commentRepository; public CommentServiceImpl( CommentRepository repository, - RoomRepository roomRepository, + RoomService roomService, UserService userService, @Qualifier("defaultJsonMessageConverter") MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) { super(Comment.class, repository, jackson2HttpMessageConverter.getObjectMapper()); this.commentRepository = repository; - this.roomRepository = roomRepository; + this.roomService = roomService; this.userService = userService; } @Override @PreAuthorize("isAuthenticated()") public void prepareCreate(final Comment comment) { - final Room room = roomRepository.findOne(comment.getRoomId()); + final Room room = roomService.get(comment.getRoomId()); final User user = userService.getCurrentUser(); comment.setCreatorId(user.getId()); comment.setRead(false); @@ -57,23 +54,10 @@ public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implem /* TODO: fire event */ } - /* FIXME: Remove, EntityService should handle this! */ - @Override - @PreAuthorize("hasPermission(#commentId, 'comment', 'owner')") - public void delete(final String commentId) { - final Comment comment = commentRepository.findOne(commentId); - if (comment == null) { - throw new NotFoundException(); - } - eventPublisher.publishEvent(new BeforeDeletionEvent<>(this, comment)); - commentRepository.delete(comment); - eventPublisher.publishEvent(new AfterDeletionEvent<>(this, comment)); - } - @Override @PreAuthorize("isAuthenticated()") public void deleteByRoomId(final String roomId) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (room == null) { throw new UnauthorizedException(); } @@ -109,7 +93,7 @@ public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implem @Override @PreAuthorize("isAuthenticated()") public List<Comment> getByRoomId(final String roomId, final int offset, final int limit) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); final User user = getCurrentUser(); if (room.getOwnerId().equals(user.getId())) { return commentRepository.findByRoomId(room.getId(), offset, limit); @@ -121,7 +105,7 @@ public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implem @Override @PreAuthorize("hasPermission(#commentId, 'comment', 'update')") public Comment getAndMarkRead(final String commentId) throws IOException { - final Comment comment = commentRepository.findOne(commentId); + final Comment comment = get(commentId); if (comment == null) { throw new NotFoundException(); } diff --git a/src/main/java/de/thm/arsnova/service/ContentService.java b/src/main/java/de/thm/arsnova/service/ContentService.java index dbb3d8b5a9806e42c94aacbbded01fa8d3eb687e..355377a440aa1f33c293cc174663a3e66229e66f 100644 --- a/src/main/java/de/thm/arsnova/service/ContentService.java +++ b/src/main/java/de/thm/arsnova/service/ContentService.java @@ -36,6 +36,7 @@ package de.thm.arsnova.service; import de.thm.arsnova.model.Content; +import java.io.IOException; import java.util.List; /** @@ -74,9 +75,9 @@ public interface ContentService extends EntityService<Content> { List<String> getUnAnsweredPreparationContentIds(String roomId, String userId); - void publishAll(String roomId, boolean publish); + void publishAll(String roomId, boolean publish) throws IOException; - void publishContents(String roomId, boolean publish, Iterable<Content> contents); + void publishContents(String roomId, boolean publish, Iterable<Content> contents) throws IOException; void deleteAllContentsAnswers(String roomId); diff --git a/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java b/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java index eec4adbd4c1b07258eccf1daaa43aaecf5177551..1f31288f168518873d2d5ce184c80e54efde0d15 100644 --- a/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java @@ -17,13 +17,11 @@ */ package de.thm.arsnova.service; -import de.thm.arsnova.event.*; import de.thm.arsnova.model.Content; import de.thm.arsnova.model.Room; import de.thm.arsnova.persistence.AnswerRepository; import de.thm.arsnova.persistence.ContentRepository; import de.thm.arsnova.persistence.LogEntryRepository; -import de.thm.arsnova.persistence.RoomRepository; import de.thm.arsnova.security.User; import de.thm.arsnova.web.exceptions.NotFoundException; import de.thm.arsnova.web.exceptions.UnauthorizedException; @@ -39,7 +37,7 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import java.io.IOException; -import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -55,9 +53,9 @@ import java.util.stream.Collectors; public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implements ContentService { private UserService userService; - private LogEntryRepository dbLogger; + private RoomService roomService; - private RoomRepository roomRepository; + private LogEntryRepository dbLogger; private ContentRepository contentRepository; @@ -67,15 +65,15 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem public ContentServiceImpl( ContentRepository repository, + RoomService roomService, AnswerRepository answerRepository, - RoomRepository roomRepository, LogEntryRepository dbLogger, UserService userService, @Qualifier("defaultJsonMessageConverter") MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) { super(Content.class, repository, jackson2HttpMessageConverter.getObjectMapper()); this.contentRepository = repository; + this.roomService = roomService; this.answerRepository = answerRepository; - this.roomRepository = roomRepository; this.dbLogger = dbLogger; this.userService = userService; } @@ -91,7 +89,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem } //content.setSessionKeyword(roomRepository.getSessionFromId(content.getRoomId()).getKeyword()); - Room room = roomRepository.findOne(content.getRoomId()); + Room room = roomService.get(content.getRoomId()); content.setGroups(room.getContentGroups().stream() .map(Room.ContentGroup::getName).collect(Collectors.toSet())); @@ -108,7 +106,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @PreAuthorize("isAuthenticated()") //@Cacheable("contentlists") public List<Content> getByRoomId(final String roomId) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); final User user = userService.getCurrentUser(); if (room.getOwnerId().equals(user.getId())) { return contentRepository.findByRoomIdForSpeaker(roomId); @@ -119,7 +117,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override public Iterable<Content> getByRoomIdAndGroup(final String roomId, final String group) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); Room.ContentGroup contentGroup = null; for (Room.ContentGroup cg : room.getContentGroups()) { if (cg.getName().equals(group)) { @@ -141,7 +139,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override public int countByRoomIdAndGroup(final String roomId, final String group) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); Room.ContentGroup contentGroup = null; for (Room.ContentGroup cg : room.getContentGroups()) { if (cg.getName().equals(group)) { @@ -181,7 +179,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override public void finalizeCreate(final Content content) { /* Update content groups of room */ - final Room room = roomRepository.findOne(content.getRoomId()); + final Room room = roomService.get(content.getRoomId()); final Set<Room.ContentGroup> contentGroups = room.getContentGroups(); for (final Room.ContentGroup cg : contentGroups) { if (content.getGroups().contains(cg.getName())) { @@ -198,20 +196,18 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem newGroup.setContentIds(newContentIds); room.getContentGroups().add(newGroup); } - eventPublisher.publishEvent(new BeforeCreationEvent<>(this, content)); - roomRepository.save(room); - eventPublisher.publishEvent(new AfterCreationEvent<>(this, content)); + roomService.update(room); } @Override public void prepareUpdate(final Content content) { final User user = userService.getCurrentUser(); - final Content oldContent = contentRepository.findOne(content.getId()); + final Content oldContent = get(content.getId()); if (null == oldContent) { throw new NotFoundException(); } - final Room room = roomRepository.findOne(content.getRoomId()); + final Room room = roomService.get(content.getRoomId()); if (user == null || room == null || !room.getOwnerId().equals(user.getId())) { throw new UnauthorizedException(); } @@ -229,7 +225,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override public void finalizeUpdate(final Content content) { /* Update content groups of room */ - final Room room = roomRepository.findOne(content.getRoomId()); + final Room room = roomService.get(content.getRoomId()); for (final Room.ContentGroup cg : room.getContentGroups()) { if (content.getGroups().contains(cg.getName())) { cg.getContentIds().add(content.getId()); @@ -250,7 +246,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem newGroup.setContentIds(newContentIds); room.getContentGroups().add(newGroup); } - roomRepository.save(room); + roomService.update(room); /* TODO: not sure yet how to refactor this code - we need access to the old and new entity if (!oldContent.getState().isVisible() && content.getState().isVisible()) { @@ -274,28 +270,14 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @CacheEvict(value = "preparationcontentlists", allEntries = true /*, condition = "#content.getGroups().contains('preparation')"*/), @CacheEvict(value = "flashcardcontentlists", allEntries = true /*, condition = "#content.getGroups().contains('flashcard')"*/) }) public void delete(final String contentId) { - final Content content = contentRepository.findOne(contentId); + final Content content = get(contentId); if (content == null) { throw new NotFoundException(); } - final Room room = roomRepository.findOne(content.getRoomId()); - if (room == null) { - throw new UnauthorizedException(); - } - - for (final Room.ContentGroup contentGroup : room.getContentGroups()) { - if (content.getGroups().contains(contentGroup.getName())) { - contentGroup.getContentIds().remove(contentId); - } - } - roomRepository.save(room); - try { final int count = answerRepository.deleteByContentId(contentId); - eventPublisher.publishEvent(new BeforeDeletionEvent<>(this, content)); - contentRepository.deleteById(contentId); - eventPublisher.publishEvent(new AfterDeletionEvent<>(this, content)); + delete(content); dbLogger.log("delete", "type", "content", "answerCount", count); } catch (final IllegalArgumentException e) { logger.error("Could not delete content {}.", contentId, e); @@ -317,13 +299,11 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem contentIds = contentRepository.findIdsByRoomIdAndVariant(room.getId(), variant); } + /* TODO: use EntityService! */ final int answerCount = answerRepository.deleteByContentIds(contentIds); final int contentCount = contentRepository.deleteByRoomId(room.getId()); dbLogger.log("delete", "type", "question", "questionCount", contentCount); dbLogger.log("delete", "type", "answer", "answerCount", answerCount); - - final DeleteAllQuestionsEvent event = new DeleteAllQuestionsEvent(this, room.getId()); - this.eventPublisher.publishEvent(event); } @Override @@ -357,8 +337,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override @PreAuthorize("hasPermission(#contentId, 'content', 'owner')") public void setVotingAdmission(final String contentId, final boolean disableVoting) { - final Content content = contentRepository.findOne(contentId); - final Room room = roomRepository.findOne(content.getRoomId()); + final Content content = get(contentId); content.getState().setResponsesEnabled(!disableVoting); if (!disableVoting && !content.getState().isVisible()) { @@ -367,13 +346,6 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem } else { update(content); } - ArsnovaEvent event; - if (disableVoting) { - event = new LockVoteEvent(this, room.getId(), content); - } else { - event = new UnlockVoteEvent(this, room.getId(), content); - } - this.eventPublisher.publishEvent(event); } @Override @@ -385,7 +357,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @CacheEvict(value = "flashcardcontentlists", key = "#roomId") }) public void setVotingAdmissions(final String roomId, final boolean disableVoting, Iterable<Content> contents) { final User user = getCurrentUser(); - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (!room.getOwnerId().equals(user.getId())) { throw new UnauthorizedException(); } @@ -395,15 +367,6 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem patches.put("responsesEnabled", !disableVoting); try { patch(contents, patches, Content::getState); - ArsnovaEvent event; - List<Content> list = new ArrayList<>(); - contents.forEach(list::add); - if (disableVoting) { - event = new LockVotesEvent(this, room.getId(), list); - } else { - event = new UnlockVotesEvent(this, room.getId(), list); - } - this.eventPublisher.publishEvent(event); } catch (IOException e) { logger.error("Patching of contents failed", e); } @@ -411,7 +374,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem private Room getRoomWithAuthCheck(final String roomId) { final User user = userService.getCurrentUser(); - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (user == null || room == null || !room.getOwnerId().equals(user.getId())) { throw new UnauthorizedException(); } @@ -468,10 +431,10 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override @PreAuthorize("isAuthenticated()") - public void publishAll(final String roomId, final boolean publish) { + public void publishAll(final String roomId, final boolean publish) throws IOException { /* TODO: resolve redundancies */ final User user = getCurrentUser(); - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (!room.getOwnerId().equals(user.getId())) { throw new UnauthorizedException(); } @@ -486,25 +449,13 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @CacheEvict(value = "lecturecontentlists", key = "#roomId"), @CacheEvict(value = "preparationcontentlists", key = "#roomId"), @CacheEvict(value = "flashcardcontentlists", key = "#roomId") }) - public void publishContents(final String roomId, final boolean publish, Iterable<Content> contents) { + public void publishContents(final String roomId, final boolean publish, Iterable<Content> contents) throws IOException { final User user = getCurrentUser(); - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (!room.getOwnerId().equals(user.getId())) { throw new UnauthorizedException(); } - for (final Content content : contents) { - content.getState().setVisible(publish); - } - contentRepository.saveAll(contents); - ArsnovaEvent event; - List<Content> list = new ArrayList<>(); - contents.forEach(list::add); - if (publish) { - event = new UnlockQuestionsEvent(this, room.getId(), list); - } else { - event = new LockQuestionsEvent(this, room.getId(), list); - } - this.eventPublisher.publishEvent(event); + patch(contents, Collections.singletonMap("visible", publish), Content::getState); } /* TODO: Split and move answer part to AnswerService */ @@ -513,7 +464,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @CacheEvict(value = "answerlists", allEntries = true) public void deleteAllContentsAnswers(final String roomId) { final User user = getCurrentUser(); - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (!room.getOwnerId().equals(user.getId())) { throw new UnauthorizedException(); } @@ -521,9 +472,8 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem final List<Content> contents = contentRepository.findByRoomIdAndVariantAndActive(room.getId()); resetContentsRoundState(room.getId(), contents); final List<String> contentIds = contents.stream().map(Content::getId).collect(Collectors.toList()); + /* TODO: use EntityService! */ answerRepository.deleteAllAnswersForQuestions(contentIds); - - this.eventPublisher.publishEvent(new DeleteAllQuestionsAnswersEvent(this, room.getId())); } /* TODO: Split and move answer part to AnswerService */ @@ -532,14 +482,13 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @PreAuthorize("hasPermission(#roomId, 'room', 'owner')") @CacheEvict(value = "answerlists", allEntries = true) public void deleteAllPreparationAnswers(String roomId) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); final List<Content> contents = contentRepository.findByRoomIdAndVariantAndActive(room.getId(), "preparation"); resetContentsRoundState(room.getId(), contents); final List<String> contentIds = contents.stream().map(Content::getId).collect(Collectors.toList()); + /* TODO: use EntityService! */ answerRepository.deleteAllAnswersForQuestions(contentIds); - - this.eventPublisher.publishEvent(new DeleteAllPreparationAnswersEvent(this, room.getId())); } /* TODO: Split and move answer part to AnswerService */ @@ -548,14 +497,13 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @PreAuthorize("hasPermission(#roomId, 'room', 'owner')") @CacheEvict(value = "answerlists", allEntries = true) public void deleteAllLectureAnswers(String roomId) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); final List<Content> contents = contentRepository.findByRoomIdAndVariantAndActive(room.getId(), "lecture"); resetContentsRoundState(room.getId(), contents); final List<String> contentIds = contents.stream().map(Content::getId).collect(Collectors.toList()); + /* TODO: use EntityService! */ answerRepository.deleteAllAnswersForQuestions(contentIds); - - this.eventPublisher.publishEvent(new DeleteAllLectureAnswersEvent(this, room.getId())); } @Caching(evict = { diff --git a/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java b/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java index 1cd54312953fe8c3ff5677acfadae915d6daa3e6..194822867c9ed71650d7d63f0e50de47bfa4b4c0 100644 --- a/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/DefaultEntityServiceImpl.java @@ -101,7 +101,7 @@ public class DefaultEntityServiceImpl<T extends Entity> implements EntityService eventPublisher.publishEvent(new BeforeCreationEvent<>(this, entity)); final T createdEntity = repository.save(entity); eventPublisher.publishEvent(new AfterCreationEvent<>(this, createdEntity)); - finalizeCreate(entity); + finalizeCreate(createdEntity); modifyRetrieved(entity); return createdEntity; diff --git a/src/main/java/de/thm/arsnova/service/FeedbackServiceImpl.java b/src/main/java/de/thm/arsnova/service/FeedbackServiceImpl.java index ea4b87312625056348c3d7d38f5bdc3c9916b396..b542ec44c93b21d52664c224b71e7af12b7adbe7 100644 --- a/src/main/java/de/thm/arsnova/service/FeedbackServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/FeedbackServiceImpl.java @@ -21,7 +21,6 @@ import de.thm.arsnova.event.DeleteFeedbackForRoomsEvent; import de.thm.arsnova.event.NewFeedbackEvent; import de.thm.arsnova.model.Feedback; import de.thm.arsnova.model.Room; -import de.thm.arsnova.persistence.RoomRepository; import de.thm.arsnova.web.exceptions.NoContentException; import de.thm.arsnova.web.exceptions.NotFoundException; import org.springframework.beans.factory.annotation.Value; @@ -51,15 +50,15 @@ public class FeedbackServiceImpl implements FeedbackService, ApplicationEventPub @Value("${feedback.cleanup}") private int cleanupFeedbackDelay; - private RoomRepository roomRepository; + private RoomService roomService; private FeedbackStorageService feedbackStorage; private ApplicationEventPublisher publisher; - public FeedbackServiceImpl(FeedbackStorageService feedbackStorage, RoomRepository roomRepository) { + public FeedbackServiceImpl(FeedbackStorageService feedbackStorage, RoomService roomService) { this.feedbackStorage = feedbackStorage; - this.roomRepository = roomRepository; + this.roomService = roomService; } @Override @@ -101,7 +100,7 @@ public class FeedbackServiceImpl implements FeedbackService, ApplicationEventPub @Override public void cleanFeedbackVotesByRoomId(final String roomId, final int cleanupFeedbackDelayInMins) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); List<String> affectedUserIds = feedbackStorage.cleanVotesByRoom(room, cleanupFeedbackDelayInMins); Set<Room> sessionSet = new HashSet<>(); sessionSet.add(room); @@ -116,7 +115,7 @@ public class FeedbackServiceImpl implements FeedbackService, ApplicationEventPub @Override public Feedback getByRoomId(final String roomId) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (room == null) { throw new NotFoundException(); } @@ -133,7 +132,7 @@ public class FeedbackServiceImpl implements FeedbackService, ApplicationEventPub @Override public double calculateAverageFeedback(final String roomId) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (room == null) { throw new NotFoundException(); } @@ -157,7 +156,7 @@ public class FeedbackServiceImpl implements FeedbackService, ApplicationEventPub @Override public boolean save(final String roomId, final int value, final String userId) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (room == null) { throw new NotFoundException(); } @@ -169,7 +168,7 @@ public class FeedbackServiceImpl implements FeedbackService, ApplicationEventPub @Override public Integer getByRoomIdAndUserId(final String roomId, final String userId) { - final Room room = roomRepository.findOne(roomId); + final Room room = roomService.get(roomId); if (room == null) { throw new NotFoundException(); } diff --git a/src/main/java/de/thm/arsnova/service/MotdService.java b/src/main/java/de/thm/arsnova/service/MotdService.java index 6de4cc1d24135a3bec0015c6dfca451ae92683fc..c0ce86e000ce5b6274bd3863afb5813fa06b7432 100644 --- a/src/main/java/de/thm/arsnova/service/MotdService.java +++ b/src/main/java/de/thm/arsnova/service/MotdService.java @@ -38,10 +38,6 @@ public interface MotdService extends EntityService<Motd> { List<Motd> filterMotdsByList(List<Motd> list, List<String> ids); - void delete(Motd motd); - - void deleteByRoomId(final String roomId, Motd motd); - Motd save(Motd motd); Motd save(final String roomId, final Motd motd); diff --git a/src/main/java/de/thm/arsnova/service/MotdServiceImpl.java b/src/main/java/de/thm/arsnova/service/MotdServiceImpl.java index 6a2b09d40b421e1b9d3a5ddb98f1351dbdc0c97e..53dcf4fb6198b5e9fe1151ef72be5ce4350208e2 100644 --- a/src/main/java/de/thm/arsnova/service/MotdServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/MotdServiceImpl.java @@ -135,7 +135,7 @@ public class MotdServiceImpl extends DefaultEntityServiceImpl<Motd> implements M @CacheEvict(cacheNames = "motds", key = "#motd.audience + #motd.roomId") private Motd createOrUpdateMotd(final Motd motd) { if (motd.getId() != null) { - Motd oldMotd = motdRepository.findOne(motd.getId()); + Motd oldMotd = get(motd.getId()); if (!(motd.getId().equals(oldMotd.getId()) && motd.getRoomId().equals(oldMotd.getRoomId()) && motd.getAudience().equals(oldMotd.getAudience()))) { throw new BadRequestException(); @@ -151,17 +151,4 @@ public class MotdServiceImpl extends DefaultEntityServiceImpl<Motd> implements M return super.create(motd); } - - @Override - @PreAuthorize("hasPermission('', 'motd', 'admin')") - @CacheEvict(cacheNames = "motds", key = "#motd.audience + #motd.roomId") - public void delete(Motd motd) { - motdRepository.delete(motd); - } - - @Override - @PreAuthorize("hasPermission(#roomId, 'room', 'owner')") - public void deleteByRoomId(final String roomId, Motd motd) { - motdRepository.delete(motd); - } } diff --git a/src/main/java/de/thm/arsnova/service/RoomService.java b/src/main/java/de/thm/arsnova/service/RoomService.java index 2c30896d2c5b137d3de79d8c1870c6ae9f493308..1660058b6a2cba8e95e855b64f78fae471692696 100644 --- a/src/main/java/de/thm/arsnova/service/RoomService.java +++ b/src/main/java/de/thm/arsnova/service/RoomService.java @@ -19,10 +19,10 @@ package de.thm.arsnova.service; import de.thm.arsnova.connector.model.Course; import de.thm.arsnova.model.Room; -import de.thm.arsnova.model.migration.v2.ClientAuthentication; import de.thm.arsnova.model.transport.ImportExportContainer; import de.thm.arsnova.model.transport.ScoreStatistics; +import java.io.IOException; import java.util.List; import java.util.UUID; @@ -56,14 +56,12 @@ public interface RoomService extends EntityService<Room> { int activeUsers(String id); - Room setActive(String id, Boolean lock); + Room setActive(String id, Boolean lock) throws IOException; Room join(String id, UUID socketId); Room updateCreator(String id, String newCreator); - Room updateInternal(Room room, ClientAuthentication user); - int[] deleteCascading(Room room); ScoreStatistics getLearningProgress(String id, String type, String questionVariant); @@ -88,7 +86,7 @@ public interface RoomService extends EntityService<Room> { Room.Settings updateFeatures(String id, Room.Settings settings); - boolean lockFeedbackInput(String id, Boolean lock); + boolean lockFeedbackInput(String id, Boolean lock) throws IOException; boolean flipFlashcards(String id, Boolean flip); diff --git a/src/main/java/de/thm/arsnova/service/RoomServiceImpl.java b/src/main/java/de/thm/arsnova/service/RoomServiceImpl.java index 83b06681be2f48bf1340ce33d184be14ecb77552..6d9b4fef6dab946c1be23cf39866cdf8a550f4d8 100644 --- a/src/main/java/de/thm/arsnova/service/RoomServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/RoomServiceImpl.java @@ -19,15 +19,9 @@ package de.thm.arsnova.service; import de.thm.arsnova.connector.client.ConnectorClient; import de.thm.arsnova.connector.model.Course; -import de.thm.arsnova.event.AfterDeletionEvent; -import de.thm.arsnova.event.BeforeDeletionEvent; -import de.thm.arsnova.event.FeatureChangeEvent; import de.thm.arsnova.event.FlipFlashcardsEvent; -import de.thm.arsnova.event.LockFeedbackEvent; -import de.thm.arsnova.event.StatusRoomEvent; import de.thm.arsnova.model.Room; import de.thm.arsnova.model.UserProfile; -import de.thm.arsnova.model.migration.v2.ClientAuthentication; import de.thm.arsnova.model.transport.ImportExportContainer; import de.thm.arsnova.model.transport.ScoreStatistics; import de.thm.arsnova.persistence.AnswerRepository; @@ -53,8 +47,10 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; @@ -97,25 +93,37 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R public RoomServiceImpl( RoomRepository repository, - ContentRepository contentRepository, - AnswerRepository answerRepository, - CommentRepository commentRepository, LogEntryRepository dbLogger, UserService userService, - FeedbackService feedbackService, ScoreCalculatorFactory scoreCalculatorFactory, @Qualifier("defaultJsonMessageConverter") MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) { super(Room.class, repository, jackson2HttpMessageConverter.getObjectMapper()); this.roomRepository = repository; - this.contentRepository = contentRepository; - this.answerRepository = answerRepository; - this.commentRepository = commentRepository; this.dbLogger = dbLogger; this.userService = userService; - this.feedbackService = feedbackService; this.scoreCalculatorFactory = scoreCalculatorFactory; } + @Autowired + public void setCommentRepository(final CommentRepository commentRepository) { + this.commentRepository = commentRepository; + } + + @Autowired + public void setContentRepository(final ContentRepository contentRepository) { + this.contentRepository = contentRepository; + } + + @Autowired + public void setAnswerRepository(final AnswerRepository answerRepository) { + this.answerRepository = answerRepository; + } + + @Autowired + public void setFeedbackService(final FeedbackService feedbackService) { + this.feedbackService = feedbackService; + } + public static class RoomNameComparator implements Comparator<Room>, Serializable { private static final long serialVersionUID = 1L; @@ -197,7 +205,7 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R @Override public Room join(final String id, final UUID socketId) { - Room room = null != id ? roomRepository.findOne(id) : null; + Room room = null != id ? get(id) : null; if (null == room) { userService.removeUserFromRoomBySocketId(socketId); return null; @@ -241,7 +249,7 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R @PreAuthorize("hasPermission(#id, 'room', 'owner')") public Room getForAdmin(final String id) { - return roomRepository.findOne(id); + return get(id); } /* @@ -250,7 +258,7 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R */ @Override public Room getInternal(final String id, final String userId) { - final Room room = roomRepository.findOne(id); + final Room room = get(id, true); if (room == null) { throw new NotFoundException(); } @@ -401,11 +409,9 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R @Override @PreAuthorize("hasPermission(#id, 'room', 'owner')") - public Room setActive(final String id, final Boolean lock) { - final Room room = roomRepository.findOne(id); - room.setClosed(!lock); - this.eventPublisher.publishEvent(new StatusRoomEvent(this, room.getId())); - roomRepository.save(room); + public Room setActive(final String id, final Boolean lock) throws IOException { + final Room room = get(id); + patch(room, Collections.singletonMap("closed", lock)); return room; } @@ -414,7 +420,7 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R /* TODO: move caching to DefaultEntityServiceImpl */ //@CachePut(value = "rooms", key = "#room") protected void prepareUpdate(final Room room) { - final Room existingRoom = roomRepository.findOne(room.getId()); + final Room existingRoom = get(room.getId()); room.setOwnerId(existingRoom.getOwnerId()); handleLogo(room); @@ -430,19 +436,6 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R throw new UnsupportedOperationException("No longer implemented."); } - /* - * The "internal" suffix means it is called by internal services that have no authentication! - * TODO: Find a better way of doing this... - */ - @Override - public Room updateInternal(final Room room, final ClientAuthentication user) { - if (room.getOwnerId().equals(user.getId())) { - roomRepository.save(room); - return room; - } - return null; - } - @Override @PreAuthorize("hasPermission(#room, 'owner')") @Caching(evict = { @@ -455,9 +448,7 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R count[2] = commentRepository.deleteByRoomId(room.getId()); count[1] = answerRepository.deleteByContentIds(contentIds); count[0] = contentRepository.deleteByRoomId(room.getId()); - this.eventPublisher.publishEvent(new BeforeDeletionEvent<>(this, room)); - roomRepository.delete(room); - this.eventPublisher.publishEvent(new AfterDeletionEvent<>(this, room)); + delete(room); logger.debug("Deleted room document {} and related data.", room.getId()); dbLogger.log("delete", "type", "session", "id", room.getId()); @@ -467,7 +458,7 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R @Override @PreAuthorize("hasPermission(#id, 'room', 'read')") public ScoreStatistics getLearningProgress(final String id, final String type, final String questionVariant) { - final Room room = roomRepository.findOne(id); + final Room room = get(id); ScoreCalculator scoreCalculator = scoreCalculatorFactory.create(type, questionVariant); return scoreCalculator.getCourseProgress(room); } @@ -475,7 +466,7 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R @Override @PreAuthorize("hasPermission(#id, 'room', 'read')") public ScoreStatistics getMyLearningProgress(final String id, final String type, final String questionVariant) { - final Room room = roomRepository.findOne(id); + final Room room = get(id); final User user = userService.getCurrentUser(); ScoreCalculator scoreCalculator = scoreCalculatorFactory.create(type, questionVariant); return scoreCalculator.getMyProgress(room, user.getId()); @@ -511,31 +502,28 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R @Override @PreAuthorize("hasPermission(#id, 'room', 'read')") public Room.Settings getFeatures(String id) { - return roomRepository.findOne(id).getSettings(); + return get(id).getSettings(); } @Override @PreAuthorize("hasPermission(#id, 'room', 'owner')") public Room.Settings updateFeatures(String id, Room.Settings settings) { - final Room room = roomRepository.findOne(id); + final Room room = get(id); room.setSettings(settings); - this.eventPublisher.publishEvent(new FeatureChangeEvent(this, room.getId())); - roomRepository.save(room); + + update(room); return room.getSettings(); } @Override @PreAuthorize("hasPermission(#id, 'room', 'owner')") - public boolean lockFeedbackInput(String id, Boolean lock) { - final Room room = roomRepository.findOne(id); + public boolean lockFeedbackInput(String id, Boolean lock) throws IOException { + final Room room = get(id); if (!lock) { feedbackService.cleanFeedbackVotesByRoomId(id, 0); } - - room.getSettings().setFeedbackLocked(lock); - this.eventPublisher.publishEvent(new LockFeedbackEvent(this, room.getId())); - roomRepository.save(room); + patch(room, Collections.singletonMap("feedbackLocked", lock), Room::getSettings); return room.getSettings().isFeedbackLocked(); } @@ -543,7 +531,7 @@ public class RoomServiceImpl extends DefaultEntityServiceImpl<Room> implements R @Override @PreAuthorize("hasPermission(#id, 'room', 'owner')") public boolean flipFlashcards(String id, Boolean flip) { - final Room room = roomRepository.findOne(id); + final Room room = get(id); this.eventPublisher.publishEvent(new FlipFlashcardsEvent(this, room.getId())); return flip; diff --git a/src/main/java/de/thm/arsnova/service/TimerServiceImpl.java b/src/main/java/de/thm/arsnova/service/TimerServiceImpl.java index 40b07f175fedad40329e6f930d3c00ec4ab6ecf3..5a4fad25a5b18feae35a0012d4f943011b8205d3 100644 --- a/src/main/java/de/thm/arsnova/service/TimerServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/TimerServiceImpl.java @@ -1,18 +1,10 @@ package de.thm.arsnova.service; -import de.thm.arsnova.event.PiRoundCancelEvent; -import de.thm.arsnova.event.PiRoundDelayedStartEvent; -import de.thm.arsnova.event.PiRoundEndEvent; -import de.thm.arsnova.event.PiRoundResetEvent; import de.thm.arsnova.model.Content; import de.thm.arsnova.model.Room; import de.thm.arsnova.persistence.AnswerRepository; -import de.thm.arsnova.persistence.ContentRepository; -import de.thm.arsnova.persistence.RoomRepository; import de.thm.arsnova.security.User; import org.springframework.cache.annotation.CacheEvict; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; @@ -22,52 +14,48 @@ import java.util.Timer; import java.util.TimerTask; @Service -public class TimerServiceImpl implements TimerService, ApplicationEventPublisherAware { +public class TimerServiceImpl implements TimerService { private HashMap<String, Timer> timerList = new HashMap<>(); private UserService userService; - private RoomRepository roomRepository; - private ContentRepository contentRepository; + private RoomService roomService; + private ContentService contentService; private AnswerRepository answerRepository; - private ApplicationEventPublisher publisher; - public TimerServiceImpl(final UserService userService, final RoomRepository roomRepository, - final ContentRepository contentRepository, final AnswerRepository answerRepository) { + public TimerServiceImpl(final UserService userService, final RoomService roomService, + final ContentService contentService, final AnswerRepository answerRepository) { this.userService = userService; - this.roomRepository = roomRepository; - this.contentRepository = contentRepository; + this.roomService = roomService; + this.contentService = contentService; this.answerRepository = answerRepository; } @Override @PreAuthorize("isAuthenticated() and hasPermission(#contentId, 'content', 'owner')") public void startNewRound(final String contentId) { - final Content content = contentRepository.findOne(contentId); - final Room room = roomRepository.findOne(content.getRoomId()); + final Content content = contentService.get(contentId); + final Room room = roomService.get(content.getRoomId()); cancelDelayedRoundChange(contentId); content.getState().setRoundEndTimestamp(null); content.getState().setResponsesEnabled(false); updateRoundManagementState(content); - contentRepository.save(content); - - this.publisher.publishEvent(new PiRoundEndEvent(this, room.getId(), content)); + contentService.update(content); } @Override @PreAuthorize("hasPermission(#contentId, 'content', 'owner')") public void startNewRoundDelayed(final String contentId, final int time) { final User user = userService.getCurrentUser(); - final Content content = contentRepository.findOne(contentId); - final Room room = roomRepository.findOne(content.getRoomId()); + final Content content = contentService.get(contentId); + final Room room = roomService.get(content.getRoomId()); final Date date = new Date(); final Timer timer = new Timer(); final Date endDate = new Date(date.getTime() + (time * 1000)); updateRoundStartVariables(content, date, endDate); - contentRepository.save(content); + contentService.update(content); - this.publisher.publishEvent(new PiRoundDelayedStartEvent(this, room.getId(), content)); timerList.put(contentId, timer); timer.schedule(new TimerTask() { @@ -81,8 +69,8 @@ public class TimerServiceImpl implements TimerService, ApplicationEventPublisher @Override @PreAuthorize("hasPermission(#contentId, 'content', 'owner')") public void cancelRoundChange(final String contentId) { - final Content content = contentRepository.findOne(contentId); - final Room room = roomRepository.findOne(content.getRoomId()); + final Content content = contentService.get(contentId); + final Room room = roomService.get(content.getRoomId()); cancelDelayedRoundChange(contentId); resetRoundManagementState(content); @@ -92,8 +80,7 @@ public class TimerServiceImpl implements TimerService, ApplicationEventPublisher } content.getState().setRoundEndTimestamp(null); - contentRepository.save(content); - this.publisher.publishEvent(new PiRoundCancelEvent(this, room.getId(), content)); + contentService.update(content); } @Override @@ -111,8 +98,8 @@ public class TimerServiceImpl implements TimerService, ApplicationEventPublisher @PreAuthorize("hasPermission(#contentId, 'content', 'owner')") @CacheEvict("answerlists") public void resetRoundState(final String contentId) { - final Content content = contentRepository.findOne(contentId); - final Room room = roomRepository.findOne(content.getRoomId()); + final Content content = contentService.get(contentId); + final Room room = roomService.get(content.getRoomId()); cancelDelayedRoundChange(contentId); if (Content.Format.TEXT == content.getFormat()) { @@ -123,8 +110,7 @@ public class TimerServiceImpl implements TimerService, ApplicationEventPublisher resetRoundManagementState(content); answerRepository.deleteByContentId(content.getId()); - contentRepository.save(content); - this.publisher.publishEvent(new PiRoundResetEvent(this, room.getId(), content)); + contentService.update(content); } private void updateRoundStartVariables(final Content content, final Date start, final Date end) { @@ -157,9 +143,4 @@ public class TimerServiceImpl implements TimerService, ApplicationEventPublisher content.getState().setRound(1); content.getState().setRoundEndTimestamp(null); } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - this.publisher = applicationEventPublisher; - } } diff --git a/src/main/java/de/thm/arsnova/service/score/ScoreCalculatorFactoryImpl.java b/src/main/java/de/thm/arsnova/service/score/ScoreCalculatorFactoryImpl.java index 908c17bccfa9103764fefd3c999e3fe26b7d7411..2eea760750f48d6cc15682d443d8c00bcd7fd2ea 100644 --- a/src/main/java/de/thm/arsnova/service/score/ScoreCalculatorFactoryImpl.java +++ b/src/main/java/de/thm/arsnova/service/score/ScoreCalculatorFactoryImpl.java @@ -17,7 +17,10 @@ */ package de.thm.arsnova.service.score; -import de.thm.arsnova.event.*; +import de.thm.arsnova.event.AfterCreationEvent; +import de.thm.arsnova.event.AfterDeletionEvent; +import de.thm.arsnova.event.ChangeScoreEvent; +import de.thm.arsnova.event.StateChangeEvent; import de.thm.arsnova.model.Answer; import de.thm.arsnova.model.Content; import de.thm.arsnova.persistence.SessionStatisticsRepository; @@ -59,28 +62,10 @@ public class ScoreCalculatorFactoryImpl implements ScoreCalculatorFactory, Appli this.publisher.publishEvent(new ChangeScoreEvent(this, event.getEntity().getRoomId())); } - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handleUnlockQuestion(UnlockQuestionEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); - } - - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handleUnlockQuestions(UnlockQuestionsEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); - } - - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handleLockQuestion(LockQuestionEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); - } - - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handleLockQuestions(LockQuestionsEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); + @CacheEvict(value = "score", key = "#event.entity.roomId") + @EventListener(condition = "#event.stateName == 'state'") + public void handleContentStateChange(StateChangeEvent<Content, Content.State> event) { + this.publisher.publishEvent(new ChangeScoreEvent(this, event.getEntity().getRoomId())); } @CacheEvict(value = "score", key = "#event.entity.roomId") @@ -101,36 +86,6 @@ public class ScoreCalculatorFactoryImpl implements ScoreCalculatorFactory, Appli this.publisher.publishEvent(new ChangeScoreEvent(this, event.getEntity().getRoomId())); } - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handleDeleteAllQuestions(DeleteAllQuestionsEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); - } - - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handleDeleteAllQuestionsAnswers(DeleteAllQuestionsAnswersEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); - } - - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handleDeleteAllPreparationAnswers(DeleteAllPreparationAnswersEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); - } - - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handleDeleteAllLectureAnswers(DeleteAllLectureAnswersEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); - } - - @CacheEvict(value = "score", key = "#event.roomId") - @EventListener - public void handlePiRoundReset(PiRoundResetEvent event) { - this.publisher.publishEvent(new ChangeScoreEvent(this, event.getRoomId())); - } - @Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; diff --git a/src/main/java/de/thm/arsnova/websocket/ArsnovaSocketioServerImpl.java b/src/main/java/de/thm/arsnova/websocket/ArsnovaSocketioServerImpl.java index 8e99eca9e25362342d03d708d78117842626bf9c..874ea935bc869328fb07a3d4893dcb63ab963cc1 100644 --- a/src/main/java/de/thm/arsnova/websocket/ArsnovaSocketioServerImpl.java +++ b/src/main/java/de/thm/arsnova/websocket/ArsnovaSocketioServerImpl.java @@ -28,7 +28,13 @@ import com.corundumstudio.socketio.listener.DataListener; import com.corundumstudio.socketio.listener.DisconnectListener; import com.corundumstudio.socketio.protocol.Packet; import com.corundumstudio.socketio.protocol.PacketType; -import de.thm.arsnova.event.*; +import de.thm.arsnova.event.AfterCreationEvent; +import de.thm.arsnova.event.AfterDeletionEvent; +import de.thm.arsnova.event.ChangeScoreEvent; +import de.thm.arsnova.event.DeleteFeedbackForRoomsEvent; +import de.thm.arsnova.event.FlipFlashcardsEvent; +import de.thm.arsnova.event.NewFeedbackEvent; +import de.thm.arsnova.event.StateChangeEvent; import de.thm.arsnova.model.Answer; import de.thm.arsnova.model.Comment; import de.thm.arsnova.model.ScoreOptions; @@ -60,7 +66,9 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; @@ -496,24 +504,13 @@ public class ArsnovaSocketioServerImpl implements ArsnovaSocketioServer { this.reportContentAvailable(event.getEntity().getId(), Collections.singletonList(event.getEntity())); } - @EventListener - public void handleUnlockQuestion(UnlockQuestionEvent event) { - this.reportContentAvailable(event.getRoomId(), Collections.singletonList(event.getQuestion())); - } - - @EventListener - public void handleLockQuestion(LockQuestionEvent event) { - this.reportContentsLocked(event.getRoomId(), Collections.singletonList(event.getQuestion())); - } - - @EventListener - public void handleUnlockQuestions(UnlockQuestionsEvent event) { - this.reportContentAvailable(event.getRoomId(), event.getQuestions()); - } - - @EventListener - public void handleLockQuestions(LockQuestionsEvent event) { - this.reportContentsLocked(event.getRoomId(), event.getQuestions()); + @EventListener(condition = "#event.stateName == 'state'") + public void handleContentIsVisibleStateChange(StateChangeEvent<de.thm.arsnova.model.Content, de.thm.arsnova.model.Content.State> event) { + if (event.getEntity().getState().isVisible()) { + this.reportContentAvailable(event.getEntity().getRoomId(), Collections.singletonList(event.getEntity())); + } else { + this.reportContentsLocked(event.getEntity().getRoomId(), Collections.singletonList(event.getEntity())); + } } @EventListener @@ -555,80 +552,80 @@ public class ArsnovaSocketioServerImpl implements ArsnovaSocketioServer { } @Async - @EventListener + @EventListener(condition = "#event.stateName == 'state'") @Timed - public void handlePiRoundDelayedStart(PiRoundDelayedStartEvent event) { - final String roomId = event.getRoomId(); - broadcastInRoom(roomId, "startDelayedPiRound", event.getPiRoundInformations()); + public void handlePiRoundDelayedStart(StateChangeEvent<de.thm.arsnova.model.Content, de.thm.arsnova.model.Content.State> event) { + broadcastInRoom(event.getEntity().getRoomId(), "startDelayedPiRound", generateRoundInfo(event.getEntity())); } @Async - @EventListener + @EventListener(condition = "#event.stateName == 'state'") @Timed - public void handlePiRoundEnd(PiRoundEndEvent event) { - final String roomId = event.getRoomId(); - broadcastInRoom(roomId, "endPiRound", event.getPiRoundEndInformations()); + public void handlePiRoundEnd(StateChangeEvent<de.thm.arsnova.model.Content, de.thm.arsnova.model.Content.State> event) { + broadcastInRoom(event.getEntity().getRoomId(), "endPiRound", generateRoundInfo(event.getEntity())); } @Async - @EventListener + @EventListener(condition = "#event.stateName == 'state'") @Timed - public void handlePiRoundCancel(PiRoundCancelEvent event) { - final String roomId = event.getRoomId(); - broadcastInRoom(roomId, "cancelPiRound", event.getContentId()); + public void handlePiRoundCancel(StateChangeEvent<de.thm.arsnova.model.Content, de.thm.arsnova.model.Content.State> event) { + broadcastInRoom(event.getEntity().getRoomId(), "cancelPiRound", event.getEntity().getId()); } - @EventListener - public void handlePiRoundReset(PiRoundResetEvent event) { - final String roomId = event.getRoomId(); - broadcastInRoom(roomId, "resetPiRound", event.getPiRoundResetInformations()); + @EventListener(condition = "#event.stateName == 'state'") + public void handlePiRoundReset(StateChangeEvent<de.thm.arsnova.model.Content, de.thm.arsnova.model.Content.State> event) { + broadcastInRoom(event.getEntity().getRoomId(), "resetPiRound", generateRoundInfo(event.getEntity())); } - @EventListener - public void handleLockVote(LockVoteEvent event) { - final String roomId = event.getRoomId(); - broadcastInRoom(roomId, "lockVote", event.getVotingAdmission()); - } - - @EventListener - public void handleUnlockVote(UnlockVoteEvent event) { - final String roomId = event.getRoomId(); - broadcastInRoom(roomId, "unlockVote", event.getVotingAdmission()); - } - - @EventListener - public void handleLockVotes(LockVotesEvent event) { - List<Content> contents = new ArrayList<>(); - for (de.thm.arsnova.model.Content q : event.getQuestions()) { - contents.add(new Content(q)); + private Map<String, Object> generateRoundInfo(de.thm.arsnova.model.Content content) { + Map<String, Object> map = new HashMap<>(); + map.put("_id", content.getId()); + if (content.getState().getRoundEndTimestamp() != null) { + map.put("endTime", content.getState().getRoundEndTimestamp().getTime()); } - broadcastInRoom(event.getRoomId(), "lockVotes", contents); - } - - @EventListener - public void handleUnlockVotes(UnlockVotesEvent event) { - List<Content> contents = new ArrayList<>(); - for (de.thm.arsnova.model.Content q : event.getQuestions()) { - contents.add(new Content(q)); + /* FIXME: getRoundStartTimestamp is not implemented for Content.State. Is a delayed start still useful? */ + /* + if (content.getState().getRoundStartTimestamp() != null) { + map.put("startTime", content.getState().getRoundStartTimestamp().getTime()); + } + */ + map.put("variant", content.getGroups()); + map.put("round", content.getState().getRound()); + + return map; + } + + @EventListener(condition = "#event.stateName == 'state'") + public void handleContentResponsesEnabledStateChange(StateChangeEvent<de.thm.arsnova.model.Content, de.thm.arsnova.model.Content.State> event) { + /* Multiple groups for a single Content are not handled. */ + final String groupName = event.getEntity().getGroups().iterator().hasNext() ? + event.getEntity().getGroups().iterator().next() : ""; + Map<String, Object> map = new HashMap<>(); + map.put("_id", event.getEntity().getId()); + map.put("variant", groupName); + if (event.getEntity().getState().isResponsesEnabled()) { + this.reportContentAvailable(event.getEntity().getRoomId(), Collections.singletonList(event.getEntity())); + broadcastInRoom(event.getEntity().getRoomId(), "unlockVote", map); + } else { + broadcastInRoom(event.getEntity().getRoomId(), "lockVote", map); } - broadcastInRoom(event.getRoomId(), "unlockVotes", contents); } - @EventListener - public void handleFeatureChange(FeatureChangeEvent event) { -// final String roomId = event.getRoomId(); -// final de.thm.arsnova.model.Room.Settings settings = event.getRoom().getSettings(); -// broadcastInRoom(roomId, "featureChange", toV2Migrator.migrate(settings)); -// -// if (settings.isFlashcardsEnabled()) { -// broadcastInRoom(roomId, "countFlashcards", contentService.countFlashcardsForUserInternal(roomId)); -// broadcastInRoom(roomId, "flipFlashcards", event.getRoom().getFlipFlashcards()); -// } + @EventListener(condition = "#event.stateName == 'settings'") + public void handleFeatureChange(StateChangeEvent<de.thm.arsnova.model.Room, de.thm.arsnova.model.Room.Settings> event) { + final String roomId = event.getEntity().getId(); + final de.thm.arsnova.model.Room.Settings settings = event.getEntity().getSettings(); + broadcastInRoom(roomId, "featureChange", toV2Migrator.migrate(settings)); + + if (settings.isFlashcardsEnabled()) { + broadcastInRoom(roomId, "countFlashcards", contentService.countFlashcardsForUserInternal(roomId)); +// broadcastInRoom(roomId, "flipFlashcards", event.getEntity().getSettings().isFlipFlashcards()); + } } - @EventListener - public void handleLockFeedback(LockFeedbackEvent event) { -// broadcastInRoom(event.getRoomId(), "lockFeedback", event.getRoom().getSettings().isFeedbackLocked()); + @EventListener(condition = "#event.stateName == 'settings'") + public void handleLockFeedback(StateChangeEvent<de.thm.arsnova.model.Room, de.thm.arsnova.model.Room.Settings> event) { + broadcastInRoom(event.getEntity().getId(), "lockFeedback", event.getEntity().getSettings().isFeedbackLocked()); } @EventListener @@ -647,9 +644,9 @@ public class ArsnovaSocketioServerImpl implements ArsnovaSocketioServer { } - @EventListener - public void handleStatusRoom(StatusRoomEvent event) { -// this.reportRoomStatus(event.getRoomId(), !event.getRoom().isClosed()); + @EventListener(condition = "#event.stateName == 'closed'") + public void handleRoomClosedStateChange(StateChangeEvent<de.thm.arsnova.model.Room, Boolean> event) { + this.reportRoomStatus(event.getEntity().getId(), !event.getNewValue()); } @EventListener diff --git a/src/test/java/de/thm/arsnova/event/StateEventDispatcherTest.java b/src/test/java/de/thm/arsnova/event/StateEventDispatcherTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e1b082e6f78b2f495174db3d5820385700ad72b1 --- /dev/null +++ b/src/test/java/de/thm/arsnova/event/StateEventDispatcherTest.java @@ -0,0 +1,141 @@ +package de.thm.arsnova.event; + +import com.fasterxml.jackson.databind.ObjectMapper; +import de.thm.arsnova.config.AppConfig; +import de.thm.arsnova.config.TestAppConfig; +import de.thm.arsnova.config.TestPersistanceConfig; +import de.thm.arsnova.config.TestSecurityConfig; +import de.thm.arsnova.model.Content; +import de.thm.arsnova.model.Room; +import de.thm.arsnova.persistence.ContentRepository; +import de.thm.arsnova.persistence.RoomRepository; +import de.thm.arsnova.service.DefaultEntityServiceImpl; +import de.thm.arsnova.test.context.support.WithMockUser; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.event.EventListener; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.AdditionalAnswers.returnsFirstArg; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { + AppConfig.class, + StateEventDispatcherTest.EventListenerConfig.class, + TestAppConfig.class, + TestPersistanceConfig.class, + TestSecurityConfig.class}) +@ActiveProfiles("test") +public class StateEventDispatcherTest { + public static final String SETTINGS_PROPERTY_NAME = "settings"; + public static final String STATE_PROPERTY_NAME = "state"; + private static final String QUESTIONS_ENABLED_PROPERTY_NAME = "questionsEnabled"; + private static final String VISIBLE_PROPERTY_NAME = "visible"; + private static final String TEST_USER_ID = "TestUser"; + private static final String TEST_ROOM_ID = "TestRoom"; + + @Autowired + private EventListenerConfig eventListenerConfig; + + @Autowired + @Qualifier("defaultJsonMessageConverter") + private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter; + + @Autowired + private ApplicationEventPublisher eventPublisher; + + @Autowired + private RoomRepository roomRepository; + + @Autowired + private ContentRepository contentRepository; + + @Before + public void prepare() { + eventListenerConfig.resetEvents(); + } + + @Test + @WithMockUser(TEST_USER_ID) + public void testDispatchRoomSettingsStateEvent() throws IOException { + final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper(); + final DefaultEntityServiceImpl<Room> entityService = new DefaultEntityServiceImpl<>( + Room.class, roomRepository, objectMapper); + entityService.setApplicationEventPublisher(eventPublisher); + + when(roomRepository.save(any(Room.class))).then(returnsFirstArg()); + + Room room = new Room(); + room.setOwnerId(TEST_USER_ID); + entityService.patch(room, Collections.singletonMap(QUESTIONS_ENABLED_PROPERTY_NAME, false), Room::getSettings); + assertEquals(1, eventListenerConfig.getRoomSettingsStateChangeEvents().size()); + assertEquals(SETTINGS_PROPERTY_NAME, eventListenerConfig.getRoomSettingsStateChangeEvents().get(0).getStateName()); + } + + @Test + @WithMockUser(TEST_USER_ID) + public void testDispatchContentStateEvent() throws IOException { + final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper(); + final DefaultEntityServiceImpl<Content> entityService = new DefaultEntityServiceImpl<>( + Content.class, contentRepository, objectMapper); + entityService.setApplicationEventPublisher(eventPublisher); + + Room room = new Room(); + room.setId(TEST_ROOM_ID); + room.setOwnerId(TEST_USER_ID); + when(contentRepository.save(any(Content.class))).then(returnsFirstArg()); + when(roomRepository.findOne(eq(room.getId()))).thenReturn(room); + + Content content = new Content(); + content.setRoomId(room.getId()); + entityService.patch(content, Collections.singletonMap(VISIBLE_PROPERTY_NAME, false), Content::getState); + assertEquals(1, eventListenerConfig.getContentStateChangeEvents().size()); + assertEquals(STATE_PROPERTY_NAME, eventListenerConfig.getContentStateChangeEvents().get(0).getStateName()); + } + + public static class EventListenerConfig { + private List<StateChangeEvent<Room, Room.Settings>> roomSettingsStateChangeEvents = new ArrayList<>(); + private List<StateChangeEvent<Content, Content.State>> contentStateChangeEvents = new ArrayList<>(); + + @EventListener(condition = "#event.stateName == '" + SETTINGS_PROPERTY_NAME + "'") + public void handleRoomSettingsStateChangeEvent(StateChangeEvent<Room, Room.Settings> event) { + roomSettingsStateChangeEvents.add(event); + } + + @EventListener(condition = "#event.stateName == '" + STATE_PROPERTY_NAME + "'") + public void handleContentStateChangeEvent(StateChangeEvent<Content, Content.State> event) { + contentStateChangeEvents.add(event); + } + + public List<StateChangeEvent<Room, Room.Settings>> getRoomSettingsStateChangeEvents() { + return roomSettingsStateChangeEvents; + } + + public List<StateChangeEvent<Content, Content.State>> getContentStateChangeEvents() { + return contentStateChangeEvents; + } + + public void resetEvents() { + roomSettingsStateChangeEvents.clear(); + contentStateChangeEvents.clear(); + } + } +}