Skip to content

Commit c10b739

Browse files
authored
Add lecturer interface models (#4)
2 parents e334561 + b74508f commit c10b739

File tree

8 files changed

+213
-11
lines changed

8 files changed

+213
-11
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package de.unistuttgart.bugfinder.code;
2+
3+
import java.util.UUID;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
@Repository
8+
public interface CodeRepository extends JpaRepository<Code, UUID> {}

src/main/java/de/unistuttgart/bugfinder/configuration/ConfigurationController.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package de.unistuttgart.bugfinder.configuration;
22

3+
import de.unistuttgart.bugfinder.configuration.vm.ConfigurationVM;
34
import java.util.List;
4-
import java.util.Optional;
55
import java.util.UUID;
66
import lombok.extern.slf4j.Slf4j;
77
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,13 +27,32 @@ public ConfigurationDTO get(@PathVariable final UUID id) {
2727
return configurationService.find(id);
2828
}
2929

30+
@GetMapping("/configurations/vm/{id}")
31+
public ConfigurationVM getVM(@PathVariable final UUID id) {
32+
log.debug("GET /configurations/{}", id);
33+
return configurationService.getViewModel(id);
34+
}
35+
3036
@ResponseStatus(HttpStatus.CREATED)
3137
@PostMapping("/configurations")
3238
public ConfigurationDTO createConfiguration(@RequestBody final ConfigurationDTO configurationDTO) {
3339
log.debug("POST /configurations with body {}", configurationDTO);
3440
return configurationService.save(configurationDTO);
3541
}
3642

43+
/**
44+
* used by the lecture interface to build a configuration by the view model
45+
*
46+
* @param configurationBuilderCodeDTO
47+
* @return
48+
*/
49+
@ResponseStatus(HttpStatus.CREATED)
50+
@PostMapping("/configurations/build")
51+
public ConfigurationDTO buildConfiguration(@RequestBody final ConfigurationVM configurationBuilderCodeDTO) {
52+
log.debug("POST /configurations/builder with body {}", configurationBuilderCodeDTO);
53+
return configurationService.build(configurationBuilderCodeDTO);
54+
}
55+
3756
@PutMapping("/configurations/{id}")
3857
public ConfigurationDTO updateConfiguration(
3958
@PathVariable final UUID id,

src/main/java/de/unistuttgart/bugfinder/configuration/ConfigurationDTO.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package de.unistuttgart.bugfinder.configuration;
22

3-
import de.unistuttgart.bugfinder.code.Code;
43
import de.unistuttgart.bugfinder.code.CodeDTO;
54
import java.util.List;
65
import java.util.UUID;

src/main/java/de/unistuttgart/bugfinder/configuration/ConfigurationService.java

Lines changed: 122 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package de.unistuttgart.bugfinder.configuration;
22

3-
import static org.springframework.http.HttpStatus.NOT_FOUND;
4-
3+
import de.unistuttgart.bugfinder.code.Code;
54
import de.unistuttgart.bugfinder.code.CodeDTO;
65
import de.unistuttgart.bugfinder.code.CodeMapper;
7-
import de.unistuttgart.bugfinder.code.CodeService;
8-
import java.util.List;
9-
import java.util.Optional;
10-
import java.util.UUID;
6+
import de.unistuttgart.bugfinder.code.CodeRepository;
7+
import de.unistuttgart.bugfinder.code.word.Word;
8+
import de.unistuttgart.bugfinder.code.word.WordRepository;
9+
import de.unistuttgart.bugfinder.configuration.vm.CodeVM;
10+
import de.unistuttgart.bugfinder.configuration.vm.ConfigurationVM;
11+
import de.unistuttgart.bugfinder.configuration.vm.WordVM;
12+
import de.unistuttgart.bugfinder.solution.Solution;
13+
import de.unistuttgart.bugfinder.solution.SolutionRepository;
14+
import de.unistuttgart.bugfinder.solution.bug.Bug;
15+
import de.unistuttgart.bugfinder.solution.bug.BugRepository;
16+
import java.util.*;
1117
import lombok.extern.slf4j.Slf4j;
1218
import org.springframework.beans.factory.annotation.Autowired;
1319
import org.springframework.http.HttpStatus;
@@ -27,11 +33,24 @@ public class ConfigurationService {
2733
@Autowired
2834
private CodeMapper codeMapper;
2935

36+
@Autowired
37+
private CodeRepository codeRepository;
38+
39+
@Autowired
40+
private SolutionRepository solutionRepository;
41+
42+
@Autowired
43+
private WordRepository wordRepository;
44+
45+
@Autowired
46+
private BugRepository bugRepository;
47+
3048
/**
3149
* Get a configuration by its id.
50+
*
3251
* @param id the id of the configuration
33-
* @throws ResponseStatusException (404) when configuration with its id does not exist
3452
* @return the found configuration
53+
* @throws ResponseStatusException (404) when configuration with its id does not exist
3554
*/
3655
public Configuration getConfiguration(final UUID id) {
3756
return configurationRepository
@@ -51,9 +70,10 @@ public List<ConfigurationDTO> findAll() {
5170

5271
/**
5372
* Get the configuration by its id as DTO.
73+
*
5474
* @param id the id of the configuration
55-
* @throws ResponseStatusException (404) when configuration with its id does not exist
5675
* @return the found configuration as DTO
76+
* @throws ResponseStatusException (404) when configuration with its id does not exist
5777
*/
5878
public ConfigurationDTO find(final UUID id) {
5979
log.debug("get configuration {}", id);
@@ -72,6 +92,53 @@ public ConfigurationDTO save(final ConfigurationDTO configurationDTO) {
7292
return configurationMapper.toDTO(configurationRepository.save(configurationMapper.fromDTO(configurationDTO)));
7393
}
7494

95+
public ConfigurationDTO build(final ConfigurationVM configurationVM) {
96+
Set<Code> codesToPersist = new HashSet<>(configurationVM.getCodes().size());
97+
for (CodeVM codeVM : configurationVM.getCodes()) {
98+
List<Word> wordsToPersistToCode = new ArrayList<>(codeVM.getWords().size());
99+
Set<Bug> bugsToPersistToSolution = new HashSet<>();
100+
bugsToPersistToSolution = new HashSet<>();
101+
for (List<WordVM> row : codeVM.getWords()) {
102+
// check if the row only contains blank strings
103+
// the first row will never contain only blank strings since it comes from the lecture interface
104+
if (row.stream().allMatch(wordVM -> wordVM.getCorrectValue().isBlank())) {
105+
continue;
106+
}
107+
// if it is not the first row in the code we add a new line
108+
if (codeVM.getWords().indexOf(row) != 0) {
109+
wordsToPersistToCode.add(wordRepository.save(new Word(null, "\n")));
110+
}
111+
for (WordVM wordVM : row) {
112+
// check if the word is blank
113+
// the first word will never be blank since it comes from the lecture interface
114+
if (wordVM.getCorrectValue().isBlank()) {
115+
continue;
116+
}
117+
// if it is not the first word in the row we add a space
118+
if (row.indexOf(wordVM) != 0) {
119+
wordsToPersistToCode.add(wordRepository.save(new Word(null, " ")));
120+
}
121+
String displayValue = wordVM.getDisplayValue() != null ? wordVM.getDisplayValue() : wordVM.getCorrectValue();
122+
Word word = new Word(null, displayValue);
123+
word = wordRepository.save(word);
124+
wordsToPersistToCode.add(word);
125+
if (wordVM.getErrorType() != null) {
126+
Bug bug = new Bug(word, wordVM.getErrorType(), wordVM.getCorrectValue());
127+
bugsToPersistToSolution.add(bug);
128+
bug = bugRepository.save(bug);
129+
}
130+
}
131+
}
132+
Code code = new Code(null, wordsToPersistToCode);
133+
codesToPersist.add(code);
134+
Solution solution = new Solution(null, bugsToPersistToSolution, code);
135+
code = codeRepository.save(code);
136+
solution = solutionRepository.save(solution);
137+
}
138+
Configuration configuration = new Configuration(null, codesToPersist);
139+
return configurationMapper.toDTO(configurationRepository.save(configuration));
140+
}
141+
75142
/**
76143
* Deletes the configuration with the given ID, if present.
77144
*
@@ -99,4 +166,51 @@ public List<CodeDTO> getCodes(final UUID id) {
99166
final Configuration configuration = getConfiguration(id);
100167
return codeMapper.toDTO(configuration.getCodes());
101168
}
169+
170+
public ConfigurationVM getViewModel(UUID id) {
171+
log.debug("get configuration view model {}", id);
172+
final Configuration configuration = getConfiguration(id);
173+
final ConfigurationVM configurationVM = new ConfigurationVM(new ArrayList<>());
174+
for (Code code : configuration.getCodes()) {
175+
final CodeVM codeVM = new CodeVM(new ArrayList<>());
176+
final Solution solution = solutionRepository
177+
.findByCodeId(code.getId())
178+
.orElseThrow(() ->
179+
new ResponseStatusException(
180+
HttpStatus.NOT_FOUND,
181+
String.format("Solution with code id %s not found.", code.getId())
182+
)
183+
);
184+
185+
List<WordVM> row = new ArrayList<>();
186+
for (Word word : code.getWords()) {
187+
if (word.getWord().equals(" ")) {
188+
continue;
189+
}
190+
if (word.getWord().equals("\n")) {
191+
codeVM.getWords().add(row);
192+
row = new ArrayList<>();
193+
continue;
194+
}
195+
Optional<Bug> bug = solution
196+
.getBugs()
197+
.stream()
198+
.filter(b -> b.getWord().getId().equals(word.getId()))
199+
.findFirst();
200+
final WordVM wordVM = new WordVM();
201+
if (bug.isPresent()) {
202+
wordVM.setErrorType(bug.get().getErrorType());
203+
wordVM.setCorrectValue(bug.get().getCorrectValue());
204+
wordVM.setDisplayValue(word.getWord());
205+
} else {
206+
wordVM.setCorrectValue(word.getWord());
207+
}
208+
row.add(wordVM);
209+
}
210+
codeVM.getWords().add(row);
211+
configurationVM.getCodes().add(codeVM);
212+
}
213+
214+
return configurationVM;
215+
}
102216
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package de.unistuttgart.bugfinder.configuration.vm;
2+
3+
import java.util.List;
4+
import lombok.AccessLevel;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
import lombok.experimental.FieldDefaults;
9+
10+
@Data
11+
@NoArgsConstructor
12+
@AllArgsConstructor
13+
@FieldDefaults(level = AccessLevel.PRIVATE)
14+
public class CodeVM {
15+
16+
List<List<WordVM>> words;
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package de.unistuttgart.bugfinder.configuration.vm;
2+
3+
import java.util.List;
4+
import lombok.AccessLevel;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
import lombok.experimental.FieldDefaults;
9+
10+
/**
11+
* describes the view model of the lecture interface and is used to build configurations
12+
*/
13+
@Data
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
@FieldDefaults(level = AccessLevel.PRIVATE)
17+
public class ConfigurationVM {
18+
19+
List<CodeVM> codes;
20+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package de.unistuttgart.bugfinder.configuration.vm;
2+
3+
import de.unistuttgart.bugfinder.solution.bug.ErrorType;
4+
import lombok.AccessLevel;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
import lombok.experimental.FieldDefaults;
9+
import org.springframework.lang.Nullable;
10+
11+
@Data
12+
@NoArgsConstructor
13+
@AllArgsConstructor
14+
@FieldDefaults(level = AccessLevel.PRIVATE)
15+
public class WordVM {
16+
17+
String correctValue;
18+
19+
@Nullable
20+
String displayValue;
21+
22+
@Nullable
23+
ErrorType errorType;
24+
}

src/test/java/de/unistuttgart/bugfinder/ConfigurationControllerTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
3131
public class ConfigurationControllerTest {
3232

33+
private final String API_URL = "/configurations";
34+
3335
@Autowired
3436
private MockMvc mvc;
3537

@@ -39,7 +41,6 @@ public class ConfigurationControllerTest {
3941
@Autowired
4042
private ConfigurationRepository configurationRepository;
4143

42-
private final String API_URL = "/configurations";
4344
private ObjectMapper objectMapper;
4445
private Configuration initialConfig;
4546
private ConfigurationDTO initialConfigDTO;

0 commit comments

Comments
 (0)