From 94888c170378f576643da31bf05da0ebc3ba881e Mon Sep 17 00:00:00 2001
From: Paul-Christian Volkmer <paul-christian.volkmer@mni.thm.de>
Date: Wed, 5 Jun 2013 11:32:31 +0200
Subject: [PATCH] Add UserSessionAspect aspect

This sets current user and ARSnova session information in a session
scoped service bean. If the user connects with a websocket, the
websocket session ID will be set in addition to the user and session
object.

The aspects methods pointcut after returning from joinSession() method
in SessionService. So the UserSessionService will be set with all needed
data after a user successfully joins a session.

With this service available, it can be used to replace some usage of
Array/Map based application wide data structures that cause some trouble
when stopping or redeploying the application.
---
 .../de/thm/arsnova/aop/UserSessionAspect.java | 59 +++++++++++++++++++
 .../arsnova/controller/SessionController.java |  6 --
 .../arsnova/services/UserSessionService.java  |  4 ++
 .../services/UserSessionServiceImpl.java      | 13 ++++
 .../webapp/WEB-INF/spring/arsnova-servlet.xml |  4 --
 .../webapp/WEB-INF/spring/spring-main.xml     |  7 +++
 6 files changed, 83 insertions(+), 10 deletions(-)
 create mode 100644 src/main/java/de/thm/arsnova/aop/UserSessionAspect.java

diff --git a/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java b/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java
new file mode 100644
index 00000000..a54a9127
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java
@@ -0,0 +1,59 @@
+package de.thm.arsnova.aop;
+
+import java.util.UUID;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import de.thm.arsnova.controller.SessionController;
+import de.thm.arsnova.entities.Session;
+import de.thm.arsnova.services.IUserService;
+import de.thm.arsnova.services.UserSessionService;
+
+@Aspect
+public class UserSessionAspect {
+
+	public static final Logger LOGGER = LoggerFactory.getLogger(SessionController.class);
+	
+	@Autowired
+	private UserSessionService userSessionService;
+	
+	@Autowired
+	private IUserService userService;
+	
+	/** Sets current user and ARSnova session in session scoped UserSessionService 
+	 * 
+	 * @param jp
+	 * @param keyword
+	 * @param session
+	 */
+	@AfterReturning(
+		pointcut="execution(public * de.thm.arsnova.services.SessionService.joinSession(..)) && args(keyword)",
+		returning="session"
+	)
+	public final void joinSessionAdvice(final JoinPoint jp, final String keyword, final Session session) {
+		userSessionService.setUser(userService.getCurrentUser());
+		userSessionService.setSession(session);
+	}
+	
+	/** Sets current user, ARSnova session and websocket session ID in session scoped UserSessionService 
+	 * 
+	 * @param jp
+	 * @param keyword
+	 * @param socketId
+	 * @param session
+	 */
+	@AfterReturning(
+		pointcut="execution(public * de.thm.arsnova.services.SessionService.joinSession(..)) && args(keyword, socketId)",
+		returning="session"
+	)
+	public final void joinSessionAdviceWithWebsocket(final JoinPoint jp, final String keyword, final UUID socketId, final Session session) {
+		userSessionService.setUser(userService.getCurrentUser());
+		userSessionService.setSession(session);
+		userSessionService.setSocketId(socketId);
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/controller/SessionController.java b/src/main/java/de/thm/arsnova/controller/SessionController.java
index 59b9e529..ecdb8b5f 100644
--- a/src/main/java/de/thm/arsnova/controller/SessionController.java
+++ b/src/main/java/de/thm/arsnova/controller/SessionController.java
@@ -43,7 +43,6 @@ import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
 import de.thm.arsnova.services.ISessionService;
 import de.thm.arsnova.services.IUserService;
-import de.thm.arsnova.services.UserSessionService;
 import de.thm.arsnova.services.SessionService.SessionNameComperator;
 import de.thm.arsnova.services.SessionService.SessionShortNameComperator;
 
@@ -59,15 +58,10 @@ public class SessionController extends AbstractController {
 	@Autowired
 	private IUserService userService;
 
-	@Autowired
-	private UserSessionService userSessionService;
-
 	@RequestMapping(value = "/{sessionkey}", method = RequestMethod.GET)
 	@ResponseBody
 	public final Session joinSession(@PathVariable final String sessionkey) {
 		Session session = sessionService.joinSession(sessionkey);
-		userSessionService.setUser(userService.getCurrentUser());
-		userSessionService.setSession(session);
 		return session;
 	}
 
diff --git a/src/main/java/de/thm/arsnova/services/UserSessionService.java b/src/main/java/de/thm/arsnova/services/UserSessionService.java
index ea5b0968..d26a8f18 100644
--- a/src/main/java/de/thm/arsnova/services/UserSessionService.java
+++ b/src/main/java/de/thm/arsnova/services/UserSessionService.java
@@ -1,5 +1,7 @@
 package de.thm.arsnova.services;
 
+import java.util.UUID;
+
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
 
@@ -11,4 +13,6 @@ public interface UserSessionService {
 	void setSession(Session session);
 	Session getSession();
 	
+	void setSocketId(UUID socketId);
+	UUID getSocketId();
 }
\ No newline at end of file
diff --git a/src/main/java/de/thm/arsnova/services/UserSessionServiceImpl.java b/src/main/java/de/thm/arsnova/services/UserSessionServiceImpl.java
index a340bfb7..69a51cae 100644
--- a/src/main/java/de/thm/arsnova/services/UserSessionServiceImpl.java
+++ b/src/main/java/de/thm/arsnova/services/UserSessionServiceImpl.java
@@ -1,5 +1,7 @@
 package de.thm.arsnova.services;
 
+import java.util.UUID;
+
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.annotation.ScopedProxyMode;
 import org.springframework.stereotype.Component;
@@ -13,6 +15,7 @@ public class UserSessionServiceImpl implements UserSessionService {
 	
 	private User user;
 	private Session session;
+	private UUID socketId;
 	
 	@Override
 	public void setUser(User u) {
@@ -33,4 +36,14 @@ public class UserSessionServiceImpl implements UserSessionService {
 	public Session getSession() {
 		return this.session;
 	}
+	
+	@Override
+	public void setSocketId(UUID sId) {
+		this.socketId = sId;
+	}
+	
+	@Override
+	public UUID getSocketId() {
+		return this.socketId;
+	}
 }
diff --git a/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml b/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml
index 0026ff24..e0e455c0 100644
--- a/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml
+++ b/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml
@@ -24,10 +24,6 @@
 	        </value>
 	    </property>
 	</bean>
-	
-	<aop:aspectj-autoproxy>
-		<aop:include name="authorizationAdviser" />
-	</aop:aspectj-autoproxy>
 
 	<mvc:annotation-driven />
 	<mvc:resources mapping="/**" location="/" />
diff --git a/src/main/webapp/WEB-INF/spring/spring-main.xml b/src/main/webapp/WEB-INF/spring/spring-main.xml
index d97cf9c9..410ed279 100644
--- a/src/main/webapp/WEB-INF/spring/spring-main.xml
+++ b/src/main/webapp/WEB-INF/spring/spring-main.xml
@@ -33,6 +33,11 @@
 	<context:annotation-config />
 
 	<task:annotation-driven />
+	
+	<aop:aspectj-autoproxy>
+		<aop:include name="authorizationAdviser" />
+		<aop:include name="userSessionAspect" />
+	</aop:aspectj-autoproxy>
 
 	<bean id="socketServer" class="de.thm.arsnova.socket.ARSnovaSocketIOServer"
 		init-method="startServer" destroy-method="stopServer" scope="singleton"
@@ -42,6 +47,8 @@
 	<bean id="authorizationAdviser" class="de.thm.arsnova.aop.AuthorizationAdviser">
 		<property name="userService" ref="userService" />
 	</bean>
+	
+	<bean id="userSessionAspect" class="de.thm.arsnova.aop.UserSessionAspect" />
 
 	<bean id="userService" scope="singleton" class="de.thm.arsnova.services.UserService" />
 
-- 
GitLab