diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index cad6b9d1e6c27cb6f1735798b1f9573b7c3ac1f9..aadd3d1e7b4cae914f61e54b307311b165e95637 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -870,6 +870,27 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware ); } + @SuppressWarnings("unchecked") + @Override + public <T> T getObjectFromId(final String documentId, final Class<T> klass) { + T obj = null; + try { + final Document doc = getDatabase().getDocument(documentId); + if (doc == null) { + return null; + } + // TODO: This needs some more error checking... + obj = (T) JSONObject.toBean(doc.getJSONObject(), klass); + } catch (IOException e) { + return null; + } catch (ClassCastException e) { + return null; + } catch (net.sf.json.JSONException e) { + return null; + } + return obj; + } + @Override public List<Answer> getAnswers(final Question question, final int piRound) { final String questionId = question.get_id(); @@ -1375,8 +1396,8 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware a.put("abstention", answer.isAbstention()); a.put("questionValue", answer.getQuestionValue()); a.put("answerImage", answer.getAnswerImage()); - a.put("answerThumbnailImage", answer.getAnswerThumbnailImage()); + a.put("read", answer.isRead()); database.saveDocument(a); answer.set_rev(a.getRev()); return answer; diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java index 833761262ac58c9861eaddf7067100f3a96437e5..f910ecbbabf98f169a05432ded496f06ca0be296 100644 --- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java +++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java @@ -222,4 +222,6 @@ public interface IDatabaseDao { void setVotingAdmissions(Session session, boolean disableVoting, List<Question> questions); List<Question> setVotingAdmissionForAllQuestions(Session session, boolean disableVoting); + + <T> T getObjectFromId(String documentId, Class<T> klass); } diff --git a/src/main/java/de/thm/arsnova/entities/Answer.java b/src/main/java/de/thm/arsnova/entities/Answer.java index ef2d18d82045650a7a9ac816cdf8260cb323e41e..4aa859228e8b3c1ec0351586b0661f7e2c144c08 100644 --- a/src/main/java/de/thm/arsnova/entities/Answer.java +++ b/src/main/java/de/thm/arsnova/entities/Answer.java @@ -38,6 +38,7 @@ public class Answer { private int piRound; private String user; private long timestamp; + private boolean read; private int answerCount = 1; private boolean abstention; private int abstentionCount; @@ -150,6 +151,14 @@ public class Answer { this.timestamp = timestamp; } + public boolean isRead() { + return read; + } + + public void setRead(boolean read) { + this.read = read; + } + public final int getAnswerCount() { return answerCount; } diff --git a/src/main/java/de/thm/arsnova/services/IQuestionService.java b/src/main/java/de/thm/arsnova/services/IQuestionService.java index 0a2f1fce3b1c1ff30cd71d6a2a44ea8b5dcf5b4e..a21d8424473ec5db4dc2932ee40c86f7908f539b 100644 --- a/src/main/java/de/thm/arsnova/services/IQuestionService.java +++ b/src/main/java/de/thm/arsnova/services/IQuestionService.java @@ -59,6 +59,8 @@ public interface IQuestionService { Answer getMyAnswer(String questionId); + void readFreetextAnswer(String answerId, User user); + List<Answer> getAnswers(String questionId, int piRound); List<Answer> getAnswers(String questionId); diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java index 4504565269c2e3d79140d08a8199aedd7305ab65..5edb106f564d08693781c800055ab96c0015b83a 100644 --- a/src/main/java/de/thm/arsnova/services/QuestionService.java +++ b/src/main/java/de/thm/arsnova/services/QuestionService.java @@ -462,6 +462,22 @@ public class QuestionService implements IQuestionService, ApplicationEventPublis return databaseDao.getMyAnswer(userService.getCurrentUser(), questionId, question.getPiRound()); } + @Override + public void readFreetextAnswer(final String answerId, final User user) { + final Answer answer = databaseDao.getObjectFromId(answerId, Answer.class); + if (answer == null) { + throw new NotFoundException(); + } + if (answer.isRead()) { + return; + } + final Session session = databaseDao.getSessionFromId(answer.getSessionId()); + if (session.isCreator(user)) { + answer.setRead(true); + databaseDao.updateAnswer(answer); + } + } + @Override @PreAuthorize("isAuthenticated()") public List<Answer> getAnswers(final String questionId, final int piRound) { diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java index b764d11f0847e49def5a67e29dd0266700108cb1..62b3b23ff194ce73222ca21ea16ef16c3ef7e4a6 100644 --- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java +++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java @@ -221,6 +221,18 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor { } }); + server.addEventListener("readFreetextAnswer", String.class, new DataListener<String>() { + @Override + public void onData(SocketIOClient client, String answerId, AckRequest ackRequest) { + final User user = userService.getUser2SocketId(client.getSessionId()); + try { + questionService.readFreetextAnswer(answerId, user); + } catch (NotFoundException | UnauthorizedException e) { + LOGGER.error("Marking answer {} as read failed for user {} with exception {}", answerId, user, e.getMessage()); + } + } + }); + server.addEventListener( "setLearningProgressOptions", LearningProgressOptions.class, diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index 1c3604d8fb00de63f996d2abfe41d575a48ae09e..32ec1204a3c10734e2ff5d0672b73340161aeac8 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -640,4 +640,10 @@ public class StubDatabaseDao implements IDatabaseDao { // TODO Auto-generated method stub return null; } + + @Override + public <T> T getObjectFromId(String documentId, Class<T> klass) { + // TODO Auto-generated method stub + return null; + } }