Skip to content

Commit

Permalink
changes for json convertion
Browse files Browse the repository at this point in the history
  • Loading branch information
beyzaaltuntas committed Apr 28, 2024
1 parent 144c29f commit b2d603b
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package de.tum.in.www1.artemis.domain.quiz;

import java.io.Serializable;

/**
* A AnswerOption.
*/
public class AnswerOptionDTO {
public class AnswerOptionDTO implements Serializable {

private Long id;
private Long id = 1L;

private String text;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public abstract class SubmittedAnswer extends DomainObject {
@JsonIgnore
private AbstractQuizSubmission submission;

@Column(name = "selection")
@JsonView(QuizView.Before.class)
private String selection;

public Double getScoreInPoints() {
return scoreInPoints;
}
Expand All @@ -72,6 +76,14 @@ public void setSubmission(AbstractQuizSubmission quizSubmission) {
this.submission = quizSubmission;
}

public String getSelection() {
return selection;
}

public void setSelection(String selection) {
this.selection = selection;
}

/**
* Filter out information about correct answers.
* Calls {@link QuizQuestion#filterForStudentsDuringQuiz()} which removes all relevant fields.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package de.tum.in.www1.artemis.repository.aspects;

import static de.tum.in.www1.artemis.config.Constants.PROFILE_CORE;

import java.util.List;

import jakarta.transaction.Transactional;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import de.tum.in.www1.artemis.domain.quiz.AnswerOptionDTO;
import de.tum.in.www1.artemis.domain.quiz.MultipleChoiceQuestion;
import de.tum.in.www1.artemis.domain.quiz.QuizExercise;
import de.tum.in.www1.artemis.domain.quiz.QuizQuestion;
import de.tum.in.www1.artemis.service.QuizExerciseService;

@Profile(PROFILE_CORE)
@Component
@Aspect
@Transactional
public class QuizExerciseAspect {

private final QuizExerciseService quizExerciseService;

public QuizExerciseAspect(QuizExerciseService quizExerciseService) {
this.quizExerciseService = quizExerciseService;
}

@Before("execution(* de.tum.in.www1.artemis.repository.QuizExerciseRepository.save*(..)) && args(de.tum.in.www1.artemis.domain.quiz.QuizExercise)")
public void beforeSavingQuizExercise(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
QuizExercise quizExercise = (QuizExercise) args[0];

processQuizQuestions(quizExercise.getQuizQuestions());
}

@AfterReturning(pointcut = "execution(de.tum.in.www1.artemis.domain.quiz.QuizExercise de.tum.in.www1.artemis.repository.QuizExerciseRepository.find*(..))", returning = "quizExercise")
public void afterReturningQuizExercise(QuizExercise quizExercise) {
quizExerciseService.deserializeFromJSON(quizExercise.getQuizQuestions());
}

@AfterReturning(pointcut = "execution(java.util.List<de.tum.in.www1.artemis.domain.quiz.QuizExercise> de.tum.in.www1.artemis.repository.QuizExerciseRepository.find*(..))", returning = "quizExercises")
public void afterReturningQuizExerciseList(List<QuizExercise> quizExercises) {
for (QuizExercise quizExercise : quizExercises) {
quizExerciseService.deserializeFromJSON(quizExercise.getQuizQuestions());
}
}

/**
* Processes a list of quiz questions by converting each question into a JSON string
* and setting it as the content of the question. This method iterates over all
* questions in the given quiz exercise.
*
* @param quizQuestions List of quiz questions. It must not be null.
* @throws RuntimeException if there is a problem in serializing the question object to JSON.
*/
public void processQuizQuestions(List<QuizQuestion> quizQuestions) {
ObjectMapper objectMapper = new ObjectMapper();

if (quizQuestions != null) {
for (QuizQuestion question : quizQuestions) {
if (question instanceof MultipleChoiceQuestion) {
question.setContent(serializeToJson(((MultipleChoiceQuestion) question).getAnswerOptions(), objectMapper));
}
}
}
}

/**
* Serializes a QuizQuestion object to its JSON representation using the provided ObjectMapper.
* This method is called for each individual question during the quiz processing.
*
* @param answerOptions
* @param objectMapper the ObjectMapper instance used for serialization. It must not be null.
* @return String representing the JSON serialized form of the QuizQuestion.
* @throws RuntimeException if JSON processing fails, encapsulating the underlying JsonProcessingException.
*/
public String serializeToJson(List<AnswerOptionDTO> answerOptions, ObjectMapper objectMapper) {
try {
return objectMapper.writeValueAsString(answerOptions);
}
catch (JsonProcessingException e) {
throw new RuntimeException("Error serializing to JSON", e);
}
}

/**
* Deserializes a list of QuizQuestion objects from their JSON representation.
* Each QuizQuestion in the input list is assumed to have its content in a JSON format.
* This method attempts to deserialize that JSON content back into QuizQuestion objects,
* preserving the original IDs. If any JSON parsing errors occur, a RuntimeException
* is thrown encapsulating the original exception.
*
* @param quizQuestions the list of QuizQuestions with JSON content to be deserialized.
* @throws RuntimeException if any JSON parsing errors occur during the deserialization process,
* encapsulating the underlying JsonProcessingException.
*/
@Transactional
public void deserializeFromJSON(List<QuizQuestion> quizQuestions) {
ObjectMapper objectMapper = new ObjectMapper();

if (quizQuestions != null) {
for (QuizQuestion quizQuestion : quizQuestions) {
if (quizQuestion instanceof MultipleChoiceQuestion) {
try {
List<AnswerOptionDTO> answerOptions = objectMapper.readValue(quizQuestion.getContent(), new TypeReference<>() {
});
((MultipleChoiceQuestion) quizQuestion).setAnswerOptions(answerOptions);
}
catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import de.tum.in.www1.artemis.config.Constants;
Expand Down Expand Up @@ -443,7 +442,6 @@ protected QuizExercise saveAndFlush(QuizExercise quizExercise) {
// Note: save will automatically remove deleted questions from the exercise and deleted answer options from the questions
// and delete the now orphaned entries from the database
log.debug("Save quiz exercise to database: {}", quizExercise);
processQuizQuestions(quizExercise);

return quizExerciseRepository.saveAndFlush(quizExercise);
}
Expand Down Expand Up @@ -483,32 +481,4 @@ private String serializeToJson(List<AnswerOptionDTO> answerOptions, ObjectMapper
throw new RuntimeException("Error serializing to JSON", e);
}
}

/**
* Deserializes a list of QuizQuestion objects from their JSON representation.
* Each QuizQuestion in the input list is assumed to have its content in a JSON format.
* This method attempts to deserialize that JSON content back into QuizQuestion objects,
* preserving the original IDs. If any JSON parsing errors occur, a RuntimeException
* is thrown encapsulating the original exception.
*
* @param quizQuestions the list of QuizQuestions with JSON content to be deserialized.
* @throws RuntimeException if any JSON parsing errors occur during the deserialization process,
* encapsulating the underlying JsonProcessingException.
*/
public void deserializeFromJSON(List<QuizQuestion> quizQuestions) {
ObjectMapper objectMapper = new ObjectMapper();

for (QuizQuestion quizQuestion : quizQuestions) {
if (quizQuestion instanceof MultipleChoiceQuestion) {
try {
List<AnswerOptionDTO> answerOptions = objectMapper.readValue(quizQuestion.getContent(), new TypeReference<>() {
});
((MultipleChoiceQuestion) quizQuestion).setAnswerOptions(answerOptions);
}
catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import de.tum.in.www1.artemis.domain.Result;
import de.tum.in.www1.artemis.domain.User;
import de.tum.in.www1.artemis.domain.enumeration.AssessmentType;
Expand All @@ -19,6 +22,7 @@
import de.tum.in.www1.artemis.domain.participation.Participation;
import de.tum.in.www1.artemis.domain.participation.StudentParticipation;
import de.tum.in.www1.artemis.domain.quiz.AbstractQuizSubmission;
import de.tum.in.www1.artemis.domain.quiz.MultipleChoiceSubmittedAnswer;
import de.tum.in.www1.artemis.domain.quiz.QuizBatch;
import de.tum.in.www1.artemis.domain.quiz.QuizExercise;
import de.tum.in.www1.artemis.domain.quiz.QuizSubmission;
Expand Down Expand Up @@ -241,4 +245,40 @@ protected QuizSubmission save(QuizExercise quizExercise, QuizSubmission quizSubm
quizSubmission.setParticipation(this.getParticipation(quizExercise, quizSubmission, user));
return quizSubmissionRepository.save(quizSubmission);
}

/**
* Processes a list of quiz questions by converting each question into a JSON string
* and setting it as the content of the question. This method iterates over all
* questions in the given quiz exercise.
*
* @param quizSubmission the QuizSubmission object containing the list of submitted answers. It must not be null.
* @throws RuntimeException if there is a problem in serializing the question object to JSON.
*/
public void processSubmittedAnswers(QuizSubmission quizSubmission) {
ObjectMapper objectMapper = new ObjectMapper();

for (SubmittedAnswer submittedAnswer : quizSubmission.getSubmittedAnswers()) {
if (submittedAnswer instanceof MultipleChoiceSubmittedAnswer) {
submittedAnswer.setSelection(serializeToJson(((MultipleChoiceSubmittedAnswer) submittedAnswer).getSelectedOptions(), objectMapper));
}
}
}

/**
* Serializes a QuizQuestion object to its JSON representation using the provided ObjectMapper.
* This method is called for each individual question during the quiz processing.
*
* @param object
* @param objectMapper the ObjectMapper instance used for serialization. It must not be null.
* @return String representing the JSON serialized form of the QuizQuestion.
* @throws RuntimeException if JSON processing fails, encapsulating the underlying JsonProcessingException.
*/
private String serializeToJson(Object object, ObjectMapper objectMapper) {
try {
return objectMapper.writeValueAsString(object);
}
catch (JsonProcessingException e) {
throw new RuntimeException("Error serializing to JSON", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,6 @@ public ResponseEntity<QuizExercise> getQuizExercise(@PathVariable Long quizExerc
log.info("REST request to get quiz exercise : {}", quizExerciseId);
User user = userRepository.getUserWithGroupsAndAuthorities();
var quizExercise = quizExerciseRepository.findByIdWithQuestionsAndStatisticsAndCompetenciesElseThrow(quizExerciseId);
var c = quizExercise.getQuizQuestions();
quizExerciseService.deserializeFromJSON(quizExercise.getQuizQuestions());
var d = quizExercise.getQuizQuestions();

if (quizExercise.isExamExercise()) {
authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.EDITOR, quizExercise, user);
Expand Down

0 comments on commit b2d603b

Please sign in to comment.