diff --git a/src/main/java/de/thm/arsnova/controller/v2/ContentController.java b/src/main/java/de/thm/arsnova/controller/v2/ContentController.java index 46a5110dfaba6041b6c0e63999b9616e5422b477..074b1a02b16cb5d477c181ea8a15aa524d25dd06 100644 --- a/src/main/java/de/thm/arsnova/controller/v2/ContentController.java +++ b/src/main/java/de/thm/arsnova/controller/v2/ContentController.java @@ -18,6 +18,9 @@ package de.thm.arsnova.controller.v2; import de.thm.arsnova.controller.PaginationController; +import de.thm.arsnova.entities.ChoiceAnswer; +import de.thm.arsnova.entities.ChoiceQuestionContent; +import de.thm.arsnova.entities.TextAnswer; import de.thm.arsnova.entities.migration.FromV2Migrator; import de.thm.arsnova.entities.migration.ToV2Migrator; import de.thm.arsnova.entities.migration.v2.Answer; @@ -46,6 +49,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import javax.naming.OperationNotSupportedException; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Arrays; @@ -413,13 +417,18 @@ public class ContentController extends PaginationController { @PathVariable final String questionId, final HttpServletResponse response ) { + final de.thm.arsnova.entities.Content content = contentService.get(questionId); final de.thm.arsnova.entities.Answer answer = contentService.getMyAnswer(questionId); if (answer == null) { response.setStatus(HttpStatus.NO_CONTENT.value()); return null; } - return toV2Migrator.migrate(answer); + if (content.getFormat().equals(de.thm.arsnova.entities.Content.Format.TEXT)) { + return toV2Migrator.migrate((TextAnswer) answer); + } else { + return toV2Migrator.migrate((ChoiceAnswer) answer, (ChoiceQuestionContent) content); + } } /** @@ -443,25 +452,31 @@ public class ContentController extends PaginationController { @PathVariable final String questionId, @RequestParam(value = "piround", required = false) final Integer piRound, @RequestParam(value = "all", required = false, defaultValue = "false") final Boolean allAnswers, - final HttpServletResponse response - ) { - List<de.thm.arsnova.entities.Answer> answers; - if (allAnswers) { - answers = contentService.getAllAnswers(questionId, -1, -1); - } else if (null == piRound) { - answers = contentService.getAnswers(questionId, offset, limit); + final HttpServletResponse response) throws OperationNotSupportedException { + final de.thm.arsnova.entities.Content content = contentService.get(questionId); + if (content instanceof ChoiceQuestionContent) { + // FIXME migration needed! + // contentService.getAllStatistics() + throw new OperationNotSupportedException(); } else { - if (piRound < 1 || piRound > 2) { - response.setStatus(HttpStatus.BAD_REQUEST.value()); - - return null; + List<de.thm.arsnova.entities.TextAnswer> answers; + if (allAnswers) { + answers = contentService.getAllTextAnswers(questionId, -1, -1); + } else if (null == piRound) { + answers = contentService.getTextAnswers(questionId, offset, limit); + } else { + if (piRound < 1 || piRound > 2) { + response.setStatus(HttpStatus.BAD_REQUEST.value()); + + return null; + } + answers = contentService.getTextAnswers(questionId, piRound, offset, limit); } - answers = contentService.getAnswers(questionId, piRound, offset, limit); - } - if (answers == null) { - return new ArrayList<>(); + if (answers == null) { + return new ArrayList<>(); + } + return answers.stream().map(toV2Migrator::migrate).collect(Collectors.toList()); } - return answers.stream().map(toV2Migrator::migrate).collect(Collectors.toList()); } @ApiOperation(value = "Save answer, provided in the Request Body, for a question, identified by provided question ID", @@ -472,7 +487,15 @@ public class ContentController extends PaginationController { @RequestBody final Answer answer, final HttpServletResponse response ) { - return toV2Migrator.migrate(contentService.saveAnswer(questionId, fromV2Migrator.migrate(answer))); + final de.thm.arsnova.entities.Content content = contentService.get(questionId); + final Content contentV2 = toV2Migrator.migrate(content); + final de.thm.arsnova.entities.Answer answerV3 = fromV2Migrator.migrate(answer, contentV2); + + if (answerV3 instanceof TextAnswer) { + return toV2Migrator.migrate((TextAnswer) contentService.saveAnswer(questionId, answerV3)); + } else { + return toV2Migrator.migrate((ChoiceAnswer) contentService.saveAnswer(questionId, answerV3), (ChoiceQuestionContent) content); + } } @ApiOperation(value = "Update answer, provided in Request Body, identified by question ID and answer ID", @@ -484,7 +507,15 @@ public class ContentController extends PaginationController { @RequestBody final Answer answer, final HttpServletResponse response ) { - return toV2Migrator.migrate(contentService.updateAnswer(fromV2Migrator.migrate(answer))); + final de.thm.arsnova.entities.Content content = contentService.get(questionId); + final Content contentV2 = toV2Migrator.migrate(content); + final de.thm.arsnova.entities.Answer answerV3 = fromV2Migrator.migrate(answer, contentV2); + + if (answerV3 instanceof TextAnswer) { + return toV2Migrator.migrate((TextAnswer) contentService.updateAnswer(answerV3)); + } else { + return toV2Migrator.migrate((ChoiceAnswer) contentService.updateAnswer(answerV3), (ChoiceQuestionContent) content); + } } @ApiOperation(value = "Get Image, identified by question ID and answer ID", @@ -590,7 +621,7 @@ public class ContentController extends PaginationController { @RequestMapping(value = "/{questionId}/freetextanswer/", method = RequestMethod.GET) @Pagination public List<Answer> getFreetextAnswers(@PathVariable final String questionId) { - return contentService.getFreetextAnswersByContentId(questionId, offset, limit).stream() + return contentService.getTextAnswersByContentId(questionId, offset, limit).stream() .map(toV2Migrator::migrate).collect(Collectors.toList()); } @@ -599,9 +630,10 @@ public class ContentController extends PaginationController { @DeprecatedApi @Deprecated @RequestMapping(value = "/myanswers", method = RequestMethod.GET) - public List<Answer> getMyAnswers(@RequestParam final String sessionkey) { - return contentService.getMyAnswersByRoomShortId(sessionkey).stream() - .map(toV2Migrator::migrate).collect(Collectors.toList()); + public List<Answer> getMyAnswers(@RequestParam final String sessionkey) throws OperationNotSupportedException { + throw new OperationNotSupportedException(); +// return contentService.getMyAnswersByRoomShortId(sessionkey).stream() +// .map(toV2Migrator::migrate).collect(Collectors.toList()); } @ApiOperation(value = "Get the total amount of answers of an session, identified by the sessionkey", diff --git a/src/main/java/de/thm/arsnova/entities/Answer.java b/src/main/java/de/thm/arsnova/entities/Answer.java index e96a298d27c180949abd08383929628ff149de9c..6fc558bcf5956b952117e518140dea6dd3a4d1cd 100644 --- a/src/main/java/de/thm/arsnova/entities/Answer.java +++ b/src/main/java/de/thm/arsnova/entities/Answer.java @@ -1,11 +1,17 @@ package de.thm.arsnova.entities; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonView; import de.thm.arsnova.entities.serialization.View; import java.util.Date; import java.util.Map; +@JsonTypeInfo( + use = JsonTypeInfo.Id.MINIMAL_CLASS, + include = JsonTypeInfo.As.PROPERTY, + property = "type" +) public abstract class Answer implements Entity { private String id; private String rev; diff --git a/src/main/java/de/thm/arsnova/entities/Content.java b/src/main/java/de/thm/arsnova/entities/Content.java index 1cb3e875b6c223d0b4107508f74bd34c89b47b26..199ea3097840a26003f7eee43d72812f8143e7a7 100644 --- a/src/main/java/de/thm/arsnova/entities/Content.java +++ b/src/main/java/de/thm/arsnova/entities/Content.java @@ -1,11 +1,17 @@ package de.thm.arsnova.entities; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonView; import de.thm.arsnova.entities.serialization.View; import java.util.Date; import java.util.Map; +@JsonTypeInfo( + use = JsonTypeInfo.Id.MINIMAL_CLASS, + include = JsonTypeInfo.As.PROPERTY, + property = "type" +) public class Content implements Entity { public enum Format { CHOICE, diff --git a/src/main/java/de/thm/arsnova/persistance/AnswerRepository.java b/src/main/java/de/thm/arsnova/persistance/AnswerRepository.java index 610c1453777e56d7a9c8345c52622f86101468d6..eea81a7ae99e21910429a51db6944f85210008b1 100644 --- a/src/main/java/de/thm/arsnova/persistance/AnswerRepository.java +++ b/src/main/java/de/thm/arsnova/persistance/AnswerRepository.java @@ -25,11 +25,11 @@ import org.springframework.data.repository.CrudRepository; import java.util.List; public interface AnswerRepository extends CrudRepository<Answer, String> { - Answer findByContentIdUserPiRound(String contentId, UserAuthentication user, int piRound); + <T extends Answer> T findByContentIdUserPiRound(String contentId, Class<T> type, UserAuthentication user, int piRound); AnswerStatistics findByContentIdPiRound(String contentId, int piRound); int countByContentIdRound(String contentId, int round); int countByContentId(String contentId); - List<Answer> findByContentId(String contentId, int start, int limit); + <T extends Answer> List<T> findByContentId(String contentId, Class<T> type, int start, int limit); List<Answer> findByUserRoomId(UserAuthentication user, String roomId); int countByRoomShortId(String roomShortId); int deleteByContentId(String contentId); diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbAnswerRepository.java b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbAnswerRepository.java index 52f25bc6e2361dc9d4395b0e3b9fe9c8baed3f98..b3e52494230207b77abb8e635cb66b33fd8cbcb2 100644 --- a/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbAnswerRepository.java +++ b/src/main/java/de/thm/arsnova/persistance/couchdb/CouchDbAnswerRepository.java @@ -70,9 +70,9 @@ public class CouchDbAnswerRepository extends CouchDbCrudRepository<Answer> imple } @Override - public Answer findByContentIdUserPiRound(final String contentId, final UserAuthentication user, final int piRound) { - final List<Answer> answerList = queryView("by_contentid_creatorid_round", - ComplexKey.of(contentId, user.getUsername(), piRound)); + public <T extends Answer> T findByContentIdUserPiRound(final String contentId, final Class<T> type, final UserAuthentication user, final int piRound) { + final List<T> answerList = db.queryView(createQuery("by_contentid_creatorid_round") + .key(ComplexKey.of(contentId, user.getUsername(), piRound)), type); return answerList.isEmpty() ? null : answerList.get(0); } @@ -128,18 +128,18 @@ public class CouchDbAnswerRepository extends CouchDbCrudRepository<Answer> imple } @Override - public List<Answer> findByContentId(final String contentId, final int start, final int limit) { + public <T extends Answer> List<T> findByContentId(final String contentId, final Class<T> type, final int start, final int limit) { final int qSkip = start > 0 ? start : -1; final int qLimit = limit > 0 ? limit : -1; - final List<Answer> answers = db.queryView(createQuery("by_contentid_creationtimestamp") + final List<T> answers = db.queryView(createQuery("by_contentid_creationtimestamp") .skip(qSkip) .limit(qLimit) //.includeDocs(true) .startKey(ComplexKey.of(contentId)) .endKey(ComplexKey.of(contentId, ComplexKey.emptyObject())) .descending(true), - Answer.class); + type); return answers; } diff --git a/src/main/java/de/thm/arsnova/services/ContentService.java b/src/main/java/de/thm/arsnova/services/ContentService.java index bdcc5fc14c01fb08e735ebfb41fadc3373e14382..95f6b4059bd26f5ce36e3cec60d57d8b9dbb3d35 100644 --- a/src/main/java/de/thm/arsnova/services/ContentService.java +++ b/src/main/java/de/thm/arsnova/services/ContentService.java @@ -20,6 +20,7 @@ package de.thm.arsnova.services; import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.AnswerStatistics; import de.thm.arsnova.entities.Content; +import de.thm.arsnova.entities.TextAnswer; import de.thm.arsnova.entities.UserAuthentication; import java.util.List; @@ -51,17 +52,17 @@ public interface ContentService extends EntityService<Content> { AnswerStatistics getAllStatistics(String contentId); - List<Answer> getAnswers(String contentId, int piRound, int offset, int limit); + List<TextAnswer> getTextAnswers(String contentId, int piRound, int offset, int limit); - List<Answer> getAnswers(String contentId, int offset, int limit); + List<TextAnswer> getTextAnswers(String contentId, int offset, int limit); - List<Answer> getAllAnswers(String contentId, int offset, int limit); + List<TextAnswer> getAllTextAnswers(String contentId, int offset, int limit); int countAnswersByContentIdAndRound(String contentId); int countAnswersByContentIdAndRound(String contentId, int piRound); - List<Answer> getFreetextAnswersByContentId(String contentId, int offset, int limit); + List<TextAnswer> getTextAnswersByContentId(String contentId, int offset, int limit); List<Answer> getMyAnswersByRoomShortId(String roomShortId); diff --git a/src/main/java/de/thm/arsnova/services/ContentServiceImpl.java b/src/main/java/de/thm/arsnova/services/ContentServiceImpl.java index 331c6c154958d53a1bcb3f6c93a21e668863daa5..b49ddc0079d258f5fdc3ecb6153fdbf559043421 100644 --- a/src/main/java/de/thm/arsnova/services/ContentServiceImpl.java +++ b/src/main/java/de/thm/arsnova/services/ContentServiceImpl.java @@ -439,7 +439,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem if (content == null) { throw new NotFoundException(); } - return answerRepository.findByContentIdUserPiRound(contentId, userService.getCurrentUser(), content.getState().getRound()); + return answerRepository.findByContentIdUserPiRound(contentId, Answer.class, userService.getCurrentUser(), content.getState().getRound()); } @Override @@ -497,31 +497,31 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override @PreAuthorize("isAuthenticated()") - public List<Answer> getAnswers(final String contentId, final int piRound, final int offset, final int limit) { + public List<TextAnswer> getTextAnswers(final String contentId, final int piRound, final int offset, final int limit) { /* FIXME: round support not implemented */ final Content content = contentRepository.findOne(contentId); if (content == null) { throw new NotFoundException(); } - return getFreetextAnswersByContentId(contentId, offset, limit); + return getTextAnswersByContentId(contentId, offset, limit); } @Override @PreAuthorize("isAuthenticated()") - public List<Answer> getAnswers(final String contentId, final int offset, final int limit) { - return getAnswers(contentId, 0, offset, limit); + public List<TextAnswer> getTextAnswers(final String contentId, final int offset, final int limit) { + return getTextAnswers(contentId, 0, offset, limit); } @Override @PreAuthorize("isAuthenticated()") - public List<Answer> getAllAnswers(final String contentId, final int offset, final int limit) { + public List<TextAnswer> getAllTextAnswers(final String contentId, final int offset, final int limit) { final Content content = get(contentId); if (content == null) { throw new NotFoundException(); } - return getFreetextAnswersByContentId(contentId, offset, limit); + return getTextAnswersByContentId(contentId, offset, limit); } @Override @@ -574,8 +574,8 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override @PreAuthorize("isAuthenticated()") - public List<Answer> getFreetextAnswersByContentId(final String contentId, final int offset, final int limit) { - final List<Answer> answers = answerRepository.findByContentId(contentId, offset, limit); + public List<TextAnswer> getTextAnswersByContentId(final String contentId, final int offset, final int limit) { + final List<TextAnswer> answers = answerRepository.findByContentId(contentId, TextAnswer.class, offset, limit); if (answers == null) { throw new NotFoundException(); }