Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package de.unistuttgart.bugfinder.code;

import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CodeRepository extends JpaRepository<Code, UUID> {}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.unistuttgart.bugfinder.configuration;

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

@GetMapping("/configurations/vm/{id}")
public ConfigurationVM getVM(@PathVariable final UUID id) {
log.debug("GET /configurations/{}", id);
return configurationService.getViewModel(id);
}

@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/configurations")
public ConfigurationDTO createConfiguration(@RequestBody final ConfigurationDTO configurationDTO) {
log.debug("POST /configurations with body {}", configurationDTO);
return configurationService.save(configurationDTO);
}

/**
* used by the lecture interface to build a configuration by the view model
*
* @param configurationBuilderCodeDTO
* @return
*/
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/configurations/build")
public ConfigurationDTO buildConfiguration(@RequestBody final ConfigurationVM configurationBuilderCodeDTO) {
log.debug("POST /configurations/builder with body {}", configurationBuilderCodeDTO);
return configurationService.build(configurationBuilderCodeDTO);
}

@PutMapping("/configurations/{id}")
public ConfigurationDTO updateConfiguration(
@PathVariable final UUID id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.unistuttgart.bugfinder.configuration;

import de.unistuttgart.bugfinder.code.Code;
import de.unistuttgart.bugfinder.code.CodeDTO;
import java.util.List;
import java.util.UUID;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,102 +1,217 @@
package de.unistuttgart.bugfinder.configuration;

import static org.springframework.http.HttpStatus.NOT_FOUND;

import de.unistuttgart.bugfinder.code.Code;
import de.unistuttgart.bugfinder.code.CodeDTO;
import de.unistuttgart.bugfinder.code.CodeMapper;
import de.unistuttgart.bugfinder.code.CodeService;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import de.unistuttgart.bugfinder.code.CodeRepository;
import de.unistuttgart.bugfinder.code.word.Word;
import de.unistuttgart.bugfinder.code.word.WordRepository;
import de.unistuttgart.bugfinder.configuration.vm.CodeVM;
import de.unistuttgart.bugfinder.configuration.vm.ConfigurationVM;
import de.unistuttgart.bugfinder.configuration.vm.WordVM;
import de.unistuttgart.bugfinder.solution.Solution;
import de.unistuttgart.bugfinder.solution.SolutionRepository;
import de.unistuttgart.bugfinder.solution.bug.Bug;
import de.unistuttgart.bugfinder.solution.bug.BugRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import java.util.*;

@Service
@Slf4j
public class ConfigurationService {

@Autowired
private ConfigurationRepository configurationRepository;

@Autowired
private ConfigurationMapper configurationMapper;

@Autowired
private CodeMapper codeMapper;

/**
* Get a configuration by its id.
* @param id the id of the configuration
* @throws ResponseStatusException (404) when configuration with its id does not exist
* @return the found configuration
*/
public Configuration getConfiguration(final UUID id) {
return configurationRepository
.findById(id)
.orElseThrow(() ->
new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Configuration with id %s not found.", id))
);
}

/**
* @return all configurations as list of DTOs
*/
public List<ConfigurationDTO> findAll() {
log.debug("get all configurations");
return configurationMapper.toDTO(configurationRepository.findAll());
}

/**
* Get the configuration by its id as DTO.
* @param id the id of the configuration
* @throws ResponseStatusException (404) when configuration with its id does not exist
* @return the found configuration as DTO
*/
public ConfigurationDTO find(final UUID id) {
log.debug("get configuration {}", id);
Configuration configuration = getConfiguration(id);
return configurationMapper.toDTO(configuration);
}

/**
* Save a configuration.
*
* @param configurationDTO the configuration to save
* @return the saved configuration as DTO
*/
public ConfigurationDTO save(final ConfigurationDTO configurationDTO) {
log.debug("create configuration {}", configurationDTO);
return configurationMapper.toDTO(configurationRepository.save(configurationMapper.fromDTO(configurationDTO)));
}

/**
* Deletes the configuration with the given ID, if present.
*
* @param id the ID of the configuration to delete
* @return the deleted configuration, if found
* @throws ResponseStatusException (204 - NO_CONTENT) if the configuration was not found
*/
public ConfigurationDTO delete(final UUID id) {
log.info("delete configuration {}", id);
Configuration configuration = configurationRepository
.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NO_CONTENT));
configurationRepository.deleteById(id);
return configurationMapper.toDTO(configuration);
}

/**
* Get all codes of a configuration.
*
* @param id the configuration id
* @return the codes of the specified configuration
*/
public List<CodeDTO> getCodes(final UUID id) {
log.debug("get codes from configuration {}", id);
final Configuration configuration = getConfiguration(id);
return codeMapper.toDTO(configuration.getCodes());
}
@Autowired
private ConfigurationRepository configurationRepository;

@Autowired
private ConfigurationMapper configurationMapper;

@Autowired
private CodeMapper codeMapper;

@Autowired
private CodeRepository codeRepository;

@Autowired
private SolutionRepository solutionRepository;

@Autowired
private WordRepository wordRepository;

@Autowired
private BugRepository bugRepository;

/**
* Get a configuration by its id.
*
* @param id the id of the configuration
* @return the found configuration
* @throws ResponseStatusException (404) when configuration with its id does not exist
*/
public Configuration getConfiguration(final UUID id) {
return configurationRepository
.findById(id)
.orElseThrow(() ->
new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Configuration with id %s not found.", id))
);
}

/**
* @return all configurations as list of DTOs
*/
public List<ConfigurationDTO> findAll() {
log.debug("get all configurations");
return configurationMapper.toDTO(configurationRepository.findAll());
}

/**
* Get the configuration by its id as DTO.
*
* @param id the id of the configuration
* @return the found configuration as DTO
* @throws ResponseStatusException (404) when configuration with its id does not exist
*/
public ConfigurationDTO find(final UUID id) {
log.debug("get configuration {}", id);
Configuration configuration = getConfiguration(id);
return configurationMapper.toDTO(configuration);
}

/**
* Save a configuration.
*
* @param configurationDTO the configuration to save
* @return the saved configuration as DTO
*/
public ConfigurationDTO save(final ConfigurationDTO configurationDTO) {
log.debug("create configuration {}", configurationDTO);
return configurationMapper.toDTO(configurationRepository.save(configurationMapper.fromDTO(configurationDTO)));
}

public ConfigurationDTO build(final ConfigurationVM configurationVM) {
Set<Code> codesToPersist = new HashSet<>(configurationVM.getCodes().size());
for (CodeVM codeVM : configurationVM.getCodes()) {
List<Word> wordsToPersistToCode = new ArrayList<>(codeVM.getWords().size());
Set<Bug> bugsToPersistToSolution = new HashSet<>();
bugsToPersistToSolution = new HashSet<>();
for (List<WordVM> row : codeVM.getWords()) {
// check if the row only contains blank strings
// the first row will never contain only blank strings since it comes from the lecture interface
if (row.stream().allMatch(wordVM -> wordVM.getCorrectValue().isBlank())) {
continue;
}
// if it is not the first row in the code we add a new line
if (codeVM.getWords().indexOf(row) != 0) {
wordsToPersistToCode.add(wordRepository.save(new Word(null, "\n")));
}
for (WordVM wordVM : row) {
// check if the word is blank
// the first word will never be blank since it comes from the lecture interface
if (wordVM.getCorrectValue().isBlank()) {
continue;
}
// if it is not the first word in the row we add a space
if (row.indexOf(wordVM) != 0) {
wordsToPersistToCode.add(wordRepository.save(new Word(null, " ")));
}
String displayValue = wordVM.getDisplayValue() != null ? wordVM.getDisplayValue() : wordVM.getCorrectValue();
Word word = new Word(null, displayValue);
word = wordRepository.save(word);
wordsToPersistToCode.add(word);
if (wordVM.getErrorType() != null) {
Bug bug = new Bug(word, wordVM.getErrorType(), wordVM.getCorrectValue());
bug = bugRepository.save(bug);
bugsToPersistToSolution.add(bug);
}
}
}
Code code = new Code(null, wordsToPersistToCode);
codesToPersist.add(code);
Solution solution = new Solution(null, bugsToPersistToSolution, code);
code = codeRepository.save(code);
solution = solutionRepository.save(solution);
}
Configuration configuration = new Configuration(null, codesToPersist);
return configurationMapper.toDTO(configurationRepository.save(configuration));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

way too long method, also javadoc missing


/**
* Deletes the configuration with the given ID, if present.
*
* @param id the ID of the configuration to delete
* @return the deleted configuration, if found
* @throws ResponseStatusException (204 - NO_CONTENT) if the configuration was not found
*/
public ConfigurationDTO delete(final UUID id) {
log.info("delete configuration {}", id);
Configuration configuration = configurationRepository
.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NO_CONTENT));
configurationRepository.deleteById(id);
return configurationMapper.toDTO(configuration);
}

/**
* Get all codes of a configuration.
*
* @param id the configuration id
* @return the codes of the specified configuration
*/
public List<CodeDTO> getCodes(final UUID id) {
log.debug("get codes from configuration {}", id);
final Configuration configuration = getConfiguration(id);
return codeMapper.toDTO(configuration.getCodes());
}

public ConfigurationVM getViewModel(UUID id) {
log.debug("get configuration view model {}", id);
final Configuration configuration = getConfiguration(id);
final ConfigurationVM configurationVM = new ConfigurationVM(new ArrayList<>());
for (Code code : configuration.getCodes()) {
final CodeVM codeVM = new CodeVM(new ArrayList<>());
final Solution solution = solutionRepository
.findByCodeId(code.getId())
.orElseThrow(() ->
new ResponseStatusException(
HttpStatus.NOT_FOUND,
String.format("Solution with code id %s not found.", code.getId())
)
);

List<WordVM> row = new ArrayList<>();
for (Word word : code.getWords()) {
if (word.getWord().equals("\n")) {
codeVM.getWords().add(row);
row = new ArrayList<>();
continue;
}
Optional<Bug> bug = solution
.getBugs()
.stream()
.filter(b -> b.getWord().getId().equals(word.getId()))
.findFirst();
if (word.getWord().equals(" ") && bug.isEmpty()) {
continue;
}
final WordVM wordVM = new WordVM();
if (bug.isPresent()) {
wordVM.setErrorType(bug.get().getErrorType());
wordVM.setCorrectValue(bug.get().getCorrectValue());
wordVM.setDisplayValue(word.getWord());
} else {
wordVM.setCorrectValue(word.getWord());
}
row.add(wordVM);
}
codeVM.getWords().add(row);
configurationVM.getCodes().add(codeVM);
}

return configurationVM;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too long method, split it up, add java doc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, misused Optional use.

Copy link
Copy Markdown
Contributor

@delvh delvh Sep 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And equals(" ") or equals("\n") WON'T scale well!
Those are error prone AF.
It's probably best to extract them into methods.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package de.unistuttgart.bugfinder.configuration.vm;

import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;

@Data
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class CodeVM {

List<List<WordVM>> words;
}
Loading