From 4000246840a814e9d52e5be171abd1eb28124c4f Mon Sep 17 00:00:00 2001
From: agrt56 <andreas.gaertner@mni.thm.de>
Date: Sat, 23 May 2015 21:00:38 +0200
Subject: [PATCH] Task #15973: Add methods to lock/unlock vote for all
 questions.

---
 .../de/thm/arsnova/cache/CacheBuster.java     | 16 ++++-
 .../LecturerQuestionController.java           | 37 ++++++++++--
 .../java/de/thm/arsnova/dao/CouchDBDao.java   | 34 +++++++++++
 .../java/de/thm/arsnova/dao/IDatabaseDao.java |  4 ++
 .../domain/LearningProgressFactory.java       | 17 +++++-
 .../de/thm/arsnova/events/LockVoteEvent.java  | 60 +++++++++++++++++++
 .../de/thm/arsnova/events/LockVotesEvent.java | 45 ++++++++++++++
 .../thm/arsnova/events/NovaEventVisitor.java  |  8 ++-
 ...kVotingEvent.java => UnlockVoteEvent.java} |  5 +-
 .../thm/arsnova/events/UnlockVotesEvent.java  | 45 ++++++++++++++
 .../arsnova/services/IQuestionService.java    |  6 +-
 .../thm/arsnova/services/QuestionService.java | 50 +++++++++++++++-
 .../arsnova/socket/ARSnovaSocketIOServer.java | 37 +++++++++---
 .../de/thm/arsnova/dao/StubDatabaseDao.java   | 12 ++++
 14 files changed, 352 insertions(+), 24 deletions(-)
 create mode 100644 src/main/java/de/thm/arsnova/events/LockVoteEvent.java
 create mode 100644 src/main/java/de/thm/arsnova/events/LockVotesEvent.java
 rename src/main/java/de/thm/arsnova/events/{LockVotingEvent.java => UnlockVoteEvent.java} (90%)
 create mode 100644 src/main/java/de/thm/arsnova/events/UnlockVotesEvent.java

diff --git a/src/main/java/de/thm/arsnova/cache/CacheBuster.java b/src/main/java/de/thm/arsnova/cache/CacheBuster.java
index 00c9ab4a5..ed10194b5 100644
--- a/src/main/java/de/thm/arsnova/cache/CacheBuster.java
+++ b/src/main/java/de/thm/arsnova/cache/CacheBuster.java
@@ -32,7 +32,8 @@ import de.thm.arsnova.events.DeleteQuestionEvent;
 import de.thm.arsnova.events.DeleteSessionEvent;
 import de.thm.arsnova.events.LockQuestionEvent;
 import de.thm.arsnova.events.LockQuestionsEvent;
-import de.thm.arsnova.events.LockVotingEvent;
+import de.thm.arsnova.events.LockVoteEvent;
+import de.thm.arsnova.events.LockVotesEvent;
 import de.thm.arsnova.events.NewAnswerEvent;
 import de.thm.arsnova.events.NewFeedbackEvent;
 import de.thm.arsnova.events.NewInterposedQuestionEvent;
@@ -46,6 +47,8 @@ import de.thm.arsnova.events.PiRoundDelayedStartEvent;
 import de.thm.arsnova.events.PiRoundEndEvent;
 import de.thm.arsnova.events.PiRoundResetEvent;
 import de.thm.arsnova.events.StatusSessionEvent;
+import de.thm.arsnova.events.UnlockVoteEvent;
+import de.thm.arsnova.events.UnlockVotesEvent;
 
 /**
  * This class is used to evict caches based on events. The events carry all necessary information to clear the
@@ -133,6 +136,15 @@ public class CacheBuster implements ICacheBuster, NovaEventVisitor {
 	public void visit(DeleteSessionEvent deleteSessionEvent) {}
 
 	@Override
-	public void visit(LockVotingEvent lockVotingEvent) {}
+	public void visit(LockVoteEvent lockVoteEvent) {}
+
+	@Override
+	public void visit(LockVotesEvent lockVotesEvent) {}
+
+	@Override
+	public void visit(UnlockVoteEvent unlockVoteEvent) {}
+
+	@Override
+	public void visit(UnlockVotesEvent unlockVotesEvent) {}
 
 }
diff --git a/src/main/java/de/thm/arsnova/controller/LecturerQuestionController.java b/src/main/java/de/thm/arsnova/controller/LecturerQuestionController.java
index aeabcb510..cd2577a1e 100644
--- a/src/main/java/de/thm/arsnova/controller/LecturerQuestionController.java
+++ b/src/main/java/de/thm/arsnova/controller/LecturerQuestionController.java
@@ -111,13 +111,42 @@ public class LecturerQuestionController extends AbstractController {
 		questionService.resetPiRoundState(questionId);
 	}
 
-	@RequestMapping(value = "/{questionId}/disableVoting", method = RequestMethod.POST)
+	@RequestMapping(value = "/{questionId}/disablevote", method = RequestMethod.POST)
 	public void setVotingAdmission(
 			@PathVariable final String questionId,
-			@RequestParam(required = true) final Boolean disable
+			@RequestParam(value = "disable", defaultValue = "false", required = false) final Boolean disableVote
 			) {
-		if (disable != null) {
-			questionService.setVotingAdmission(questionId, disable);
+		boolean disable = false;
+
+		if (disableVote != null) {
+			disable = disableVote;
+		}
+
+		questionService.setVotingAdmission(questionId, disable);
+	}
+
+	@RequestMapping(value = "/disablevote", method = RequestMethod.POST)
+	public void setVotingAdmissionForAllQuestions(
+			@RequestParam final String sessionkey,
+			@RequestParam(value = "disable", defaultValue = "false", required = false) final Boolean disableVote,
+			@RequestParam(value = "lecturequestionsonly", defaultValue = "false", required = false) final boolean lectureQuestionsOnly,
+			@RequestParam(value = "preparationquestionsonly", defaultValue = "false", required = false) final boolean preparationQuestionsOnly
+			) {
+		boolean disable = false;
+		List<Question> questions;
+
+		if (disableVote != null) {
+			disable = disableVote;
+		}
+
+		if (lectureQuestionsOnly) {
+			questions = questionService.getLectureQuestions(sessionkey);
+			questionService.setVotingAdmissions(sessionkey, disable, questions);
+		} else if (preparationQuestionsOnly) {
+			questions = questionService.getPreparationQuestions(sessionkey);
+			questionService.setVotingAdmissions(sessionkey, disable, questions);
+		} else {
+			questionService.setVotingAdmissionForAllQuestions(sessionkey, disable);
 		}
 	}
 
diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 22830899b..bb739e609 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -1733,6 +1733,40 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		}
 	}
 
+	@Override
+	public List<Question> setVotingAdmissionForAllQuestions(final Session session, final boolean disableVoting) {
+		final List<Question> questions = getQuestions(new NovaView("skill_question/by_session"), session);
+		setVotingAdmissions(session, disableVoting, questions);
+		return questions;
+	}
+
+	@Caching(evict = { @CacheEvict(value = "questions", allEntries = true),
+			@CacheEvict(value = "skillquestions", allEntries = true),
+			@CacheEvict(value = "lecturequestions", allEntries = true),
+			@CacheEvict(value = "preparationquestions", allEntries = true),
+			@CacheEvict(value = "flashcardquestions", allEntries = true) })
+	@Override
+	public void setVotingAdmissions(final Session session, final boolean disableVoting, List<Question> questions) {
+		for (final Question q : questions) {
+			if (!q.getQuestionType().equals("flashcard")) {
+				q.setVotingDisabled(disableVoting);
+			}
+		}
+		final List<Document> documents = new ArrayList<Document>();
+		for (final Question q : questions) {
+			final Document d = toQuestionDocument(session, q);
+			d.setId(q.get_id());
+			d.setRev(q.get_rev());
+			documents.add(d);
+		}
+
+		try {
+			database.bulkSaveDocuments(documents.toArray(new Document[documents.size()]));
+		} catch (final IOException e) {
+			LOGGER.error("Could not bulk set voting admission for all questions: {}", e.getMessage());
+		}
+	}
+
 	@CacheEvict(value = "answers", allEntries = true)
 	@Override
 	public void deleteAllQuestionsAnswers(final Session session) {
diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
index 1fd1fb10c..0f6255948 100644
--- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
+++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
@@ -215,4 +215,8 @@ public interface IDatabaseDao {
 	List<Question> getQuestionsByIds(List<String> ids, Session session);
 
 	void resetQuestionsRoundState(Session session, List<Question> questions);
+
+	void setVotingAdmissions(Session session, boolean disableVoting, List<Question> questions);
+
+	List<Question> setVotingAdmissionForAllQuestions(Session session, boolean disableVoting);
 }
diff --git a/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java b/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java
index bbd453b9c..2ef264989 100644
--- a/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java
+++ b/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java
@@ -36,7 +36,8 @@ import de.thm.arsnova.events.DeleteQuestionEvent;
 import de.thm.arsnova.events.DeleteSessionEvent;
 import de.thm.arsnova.events.LockQuestionEvent;
 import de.thm.arsnova.events.LockQuestionsEvent;
-import de.thm.arsnova.events.LockVotingEvent;
+import de.thm.arsnova.events.LockVoteEvent;
+import de.thm.arsnova.events.LockVotesEvent;
 import de.thm.arsnova.events.NewAnswerEvent;
 import de.thm.arsnova.events.NewFeedbackEvent;
 import de.thm.arsnova.events.NewInterposedQuestionEvent;
@@ -50,6 +51,8 @@ import de.thm.arsnova.events.PiRoundDelayedStartEvent;
 import de.thm.arsnova.events.PiRoundEndEvent;
 import de.thm.arsnova.events.PiRoundResetEvent;
 import de.thm.arsnova.events.StatusSessionEvent;
+import de.thm.arsnova.events.UnlockVoteEvent;
+import de.thm.arsnova.events.UnlockVotesEvent;
 
 @Component
 public class LearningProgressFactory implements NovaEventVisitor, ILearningProgressFactory, ApplicationEventPublisherAware {
@@ -188,5 +191,15 @@ public class LearningProgressFactory implements NovaEventVisitor, ILearningProgr
 	}
 
 	@Override
-	public void visit(LockVotingEvent lockVotingEvent) {}
+	public void visit(LockVoteEvent lockVoteEvent) {}
+
+	@Override
+	public void visit(LockVotesEvent lockVotesEvent) {}
+
+	@Override
+	public void visit(UnlockVoteEvent unlockVoteEvent) {}
+
+	@Override
+	public void visit(UnlockVotesEvent unlockVotesEvent) {}
+
 }
diff --git a/src/main/java/de/thm/arsnova/events/LockVoteEvent.java b/src/main/java/de/thm/arsnova/events/LockVoteEvent.java
new file mode 100644
index 000000000..8a695a109
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/LockVoteEvent.java
@@ -0,0 +1,60 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * 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.events;
+
+import java.util.HashMap;
+
+import de.thm.arsnova.entities.Question;
+import de.thm.arsnova.entities.Session;
+
+public class LockVoteEvent extends SessionEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	private final Question question;
+
+	public LockVoteEvent(Object source, Session session, Question question) {
+		super(source, session);
+		this.question = question;
+	}
+
+	public String getQuestionId() {
+		return this.question.get_id();
+	}
+
+	public String getQuestionVariant() {
+		return this.question.getQuestionVariant();
+	}
+
+	public Boolean getVotingDisabled() {
+		return this.question.isVotingDisabled();
+	}
+
+	public HashMap<String, Object> getVotingAdmission() {
+		HashMap<String, Object> map = new HashMap<String, Object>();
+
+		map.put("_id", getQuestionId());
+		map.put("variant", getQuestionVariant());
+		return map;
+	}
+
+	@Override
+	public void accept(NovaEventVisitor visitor) {
+		visitor.visit(this);
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/events/LockVotesEvent.java b/src/main/java/de/thm/arsnova/events/LockVotesEvent.java
new file mode 100644
index 000000000..2f42f00a1
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/LockVotesEvent.java
@@ -0,0 +1,45 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * 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.events;
+
+import java.util.List;
+
+import de.thm.arsnova.entities.Question;
+import de.thm.arsnova.entities.Session;
+
+public class LockVotesEvent extends SessionEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	private List<Question> questions;
+
+	public LockVotesEvent(Object source, Session session, List<Question> questions) {
+		super(source, session);
+		this.questions = questions;
+	}
+
+	public List<Question> getQuestions() {
+		return this.questions;
+	}
+
+	@Override
+	public void accept(NovaEventVisitor visitor) {
+		visitor.visit(this);
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java b/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
index 26e956bd1..eba55e64e 100644
--- a/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
+++ b/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
@@ -67,6 +67,12 @@ public interface NovaEventVisitor {
 
 	void visit(DeleteSessionEvent deleteSessionEvent);
 
-	void visit(LockVotingEvent lockVotingEvent);
+	void visit(LockVoteEvent lockVoteEvent);
+
+	void visit(LockVotesEvent lockVotesEvent);
+
+	void visit(UnlockVoteEvent unlockVoteEvent);
+
+	void visit(UnlockVotesEvent unlockVotesEvent);
 
 }
diff --git a/src/main/java/de/thm/arsnova/events/LockVotingEvent.java b/src/main/java/de/thm/arsnova/events/UnlockVoteEvent.java
similarity index 90%
rename from src/main/java/de/thm/arsnova/events/LockVotingEvent.java
rename to src/main/java/de/thm/arsnova/events/UnlockVoteEvent.java
index ab5c27f0d..eb8441179 100644
--- a/src/main/java/de/thm/arsnova/events/LockVotingEvent.java
+++ b/src/main/java/de/thm/arsnova/events/UnlockVoteEvent.java
@@ -22,13 +22,13 @@ import java.util.HashMap;
 import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.Session;
 
-public class LockVotingEvent extends SessionEvent {
+public class UnlockVoteEvent extends SessionEvent {
 
 	private static final long serialVersionUID = 1L;
 
 	private final Question question;
 
-	public LockVotingEvent(Object source, Session session, Question question) {
+	public UnlockVoteEvent(Object source, Session session, Question question) {
 		super(source, session);
 		this.question = question;
 	}
@@ -49,7 +49,6 @@ public class LockVotingEvent extends SessionEvent {
 		HashMap<String, Object> map = new HashMap<String, Object>();
 
 		map.put("_id", getQuestionId());
-		map.put("disable", getVotingDisabled());
 		map.put("variant", getQuestionVariant());
 		return map;
 	}
diff --git a/src/main/java/de/thm/arsnova/events/UnlockVotesEvent.java b/src/main/java/de/thm/arsnova/events/UnlockVotesEvent.java
new file mode 100644
index 000000000..90ce5127b
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/UnlockVotesEvent.java
@@ -0,0 +1,45 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * 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.events;
+
+import java.util.List;
+
+import de.thm.arsnova.entities.Question;
+import de.thm.arsnova.entities.Session;
+
+public class UnlockVotesEvent extends SessionEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	private List<Question> questions;
+
+	public UnlockVotesEvent(Object source, Session session, List<Question> questions) {
+		super(source, session);
+		this.questions = questions;
+	}
+
+	public List<Question> getQuestions() {
+		return this.questions;
+	}
+
+	@Override
+	public void accept(NovaEventVisitor visitor) {
+		visitor.visit(this);
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/services/IQuestionService.java b/src/main/java/de/thm/arsnova/services/IQuestionService.java
index c6fe40ef6..7a279e5d5 100644
--- a/src/main/java/de/thm/arsnova/services/IQuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/IQuestionService.java
@@ -156,6 +156,10 @@ public interface IQuestionService {
 
 	String getQuestionSortType(String sessionkey, boolean isPreparation, String subject);
 
-	void setVotingAdmission(String questionId, boolean disable);
+	void setVotingAdmission(String questionId, boolean disableVoting);
+	
+	void setVotingAdmissions(String sessionkey, boolean disableVoting, List<Question> questions);
+
+	void setVotingAdmissionForAllQuestions(String sessionkey, boolean disableVoting);
 
 }
diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java
index 6c5dca9d8..103b9374b 100644
--- a/src/main/java/de/thm/arsnova/services/QuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/QuestionService.java
@@ -55,7 +55,8 @@ import de.thm.arsnova.events.DeleteInterposedQuestionEvent;
 import de.thm.arsnova.events.DeleteQuestionEvent;
 import de.thm.arsnova.events.LockQuestionEvent;
 import de.thm.arsnova.events.LockQuestionsEvent;
-import de.thm.arsnova.events.LockVotingEvent;
+import de.thm.arsnova.events.LockVoteEvent;
+import de.thm.arsnova.events.LockVotesEvent;
 import de.thm.arsnova.events.NewAnswerEvent;
 import de.thm.arsnova.events.NewInterposedQuestionEvent;
 import de.thm.arsnova.events.NewQuestionEvent;
@@ -66,6 +67,8 @@ import de.thm.arsnova.events.PiRoundCancelEvent;
 import de.thm.arsnova.events.PiRoundDelayedStartEvent;
 import de.thm.arsnova.events.PiRoundEndEvent;
 import de.thm.arsnova.events.PiRoundResetEvent;
+import de.thm.arsnova.events.UnlockVoteEvent;
+import de.thm.arsnova.events.UnlockVotesEvent;
 import de.thm.arsnova.exceptions.BadRequestException;
 import de.thm.arsnova.exceptions.ForbiddenException;
 import de.thm.arsnova.exceptions.NotFoundException;
@@ -338,8 +341,49 @@ public class QuestionService implements IQuestionService, ApplicationEventPublis
 		} else {
 			databaseDao.updateQuestion(question);
 		}
-		
-		this.publisher.publishEvent(new LockVotingEvent(this, session, question));
+		NovaEvent event;
+		if (disableVoting) {
+			event = new LockVoteEvent(this, session, question);
+		} else {
+			event = new UnlockVoteEvent(this, session, question);
+		}
+		this.publisher.publishEvent(event);
+	}
+
+	@Override
+	@PreAuthorize("isAuthenticated()")
+	public void setVotingAdmissions(final String sessionkey, final boolean disableVoting, List<Question> questions) {
+		final User user = getCurrentUser();
+		final Session session = getSession(sessionkey);
+		if (!session.isCreator(user)) {
+			throw new UnauthorizedException();
+		}
+		databaseDao.setVotingAdmissions(session, disableVoting, questions);
+		NovaEvent event;
+		if (disableVoting) {
+			event = new LockVotesEvent(this, session, questions);
+		} else {
+			event = new UnlockVotesEvent(this, session, questions);
+		}
+		this.publisher.publishEvent(event);
+	}
+
+	@Override
+	@PreAuthorize("isAuthenticated()")
+	public void setVotingAdmissionForAllQuestions(final String sessionkey, final boolean disableVoting) {
+		final User user = getCurrentUser();
+		final Session session = getSession(sessionkey);
+		if (!session.isCreator(user)) {
+			throw new UnauthorizedException();
+		}
+		final List<Question> questions = databaseDao.setVotingAdmissionForAllQuestions(session, disableVoting);
+		NovaEvent event;
+		if (disableVoting) {
+			event = new LockVotesEvent(this, session, questions);
+		} else {
+			event = new UnlockVotesEvent(this, session, questions);
+		}
+		this.publisher.publishEvent(event);
 	}
 
 	private Session getSessionWithAuthCheck(final String sessionKeyword) {
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
index b54ce1f7b..ebb09d10a 100644
--- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
@@ -62,7 +62,8 @@ import de.thm.arsnova.events.DeleteQuestionEvent;
 import de.thm.arsnova.events.DeleteSessionEvent;
 import de.thm.arsnova.events.LockQuestionEvent;
 import de.thm.arsnova.events.LockQuestionsEvent;
-import de.thm.arsnova.events.LockVotingEvent;
+import de.thm.arsnova.events.LockVoteEvent;
+import de.thm.arsnova.events.LockVotesEvent;
 import de.thm.arsnova.events.NewAnswerEvent;
 import de.thm.arsnova.events.NewFeedbackEvent;
 import de.thm.arsnova.events.NewInterposedQuestionEvent;
@@ -76,6 +77,8 @@ import de.thm.arsnova.events.PiRoundDelayedStartEvent;
 import de.thm.arsnova.events.PiRoundEndEvent;
 import de.thm.arsnova.events.PiRoundResetEvent;
 import de.thm.arsnova.events.StatusSessionEvent;
+import de.thm.arsnova.events.UnlockVoteEvent;
+import de.thm.arsnova.events.UnlockVotesEvent;
 import de.thm.arsnova.exceptions.NoContentException;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.exceptions.UnauthorizedException;
@@ -532,7 +535,6 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 	@Override
 	public void visit(PiRoundDelayedStartEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
-
 		broadcastInSession(sessionKey, "startDelayedPiRound", event.getPiRoundInformations());
 	}
 
@@ -540,7 +542,6 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 	@Override
 	public void visit(PiRoundEndEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
-
 		broadcastInSession(sessionKey, "endPiRound", event.getPiRoundEndInformations());
 	}
 
@@ -548,22 +549,43 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 	@Override
 	public void visit(PiRoundCancelEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
-
 		broadcastInSession(sessionKey, "cancelPiRound", event.getQuestionId());
 	}
 
 	@Override
 	public void visit(PiRoundResetEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
-
 		broadcastInSession(sessionKey, "resetPiRound", event.getPiRoundResetInformations());
 	}
 
 	@Override
-	public void visit(LockVotingEvent event) {
+	public void visit(LockVoteEvent event) {
+		final String sessionKey = event.getSession().getKeyword();
+		broadcastInSession(sessionKey, "lockVote", event.getVotingAdmission());
+	}
+
+	@Override
+	public void visit(UnlockVoteEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
+		broadcastInSession(sessionKey, "unlockVote", event.getVotingAdmission());
+	}
+
+	@Override
+	public void visit(LockVotesEvent event) {
+		List<Question> questions = new ArrayList<Question>();
+		for (de.thm.arsnova.entities.Question q : event.getQuestions()) {
+			questions.add(new Question(q));
+		}
+		broadcastInSession(event.getSession().getKeyword(), "lockVotes", questions);
+	}
 
-		broadcastInSession(sessionKey, "lockVoting", event.getVotingAdmission());
+	@Override
+	public void visit(UnlockVotesEvent event) {
+		List<Question> questions = new ArrayList<Question>();
+		for (de.thm.arsnova.entities.Question q : event.getQuestions()) {
+			questions.add(new Question(q));
+		}
+		broadcastInSession(event.getSession().getKeyword(), "unlockVotes", questions);
 	}
 
 	@Override
@@ -628,5 +650,4 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 	@Override
 	public void visit(DeleteSessionEvent event) {}
-
 }
diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
index bbc3d8f8b..e14db9020 100644
--- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
+++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
@@ -628,4 +628,16 @@ public class StubDatabaseDao implements IDatabaseDao {
 		// TODO Auto-generated method stub
 		
 	}
+
+	@Override
+	public void setVotingAdmissions(Session session, boolean disableVoting, List<Question> questions) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public List<Question> setVotingAdmissionForAllQuestions(Session session, boolean disableVoting) {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }
\ No newline at end of file
-- 
GitLab