diff --git a/src/main/java/com/example/demo/controller/GameDefinitionController.java b/src/main/java/com/example/demo/controller/GameDefinitionController.java index 18b333e2a4e4525a68a970f6ca105a1802179e39..00ef5d0c35ce6d4c2bee5fa3e3a8e7c4f07f8d4e 100644 --- a/src/main/java/com/example/demo/controller/GameDefinitionController.java +++ b/src/main/java/com/example/demo/controller/GameDefinitionController.java @@ -1,5 +1,6 @@ package com.example.demo.controller; +import com.example.demo.dto.TrainingDefinitionDto; import com.example.demo.dto.input.GameDefinitionCreateDto; import com.example.demo.service.GameDefinitionService; import io.swagger.annotations.Api; @@ -40,8 +41,9 @@ public class GameDefinitionController { @ApiOperation(value = "Create a new game definition") @ApiResponses(value = {@ApiResponse(code = 200, message = "New game definition created"), @ApiResponse(code = 500, message = "Unexpected application error")}) - public GameDefinitionCreateDto createGameLevel(@ApiParam(value = "Game definition", required = true) @RequestBody(required = true) - List<GameDefinitionCreateDto> gameDefinition) { - return gameDefinitionService.createGameDefinition(gameDefinition); + public GameDefinitionCreateDto createGameLevel( + @ApiParam(value = "Game definition", required = true) @RequestBody(required = true) + TrainingDefinitionDto trainingDefinitionDto) { + return gameDefinitionService.createGameDefinition(trainingDefinitionDto); } } diff --git a/src/main/java/com/example/demo/domain/BaseLevel.java b/src/main/java/com/example/demo/domain/BaseLevel.java index 37f6ddf3207333569f19d0aa0562210db44128d4..7d62c686aede510a1515506e43652bf9cb677fe2 100644 --- a/src/main/java/com/example/demo/domain/BaseLevel.java +++ b/src/main/java/com/example/demo/domain/BaseLevel.java @@ -28,6 +28,9 @@ public abstract class BaseLevel { @ManyToOne(fetch = FetchType.LAZY) private UnityLevel unityLevel; + @ManyToOne(fetch = FetchType.LAZY) + private TrainingDefinition trainingDefinition; + public String getTitle() { return title; } @@ -76,6 +79,14 @@ public abstract class BaseLevel { this.unityLevel = unityLevel; } + public TrainingDefinition getTrainingDefinition() { + return trainingDefinition; + } + + public void setTrainingDefinition(TrainingDefinition trainingDefinition) { + this.trainingDefinition = trainingDefinition; + } + @Override public String toString() { return "BaseLevel{" + "title='" + title + '\'' + ", estimatedDuration='" + estimatedDuration + '\'' + diff --git a/src/main/java/com/example/demo/domain/TrainingDefinition.java b/src/main/java/com/example/demo/domain/TrainingDefinition.java index 79b634f7759fd658eea20166bff1b0c2818d8af9..243ce4da272a7c89c149036e4b1fbdd7c4f61895 100644 --- a/src/main/java/com/example/demo/domain/TrainingDefinition.java +++ b/src/main/java/com/example/demo/domain/TrainingDefinition.java @@ -1,10 +1,15 @@ package com.example.demo.domain; +import javax.persistence.CascadeType; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; import java.time.LocalDateTime; import java.util.Arrays; +import java.util.List; @Entity public class TrainingDefinition { @@ -23,6 +28,10 @@ public class TrainingDefinition { private byte[] outcomes; private byte[] prerequisites; + @OrderBy + @OneToMany(mappedBy = "trainingDefinition", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private List<BaseLevel> levels; + public Long getId() { return id; } @@ -103,6 +112,14 @@ public class TrainingDefinition { this.prerequisites = prerequisites; } + public List<BaseLevel> getLevels() { + return levels; + } + + public void setLevels(List<BaseLevel> levels) { + this.levels = levels; + } + @Override public String toString() { return "TrainingDefinition{" + "id=" + id + ", title='" + title + '\'' + ", lastEdited=" + lastEdited + diff --git a/src/main/java/com/example/demo/domain/UnityLevel.java b/src/main/java/com/example/demo/domain/UnityLevel.java index fe50f737a8a623c80bc16f3e81f72d3b884d3711..1b351a4255b7a5668824a76029113c1685acf40f 100644 --- a/src/main/java/com/example/demo/domain/UnityLevel.java +++ b/src/main/java/com/example/demo/domain/UnityLevel.java @@ -12,13 +12,13 @@ public class UnityLevel extends BaseLevel { @OrderBy @OneToMany(mappedBy = "unityLevel", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) - private List<BaseLevel> subLevels; + private List<GameLevel> subLevels; - public List<BaseLevel> getSubLevels() { + public List<GameLevel> getSubLevels() { return subLevels; } - public void setSubLevels(List<BaseLevel> subLevels) { + public void setSubLevels(List<GameLevel> subLevels) { this.subLevels = subLevels; } } diff --git a/src/main/java/com/example/demo/dto/BaseLevelDto.java b/src/main/java/com/example/demo/dto/BaseLevelDto.java index b00c134c7f363a25e3fdc23ef58a29ec7d5a13e6..d53d125c4adb89070792e186233212c7b83479ab 100644 --- a/src/main/java/com/example/demo/dto/BaseLevelDto.java +++ b/src/main/java/com/example/demo/dto/BaseLevelDto.java @@ -1,5 +1,7 @@ package com.example.demo.dto; +import com.example.demo.dto.input.LevelType; + import java.io.Serializable; public abstract class BaseLevelDto implements Serializable { @@ -9,6 +11,7 @@ public abstract class BaseLevelDto implements Serializable { private Integer order; private String estimatedDuration; private Long maxScore; + private LevelType type; public Long getId() { return id; @@ -50,6 +53,14 @@ public abstract class BaseLevelDto implements Serializable { this.maxScore = maxScore; } + public LevelType getType() { + return type; + } + + public void setType(LevelType type) { + this.type = type; + } + @Override public String toString() { return "BaseLevelDto{" + "id=" + id + ", title='" + title + '\'' + ", order=" + order + diff --git a/src/main/java/com/example/demo/dto/TrainingDefinitionDto.java b/src/main/java/com/example/demo/dto/TrainingDefinitionDto.java index 8db7e68bee7414e4c4ae66d79c9ca9c04ff29cd0..b2b16036d2503f01318d3881ac0f5f945852ee47 100644 --- a/src/main/java/com/example/demo/dto/TrainingDefinitionDto.java +++ b/src/main/java/com/example/demo/dto/TrainingDefinitionDto.java @@ -1,8 +1,11 @@ package com.example.demo.dto; +import com.example.demo.dto.input.GameDefinitionCreateDto; + import java.io.Serializable; import java.time.LocalDateTime; import java.util.Arrays; +import java.util.List; public class TrainingDefinitionDto implements Serializable { @@ -17,6 +20,8 @@ public class TrainingDefinitionDto implements Serializable { private byte[] outcomes; private byte[] prerequisites; + private List<GameDefinitionCreateDto> levels; + public Long getId() { return id; } @@ -97,6 +102,14 @@ public class TrainingDefinitionDto implements Serializable { this.prerequisites = prerequisites; } + public List<GameDefinitionCreateDto> getLevels() { + return levels; + } + + public void setLevels(List<GameDefinitionCreateDto> levels) { + this.levels = levels; + } + @Override public String toString() { return "TrainingDefinitionDto{" + "id=" + id + ", title='" + title + '\'' + ", lastEdited=" + lastEdited + diff --git a/src/main/java/com/example/demo/dto/UnityLevelDto.java b/src/main/java/com/example/demo/dto/UnityLevelDto.java index be0ac4affb6fc1d9e74835ecaf6abba7c6a28d01..aec241f7fc8c584fa73ce937a130f56b57ba7296 100644 --- a/src/main/java/com/example/demo/dto/UnityLevelDto.java +++ b/src/main/java/com/example/demo/dto/UnityLevelDto.java @@ -4,7 +4,7 @@ import java.util.List; public class UnityLevelDto extends BaseLevelDto { - // TODO any class extending BaseLevel could be used here - this piece of art is here in order to make mapstruct happy + // TODO any class extending BaseLevel probable should be used here - this piece of art is here in order to make mapstruct happy private List<GameLevelDto> subLevels; public List<GameLevelDto> getSubLevels() { diff --git a/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java b/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java index c19d1608415ba0e33d96d947615fddc938f7d334..5beacd53d101a726e7ac8df9390aa4f3daa622b6 100644 --- a/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java +++ b/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java @@ -1,5 +1,8 @@ package com.example.demo.dto.input; +import com.example.demo.dto.AttachmentDto; +import com.example.demo.dto.HintDto; + import java.util.List; public class GameDefinitionCreateDto { @@ -7,6 +10,24 @@ public class GameDefinitionCreateDto { private String title; private Integer order; private LevelType type; + + // assessment level fields + private String assessmentType; + + // game level fields + private String content; + private boolean solutionPenalized; + private String flag; + private String solution; + private Long incorrectFlagLimit; + + private List<AttachmentDto> attachments; + private List<HintDto> hints; + + // info level fields + // currently none special + + // unity level fields private List<? extends GameDefinitionCreateDto> subLevels; public Long getId() { @@ -41,6 +62,70 @@ public class GameDefinitionCreateDto { this.type = type; } + public String getAssessmentType() { + return assessmentType; + } + + public void setAssessmentType(String assessmentType) { + this.assessmentType = assessmentType; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public boolean isSolutionPenalized() { + return solutionPenalized; + } + + public void setSolutionPenalized(boolean solutionPenalized) { + this.solutionPenalized = solutionPenalized; + } + + public String getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + public String getSolution() { + return solution; + } + + public void setSolution(String solution) { + this.solution = solution; + } + + public Long getIncorrectFlagLimit() { + return incorrectFlagLimit; + } + + public void setIncorrectFlagLimit(Long incorrectFlagLimit) { + this.incorrectFlagLimit = incorrectFlagLimit; + } + + public List<AttachmentDto> getAttachments() { + return attachments; + } + + public void setAttachments(List<AttachmentDto> attachments) { + this.attachments = attachments; + } + + public List<HintDto> getHints() { + return hints; + } + + public void setHints(List<HintDto> hints) { + this.hints = hints; + } + public List<? extends GameDefinitionCreateDto> getSubLevels() { return subLevels; } diff --git a/src/main/java/com/example/demo/mapper/BeanMapper.java b/src/main/java/com/example/demo/mapper/BeanMapper.java index 3707c0d02ff2030bcc9a05bb87cc809a73777226..ecc34bf7496939dcf1af9bac3126cef3aac8fe40 100644 --- a/src/main/java/com/example/demo/mapper/BeanMapper.java +++ b/src/main/java/com/example/demo/mapper/BeanMapper.java @@ -5,6 +5,7 @@ import com.example.demo.domain.Attachment; import com.example.demo.domain.GameLevel; import com.example.demo.domain.Hint; import com.example.demo.domain.InfoLevel; +import com.example.demo.domain.TrainingDefinition; import com.example.demo.domain.UnityLevel; import com.example.demo.dto.AssessmentLevelDto; import com.example.demo.dto.AttachmentDto; @@ -15,8 +16,11 @@ import com.example.demo.dto.HintDto; import com.example.demo.dto.InfoLevelCreateDto; import com.example.demo.dto.InfoLevelDto; import com.example.demo.dto.InfoLevelUpdateDto; +import com.example.demo.dto.TrainingDefinitionDto; import com.example.demo.dto.UnityLevelDto; +import com.example.demo.dto.input.GameDefinitionCreateDto; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @@ -27,22 +31,29 @@ public interface BeanMapper { AssessmentLevelDto toDto(AssessmentLevel assessmentLevel); + @Mapping(target = "orderInTrainingDefinition", source = "order") AssessmentLevel toEntity(AssessmentLevelDto assessmentLevel); GameLevelDto toDto(GameLevel gameLevel); + @Mapping(target = "orderInTrainingDefinition", source = "order") GameLevel toEntity(GameLevelDto gameLevel); + @Mapping(target = "orderInTrainingDefinition", source = "order") GameLevel toEntity(GameLevelCreateDto gameLevel); + @Mapping(target = "orderInTrainingDefinition", source = "order") GameLevel toEntity(GameLevelUpdateDto gameLevel); InfoLevelDto toDto(InfoLevel infoLevel); + @Mapping(target = "orderInTrainingDefinition", source = "order") InfoLevel toEntity(InfoLevelDto infoLevel); + @Mapping(target = "orderInTrainingDefinition", source = "order") InfoLevel toEntity(InfoLevelCreateDto gameLevel); + @Mapping(target = "orderInTrainingDefinition", source = "order") InfoLevel toEntity(InfoLevelUpdateDto gameLevel); HintDto toDto(Hint hint); @@ -55,5 +66,23 @@ public interface BeanMapper { UnityLevelDto toDto(UnityLevel unityLevel); + @Mapping(target = "orderInTrainingDefinition", source = "order") UnityLevel toEntity(UnityLevelDto unityLevel); + + @Mapping(target = "orderInTrainingDefinition", source = "order") + AssessmentLevel toAssessmentLevel(GameDefinitionCreateDto gameDefinitionCreateDto); + + @Mapping(target = "orderInTrainingDefinition", source = "order") + InfoLevel toInfoLevel(GameDefinitionCreateDto gameDefinitionCreateDto); + + @Mapping(target = "orderInTrainingDefinition", source = "order") + GameLevel toGameLevel(GameDefinitionCreateDto gameDefinitionCreateDto); + + @Mapping(target = "orderInTrainingDefinition", source = "order") + UnityLevel toUnityLevel(GameDefinitionCreateDto gameDefinitionCreateDto); + + @Mapping(target = "levels", ignore = true) + TrainingDefinition toEntity(TrainingDefinitionDto trainingDefinition); + + TrainingDefinitionDto toDto(TrainingDefinition trainingDefinition); } diff --git a/src/main/java/com/example/demo/repository/TrainingDefinitionRepository.java b/src/main/java/com/example/demo/repository/TrainingDefinitionRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..19236c160670fba2adf1ee1935dc282a4edd07c8 --- /dev/null +++ b/src/main/java/com/example/demo/repository/TrainingDefinitionRepository.java @@ -0,0 +1,7 @@ +package com.example.demo.repository; + +import com.example.demo.domain.TrainingDefinition; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TrainingDefinitionRepository extends JpaRepository<TrainingDefinition, Long> { +} diff --git a/src/main/java/com/example/demo/service/GameDefinitionService.java b/src/main/java/com/example/demo/service/GameDefinitionService.java index 5dc2624f6f55410c81d9631ef5f08274dbc971c8..1cc5fd617f9ee0c6b4bedaae14673c9bb58c7d76 100644 --- a/src/main/java/com/example/demo/service/GameDefinitionService.java +++ b/src/main/java/com/example/demo/service/GameDefinitionService.java @@ -3,14 +3,21 @@ package com.example.demo.service; import com.example.demo.domain.AssessmentLevel; import com.example.demo.domain.BaseLevel; import com.example.demo.domain.GameLevel; +import com.example.demo.domain.InfoLevel; +import com.example.demo.domain.TrainingDefinition; import com.example.demo.domain.UnityLevel; +import com.example.demo.dto.TrainingDefinitionDto; import com.example.demo.dto.input.GameDefinitionCreateDto; import com.example.demo.dto.input.LevelType; +import com.example.demo.mapper.BeanMapper; import com.example.demo.repository.AssessmentLevelRepository; import com.example.demo.repository.GameLevelRepository; +import com.example.demo.repository.InfoLevelRepository; +import com.example.demo.repository.TrainingDefinitionRepository; import com.example.demo.repository.UnityLevelRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; @@ -27,37 +34,43 @@ public class GameDefinitionService { @Autowired private GameLevelRepository gameLevelRepository; - public GameDefinitionCreateDto createGameDefinition(List<GameDefinitionCreateDto> gameDefinition) { + @Autowired + private InfoLevelRepository infoLevelRepository; - for (GameDefinitionCreateDto gameDefinitionCreateDto : gameDefinition) { - if (gameDefinitionCreateDto.getType() == LevelType.assessment) { - AssessmentLevel assessmentLevel = new AssessmentLevel(); - assessmentLevel.setTitle(gameDefinitionCreateDto.getTitle()); - assessmentLevel.setOrderInTrainingDefinition(gameDefinitionCreateDto.getOrder()); + @Autowired + private TrainingDefinitionRepository trainingDefinitionRepository; - assessmentLevelRepository.save(assessmentLevel); - } else if (gameDefinitionCreateDto.getType() == LevelType.unity) { - UnityLevel unityLevel = new UnityLevel(); - unityLevel.setTitle(gameDefinitionCreateDto.getTitle()); - unityLevel.setOrderInTrainingDefinition(gameDefinitionCreateDto.getOrder()); + public GameDefinitionCreateDto createGameDefinition(TrainingDefinitionDto trainingDefinitionDto) { - unityLevelRepository.save(unityLevel); + TrainingDefinition trainingDefinition = BeanMapper.INSTANCE.toEntity(trainingDefinitionDto); + trainingDefinitionRepository.save(trainingDefinition); - List<BaseLevel> subLevels = new ArrayList<>(); - for (GameDefinitionCreateDto subLevel : gameDefinitionCreateDto.getSubLevels()) { - if (subLevel.getType() == LevelType.game) { - GameLevel gameLevel = new GameLevel(); - gameLevel.setTitle(subLevel.getTitle()); - gameLevel.setOrderInTrainingDefinition(subLevel.getOrder()); - gameLevel.setUnityLevel(unityLevel); + // TODO refactor this, it's really ugly + for (GameDefinitionCreateDto gameDefinitionCreateDto : trainingDefinitionDto.getLevels()) { + if (gameDefinitionCreateDto.getType() == LevelType.assessment) { + AssessmentLevel assessmentLevel = BeanMapper.INSTANCE.toAssessmentLevel(gameDefinitionCreateDto); + assessmentLevel.setTrainingDefinition(trainingDefinition); + assessmentLevelRepository.save(assessmentLevel); + } else if (gameDefinitionCreateDto.getType() == LevelType.unity) { + UnityLevel unityLevel = BeanMapper.INSTANCE.toUnityLevel(gameDefinitionCreateDto); + unityLevel.setTrainingDefinition(trainingDefinition); - subLevels.add(gameLevel); - gameLevelRepository.save(gameLevel); - } + if (!CollectionUtils.isEmpty(unityLevel.getSubLevels())) { + unityLevel.getSubLevels().forEach(x -> x.setUnityLevel(unityLevel)); + unityLevel.getSubLevels().forEach(x -> x.setTrainingDefinition(trainingDefinition)); } - unityLevel.setSubLevels(subLevels); + unityLevelRepository.save(unityLevel); + } else if (gameDefinitionCreateDto.getType() == LevelType.game) { + GameLevel gameLevel = BeanMapper.INSTANCE.toGameLevel(gameDefinitionCreateDto); + gameLevel.setTrainingDefinition(trainingDefinition); + gameLevelRepository.save(gameLevel); + + } else if (gameDefinitionCreateDto.getType() == LevelType.info) { + InfoLevel infoLevel = BeanMapper.INSTANCE.toInfoLevel(gameDefinitionCreateDto); + infoLevel.setTrainingDefinition(trainingDefinition); + infoLevelRepository.save(infoLevel); } }