save(Model,Integer,AnswerListDto,BindingResult,Integer)   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 5
c 1
b 1
f 0
dl 0
loc 50
rs 8.1696
1
package easytests.personal.controllers;
2
3
import easytests.common.controllers.AbstractCrudController;
4
import easytests.core.models.*;
5
import easytests.core.options.AnswersOptions;
6
import easytests.core.options.AnswersOptionsInterface;
7
import easytests.core.options.QuestionsOptionsInterface;
8
import easytests.core.options.builder.AnswersOptionsBuilder;
9
import easytests.core.options.builder.QuestionsOptionsBuilder;
10
import easytests.core.services.AnswersService;
11
import easytests.core.services.QuestionTypesService;
12
import easytests.core.services.QuestionsService;
13
import easytests.personal.dto.AnswerDto;
14
import easytests.personal.dto.AnswerListDto;
15
import easytests.personal.validators.AnswerDtoValidator;
16
import java.util.*;
17
import java.util.stream.Collectors;
18
import javax.validation.Valid;
19
20
import org.springframework.beans.factory.annotation.Autowired;
21
import org.springframework.stereotype.Controller;
22
import org.springframework.transaction.annotation.Propagation;
23
import org.springframework.transaction.annotation.Transactional;
24
import org.springframework.ui.Model;
25
import org.springframework.validation.BindingResult;
26
import org.springframework.web.bind.annotation.*;
27
28
/**
29
 * @author rezenbekk
30
 */
31
@Controller
32
@SuppressWarnings("checkstyle:MultipleStringLiterals")
33
@RequestMapping("/personal/topics/{topicId}/questions/{questionId}/update_answers/")
34
public class AnswersController extends AbstractCrudController {
35
36
    @Autowired
37
    private QuestionsService questionsService;
38
39
    @Autowired
40
    private QuestionsOptionsBuilder questionsOptionsBuilder;
41
42
    @Autowired
43
    private QuestionTypesService questionTypesService;
44
45
    @Autowired
46
    private AnswersOptionsBuilder answersOptionsBuilder;
47
48
    @Autowired
49
    private AnswersService answersService;
50
51
    @Autowired
52
    private AnswerDtoValidator answerDtoValidator;
53
54
    @GetMapping("")
55
    public String update(
56
            Model model,
57
            @PathVariable("questionId") Integer questionId,
58
            @PathVariable("topicId") Integer topicId) {
59
        final QuestionModelInterface questionModel = getQuestionModel(questionId, false);
60
        injectQuestionTypeModels(model);
61
        final AnswerListDto answerDtoList = new AnswerListDto();
62
        answerDtoList.map(questionModel);
63
        setUpdateBehaviour(model);
64
        model.addAttribute("questionId", questionId);
65
        model.addAttribute("question", questionModel);
66
        model.addAttribute("answerDtoList", answerDtoList);
67
        //model.addAttribute("oldDtoList", answerDtoList);
68
        model.addAttribute("topicId", topicId);
69
        return "answers/form";
70
    }
71
72
    @PostMapping("")
73
    public String save(
74
            Model model,
75
            @PathVariable("questionId") Integer questionId,
76
            @Valid AnswerListDto answerDtoList,
77
            BindingResult bindingResult,
78
            @PathVariable("topicId") Integer topicId) {
79
        final QuestionModelInterface questionModel = this.getQuestionModel(questionId, false);
80
        final List<AnswerModelInterface> oldAnswerList = questionModel.getAnswers();
81
        final List<AnswerDto> newAnswerList = new ArrayList<>();
82
        if (answerDtoList.getAnswersList() != null) {
83
            newAnswerList.addAll(answerDtoList.getAnswersList());
84
        }
85
        for (AnswerDto answerDto
86
                : newAnswerList) {
87
            this.answerDtoValidator.validate(answerDto, bindingResult);
88
        }
89
        this.answerDtoValidator.validateWithQuestionType(answerDtoList.getAnswersList(),
90
                questionModel.getQuestionType().getId(), bindingResult);
91
        if (bindingResult.hasErrors()) {
92
            injectQuestionTypeModels(model);
93
            setUpdateBehaviour(model);
94
            final AnswerListDto oldDtoList = new AnswerListDto();
95
            oldDtoList.map(questionModel);
96
97
            model.addAttribute("answerDtoList", answerDtoList);
98
            //model.addAttribute("oldDtoList", oldDtoList);
99
            model.addAttribute("topicId", topicId);
100
            model.addAttribute("question", questionModel);
101
102
            model.addAttribute("questionId", questionId);
103
            model.addAttribute("errors", bindingResult);
104
105
            System.out.println("\nHAS ERRORS");
106
            System.out.println(bindingResult + "\n\n");
107
108
            return "answers/form";
109
        }
110
111
        for (Integer i = 0; i < newAnswerList.size(); i++) {
112
            final AnswerDto answerDto = newAnswerList.get(i);
113
            final AnswerModelInterface answer = new AnswerModel();
114
            System.out.println(answerDto);
115
            answerDto.mapInto(answer);
116
            this.answersService.save(answer);
117
        }
118
119
        this.deleteDeadAnswers(newAnswerList, oldAnswerList);
120
121
        return "redirect:/personal/topics/" + topicId + "/questions/" + questionId + "/update_answers/";
122
    }
123
124
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
125
    private void deleteDeadAnswers(List<AnswerDto> newAnswers,
0 ignored issues
show
Bug introduced by
Make this method "public" or remove the "@Transactional" annotation
Loading history...
126
                                   List<AnswerModelInterface> oldAnswers) {
127
128
        final List<Integer> newAnswersIds = new ArrayList<>(newAnswers.size());
129
130
        newAnswersIds.addAll(newAnswers.stream().map(AnswerDto::getId)
131
                .collect(Collectors.toList()));
132
        for (AnswerModelInterface oldAnswer : oldAnswers) {
133
            if (!newAnswersIds.contains(oldAnswer.getId())) {
134
                System.out.println("DELETION: " + oldAnswer);
135
                this.answersService.delete(oldAnswer);
136
            }
137
        }
138
    }
139
140
    private QuestionModelInterface getQuestionModel(Integer id, Boolean forDelete) {
141
        final QuestionsOptionsInterface questionsOptions = this.questionsOptionsBuilder
142
                .forAuth()
143
                .withAnswers(new AnswersOptions());
144
        final QuestionModelInterface questionModel = this.questionsService.find(id, questionsOptions);
145
        //checkModel(questionModel, topicId);
146
        if (forDelete) {
147
            return this.questionsService.find(id, this.questionsOptionsBuilder.forDelete());
148
        }
149
        return questionModel;
150
    }
151
152
    private void injectQuestionTypeModels(Model model) {
153
        final List<QuestionTypeModelInterface> questionTypes = this.questionTypesService.findAll();
154
        model.addAttribute("questionTypes", questionTypes);
155
    }
156
157
    private List<AnswerModelInterface> getAnswerModelList(QuestionModelInterface questionModel) {
0 ignored issues
show
Unused Code introduced by
Remove this unused private "getAnswerModelList" method.
Loading history...
158
        final AnswersOptionsInterface answersOptions = this.answersOptionsBuilder.forAuth();
159
        final List<AnswerModelInterface> answersList = answersService.findByQuestion(questionModel, answersOptions);
160
161
        return answersList;
162
    }
163
}
164