diff --git a/src/main/java/de/thm/arsnova/controller/AudienceQuestionController.java b/src/main/java/de/thm/arsnova/controller/AudienceQuestionController.java index 3f42d627ea2b0e22d214a206d0695875313b3d26..a674b6b24476ea1b2e44635bc98366a02ddb37cf 100644 --- a/src/main/java/de/thm/arsnova/controller/AudienceQuestionController.java +++ b/src/main/java/de/thm/arsnova/controller/AudienceQuestionController.java @@ -32,10 +32,9 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import de.thm.arsnova.entities.InterposedQuestion; +import de.thm.arsnova.entities.transport.InterposedQuestion; import de.thm.arsnova.entities.InterposedReadingCount; import de.thm.arsnova.exceptions.BadRequestException; -import de.thm.arsnova.exceptions.PreconditionFailedException; import de.thm.arsnova.services.IQuestionService; import de.thm.arsnova.web.DeprecatedApi; @@ -62,24 +61,20 @@ public class AudienceQuestionController extends AbstractController { @RequestMapping(value = "/", method = RequestMethod.GET) public final List<InterposedQuestion> getInterposedQuestions(@RequestParam final String sessionkey) { - return questionService.getInterposedQuestions(sessionkey); + return InterposedQuestion.fromList(questionService.getInterposedQuestions(sessionkey)); } @RequestMapping(value = "/{questionId}", method = RequestMethod.GET) public final InterposedQuestion getInterposedQuestion(@PathVariable final String questionId) { - return questionService.readInterposedQuestion(questionId); + return new InterposedQuestion(questionService.readInterposedQuestion(questionId)); } @RequestMapping(value = "/", method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) public final void postInterposedQuestion( @RequestParam final String sessionkey, - @RequestBody final InterposedQuestion question + @RequestBody final de.thm.arsnova.entities.InterposedQuestion question ) { - if (!sessionkey.equals(question.getSessionId())) { - throw new PreconditionFailedException(); - } - if (questionService.saveQuestion(question)) { return; } diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index cdc03e8cf2fb9ff65f3a4b84bdee5378e96dfacb..2f43cad0bedc5a55dd295dd8215cb00b843b46e2 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -424,7 +424,7 @@ public class CouchDBDao implements IDatabaseDao { q.put("gridType", question.getGridType()); q.put("scaleFactor", question.getScaleFactor()); q.put("gridScaleFactor", question.getGridScaleFactor()); - + return q; } @@ -463,7 +463,7 @@ public class CouchDBDao implements IDatabaseDao { q.put("gridType", question.getGridType()); q.put("scaleFactor", question.getScaleFactor()); q.put("gridScaleFactor", question.getGridScaleFactor()); - + database.saveDocument(q); question.set_rev(q.getRev()); @@ -876,7 +876,7 @@ public class CouchDBDao implements IDatabaseDao { @Override public List<InterposedQuestion> getInterposedQuestions(final Session session) { - final NovaView view = new NovaView("interposed_question/by_session"); + final NovaView view = new NovaView("interposed_question/by_session_full"); view.setKey(session.get_id()); final ViewResults questions = getDatabase().view(view); if (questions == null || questions.isEmpty()) { diff --git a/src/main/java/de/thm/arsnova/entities/transport/InterposedQuestion.java b/src/main/java/de/thm/arsnova/entities/transport/InterposedQuestion.java new file mode 100644 index 0000000000000000000000000000000000000000..702836ccc5f836edf8ddfc9c9e9ad09d2e088c4f --- /dev/null +++ b/src/main/java/de/thm/arsnova/entities/transport/InterposedQuestion.java @@ -0,0 +1,71 @@ +package de.thm.arsnova.entities.transport; + +import java.util.ArrayList; +import java.util.List; + +public class InterposedQuestion { + + private String id; + private String subject; + private String text; + private long timestamp; + private boolean read; + + public static List<InterposedQuestion> fromList(List<de.thm.arsnova.entities.InterposedQuestion> questions) { + ArrayList<InterposedQuestion> interposedQuestions = new ArrayList<InterposedQuestion>(); + for (de.thm.arsnova.entities.InterposedQuestion question : questions) { + interposedQuestions.add(new InterposedQuestion(question)); + } + return interposedQuestions; + } + + public InterposedQuestion(de.thm.arsnova.entities.InterposedQuestion question) { + this.id = question.get_id(); + this.subject = question.getSubject(); + this.text = question.getText(); + this.timestamp = question.getTimestamp(); + this.read = question.isRead(); + } + + public InterposedQuestion() {} + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public boolean isRead() { + return read; + } + + public void setRead(boolean read) { + this.read = read; + } +} diff --git a/src/main/java/de/thm/arsnova/events/DeleteInterposedQuestionEvent.java b/src/main/java/de/thm/arsnova/events/DeleteInterposedQuestionEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..b8aea746a91cd56939a1be1e1fe354a7f4be1cfa --- /dev/null +++ b/src/main/java/de/thm/arsnova/events/DeleteInterposedQuestionEvent.java @@ -0,0 +1,26 @@ +package de.thm.arsnova.events; + +import de.thm.arsnova.entities.InterposedQuestion; +import de.thm.arsnova.entities.Session; + +public class DeleteInterposedQuestionEvent extends NovaEvent { + + private static final long serialVersionUID = 1L; + + private final Session session; + + private final InterposedQuestion question; + + public DeleteInterposedQuestionEvent(Object source, Session session, InterposedQuestion question) { + super(source); + this.session = session; + this.question = question; + } + + @Override + public void accept(NovaEventVisitor visitor) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/de/thm/arsnova/services/IQuestionService.java b/src/main/java/de/thm/arsnova/services/IQuestionService.java index 4b1746d1f53ca68a2eff1e3a90998ed0e00ce666..a964c77e35d51449cdddc7297c4605390fdd04fe 100644 --- a/src/main/java/de/thm/arsnova/services/IQuestionService.java +++ b/src/main/java/de/thm/arsnova/services/IQuestionService.java @@ -66,6 +66,8 @@ public interface IQuestionService { InterposedQuestion readInterposedQuestion(String questionId); + InterposedQuestion readInterposedQuestionInternal(String questionId, User user); + Question update(Question question); void deleteAnswers(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 0607ac273da418af82f3d12c982a5a35692fa4a2..2224949f81fb480bc5dbb1bccbd62f5ffde49862 100644 --- a/src/main/java/de/thm/arsnova/services/QuestionService.java +++ b/src/main/java/de/thm/arsnova/services/QuestionService.java @@ -42,6 +42,7 @@ import de.thm.arsnova.entities.Question; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; import de.thm.arsnova.events.DeleteAnswerEvent; +import de.thm.arsnova.events.DeleteInterposedQuestionEvent; import de.thm.arsnova.events.NewAnswerEvent; import de.thm.arsnova.events.NewInterposedQuestionEvent; import de.thm.arsnova.events.NewQuestionEvent; @@ -191,6 +192,10 @@ public class QuestionService implements IQuestionService, ApplicationEventPublis throw new NotFoundException(); } databaseDao.deleteInterposedQuestion(question); + + final Session session = databaseDao.getSessionFromKeyword(question.getSessionId()); + final DeleteInterposedQuestionEvent event = new DeleteInterposedQuestionEvent(this, session, question); + this.publisher.publishEvent(event); } @Override @@ -358,13 +363,22 @@ public class QuestionService implements IQuestionService, ApplicationEventPublis @Override @PreAuthorize("isAuthenticated()") public InterposedQuestion readInterposedQuestion(final String questionId) { + final User user = userService.getCurrentUser(); + return this.readInterposedQuestionInternal(questionId, user); + } + + /* + * The "internal" suffix means it is called by internal services that have no authentication! + * TODO: Find a better way of doing this... + */ + @Override + public InterposedQuestion readInterposedQuestionInternal(final String questionId, User user) { final InterposedQuestion question = databaseDao.getInterposedQuestion(questionId); if (question == null) { throw new NotFoundException(); } final Session session = databaseDao.getSessionFromKeyword(question.getSessionId()); - final User user = userService.getCurrentUser(); if (session.isCreator(user)) { databaseDao.markInterposedQuestionAsRead(question); } diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java index 254ddbc9aebe5a0b8411d7bc25eeb6ae79f6ec25..4f20db3ed622ea4c08bc05692f7a43aa18bab790 100644 --- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java +++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java @@ -151,6 +151,20 @@ public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, No } }); + server.addEventListener( + "readInterposedQuestion", + de.thm.arsnova.entities.transport.InterposedQuestion.class, + new DataListener<de.thm.arsnova.entities.transport.InterposedQuestion>() { + @Override + public void onData( + SocketIOClient client, + de.thm.arsnova.entities.transport.InterposedQuestion question, + AckRequest ackRequest) { + final User user = userService.getUser2SocketId(client.getSessionId()); + questionService.readInterposedQuestionInternal(question.getId(), user); + } + }); + server.addConnectListener(new ConnectListener() { @Override public void onConnect(final SocketIOClient client) { }