From aef9ae34bd0123afcd7eca435e1d5e4f2ef0a6df Mon Sep 17 00:00:00 2001
From: Christoph Thelen <christoph.thelen@mni.thm.de>
Date: Mon, 3 Nov 2014 14:53:17 +0100
Subject: [PATCH] Use spring events broadcast via web sockets

---
 .../events/NewInterposedQuestionEvent.java    | 32 +++++++++++++++++++
 .../thm/arsnova/events/NewQuestionEvent.java  | 32 +++++++++++++++++++
 .../java/de/thm/arsnova/events/NovaEvent.java | 15 +++++++++
 .../thm/arsnova/events/NovaEventVisitor.java  |  9 ++++++
 .../de/thm/arsnova/events/package-info.java   |  5 +++
 .../thm/arsnova/services/QuestionService.java | 21 +++++++++---
 .../arsnova/socket/ARSnovaSocketIOServer.java | 32 ++++++++++++++++---
 7 files changed, 136 insertions(+), 10 deletions(-)
 create mode 100644 src/main/java/de/thm/arsnova/events/NewInterposedQuestionEvent.java
 create mode 100644 src/main/java/de/thm/arsnova/events/NewQuestionEvent.java
 create mode 100644 src/main/java/de/thm/arsnova/events/NovaEvent.java
 create mode 100644 src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
 create mode 100644 src/main/java/de/thm/arsnova/events/package-info.java

diff --git a/src/main/java/de/thm/arsnova/events/NewInterposedQuestionEvent.java b/src/main/java/de/thm/arsnova/events/NewInterposedQuestionEvent.java
new file mode 100644
index 00000000..d66d1362
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/NewInterposedQuestionEvent.java
@@ -0,0 +1,32 @@
+package de.thm.arsnova.events;
+
+import de.thm.arsnova.entities.InterposedQuestion;
+import de.thm.arsnova.entities.Session;
+
+public class NewInterposedQuestionEvent extends NovaEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	private final Session session;
+	private final InterposedQuestion question;
+
+	public NewInterposedQuestionEvent(Object source, InterposedQuestion question, Session session) {
+		super(source);
+		this.question = question;
+		this.session = session;
+	}
+
+	public Session getSession() {
+		return session;
+	}
+
+	public InterposedQuestion getQuestion() {
+		return question;
+	}
+
+	@Override
+	public void accept(NovaEventVisitor visitor) {
+		visitor.visit(this);
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/events/NewQuestionEvent.java b/src/main/java/de/thm/arsnova/events/NewQuestionEvent.java
new file mode 100644
index 00000000..aa40f1f6
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/NewQuestionEvent.java
@@ -0,0 +1,32 @@
+package de.thm.arsnova.events;
+
+import de.thm.arsnova.entities.Question;
+import de.thm.arsnova.entities.Session;
+
+public class NewQuestionEvent extends NovaEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	private final Question question;
+
+	private final Session session;
+
+	public NewQuestionEvent(Object source, Question question, Session session) {
+		super(source);
+		this.question = question;
+		this.session = session;
+	}
+
+	public Question getQuestion() {
+		return question;
+	}
+
+	public Session getSession() {
+		return session;
+	}
+
+	@Override
+	public void accept(NovaEventVisitor visitor) {
+		visitor.visit(this);
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/events/NovaEvent.java b/src/main/java/de/thm/arsnova/events/NovaEvent.java
new file mode 100644
index 00000000..81afe7c1
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/NovaEvent.java
@@ -0,0 +1,15 @@
+package de.thm.arsnova.events;
+
+import org.springframework.context.ApplicationEvent;
+
+public abstract class NovaEvent extends ApplicationEvent {
+
+	private static final long serialVersionUID = 1L;
+
+	public NovaEvent(Object source) {
+		super(source);
+	}
+
+	public abstract void accept(NovaEventVisitor visitor);
+
+}
diff --git a/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java b/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
new file mode 100644
index 00000000..4664d21d
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/NovaEventVisitor.java
@@ -0,0 +1,9 @@
+package de.thm.arsnova.events;
+
+public interface NovaEventVisitor {
+
+	void visit(NewInterposedQuestionEvent newInterposedQuestionEvent);
+
+	void visit(NewQuestionEvent newQuestionEvent);
+
+}
diff --git a/src/main/java/de/thm/arsnova/events/package-info.java b/src/main/java/de/thm/arsnova/events/package-info.java
new file mode 100644
index 00000000..acecfa4e
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/events/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * @author Christoph Thelen
+ *
+ */
+package de.thm.arsnova.events;
diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java
index 9150b2e9..ee1d5e82 100644
--- a/src/main/java/de/thm/arsnova/services/QuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/QuestionService.java
@@ -28,6 +28,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
 
@@ -39,13 +41,15 @@ import de.thm.arsnova.entities.InterposedReadingCount;
 import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
+import de.thm.arsnova.events.NewInterposedQuestionEvent;
+import de.thm.arsnova.events.NewQuestionEvent;
 import de.thm.arsnova.exceptions.BadRequestException;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.exceptions.UnauthorizedException;
 import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 
 @Service
-public class QuestionService implements IQuestionService {
+public class QuestionService implements IQuestionService, ApplicationEventPublisherAware {
 
 	@Autowired
 	private IDatabaseDao databaseDao;
@@ -59,6 +63,8 @@ public class QuestionService implements IQuestionService {
 	@Value("${upload.filesize_b}")
 	private int uploadFileSizeByte;
 
+	private ApplicationEventPublisher publisher;
+
 	public static final Logger LOGGER = LoggerFactory.getLogger(QuestionService.class);
 
 	public void setDatabaseDao(final IDatabaseDao databaseDao) {
@@ -109,7 +115,8 @@ public class QuestionService implements IQuestionService {
 		}
 
 		final Question result = databaseDao.saveQuestion(session, question);
-		socketIoServer.reportLecturerQuestionAvailable(result.getSessionKeyword(), result.get_id());
+		final NewQuestionEvent event = new NewQuestionEvent(this, result, session);
+		this.publisher.publishEvent(event);
 
 		return result;
 	}
@@ -121,11 +128,10 @@ public class QuestionService implements IQuestionService {
 		final InterposedQuestion result = databaseDao.saveQuestion(session, question, userService.getCurrentUser());
 
 		if (null != result) {
-			socketIoServer.reportAudienceQuestionAvailable(result.getSessionId(), result.get_id());
-
+			final NewInterposedQuestionEvent event = new NewInterposedQuestionEvent(this, result, session);
+			this.publisher.publishEvent(event);
 			return true;
 		}
-
 		return false;
 	}
 
@@ -551,4 +557,9 @@ public class QuestionService implements IQuestionService {
 		}
 		databaseDao.deleteAllQuestionsAnswers(session);
 	}
+
+	@Override
+	public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
+		this.publisher = publisher;
+	}
 }
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
index 36102b49..c663b351 100644
--- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
@@ -15,6 +15,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Required;
+import org.springframework.context.ApplicationListener;
 import org.springframework.stereotype.Component;
 
 import com.corundumstudio.socketio.AckRequest;
@@ -28,7 +29,13 @@ import com.corundumstudio.socketio.listener.DisconnectListener;
 import com.corundumstudio.socketio.protocol.Packet;
 import com.corundumstudio.socketio.protocol.PacketType;
 
+import de.thm.arsnova.entities.InterposedQuestion;
+import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.User;
+import de.thm.arsnova.events.NewInterposedQuestionEvent;
+import de.thm.arsnova.events.NewQuestionEvent;
+import de.thm.arsnova.events.NovaEvent;
+import de.thm.arsnova.events.NovaEventVisitor;
 import de.thm.arsnova.exceptions.NoContentException;
 import de.thm.arsnova.services.IFeedbackService;
 import de.thm.arsnova.services.ISessionService;
@@ -37,7 +44,7 @@ import de.thm.arsnova.socket.message.Feedback;
 import de.thm.arsnova.socket.message.Session;
 
 @Component
-public class ARSnovaSocketIOServer {
+public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, NovaEventVisitor {
 
 	@Autowired
 	private IFeedbackService feedbackService;
@@ -319,14 +326,14 @@ public class ARSnovaSocketIOServer {
 		broadcastInSession(sessionKey, "answersToLecQuestionAvail", lecturerQuestionId);
 	}
 
-	public void reportAudienceQuestionAvailable(final String sessionKey, final String audienceQuestionId) {
+	public void reportAudienceQuestionAvailable(final de.thm.arsnova.entities.Session session, final InterposedQuestion audienceQuestion) {
 		/* TODO role handling implementation, send this only to users with role lecturer */
-		broadcastInSession(sessionKey, "audQuestionAvail", audienceQuestionId);
+		broadcastInSession(session.getKeyword(), "audQuestionAvail", audienceQuestion.get_id());
 	}
 
-	public void reportLecturerQuestionAvailable(final String sessionKey, final String lecturerQuestionId) {
+	public void reportLecturerQuestionAvailable(final de.thm.arsnova.entities.Session session, final Question lecturerQuestion) {
 		/* TODO role handling implementation, send this only to users with role audience */
-		broadcastInSession(sessionKey, "lecQuestionAvail", lecturerQuestionId);
+		broadcastInSession(session.getKeyword(), "lecQuestionAvail", lecturerQuestion.get_id());
 	}
 
 	public void reportSessionStatus(final String sessionKey, final boolean active) {
@@ -348,4 +355,19 @@ public class ARSnovaSocketIOServer {
 			}
 		}
 	}
+
+	@Override
+	public void visit(NewQuestionEvent event) {
+		this.reportLecturerQuestionAvailable(event.getSession(), event.getQuestion());
+	}
+
+	@Override
+	public void visit(NewInterposedQuestionEvent event) {
+		this.reportAudienceQuestionAvailable(event.getSession(), event.getQuestion());
+	}
+
+	@Override
+	public void onApplicationEvent(NovaEvent event) {
+		event.accept(this);
+	}
 }
-- 
GitLab