From 0bcc57b6141130b4c9537b1a56e3d04570e6e828 Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Thu, 6 Mar 2025 22:32:04 -0500 Subject: [PATCH] Game Classes tab working --- db/1.0.0/10. createGameClass.sql | 17 +++ .../controller/GameClassController.java | 140 ++++++++++++++++++ .../controller/IconController.java | 13 ++ .../raidbuilder/entity/AuditableEntity.java | 40 +++++ .../entity/AuditableEntityListener.java | 52 ------- .../mattrixwv/raidbuilder/entity/Game.java | 2 - .../raidbuilder/entity/GameCalendarEvent.java | 2 - .../raidbuilder/entity/GameClass.java | 33 +++++ .../raidbuilder/entity/GamePermission.java | 2 - .../raidbuilder/entity/RaidGroup.java | 2 - .../entity/RaidGroupPermission.java | 2 - .../game_class/GameClassCustomRepository.java | 5 + .../game_class/GameClassRepository.java | 23 +++ .../game_class/GameClassRepositoryImpl.java | 9 ++ .../raidbuilder/service/GameClassService.java | 129 ++++++++++++++++ .../raidbuilder/service/GameService.java | 2 + .../raidbuilder/service/RaidGroupService.java | 14 +- ...e9169149--Screenshot 2024-10-19 162110.png | Bin 5292 -> 0 bytes 18 files changed, 420 insertions(+), 67 deletions(-) create mode 100644 db/1.0.0/10. createGameClass.sql create mode 100644 src/main/java/com/mattrixwv/raidbuilder/controller/GameClassController.java delete mode 100644 src/main/java/com/mattrixwv/raidbuilder/entity/AuditableEntityListener.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/entity/GameClass.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassCustomRepository.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassRepository.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassRepositoryImpl.java create mode 100644 src/main/java/com/mattrixwv/raidbuilder/service/GameClassService.java delete mode 100644 temp/raidBuilderIcons/gameIcons/070d1ad3-48bb-438e-af01-0559e9169149--Screenshot 2024-10-19 162110.png diff --git a/db/1.0.0/10. createGameClass.sql b/db/1.0.0/10. createGameClass.sql new file mode 100644 index 0000000..91a0410 --- /dev/null +++ b/db/1.0.0/10. createGameClass.sql @@ -0,0 +1,17 @@ +CREATE TABLE raid_builder.game_class( + game_class_id uuid PRIMARY KEY, + game_id uuid REFERENCES raid_builder.game(game_id), + game_class_name text NOT NULL, + game_class_icon text, + + --Auditing + modified_by uuid, + modified_date timestamptz, + created_by uuid NOT NULL, + created_date timestamptz NOT NULL +); + +CREATE INDEX idx_game_class_game_id ON raid_builder.game_class(game_id); +CREATE INDEX idx_game_class_game_class_name ON raid_builder.game_class(game_class_name); + +GRANT ALL ON TABLE raid_builder.game_class TO raid_builder; diff --git a/src/main/java/com/mattrixwv/raidbuilder/controller/GameClassController.java b/src/main/java/com/mattrixwv/raidbuilder/controller/GameClassController.java new file mode 100644 index 0000000..68a9a3d --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/controller/GameClassController.java @@ -0,0 +1,140 @@ +package com.mattrixwv.raidbuilder.controller; + + +import java.util.List; +import java.util.UUID; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.mattrixwv.raidbuilder.annotation.AccountAuthorization; +import com.mattrixwv.raidbuilder.annotation.GameAuthorization; +import com.mattrixwv.raidbuilder.entity.GameClass; +import com.mattrixwv.raidbuilder.service.GameClassService; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.GamePermissionType; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@RestController +@RequestMapping("/gameClass") +@RequiredArgsConstructor +public class GameClassController{ + private final ObjectMapper mapper; + private final GameClassService gameClassService; + + + @GetMapping("/game/{gameId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public List getByGameId(@PathVariable("gameId") UUID gameId, @RequestParam("page") int page, @RequestParam("pageSize") int pageSize, @RequestParam(name = "searchTerm", required = false) String searchTerm){ + log.info("Getting game classes for game {} with page {} of size {} with search term {}", gameId, page, pageSize, searchTerm); + + + List gameClasses; + if((searchTerm == null) || (searchTerm.isBlank())){ + gameClasses = gameClassService.getByGameId(gameId, page, pageSize); + } + else{ + gameClasses = gameClassService.getByGameId(gameId, page, pageSize, searchTerm); + } + + + return gameClasses; + } + + + @GetMapping("/game/{gameId}/count") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public ObjectNode getByGameCount(@PathVariable("gameId") UUID gameId, @RequestParam(name = "searchTerm", required = false) String searchTerm){ + log.info("Getting game classes count for game {} with search term {}", gameId, searchTerm); + + + Long gameClassesCount; + if((searchTerm == null) || (searchTerm.isBlank())){ + gameClassesCount = gameClassService.countByGameId(gameId); + } + else{ + gameClassesCount = gameClassService.countByGameId(gameId, searchTerm); + } + + ObjectNode countNode = mapper.createObjectNode(); + countNode.put("count", gameClassesCount); + countNode.put("status", "success"); + + + return countNode; + } + + + @PostMapping("/game/{gameId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @GameAuthorization(permissions = {GamePermissionType.ADMIN}) + public ObjectNode createGameClass(@PathVariable("gameId") UUID gameId, @RequestParam(value = "iconFile", required = false) MultipartFile file, @RequestParam("gameClassName") String gameClassName){ + log.info("Creating game class {}", gameClassName); + + + ObjectNode returnNode = mapper.createObjectNode(); + GameClass gameClass = new GameClass(); + gameClass.setGameId(gameId); + gameClass.setGameClassName(gameClassName); + gameClassService.createGameClass(gameClass, file); + + returnNode.put("gameClassId", gameClass.getGameClassId().toString()); + returnNode.put("status", "success"); + + log.info("Successfully created game class: {}", gameClass.getGameClassId()); + + return returnNode; + } + + @PutMapping("/{gameClassId}/game/{gameId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @GameAuthorization(permissions = {GamePermissionType.ADMIN}) + public ObjectNode updateGameClass(@PathVariable("gameClassId") UUID gameClassId, @PathVariable("gameId") UUID gameId, @RequestParam(value = "iconFile", required = false) MultipartFile file, @RequestParam("gameClassName") String gameClassName, @RequestParam(value = "gameClassIcon", required = false) String gameClassIcon){ + log.info("Updating game class {}", gameClassName); + + + ObjectNode returnNode = mapper.createObjectNode(); + GameClass gameClass = new GameClass(); + gameClass.setGameClassId(gameClassId); + gameClass.setGameId(gameId); + gameClass.setGameClassName(gameClassName); + gameClass.setGameClassIcon(gameClassIcon); + gameClassService.updateGameClass(gameClass, file); + + returnNode.put("gameClassId", gameClass.getGameClassId().toString()); + returnNode.put("status", "success"); + + log.info("Successfully updated game class: {}", gameClass.getGameClassId()); + + return returnNode; + } + + @DeleteMapping("/{gameClassId}/game/{gameId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @GameAuthorization(permissions = {GamePermissionType.ADMIN}) + public ObjectNode deleteGameClass(@PathVariable("gameClassId") UUID gameClassId, @PathVariable("gameId") UUID gameId){ + log.info("Deleting game class {}", gameClassId); + + + ObjectNode returnNode = mapper.createObjectNode(); + gameClassService.deleteById(gameClassId); + returnNode.put("status", "success"); + + log.info("Successfully deleted game class: {}", gameClassId); + + return returnNode; + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/controller/IconController.java b/src/main/java/com/mattrixwv/raidbuilder/controller/IconController.java index c5faab1..3b653cc 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/controller/IconController.java +++ b/src/main/java/com/mattrixwv/raidbuilder/controller/IconController.java @@ -17,6 +17,7 @@ import com.mattrixwv.raidbuilder.annotation.AccountAuthorization; import lombok.extern.slf4j.Slf4j; + @Slf4j @RestController @RequestMapping("/icons") @@ -46,6 +47,18 @@ public class IconController{ byte[] resource = Files.readAllBytes(Path.of(uploadFileDirectory + "/raidGroupIcons/" + raidGroupIconName)); + return ResponseEntity.ok().body(resource); + } + + @GetMapping("/gameClassIcons/{gameClassIconName}") + @AccountAuthorization(permissions = {}) + public ResponseEntity getGameClassIcons(@PathVariable("gameClassIconName") String gameClassIconName) throws IOException{ + log.info("Getting game class icon {}", gameClassIconName); + + + byte[] resource = Files.readAllBytes(Path.of(uploadFileDirectory + "/gameClassIcons/" + gameClassIconName)); + + return ResponseEntity.ok().body(resource); } } diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/AuditableEntity.java b/src/main/java/com/mattrixwv/raidbuilder/entity/AuditableEntity.java index e1b9d0b..284be60 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/entity/AuditableEntity.java +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/AuditableEntity.java @@ -4,13 +4,21 @@ package com.mattrixwv.raidbuilder.entity; import java.time.ZonedDateTime; import java.util.UUID; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.jwt.Jwt; + import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.Column; import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.PrePersist; +import jakarta.persistence.PreUpdate; import lombok.Data; +import lombok.extern.slf4j.Slf4j; +@Slf4j @Data @MappedSuperclass public abstract class AuditableEntity{ @@ -26,4 +34,36 @@ public abstract class AuditableEntity{ @JsonIgnore @Column(name = "created_date", updatable = false) protected ZonedDateTime createdDate; + + + @PrePersist + public void prePersist() throws NoSuchFieldException, IllegalAccessException{ + this.createdBy = getCurrentUserId(); + this.createdDate = ZonedDateTime.now(); + } + + @PreUpdate + public void preUpdate(){ + this.modifiedBy = getCurrentUserId(); + this.modifiedDate = ZonedDateTime.now(); + } + + + private UUID getCurrentUserId(){ + log.debug("Getting current auditor"); + + + UUID returnUUID; + + try{ + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + returnUUID = UUID.fromString(((Jwt)auth.getPrincipal()).getClaimAsString("accountId")); + } + catch(Exception e){ + returnUUID = new UUID(0, 0); + log.debug("No user logged in: {}", returnUUID); + } + + return returnUUID; + } } diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/AuditableEntityListener.java b/src/main/java/com/mattrixwv/raidbuilder/entity/AuditableEntityListener.java deleted file mode 100644 index 76d78fa..0000000 --- a/src/main/java/com/mattrixwv/raidbuilder/entity/AuditableEntityListener.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.mattrixwv.raidbuilder.entity; - - -import java.time.ZonedDateTime; -import java.util.UUID; - -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.jwt.Jwt; -import org.springframework.stereotype.Component; - -import jakarta.persistence.PrePersist; -import jakarta.persistence.PreUpdate; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - - -@Slf4j -@Component -@RequiredArgsConstructor -public class AuditableEntityListener{ - @PrePersist - public void prePersist(AuditableEntity entity) throws NoSuchFieldException, IllegalAccessException{ - entity.createdBy = getCurrentUserId(); - entity.createdDate = ZonedDateTime.now(); - } - - @PreUpdate - public void preUpdate(AuditableEntity entity){ - entity.modifiedBy = getCurrentUserId(); - entity.modifiedDate = ZonedDateTime.now(); - } - - - private UUID getCurrentUserId(){ - log.debug("Getting current auditor"); - - - UUID returnUUID; - - try{ - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - returnUUID = UUID.fromString(((Jwt)auth.getPrincipal()).getClaimAsString("accountId")); - } - catch(Exception e){ - returnUUID = new UUID(0, 0); - log.debug("No user logged in: {}", returnUUID); - } - - return returnUUID; - } -} diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/Game.java b/src/main/java/com/mattrixwv/raidbuilder/entity/Game.java index ddd5c7a..0bfb723 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/entity/Game.java +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/Game.java @@ -5,7 +5,6 @@ import java.util.UUID; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -17,7 +16,6 @@ import lombok.NoArgsConstructor; @Entity @Table(name = "game", schema = "raid_builder") -@EntityListeners(AuditableEntityListener.class) @Data @EqualsAndHashCode(callSuper = false) @NoArgsConstructor diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/GameCalendarEvent.java b/src/main/java/com/mattrixwv/raidbuilder/entity/GameCalendarEvent.java index 0ece4e4..28a3951 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/entity/GameCalendarEvent.java +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/GameCalendarEvent.java @@ -6,7 +6,6 @@ import java.util.UUID; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -18,7 +17,6 @@ import lombok.NoArgsConstructor; @Entity @Table(name = "game_calendar_event", schema = "raid_builder") -@EntityListeners(AuditableEntityListener.class) @Data @EqualsAndHashCode(callSuper = false) @NoArgsConstructor diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/GameClass.java b/src/main/java/com/mattrixwv/raidbuilder/entity/GameClass.java new file mode 100644 index 0000000..eebcf25 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/GameClass.java @@ -0,0 +1,33 @@ +package com.mattrixwv.raidbuilder.entity; + + +import java.util.UUID; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + + +@Entity +@Table(name = "game_class", schema = "raid_builder") +@Data +@EqualsAndHashCode(callSuper = false) +@NoArgsConstructor +public class GameClass extends AuditableEntity{ + @Id + @GeneratedValue(strategy = GenerationType.UUID) + @Column(name = "game_class_id") + private UUID gameClassId; + @Column(name = "game_id") + private UUID gameId; + @Column(name = "game_class_name") + private String gameClassName; + @Column(name = "game_class_icon") + private String gameClassIcon; +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/GamePermission.java b/src/main/java/com/mattrixwv/raidbuilder/entity/GamePermission.java index 703e4b4..46ed3c5 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/entity/GamePermission.java +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/GamePermission.java @@ -7,7 +7,6 @@ import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.GamePermissionType; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; @@ -21,7 +20,6 @@ import lombok.NoArgsConstructor; @Entity @Table(name = "game_permission", schema = "raid_builder") -@EntityListeners(AuditableEntityListener.class) @Data @EqualsAndHashCode(callSuper = false) @NoArgsConstructor diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroup.java b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroup.java index 5037881..01f1735 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroup.java +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroup.java @@ -5,7 +5,6 @@ import java.util.UUID; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -17,7 +16,6 @@ import lombok.NoArgsConstructor; @Entity @Table(name = "raid_group", schema = "raid_builder") -@EntityListeners(AuditableEntityListener.class) @Data @EqualsAndHashCode(callSuper = false) @NoArgsConstructor diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupPermission.java b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupPermission.java index b649525..4fe8386 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupPermission.java +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupPermission.java @@ -7,7 +7,6 @@ import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.RaidGroupPermissionType; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; @@ -21,7 +20,6 @@ import lombok.NoArgsConstructor; @Entity @Table(name = "raid_group_permission", schema = "raid_builder") -@EntityListeners(AuditableEntityListener.class) @Data @EqualsAndHashCode(callSuper = false) @NoArgsConstructor diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassCustomRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassCustomRepository.java new file mode 100644 index 0000000..9c603ae --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassCustomRepository.java @@ -0,0 +1,5 @@ +package com.mattrixwv.raidbuilder.repository.game_class; + + +public interface GameClassCustomRepository{ +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassRepository.java new file mode 100644 index 0000000..964bec6 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassRepository.java @@ -0,0 +1,23 @@ +package com.mattrixwv.raidbuilder.repository.game_class; + + +import java.util.List; +import java.util.UUID; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.mattrixwv.raidbuilder.entity.GameClass; + + +public interface GameClassRepository extends GameClassCustomRepository, JpaRepository{ + public void deleteByGameId(UUID gameId); + + + public List findAllByGameId(UUID gameId); + public List findAllByGameId(UUID gameId, PageRequest pageRequest); + public List findAllByGameIdAndGameClassNameContainingIgnoreCase(UUID gameId, String searchTerm, PageRequest pageRequest); + + public long countByGameId(UUID gameId); + public long countByGameIdAndGameClassNameContainingIgnoreCase(UUID gameId, String searchTerm); +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassRepositoryImpl.java b/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassRepositoryImpl.java new file mode 100644 index 0000000..2cb45fc --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/game_class/GameClassRepositoryImpl.java @@ -0,0 +1,9 @@ +package com.mattrixwv.raidbuilder.repository.game_class; + + +import org.springframework.stereotype.Repository; + + +@Repository +public class GameClassRepositoryImpl implements GameClassCustomRepository{ +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/GameClassService.java b/src/main/java/com/mattrixwv/raidbuilder/service/GameClassService.java new file mode 100644 index 0000000..c2104f7 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/service/GameClassService.java @@ -0,0 +1,129 @@ +package com.mattrixwv.raidbuilder.service; + + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import com.mattrixwv.raidbuilder.entity.GameClass; +import com.mattrixwv.raidbuilder.repository.game_class.GameClassRepository; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +@RequiredArgsConstructor +public class GameClassService{ + private final GameClassRepository gameClassRepository; + //Values + @Value("${uploadFileDirectory}") + private String uploadFileDirectory; + + + //Write + public GameClass createGameClass(GameClass gameClass, MultipartFile file){ + if(file != null){ + String fileName = UUID.randomUUID().toString() + "--" + file.getOriginalFilename(); + Path filePath = Paths.get(uploadFileDirectory + "/gameClassIcons").resolve(fileName); + + try{ + file.transferTo(filePath); + gameClass.setGameClassIcon(fileName); + } + catch(Exception error){ + log.error("Error uploading file: " + error.getMessage(), error); + throw new RuntimeException("Error uploading file: " + error.getMessage(), error); + } + } + return gameClassRepository.save(gameClass); + } + + public GameClass updateGameClass(GameClass gameClass, MultipartFile file){ + GameClass existingGameClass = gameClassRepository.findById(gameClass.getGameClassId()).orElse(null); + + //Delete the old file if one exists + if((existingGameClass != null) && (existingGameClass.getGameClassIcon() != null) && (gameClass.getGameClassIcon() == null)){ + log.debug("Deleting old file: {}", existingGameClass.getGameClassIcon()); + File existingFile = new File(uploadFileDirectory + "/gameClassIcons/" + existingGameClass.getGameClassIcon()); + if(existingFile.exists()){ + existingFile.delete(); + } + } + + if(file != null){ + //Upload the new file + String fileName = UUID.randomUUID().toString() + "--" + file.getOriginalFilename(); + Path filePath = Paths.get(uploadFileDirectory + "/gameClassIcons").resolve(fileName); + try{ + file.transferTo(filePath); + gameClass.setGameClassIcon(fileName); + } + catch(Exception error){ + log.error("Error uploading file: " + error.getMessage(), error); + throw new RuntimeException("Error uploading file: " + error.getMessage(), error); + } + } + + return gameClassRepository.save(gameClass); + } + + public void deleteById(UUID gameClassId){ + GameClass gameClass = gameClassRepository.findById(gameClassId).orElse(null); + if(gameClass != null){ + if(gameClass.getGameClassIcon() != null){ + File existingFile = new File(uploadFileDirectory + "/gameClassIcons/" + gameClass.getGameClassIcon()); + if(existingFile.exists()){ + existingFile.delete(); + } + } + } + + + gameClassRepository.deleteById(gameClassId); + } + + public void deleteByGameId(UUID gameId){ + List gameClasses = gameClassRepository.findAllByGameId(gameId); + for(GameClass gameClass : gameClasses){ + if(gameClass.getGameClassIcon() != null){ + File existingFile = new File(uploadFileDirectory + "/gameClassIcons/" + gameClass.getGameClassIcon()); + if(existingFile.exists()){ + existingFile.delete(); + } + } + } + + + gameClassRepository.deleteByGameId(gameId); + } + + + //Read + public List getByGameId(UUID gameId, int page, int pageSize){ + return gameClassRepository.findAllByGameId(gameId, PageRequest.of(page, pageSize, Sort.by("gameClassName").ascending())); + } + + public List getByGameId(UUID gameId, int page, int pageSize, String searchTerm){ + return gameClassRepository.findAllByGameIdAndGameClassNameContainingIgnoreCase(gameId, searchTerm, PageRequest.of(page, pageSize, Sort.by("gameClassName").ascending())); + } + + public long countByGameId(UUID gameId){ + return gameClassRepository.countByGameId(gameId); + } + + public long countByGameId(UUID gameId, String searchTerm){ + return gameClassRepository.countByGameIdAndGameClassNameContainingIgnoreCase(gameId, searchTerm); + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/GameService.java b/src/main/java/com/mattrixwv/raidbuilder/service/GameService.java index 4a7b449..b71bac3 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/service/GameService.java +++ b/src/main/java/com/mattrixwv/raidbuilder/service/GameService.java @@ -29,6 +29,7 @@ public class GameService{ private final GameRepository gameRepository; //Related Services private final GameCalendarEventService gameCalendarEventService; + private final GameClassService gameClassService; private final GamePermissionService gamePermissionService; private final RaidGroupService raidGroupService; //Values @@ -93,6 +94,7 @@ public class GameService{ } gameCalendarEventService.deleteByGameId(gameId); + gameClassService.deleteByGameId(gameId); gamePermissionService.deleteByGameId(gameId); raidGroupService.deleteByGameId(gameId); gameRepository.flush(); diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java index c16b17b..9618a75 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java +++ b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java @@ -99,6 +99,14 @@ public class RaidGroupService{ public void deleteByGameId(UUID gameId){ List raidGroups = raidGroupRepository.findAllByGameId(gameId); + for(RaidGroup raidGroup : raidGroups){ + if(raidGroup.getRaidGroupIcon() != null){ + File existingFile = new File(uploadFileDirectory + "/raidGroupIcons/" + raidGroup.getRaidGroupIcon()); + if(existingFile.exists()){ + existingFile.delete(); + } + } + } raidGroupPermissionService.deleteByRaidGroupIds(raidGroups.stream().map(RaidGroup::getRaidGroupId).toList()); raidGroupRepository.flush(); @@ -127,11 +135,7 @@ public class RaidGroupService{ } public List getRaidGroupsByGame(UUID gameId, int page, int pageSize, String searchTerm){ - return raidGroupRepository.findAllByGameIdAndRaidGroupNameContainingIgnoreCase( - gameId, - searchTerm, - PageRequest.of(page, pageSize, Sort.by("raidGroupName").ascending()) - ); + return raidGroupRepository.findAllByGameIdAndRaidGroupNameContainingIgnoreCase(gameId, searchTerm, PageRequest.of(page, pageSize, Sort.by("raidGroupName").ascending())); } public long getRaidGroupsCount(){ diff --git a/temp/raidBuilderIcons/gameIcons/070d1ad3-48bb-438e-af01-0559e9169149--Screenshot 2024-10-19 162110.png b/temp/raidBuilderIcons/gameIcons/070d1ad3-48bb-438e-af01-0559e9169149--Screenshot 2024-10-19 162110.png deleted file mode 100644 index 304e84719e261e2ec4eeda941718ab72d71d8f23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5292 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