Merge branch 'adrian'

This commit is contained in:
yetju000 2019-11-23 13:32:32 +01:00
commit 8904bdbeba
42 changed files with 1591 additions and 2 deletions

View File

@ -0,0 +1,449 @@
package studycave.studycaverestservice.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import studycave.studycaverestservice.model.badge.Badge;
import studycave.studycaverestservice.model.badge.BadgeRepository;
import studycave.studycaverestservice.model.simpleTest.SimpleTest;
import studycave.studycaverestservice.model.simpleTest.SimpleTestRepository;
import studycave.studycaverestservice.model.simpleTest.dto.SimpleTestDTO;
import studycave.studycaverestservice.model.studyGroup.GroupRepository;
import studycave.studycaverestservice.model.test.Test;
import studycave.studycaverestservice.model.test.TestRepository;
import studycave.studycaverestservice.model.test.dto.*;
import studycave.studycaverestservice.model.test.question.*;
import studycave.studycaverestservice.model.test.result.TestResult;
import studycave.studycaverestservice.model.test.result.TestResultRepository;
import studycave.studycaverestservice.model.test.verifier.QuestionVerifier;
import studycave.studycaverestservice.model.user.User;
import studycave.studycaverestservice.model.user.UserRepository;
import studycave.studycaverestservice.model.userActivity.UserActivityService;
import studycave.studycaverestservice.model.userBadge.UserBadge;
import studycave.studycaverestservice.model.userBadge.UserBadgeRepository;
@RestController
@CrossOrigin
@RequestMapping("/tests")
@Api
public class TestController {
@Autowired
TestRepository testRepository;
@Autowired
QuestionRepository questionRepository;
@Autowired
AnswerRepository answerRepository;
@Autowired
SimpleTestRepository simpleTestRepository;
@Autowired
UserRepository userRepository;
@Autowired
BadgeRepository badgeRepository;
@Autowired
GroupRepository groupRepository;
@Autowired
UserBadgeRepository userBadgeRepository;
@Autowired
ModelMapper modelMapper;
@Autowired
QuestionVerifier questionVerifier;
@Autowired
TestResultRepository testResultRepository;
@Autowired
UserActivityService userActivityService;
@GetMapping("/{id}")
public Optional<Test> getTest(@PathVariable(required = true) Long id) {
Optional<Test> test = testRepository.findById(id);
for (Question question : test.get().getQuestions()) {
if(question instanceof QuestionGaps) {
List<AnswerGaps> answers = ((QuestionGaps)question).getAnswers();
Collections.sort(answers,
(o1, o2) -> o1.getId().compareTo(o2.getId()));
}
}
test.get().setGroup(null);
test.get().setActivity(null);
return test;
}
@GetMapping("/{id}/solve")
public TestOwnerDTO getTestToSolve(@PathVariable(required = true) Long id) {
Optional<Test> test = testRepository.findById(id);
for (Question question : test.get().getQuestions()) {
if (question.getType().equals("true-false") || question.getType().equals("single-choice")
|| question.getType().equals("multiple-choice")) {
List<AnswerChoices> answersDTOs = new ArrayList<AnswerChoices>();
for (Answer answer : ((QuestionChoices) question).getAnswers()) {
AnswerChoicesSolveDTO answerDTO = modelMapper.map(answer, AnswerChoicesSolveDTO.class);
answersDTOs.add(answerDTO);
}
((QuestionChoices) question).setAnswers(answersDTOs);
}
if (question.getType().equals("puzzle")) {
List<AnswerPuzzle> answersDTOs = new ArrayList<AnswerPuzzle>();
for (Answer answer : ((QuestionPuzzle) question).getAnswers()) {
AnswerPuzzleSolveDTO answerDTO = modelMapper.map(answer, AnswerPuzzleSolveDTO.class);
answerDTO.generatePuzzles();
answersDTOs.add(answerDTO);
}
((QuestionPuzzle) question).setAnswers(answersDTOs);
}
if (question.getType().equals("gaps")) {
{
List<AnswerGaps> answersDTOs = new ArrayList<AnswerGaps>();
for (Answer answer : ((QuestionGaps) question).getAnswers()) {
AnswerGapsSolveDTO answerDTO = modelMapper.map(answer, AnswerGapsSolveDTO.class);
if (answerDTO.isGap())
answerDTO.setContent(null);
answersDTOs.add(answerDTO);
}
((QuestionGaps) question).setAnswers(answersDTOs);
}
}
if (question.getType().equals("pairs")) {
List<AnswerPairs> answersDTOs = new ArrayList<AnswerPairs>();
List<String> left = new ArrayList<String>();
List<String> right = new ArrayList<String>();
for (Answer answer : ((QuestionPairs) question).getAnswers()) {
left.add(((AnswerPairs) answer).getFirst());
right.add(((AnswerPairs) answer).getSecond());
}
Collections.shuffle(left);
Collections.shuffle(right);
answersDTOs.add(new AnswerPairsSolveDTO(left, right));
((QuestionPairs) question).setAnswers(answersDTOs);
}
}
User user = userRepository.findById(test.get().getIdOwner()).get();
TestOwnerDTO testDTO = modelMapper.map(test.get(), TestOwnerDTO.class);
testDTO.setOwner(user.getUsername());
return testDTO;
}
@PostMapping("/results")
public void saveResult(@RequestBody SaveTestResultDTO resultDTO) {
User user = userRepository.findByUsername(resultDTO.getOwner()).orElse(null);
Optional<Test> test = testRepository.findById(resultDTO.getIdTest());
List<TestResult> testResult = this.testResultRepository.findByIdOwnerAndIdTest(user.getId(), resultDTO.getIdTest());
if (testResult.size() > 0) {
return;
}
int maxScore = 0;
for (Question question : test.get().getQuestions()) {
maxScore += question.getPoints();
}
TestResult result = modelMapper.map(resultDTO, TestResult.class);
result.setIdOwner(user.getId());
result.setMaxScore(maxScore);
result.setIdResult((long) 0);
testResultRepository.save(result);
if(userBadgeRepository.findByIdAndUser((long)9, user.getId()).isEmpty()) {
UserBadge badgeAchieved = new UserBadge();
Badge badge = new Badge();
badge = badgeRepository.findById((long)9).orElse(null);
badgeAchieved.setBadge(badge);
badgeAchieved.setUser(user);
userBadgeRepository.save(badgeAchieved);
}
userActivityService.saveActivity("solvedTest", resultDTO.getUserScore().intValue(), null, user, null, test.get().getGroup(), null, null, test.get());
}
@GetMapping("/results/max")
public GetResultDTO saveResult(@RequestParam Long id, @RequestParam String username) {
User user = userRepository.findByUsername(username).get();
List<TestResult> result = testResultRepository.findByIdOwnerAndIdTest(user.getId(), id);
if (!result.isEmpty()) {
TestResult maxResult = result.get(0);
for (TestResult t : result) {
if (t.getUserScore() > maxResult.getUserScore()) {
maxResult = t;
}
}
return new GetResultDTO(maxResult.getUserScore(), maxResult.getMaxScore());
} else {
Optional<Test> test = testRepository.findById(id);
int maxScore = 0;
for (Question question : test.get().getQuestions()) {
maxScore += question.getPoints();
}
return new GetResultDTO(0, maxScore);
}
}
@PostMapping("/{id}/questions/verify")
public ResultResponse verifyQuestion(@PathVariable(required = true) Long id,
@RequestBody QuestionVerifyDTO question) {
return questionVerifier.verify(id, question);
}
@PreAuthorize("isAuthenticated()")
@DeleteMapping("/{id}")
public ResponseEntity deleteTest(@PathVariable(required = true) Long id) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();
Long userId = userRepository.findByUsername(currentPrincipalName).get().getId();
Optional<Test> test = testRepository.findById(id);
if (test.isPresent()) {
if (userId.equals(test.get().getIdOwner())) {
testRepository.deleteById(id);
return new ResponseEntity(HttpStatus.OK);
}
}
return new ResponseEntity("Access Forbidden", HttpStatus.FORBIDDEN);
}
@PostMapping
public void postTest(@RequestBody TestCreateDTO testDTO) {
User user = userRepository.findByUsername(testDTO.getOwner()).get();
testDTO.setIdOwner(user.getId());
Test test = modelMapper.map(testDTO, Test.class);
test.setId((long) 0);
for (Question question : test.getQuestions()) {
question.setTest(test);
if (question instanceof QuestionChoices) {
for (AnswerChoices answer : ((QuestionChoices) question).getAnswers())
answer.setQuestion(question);
// ((QuestionChoices) question).setType();
}
if (question instanceof QuestionPairs) {
for (AnswerPairs answer : ((QuestionPairs) question).getAnswers())
answer.setQuestion(question);
// ((QuestionPairs) question).setType();
}
if (question instanceof QuestionPuzzle) {
for (AnswerPuzzle answer : ((QuestionPuzzle) question).getAnswers())
answer.setQuestion(question);
// ((QuestionPuzzle) question).setType();
}
if (question instanceof QuestionGaps) {
for (AnswerGaps answer : ((QuestionGaps) question).getAnswers())
answer.setQuestion(question);
// ((QuestionGaps) question).setType();
}
}
test.setAddDate();
test.setEditDate();
test.setGrade();
// Badge for creating first test
if(userBadgeRepository.findByIdAndUser((long)4, user.getId()).isEmpty()) {
UserBadge badgeAchieved = new UserBadge();
Badge badge = new Badge();
badge = badgeRepository.findById((long)4).orElse(null);
badgeAchieved.setBadge(badge);
badgeAchieved.setUser(user);
userBadgeRepository.save(badgeAchieved);
}
testRepository.save(test);
}
@GetMapping
public ResponseEntity<?> getTest(@RequestParam(value = "owner", required = false) String owner,
@RequestParam(value = "permission", required = false) String permission) {
Optional<User> user = userRepository.findByUsername(owner);
Long ownerId = user.isPresent() ? user.get().getId() : null;
if (owner != null && !user.isPresent())
return new ResponseEntity<>(new String("User not found"), HttpStatus.NOT_FOUND);
ArrayList<SimpleTestDTO> testDTOs = new ArrayList<SimpleTestDTO>();
List<SimpleTest> tests = simpleTestRepository.findByOptionalPermissionAndOptionalOwner(permission, ownerId);
for (SimpleTest test : tests) {
String username = userRepository.findById((long) test.getIdOwner()).get().getUsername();
SimpleTestDTO testDTO = modelMapper.map(test, SimpleTestDTO.class);
testDTO.setOwner(username);
if(test.getGroupId() != null)
testDTO.setGroup(groupRepository.findById((long)test.getGroupId()).orElse(null).getName());
testDTOs.add(testDTO);
}
return new ResponseEntity<List<SimpleTestDTO>>(testDTOs, HttpStatus.OK);
}
@PutMapping
public ResponseEntity editTest(@RequestBody TestEditDTO testDTO) {
//Authorization
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();
Long userId = userRepository.findByUsername(currentPrincipalName).get().getId();
Optional<Test> originalTest = testRepository.findById(testDTO.getId());
if (userId.equals(originalTest.get().getIdOwner())) {
// pass
} else
return new ResponseEntity("Access Forbidden", HttpStatus.FORBIDDEN);
//
User user = userRepository.findByUsername(testDTO.getOwner()).get();
testDTO.setIdOwner(user.getId());
Test test = modelMapper.map(testDTO, Test.class);
for (Question question : test.getQuestions()) {
question.setTest(test);
if (question instanceof QuestionChoices) {
for (AnswerChoices answer : ((QuestionChoices) question).getAnswers())
answer.setQuestion(question);
// ((QuestionChoices) question).setType();
}
if (question instanceof QuestionPairs) {
for (AnswerPairs answer : ((QuestionPairs) question).getAnswers())
answer.setQuestion(question);
// ((QuestionPairs) question).setType();
}
if (question instanceof QuestionPuzzle) {
for (AnswerPuzzle answer : ((QuestionPuzzle) question).getAnswers())
answer.setQuestion(question);
// ((QuestionPuzzle) question).setType();
}
if (question instanceof QuestionGaps) {
for (AnswerGaps answer : ((QuestionGaps) question).getAnswers())
answer.setQuestion(question);
// ((QuestionGaps) question).setType();
}
}
List<Long> deleteq = new ArrayList<>();
List<Long> deletea = new ArrayList<>();
Test oldtest = testRepository.findById(test.getId()).orElse(null);
test.setAddDate(oldtest.getAddDate());
test.setEditDate();
test.setGrade(oldtest.getGrade());
Boolean isinq = false;
Boolean isina = false;
for (Question oldquestion : oldtest.getQuestions()) {
isinq = false;
for (Question question : test.getQuestions()) {
if (oldquestion.getId() == question.getId())
isinq = true;
if (oldquestion instanceof QuestionChoices && question instanceof QuestionChoices) {
for (AnswerChoices oldanswer : ((QuestionChoices) oldquestion).getAnswers()) {
isina = false;
for (AnswerChoices answer : ((QuestionChoices) question).getAnswers())
if (oldanswer.getId() == answer.getId())
isina = true;
if (isina == false) {
deletea.add(oldanswer.getId());
// System.out.println("usuwam answer: "+oldanswer.getId());
}
}
}
if (oldquestion instanceof QuestionPairs && question instanceof QuestionPairs) {
for (AnswerPairs oldanswer : ((QuestionPairs) oldquestion).getAnswers()) {
isina = false;
for (AnswerPairs answer : ((QuestionPairs) question).getAnswers())
if (oldanswer.getId() == answer.getId())
isina = true;
if (isina == false) {
deletea.add(oldanswer.getId());
// System.out.println("usuwam answer: "+oldanswer.getId());
}
}
}
if (oldquestion instanceof QuestionPuzzle && question instanceof QuestionPuzzle) {
for (AnswerPuzzle oldanswer : ((QuestionPuzzle) oldquestion).getAnswers()) {
isina = false;
for (AnswerPuzzle answer : ((QuestionPuzzle) question).getAnswers())
if (oldanswer.getId() == answer.getId())
isina = true;
if (isina == false) {
deletea.add(oldanswer.getId());
// System.out.println("usuwam answer: "+oldanswer.getId());
}
}
}
List<AnswerGaps> answers = new ArrayList<>();
if (oldquestion instanceof QuestionGaps && question instanceof QuestionGaps) {
for (AnswerGaps answer : ((QuestionGaps) question).getAnswers()) {
answers.add(answer);
}
Collections.reverse(answers);
for (AnswerGaps answer : answers) {
answer.setId(null);
answer.setQuestion(question);
}
for (AnswerGaps oldanswer : ((QuestionGaps) oldquestion).getAnswers()) {
if (answerRepository.findById(oldanswer.getId()) != null) {
deletea.add(oldanswer.getId());
// deleteq.add(oldquestion.getId());
// System.out.println("usuwam answer: "+oldanswer.getId());
}
}
}
// System.out.println(question.getId()+" "+ oldquestion.getId());
}
if (isinq == false) {
deleteq.add(oldquestion.getId());
// System.out.println("usuwam "+oldquestion.getId());
}
}
testRepository.save(test);
for (Long a : deletea)
if (a != null)
if (answerRepository.findById(a) != null)
answerRepository.deleteById(a);
for (Long q : deleteq)
if (q != null)
if (questionRepository.findById(q) != null)
questionRepository.deleteById(q);
return new ResponseEntity(HttpStatus.OK);
}
}

View File

@ -0,0 +1,14 @@
package studycave.studycaverestservice.model.studyGroup;
import org.springframework.data.jpa.repository.JpaRepository;
import studycave.studycaverestservice.model.studyGroup.StudyGroup;
import java.util.List;
public interface GroupRepository extends JpaRepository<StudyGroup, Long> {
List<StudyGroup> findByName(String name);
List<StudyGroup> findByGroupKey(String groupKey);
}

View File

@ -7,6 +7,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import studycave.studycaverestservice.model.studyGroup.StudyGroup;
import studycave.studycaverestservice.model.test.question.Question;
import studycave.studycaverestservice.model.userActivity.UserActivity;
import javax.persistence.*;
@ -45,16 +46,32 @@ public class Test {
private String permission;
private int grade;
/*
@JsonProperty("body")
@OneToMany(fetch = FetchType.LAZY,mappedBy="test",cascade = CascadeType.ALL)
@JsonManagedReference
List<Question> questions = new ArrayList<>();
*/
@ManyToOne
@JoinColumn(name="group_id",referencedColumnName="id")
private StudyGroup group;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "test", cascade = CascadeType.ALL)
private List<UserActivity> activity;
public void setAddDate() {
java.util.Date utilDate = new java.util.Date();
Date sqlDate = new Date(utilDate.getTime());
this.addDate = sqlDate;
}
public void setGrade() {
this.grade = 0;
}
public void setEditDate() {
java.util.Date utilDate = new java.util.Date();
Date sqlDate = new Date(utilDate.getTime());
this.editDate = sqlDate;
}
}

View File

@ -0,0 +1,19 @@
package studycave.studycaverestservice.model.test;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface TestRepository extends JpaRepository<Test, Long> {
@Query("select t from Test t where (t.permission = 'GROUP' and t.group.id = :g and t.status = 'VERIFIED' )")
List<Test> findTestByGroup(@Param("g") Long g);
@Query("select t from Test t where (t.permission = 'GROUP' and t.group.id = :g and t.status = 'UNVERIFIED' )")
List<Test> findWaitingTestByGroupKey(@Param("g") Long g);
}

View File

@ -0,0 +1,19 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import studycave.studycaverestservice.model.test.question.AnswerChoices;
public class AnswerChoicesSolveDTO extends AnswerChoices {
@JsonIgnore
private Boolean good;
public AnswerChoicesSolveDTO() {
super();
}
}

View File

@ -0,0 +1,14 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AnswerChoicesVerifyDTO extends AnswerVerifyDTO {
protected Long id;
String content;
@JsonProperty(value = "is_good")
Boolean isGood;
}

View File

@ -0,0 +1,16 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import studycave.studycaverestservice.model.test.question.AnswerGaps;
public class AnswerGapsSolveDTO extends AnswerGaps {
@JsonInclude(JsonInclude.Include.NON_NULL)
private String[] content = new String[25];
@JsonProperty("is_gap")
private boolean gap;
}

View File

@ -0,0 +1,11 @@
package studycave.studycaverestservice.model.test.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AnswerGapsVerifyDTO extends AnswerVerifyDTO {
protected Long id;
protected String content;
}

View File

@ -0,0 +1,44 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import studycave.studycaverestservice.model.test.question.AnswerPairs;
import java.util.ArrayList;
import java.util.List;
public class AnswerPairsSolveDTO extends AnswerPairs {
@JsonIgnore
private Long id;
@JsonIgnore
private String first;
@JsonIgnore
private String second;
private List<String> left = new ArrayList<String>();
private List<String> right = new ArrayList<String>();
public AnswerPairsSolveDTO(List<String> left, List<String> right) {
super();
this.left = left;
this.right = right;
}
public List<String> getLeft() {
return left;
}
public void setLeft(List<String> left) {
this.left = left;
}
public List<String> getRight() {
return right;
}
public void setRight(List<String> right) {
this.right = right;
}
}

View File

@ -0,0 +1,11 @@
package studycave.studycaverestservice.model.test.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AnswerPairsVerifyDTO extends AnswerVerifyDTO{
protected String left;
protected String right;
}

View File

@ -0,0 +1,30 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import studycave.studycaverestservice.model.test.question.AnswerPuzzle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Getter
@Setter
public class AnswerPuzzleSolveDTO extends AnswerPuzzle {
@JsonIgnore
private String[] correct = new String[10];
private List<String> puzzles = new ArrayList<String>();
public void generatePuzzles() {
this.puzzles = new ArrayList(Arrays.asList(this.getCorrect()));
Collections.shuffle(puzzles);
}
public AnswerPuzzleSolveDTO() {
super();
}
}

View File

@ -0,0 +1,14 @@
package studycave.studycaverestservice.model.test.dto;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Setter
@Getter
public class AnswerPuzzleVerifyDTO extends AnswerVerifyDTO {
protected Long id;
protected List<String> puzzles;
}

View File

@ -0,0 +1,13 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public abstract class AnswerVerifyDTO {
@JsonIgnore
protected String type;
}

View File

@ -0,0 +1,16 @@
package studycave.studycaverestservice.model.test.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class GetResultDTO {
private float userScore;
private int maxScore;
}

View File

@ -0,0 +1,28 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import studycave.studycaverestservice.model.test.verifier.QuestionVerifyDeserializer;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonDeserialize(using = QuestionVerifyDeserializer.class)
public class QuestionVerifyDTO {
@ApiModelProperty(position = 1)
Long id;
@ApiModelProperty(position = 2)
String type;
@ApiModelProperty(position = 3)
List<AnswerVerifyDTO> answers;
}

View File

@ -0,0 +1,19 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Result {
@JsonInclude(JsonInclude.Include.NON_NULL)
protected Long id;
protected Boolean correct;
}

View File

@ -0,0 +1,23 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class ResultPairs extends Result{
@JsonIgnore
protected Long id;
protected String left;
protected String right;
public ResultPairs(Long id, Boolean correct) {
super(id, correct);
// TODO Auto-generated constructor stub
}
public ResultPairs(String left, String right, Boolean correct) {
super(null, correct);
this.left=left;
this.right=right;
}
}

View File

@ -0,0 +1,19 @@
package studycave.studycaverestservice.model.test.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ResultResponse {
float points;
List<Result> results = new ArrayList<Result>();
}

View File

@ -0,0 +1,36 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
public class SaveTestResultDTO {
private String owner;
@JsonProperty(value="id")
private Long idTest;
private Float userScore;
public SaveTestResultDTO() {
super();
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Long getIdTest() {
return idTest;
}
public void setIdTest(Long idTest) {
this.idTest = idTest;
}
public Float getUserScore() {
return userScore;
}
public void setUserScore(Float userScore) {
this.userScore = userScore;
}
}

View File

@ -0,0 +1,38 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import studycave.studycaverestservice.model.test.question.Question;
import java.sql.Date;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TestCreateDTO {
private String title;
private String owner;
@JsonIgnore
private long idOwner;
//@JsonIgnore
@JsonProperty("add_date")
private Date addDate;
//@JsonIgnore
@JsonProperty("edit_date")
private Date editDate;
@ApiModelProperty(value = "Default value for note", required = true,example = "public")
private String permission;
@JsonIgnore
private Long grade;
@JsonProperty("body")
List<Question> questions;
}

View File

@ -0,0 +1,40 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import studycave.studycaverestservice.model.test.question.Question;
import java.sql.Date;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TestEditDTO {
private Long id;
private String title;
private String owner;
@JsonIgnore
private long idOwner;
@JsonIgnore
@JsonProperty("add_date")
private Date addDate;
@JsonIgnore
@JsonProperty("edit_date")
private Date editDate;
@ApiModelProperty(value = "Default value for note", required = true,example = "public")
private String permission;
@JsonIgnore
private Long grade;
@JsonProperty("body")
List<Question> questions;
}

View File

@ -0,0 +1,38 @@
package studycave.studycaverestservice.model.test.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import studycave.studycaverestservice.model.test.question.Question;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TestOwnerDTO {
private Long id;
private String title;
@JsonIgnore
private Long idOwner;
@JsonProperty("owner")
private String owner;
@JsonProperty("add_date")
private Date addDate;
@JsonProperty("edit_date")
private Date editDate;
private String permission;
private int grade;
@JsonProperty("body")
List<Question> questions = new ArrayList<>();
}

View File

@ -0,0 +1,32 @@
package studycave.studycaverestservice.model.test.question;
import com.fasterxml.jackson.annotation.JsonBackReference;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Getter
@Setter
@AllArgsConstructor
public abstract class Answer {
@Id
@Column(name="id_ans")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ApiModelProperty(hidden = true)
@ManyToOne
@JoinColumn(name="id_question",referencedColumnName="id")
@JsonBackReference
private Question question;
public Answer() {
super();
}
}

View File

@ -0,0 +1,24 @@
package studycave.studycaverestservice.model.test.question;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
public class AnswerChoices extends Answer {
private String content;
@Column(name = "is_good")
@JsonProperty("is_good")
private Boolean good;
public AnswerChoices() {
super();
}
}

View File

@ -0,0 +1,23 @@
package studycave.studycaverestservice.model.test.question;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
public class AnswerGaps extends Answer{
private String[] content = new String[25];
@Column(name="is_gap")
@JsonProperty("is_gap")
private boolean gap;
public AnswerGaps() {
super();
}
}

View File

@ -0,0 +1,19 @@
package studycave.studycaverestservice.model.test.question;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class AnswerPairs extends Answer {
private String first;
private String second;
}

View File

@ -0,0 +1,17 @@
package studycave.studycaverestservice.model.test.question;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
public class AnswerPuzzle extends Answer {
private String[] correct = new String[10];
public AnswerPuzzle() {
super();
}
}

View File

@ -0,0 +1,6 @@
package studycave.studycaverestservice.model.test.question;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AnswerRepository extends JpaRepository<Answer,Long> {
}

View File

@ -0,0 +1,67 @@
package studycave.studycaverestservice.model.test.question;
import com.fasterxml.jackson.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import studycave.studycaverestservice.model.test.Test;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.PROPERTY, property = "type", visible = true )
@JsonSubTypes({
@JsonSubTypes.Type(value = QuestionChoices.class, name="single-choice"),
@JsonSubTypes.Type(value = QuestionChoices.class, name="multiple-choice"),
@JsonSubTypes.Type(value = QuestionChoices.class, name="true-false"),
@JsonSubTypes.Type(value = QuestionPairs.class, name="pairs"),
@JsonSubTypes.Type(value = QuestionPuzzle.class, name="puzzle"),
@JsonSubTypes.Type(value = QuestionGaps.class, name="gaps")
})
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@NoArgsConstructor
@AllArgsConstructor
public abstract class Question {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Getter
@Setter
private Long id;
@Column(name="question")
@JsonProperty("question")
@Getter
@Setter
private String text;
@Column(name="nr_question")
@JsonProperty("nr")
@Getter
@Setter
private int nrQuestion;
//@NotNull
@Getter
@Setter
protected String type;
@Getter
@Setter
private int points;
@ApiModelProperty(hidden = true)
@ManyToOne
@JoinColumn(name="id_test",referencedColumnName="id")
@JsonBackReference
@Getter
@Setter
private Test test;
@OneToMany(fetch = FetchType.LAZY,mappedBy="question",cascade = CascadeType.ALL)
@JsonManagedReference
List<Answer> answers = new ArrayList<>();
}

View File

@ -0,0 +1,39 @@
package studycave.studycaverestservice.model.test.question;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
@Entity
@AllArgsConstructor
public class QuestionChoices extends Question {
@OneToMany(fetch = FetchType.LAZY,mappedBy="question",cascade = CascadeType.ALL)
@JsonManagedReference
List<AnswerChoices> answers = new ArrayList<>();
public List<AnswerChoices> getAnswers() {
return answers;
}
public void setAnswers(List<AnswerChoices> answers) {
this.answers = answers;
}
public void setType() {
this.type = "choices";
}
public QuestionChoices(){
super();
}
}

View File

@ -0,0 +1,27 @@
package studycave.studycaverestservice.model.test.question;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
public class QuestionGaps extends Question {
@OneToMany(fetch = FetchType.LAZY,mappedBy="question",cascade = CascadeType.ALL)
@JsonManagedReference
List<AnswerGaps> answers = new ArrayList<>();
public QuestionGaps(){
super();
}
}

View File

@ -0,0 +1,29 @@
package studycave.studycaverestservice.model.test.question;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
@Entity
@AllArgsConstructor
@Getter
@Setter
public class QuestionPairs extends Question{
@OneToMany(fetch = FetchType.LAZY,mappedBy="question",cascade = CascadeType.ALL)
@JsonManagedReference
List<AnswerPairs> answers = new ArrayList<>();
public QuestionPairs() {
super();
}
}

View File

@ -0,0 +1,26 @@
package studycave.studycaverestservice.model.test.question;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
public class QuestionPuzzle extends Question {
@OneToMany(fetch = FetchType.LAZY,mappedBy="question",cascade = CascadeType.ALL)
@JsonManagedReference
List<AnswerPuzzle> answers = new ArrayList<>();
public QuestionPuzzle(){
super();
}
}

View File

@ -0,0 +1,7 @@
package studycave.studycaverestservice.model.test.question;
import org.springframework.data.jpa.repository.JpaRepository;
public interface QuestionRepository extends JpaRepository<Question, Long> {
}

View File

@ -0,0 +1,27 @@
package studycave.studycaverestservice.model.test.result;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TestResult {
@Id
@Column(name="id")
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long idResult;
@Column(name="id_owner")
private Long idOwner;
@Column(name="id_test")
private Long idTest;
private float userScore;
private int maxScore;
}

View File

@ -0,0 +1,13 @@
package studycave.studycaverestservice.model.test.result;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface TestResultRepository extends JpaRepository<TestResult,Long> {
List<TestResult> findByIdOwner(Long id);
List<TestResult> findByIdOwnerAndIdTest(Long id, Long id2);
}

View File

@ -0,0 +1,159 @@
package studycave.studycaverestservice.model.test.verifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import studycave.studycaverestservice.model.test.Test;
import studycave.studycaverestservice.model.test.TestRepository;
import studycave.studycaverestservice.model.test.dto.*;
import studycave.studycaverestservice.model.test.question.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@Component
public class QuestionVerifier {
@Autowired
TestRepository testRepository;
private ResultResponse choiceVerify(QuestionVerifyDTO question, Question questionCorrect) {
List<Result> results = new ArrayList<Result>();
float points = questionCorrect.getPoints();
for (AnswerVerifyDTO element : question.getAnswers()) {
AnswerChoicesVerifyDTO answer = (AnswerChoicesVerifyDTO) element;
Optional<AnswerChoices> answerCorrect = ((QuestionChoices) questionCorrect).getAnswers().stream()
.filter(a -> a.getId().equals(answer.getId())).findAny();
if (answerCorrect.get().getGood() == ((AnswerChoicesVerifyDTO) answer).getIsGood()) {
results.add(new Result(answer.getId(), true));
} else {
results.add(new Result(answer.getId(), false));
points = 0;
}
}
return new ResultResponse(points, results);
}
private ResultResponse gapsVerify(QuestionVerifyDTO question, Question questionCorrect) {
List<Result> results = new ArrayList<Result>();
float points = questionCorrect.getPoints();
float wrongAnswers = 0;
for (AnswerVerifyDTO element : question.getAnswers()) {
AnswerGapsVerifyDTO answer = (AnswerGapsVerifyDTO) element;
Optional<AnswerGaps> answerCorrect = ((QuestionGaps) questionCorrect).getAnswers().stream()
.filter(a -> a.getId().equals(answer.getId())).findAny();
if (Arrays.asList(answerCorrect.get().getContent()).stream()
.anyMatch(((AnswerGapsVerifyDTO) answer).getContent()::equalsIgnoreCase)) {
results.add(new Result(answer.getId(), true));
} else {
results.add(new Result(answer.getId(), false));
wrongAnswers += 1;
}
}
if (wrongAnswers == question.getAnswers().size()) {
points = 0;
} else {
points = points - (points/question.getAnswers().size() * wrongAnswers);
}
return new ResultResponse(points, results);
}
private ResultResponse pairsVerify(QuestionVerifyDTO question, Question questionCorrect) {
List<Result> results = new ArrayList<Result>();
float points = questionCorrect.getPoints();
float wrongAnswers = 0;
for (AnswerVerifyDTO element : question.getAnswers()) {
AnswerPairsVerifyDTO answer = (AnswerPairsVerifyDTO) element;
Optional<AnswerPairs> answerCorrect = ((QuestionPairs) questionCorrect).getAnswers().stream()
.filter(a -> a.getFirst().equals(answer.getLeft()))
.findAny();
if (answerCorrect.isPresent()) {
if (answerCorrect.get().getSecond().equals(answer.getRight())) {
results.add(new ResultPairs(answer.getLeft(), answer.getRight(), true));
} else {
results.add(new ResultPairs(answer.getLeft(), answer.getRight(), false));
points = 0;
}
} else {
wrongAnswers += 1;
results.add(new ResultPairs(answer.getLeft(), answer.getRight(), false));
}
}
if (wrongAnswers == question.getAnswers().size()) {
points = 0;
} else {
points = points - (points/question.getAnswers().size() * wrongAnswers);
}
return new ResultResponse(points, results);
}
private ResultResponse puzzleVerify(QuestionVerifyDTO question, Question questionCorrect) {
List<Result> results = new ArrayList<Result>();
float points = questionCorrect.getPoints();
for (AnswerVerifyDTO element : question.getAnswers()) {
AnswerPuzzleVerifyDTO answer = (AnswerPuzzleVerifyDTO) element;
Optional<AnswerPuzzle> answerCorrect = ((QuestionPuzzle) questionCorrect).getAnswers().stream()
.filter(a -> a.getId().equals(answer.getId())).findAny();
List<String> userPuzzles = answer.getPuzzles();
String[] correctPuzzles = answerCorrect.get().getCorrect();
if (userPuzzles.size() == correctPuzzles.length) {
Result result = new Result(answer.getId(), true);
for (int i = 0; i < userPuzzles.size(); i++) {
if (userPuzzles.get(i).equalsIgnoreCase(correctPuzzles[i])) {
// pass
} else {
result.setCorrect(false);
points = 0;
}
}
results.add(result);
} else
points = 0;
}
return new ResultResponse(points, results);
}
public ResultResponse verify(Long idTest, QuestionVerifyDTO question) {
Optional<Test> test = testRepository.findById(idTest);
String type = question.getType();
if (test.isPresent()) {
Optional<Question> questionCorrect = test.get().getQuestions().stream()
.filter(q -> q.getId().equals(question.getId())).findAny();
if (type.equals("single-choice") || type.equals("multiple-choice") || type.equals("true-false")) {
{
return choiceVerify(question, questionCorrect.get());
}
}
if (type.equals("gaps")) {
{
return gapsVerify(question, questionCorrect.get());
}
}
if (type.equals("pairs")) {
{
return pairsVerify(question, questionCorrect.get());
}
}
if (type.equals("puzzle")) {
{
return puzzleVerify(question, questionCorrect.get());
}
}
}
return null;
}
}

View File

@ -0,0 +1,67 @@
package studycave.studycaverestservice.model.test.verifier;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.beans.factory.annotation.Autowired;
import studycave.studycaverestservice.model.test.dto.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class QuestionVerifyDeserializer extends JsonDeserializer<QuestionVerifyDTO> {
@Autowired
ObjectMapper objectMapper;
@Override
public QuestionVerifyDTO deserialize(com.fasterxml.jackson.core.JsonParser jsonParser,
DeserializationContext context) throws IOException, JsonProcessingException {
QuestionVerifyDTO question = new QuestionVerifyDTO();
ObjectCodec oc = jsonParser.getCodec();
JsonNode node = oc.readTree(jsonParser);
question.setId(node.get("id").asLong());
String type = node.get("type").textValue();
question.setType(type);
Iterator<JsonNode> elements = node.get("answers").elements();
List<AnswerVerifyDTO> answers = new ArrayList<AnswerVerifyDTO>();
while (elements.hasNext()) {
JsonNode next = elements.next();
((ObjectNode) next).put("type", type);
if (type.equals("single-choice") || type.equals("multiple-choice") || type.equals("true-false")) {
AnswerChoicesVerifyDTO answer = objectMapper.treeToValue(next, AnswerChoicesVerifyDTO.class);
answers.add(answer);
continue;
}
if (type.equals("gaps")) {
AnswerGapsVerifyDTO answer = objectMapper.treeToValue(next, AnswerGapsVerifyDTO.class);
answers.add(answer);
continue;
}
if (type.equals("puzzle")) {
AnswerPuzzleVerifyDTO answer = objectMapper.treeToValue(next, AnswerPuzzleVerifyDTO.class);
answers.add(answer);
continue;
}
if (type.equals("pairs")) {
AnswerPairsVerifyDTO answer = objectMapper.treeToValue(next, AnswerPairsVerifyDTO.class);
answers.add(answer);
continue;
}
}
question.setAnswers(answers);
return question;
}
}

View File

@ -1,5 +1,9 @@
package studycave.studycaverestservice.model.userActivity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import studycave.studycaverestservice.model.flashcardset.Set;
import studycave.studycaverestservice.model.material.Material;
import studycave.studycaverestservice.model.studyGroup.StudyGroup;
@ -10,6 +14,10 @@ import javax.persistence.*;
import java.sql.Timestamp;
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class UserActivity {
@Id
@ -48,4 +56,8 @@ public class UserActivity {
@ManyToOne
@JoinColumn(name = "fromUser_id")
private User fromUser;
public void setDate() {
this.date = new java.sql.Timestamp(new java.util.Date().getTime());
}
}

View File

@ -0,0 +1,17 @@
package studycave.studycaverestservice.model.userActivity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.List;
public interface UserActivityRepository extends JpaRepository<UserActivity, Long> {
@Query("SELECT u FROM UserActivity u WHERE (u.fromUser.id = ?1 OR u.toUser.id = ?1) "
+ "AND (?2 is null OR u.group.id = ?2) AND (?3 is null OR u.date >= ?3) AND (?4 is null OR u.date <= ?4)")
List<UserActivity> findAllByToUserOrFromUserAndGroupAndTime(Long userId, Long groupId,
Date start, Timestamp end);
}

View File

@ -0,0 +1,50 @@
package studycave.studycaverestservice.model.userActivity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import studycave.studycaverestservice.model.flashcardset.Set;
import studycave.studycaverestservice.model.material.Material;
import studycave.studycaverestservice.model.studyGroup.GroupRepository;
import studycave.studycaverestservice.model.studyGroup.StudyGroup;
import studycave.studycaverestservice.model.test.Test;
import studycave.studycaverestservice.model.user.User;
import studycave.studycaverestservice.model.user.UserRepository;
@Service
public class UserActivityService {
@Autowired
UserRepository userRepository;
@Autowired
GroupRepository groupRepository;
@Autowired
UserActivityRepository userActivityRepository;
public ResponseEntity<?> saveActivity(
String type,
int points,
String comment,
User toUser,
User fromUser,
StudyGroup group,
Material material,
Set set,
Test test
) {
UserActivity activity = new UserActivity();
activity.setType(type);
activity.setPoints(points);
activity.setComment(comment);
activity.setDate();
activity.setToUser(toUser);
activity.setFromUser(fromUser);
activity.setGroup(group);
activity.setTest(test);
activity.setSet(set);
activity.setMaterial(material);
this.userActivityRepository.save(activity);
return new ResponseEntity<>(HttpStatus.OK);
}
}

Binary file not shown.