diff --git a/src/main/java/de/thm/arsnova/controller/SessionController.java b/src/main/java/de/thm/arsnova/controller/SessionController.java index 16e808de667d4fc23bd38f93ef7221db5a7b91d4..007b5dd000ac880bad939f6f8cac5061ec1d7335 100644 --- a/src/main/java/de/thm/arsnova/controller/SessionController.java +++ b/src/main/java/de/thm/arsnova/controller/SessionController.java @@ -39,6 +39,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import de.thm.arsnova.entities.Feedback; +import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; import de.thm.arsnova.services.ISessionService; @@ -104,6 +105,20 @@ public class SessionController extends AbstractController { return null; } + @RequestMapping(value="/session/{sessionkey}/online", method=RequestMethod.POST) + @ResponseBody + public LoggedIn registerAsOnlineUser(@PathVariable String sessionkey, HttpServletResponse response) { + User user = userService.getUser(SecurityContextHolder.getContext().getAuthentication()); + LoggedIn loggedIn = sessionService.registerAsOnlineUser(user, sessionkey); + if (loggedIn != null) { + response.setStatus(HttpStatus.CREATED.value()); + return loggedIn; + } + + response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); + return null; + } + @RequestMapping(value="/session", method=RequestMethod.POST) @ResponseBody public Session postNewSession(@RequestBody Session session, HttpServletResponse response) { diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index 89c4693a141c287145b19aa844e32fd1dd2df253..435554e2658327252be550c79689f130d2f21b42 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -34,15 +34,11 @@ import java.util.Set; import net.sf.ezmorph.Morpher; import net.sf.ezmorph.MorpherRegistry; import net.sf.ezmorph.bean.BeanMorpher; -import net.sf.ezmorph.bean.MorphDynaBean; import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONObject; -import net.sf.json.JsonConfig; import net.sf.json.util.JSONUtils; -import org.apache.commons.beanutils.DynaBean; -import org.apache.commons.beanutils.DynaClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -59,8 +55,10 @@ import com.fourspaces.couchdb.View; import com.fourspaces.couchdb.ViewResults; import de.thm.arsnova.entities.Feedback; +import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; +import de.thm.arsnova.entities.VisitedSession; import de.thm.arsnova.exceptions.ForbiddenException; import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.services.ISessionService; @@ -517,4 +515,45 @@ public class CouchDBDao implements IDatabaseDao { } return null; } + + @Override + public LoggedIn registerAsOnlineUser(User u, Session s) { + try { + View view = new View("logged_in/all"); + view.setKey(URLEncoder.encode("\"" + u.getUsername() + "\"", "UTF-8")); + ViewResults results = this.getDatabase().view(view); + + LoggedIn loggedIn = new LoggedIn(); + if (results.getJSONArray("rows").optJSONObject(0) != null) { + JSONObject json = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"); + loggedIn = (LoggedIn) JSONObject.toBean(json, LoggedIn.class); + Collection<VisitedSession> visitedSessions = JSONArray.toCollection(json.getJSONArray("visitedSessions"), VisitedSession.class); + loggedIn.setVisitedSessions(new ArrayList<VisitedSession>(visitedSessions)); + } + + loggedIn.setUser(u.getUsername()); + loggedIn.setSessionId(s.get_id()); + loggedIn.addVisitedSession(s); + + JSONObject json = JSONObject.fromObject(loggedIn); + Document doc = new Document(json); + if (doc.getId() == "") { + // If this is a new user without a logged_in document, we have to remove the following + // pre-filled fields. Otherwise, CouchDB will take these empty fields as genuine + // identifiers, and will throw errors afterwards. + doc.remove("_id"); + doc.remove("_rev"); + } + this.getDatabase().saveDocument(doc); + + LoggedIn l = (LoggedIn) JSONObject.toBean(doc.getJSONObject(), LoggedIn.class); + Collection<VisitedSession> visitedSessions = JSONArray.toCollection(doc.getJSONObject().getJSONArray("visitedSessions"), VisitedSession.class); + l.setVisitedSessions(new ArrayList<VisitedSession>(visitedSessions)); + return l; + } catch (UnsupportedEncodingException e) { + return null; + } catch (IOException e) { + return null; + } + } } diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java index 1b433a0eca55dde74674cdca0a1f6424ebf63003..e1d2545c3720b09ee10c2a4c5adb66202289711a 100644 --- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java +++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java @@ -22,6 +22,7 @@ package de.thm.arsnova.dao; import java.util.List; import de.thm.arsnova.entities.Feedback; +import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; import de.thm.arsnova.socket.message.Question; @@ -40,4 +41,6 @@ public interface IDatabaseDao { public Question getQuestion(String id); List<Question> getSkillQuestions(String session, String sort); public int getSkillQuestionCount(String sessionkey); + + public LoggedIn registerAsOnlineUser(User u, Session s); } \ No newline at end of file diff --git a/src/main/java/de/thm/arsnova/entities/LoggedIn.java b/src/main/java/de/thm/arsnova/entities/LoggedIn.java new file mode 100644 index 0000000000000000000000000000000000000000..fd081f3648236306de2426d2213ae33f2ddde93b --- /dev/null +++ b/src/main/java/de/thm/arsnova/entities/LoggedIn.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2012 THM webMedia + * + * This file is part of ARSnova. + * + * ARSnova 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 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.entities; + +import java.util.ArrayList; +import java.util.List; + +public class LoggedIn { + + private String _id; + private String _rev; + private String type; + private String user; + private String sessionId; + private long timestamp; + private List<VisitedSession> visitedSessions = new ArrayList<VisitedSession>(); + + public LoggedIn() { + this.type = "logged_in"; + this.timestamp = System.currentTimeMillis(); + } + + public void addVisitedSession(Session s) { + if (!isAlreadyVisited(s)) { + this.visitedSessions.add(new VisitedSession(s)); + } + } + + private boolean isAlreadyVisited(Session s) { + for (VisitedSession vs : this.visitedSessions) { + if (vs.get_id().equals(s.get_id())) { + return true; + } + } + return false; + } + + public String get_id() { + return _id; + } + + public void set_id(String _id) { + this._id = _id; + } + + public String get_rev() { + return _rev; + } + + public void set_rev(String _rev) { + this._rev = _rev; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public List<VisitedSession> getVisitedSessions() { + return visitedSessions; + } + + public void setVisitedSessions(List<VisitedSession> visitedSessions) { + this.visitedSessions = visitedSessions; + } + + @Override + public String toString() { + return "LoggedIn [_id=" + _id + ", _rev=" + _rev + ", type=" + type + + ", user=" + user + ", sessionId=" + sessionId + + ", timestamp=" + timestamp + ", visitedSessions=" + + visitedSessions + "]"; + } +} \ No newline at end of file diff --git a/src/main/java/de/thm/arsnova/entities/Session.java b/src/main/java/de/thm/arsnova/entities/Session.java index ba107fe106dc9bd5d70863f46458a55ed9894b55..2e43385d3ad589bad50fb331b6e7163c56f3c08d 100644 --- a/src/main/java/de/thm/arsnova/entities/Session.java +++ b/src/main/java/de/thm/arsnova/entities/Session.java @@ -27,6 +27,7 @@ public class Session { private String keyword; private String creator; private boolean active; + private long lastOwnerActivity; private String _id; private String _rev; @@ -67,6 +68,12 @@ public class Session { this.active = active; } + public long getLastOwnerActivity() { + return lastOwnerActivity; + } + public void setLastOwnerActivity(long lastOwnerActivity) { + this.lastOwnerActivity = lastOwnerActivity; + } public void set_id(String id) { _id = id; } diff --git a/src/main/java/de/thm/arsnova/entities/VisitedSession.java b/src/main/java/de/thm/arsnova/entities/VisitedSession.java new file mode 100644 index 0000000000000000000000000000000000000000..50cb8819917b52d405653c3ffc73999275e9d54d --- /dev/null +++ b/src/main/java/de/thm/arsnova/entities/VisitedSession.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012 THM webMedia + * + * This file is part of ARSnova. + * + * ARSnova 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 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.entities; + +public class VisitedSession { + private String _id; + private String name; + private String keyword; + + public VisitedSession() {} + + public VisitedSession(Session s) { + this._id = s.get_id(); + this.name = s.getName(); + this.keyword = s.getKeyword(); + } + + public String get_id() { + return _id; + } + + public void set_id(String _id) { + this._id = _id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getKeyword() { + return keyword; + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } + + @Override + public String toString() { + return "VisitedSession [_id=" + _id + ", name=" + name + + ", keyword=" + keyword + "]"; + } + } \ No newline at end of file diff --git a/src/main/java/de/thm/arsnova/services/ISessionService.java b/src/main/java/de/thm/arsnova/services/ISessionService.java index 67ab4eeb4eeb9821684261e5bfff690cbe8c9852..42b3200615dbec69c9871db9e60e3c0a3027963c 100644 --- a/src/main/java/de/thm/arsnova/services/ISessionService.java +++ b/src/main/java/de/thm/arsnova/services/ISessionService.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.Set; import de.thm.arsnova.entities.Feedback; +import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; @@ -49,4 +50,5 @@ public interface ISessionService { public Question getQuestion(String id); public List<Question> getSkillQuestions(String sessionkey, String sort); public int getSkillQuestionCount(String sessionkey); + public LoggedIn registerAsOnlineUser(User user, String sessionkey); } \ No newline at end of file diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java index 55b77fceb0e92d1629c487f2bc864c164c8d9f13..e076aa898f2d3e169f2be72368a5a197cb1014f5 100644 --- a/src/main/java/de/thm/arsnova/services/SessionService.java +++ b/src/main/java/de/thm/arsnova/services/SessionService.java @@ -36,6 +36,7 @@ import org.springframework.transaction.annotation.Transactional; import de.thm.arsnova.annotation.Authenticated; import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.Feedback; +import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; import de.thm.arsnova.socket.ARSnovaSocketIOServer; @@ -175,4 +176,13 @@ public class SessionService implements ISessionService { public Question getQuestion(String id) { return databaseDao.getQuestion(id); } + + @Override + @Authenticated + public LoggedIn registerAsOnlineUser(User user, String sessionkey) { + Session session = this.getSession(sessionkey); + if (session == null) return null; + + return databaseDao.registerAsOnlineUser(user, session); + } } diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index 669087545c4968c4b09ac117ca26469bd4e2852d..b5b94afe8b2b056f9d3f43f31b88652e3c26703f 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -10,6 +10,7 @@ import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import de.thm.arsnova.entities.Feedback; +import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; import de.thm.arsnova.exceptions.ForbiddenException; @@ -150,4 +151,10 @@ public class StubDatabaseDao implements IDatabaseDao { return null; } + @Override + public LoggedIn registerAsOnlineUser(User u, Session s) { + // TODO Auto-generated method stub + return null; + } + }