Skip to content

Commit 6c815ca

Browse files
authored
Merge pull request #472 from KEEPER31337/feature/ctf_카테고리_여러개로_설정되도록_변경
Feature/ctf 카테고리 여러개로 설정되도록 변경
2 parents 265355e + cab11ae commit 6c815ca

22 files changed

+423
-128
lines changed

src/main/java/keeper/project/homepage/ctf/dto/CtfChallengeAdminDto.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package keeper.project.homepage.ctf.dto;
22

3+
import static java.util.stream.Collectors.toList;
4+
35
import com.fasterxml.jackson.annotation.JsonProperty;
46
import com.fasterxml.jackson.annotation.JsonProperty.Access;
57
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
68
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
79
import java.time.LocalDateTime;
810
import java.util.ArrayList;
9-
import keeper.project.homepage.ctf.entity.CtfChallengeCategoryEntity;
1011
import keeper.project.homepage.ctf.entity.CtfChallengeEntity;
1112
import keeper.project.homepage.ctf.entity.CtfChallengeTypeEntity;
1213
import keeper.project.homepage.ctf.entity.CtfContestEntity;
@@ -38,12 +39,12 @@ public class CtfChallengeAdminDto extends CtfChallengeDto {
3839
private CtfDynamicChallengeInfoDto dynamicInfo;
3940

4041
public CtfChallengeEntity toEntity(CtfContestEntity contest, CtfChallengeTypeEntity type,
41-
CtfChallengeCategoryEntity category, FileEntity fileEntity, MemberEntity creator) {
42+
FileEntity fileEntity, MemberEntity creator) {
4243
return CtfChallengeEntity.builder()
4344
.name(title)
4445
.description(content)
4546
.ctfContestEntity(contest)
46-
.ctfChallengeCategoryEntity(category)
47+
.ctfChallengeHasCtfChallengeCategoryList(new ArrayList<>())
4748
.ctfChallengeTypeEntity(type)
4849
.isSolvable(isSolvable)
4950
.registerTime(LocalDateTime.now())
@@ -56,8 +57,6 @@ public CtfChallengeEntity toEntity(CtfContestEntity contest, CtfChallengeTypeEnt
5657
}
5758

5859
public static CtfChallengeAdminDto toDto(CtfChallengeEntity challenge, Long solvedTeamCount) {
59-
CtfChallengeCategoryDto category = CtfChallengeCategoryDto.toDto(
60-
challenge.getCtfChallengeCategoryEntity());
6160
CtfChallengeTypeDto type = CtfChallengeTypeDto.toDto(
6261
challenge.getCtfChallengeTypeEntity());
6362
FileDto file = FileDto.toDto(
@@ -70,7 +69,9 @@ public static CtfChallengeAdminDto toDto(CtfChallengeEntity challenge, Long solv
7069
.title(challenge.getName())
7170
.content(challenge.getDescription())
7271
.contestId(challenge.getCtfContestEntity().getId())
73-
.category(category)
72+
.categories(challenge.getCtfChallengeHasCtfChallengeCategoryList().stream()
73+
.map(CtfChallengeCategoryDto::toDto)
74+
.collect(toList()))
7475
.type(type)
7576
.flag(getVirtualTeamFlag(challenge).getContent())
7677
.isSolvable(challenge.getIsSolvable())

src/main/java/keeper/project/homepage/ctf/dto/CtfChallengeCategoryDto.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.fasterxml.jackson.annotation.JsonProperty;
66
import com.fasterxml.jackson.annotation.JsonProperty.Access;
77
import keeper.project.homepage.ctf.entity.CtfChallengeCategoryEntity;
8+
import keeper.project.homepage.ctf.entity.CtfChallengeHasCtfChallengeCategoryEntity;
89
import lombok.AllArgsConstructor;
910
import lombok.Builder;
1011
import lombok.Getter;
@@ -24,10 +25,24 @@ public class CtfChallengeCategoryDto {
2425
@JsonProperty(access = Access.READ_ONLY)
2526
private String name;
2627

28+
public static CtfChallengeCategoryEntity toEntity(CtfChallengeCategoryDto ctfChallengeCategoryDto){
29+
return CtfChallengeCategoryEntity.builder()
30+
.id(ctfChallengeCategoryDto.getId())
31+
.name(ctfChallengeCategoryDto.getName())
32+
.build();
33+
}
34+
2735
public static CtfChallengeCategoryDto toDto(CtfChallengeCategoryEntity ctfChallengeCategoryEntity) {
2836
return CtfChallengeCategoryDto.builder()
2937
.id(ctfChallengeCategoryEntity.getId())
3038
.name(ctfChallengeCategoryEntity.getName())
3139
.build();
3240
}
41+
42+
public static CtfChallengeCategoryDto toDto(CtfChallengeHasCtfChallengeCategoryEntity ctfChallengeHasCtfChallengeCategoryEntity) {
43+
return CtfChallengeCategoryDto.builder()
44+
.id(ctfChallengeHasCtfChallengeCategoryEntity.getCategory().getId())
45+
.name(ctfChallengeHasCtfChallengeCategoryEntity.getCategory().getName())
46+
.build();
47+
}
3348
}

src/main/java/keeper/project/homepage/ctf/dto/CtfChallengeDto.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package keeper.project.homepage.ctf.dto;
22

3+
import static java.util.stream.Collectors.toList;
4+
35
import com.fasterxml.jackson.annotation.JsonInclude;
4-
import com.fasterxml.jackson.annotation.JsonInclude.Include;
56
import com.fasterxml.jackson.annotation.JsonProperty;
67
import com.fasterxml.jackson.annotation.JsonProperty.Access;
78
import keeper.project.homepage.ctf.entity.CtfChallengeEntity;
@@ -32,16 +33,17 @@ public class CtfChallengeDto extends CtfCommonChallengeDto {
3233

3334
public static CtfChallengeDto toDto(CtfChallengeEntity challenge, Long solvedTeamCount,
3435
Boolean isSolved, CtfFlagEntity ctfFlagEntity) {
35-
CtfChallengeCategoryDto category = CtfChallengeCategoryDto.toDto(
36-
challenge.getCtfChallengeCategoryEntity());
3736
FileDto file = FileDto.toDto(challenge.getFileEntity());
3837

3938
return CtfChallengeDto.builder()
4039
.challengeId(challenge.getId())
4140
.title(challenge.getName())
4241
.content(challenge.getDescription())
4342
.contestId(challenge.getCtfContestEntity().getId())
44-
.category(category)
43+
.categories(challenge.getCtfChallengeHasCtfChallengeCategoryList()
44+
.stream()
45+
.map(CtfChallengeCategoryDto::toDto)
46+
.collect(toList()))
4547
.creatorName(challenge.getCreator().getNickName())
4648
.score(challenge.getScore())
4749
.solvedTeamCount(solvedTeamCount)

src/main/java/keeper/project/homepage/ctf/dto/CtfCommonChallengeDto.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package keeper.project.homepage.ctf.dto;
22

3+
import static java.util.stream.Collectors.toList;
4+
35
import com.fasterxml.jackson.annotation.JsonProperty;
46
import com.fasterxml.jackson.annotation.JsonProperty.Access;
57
import com.fasterxml.jackson.annotation.JsonSetter;
68
import com.fasterxml.jackson.annotation.Nulls;
79
import java.time.LocalDateTime;
10+
import java.util.List;
811
import javax.validation.constraints.Max;
912
import javax.validation.constraints.Min;
1013
import keeper.project.homepage.ctf.entity.CtfChallengeEntity;
@@ -28,7 +31,7 @@ public class CtfCommonChallengeDto {
2831

2932
protected String title;
3033
protected Long score;
31-
protected CtfChallengeCategoryDto category;
34+
protected List<CtfChallengeCategoryDto> categories;
3235
protected Long contestId;
3336
@Max(MAX_SUBMIT_COUNT)
3437
@Min(MIN_SUBMIT_COUNT)
@@ -48,14 +51,15 @@ public class CtfCommonChallengeDto {
4851

4952
public static CtfCommonChallengeDto toDto(CtfChallengeEntity challenge, Boolean isSolved,
5053
CtfFlagEntity ctfFlagEntity) {
51-
CtfChallengeCategoryDto category = CtfChallengeCategoryDto.toDto(
52-
challenge.getCtfChallengeCategoryEntity());
5354

5455
return CtfCommonChallengeDto.builder()
5556
.challengeId(challenge.getId())
5657
.title(challenge.getName())
5758
.contestId(challenge.getCtfContestEntity().getId())
58-
.category(category)
59+
.categories(challenge.getCtfChallengeHasCtfChallengeCategoryList()
60+
.stream()
61+
.map(CtfChallengeCategoryDto::toDto)
62+
.collect(toList()))
5963
.score(challenge.getScore())
6064
.isSolved(isSolved)
6165
.remainedSubmitCount(ctfFlagEntity.getRemainedSubmitCount())

src/main/java/keeper/project/homepage/ctf/entity/CtfChallengeEntity.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ public class CtfChallengeEntity {
5757
@JoinColumn(name = "type_id", nullable = false)
5858
CtfChallengeTypeEntity ctfChallengeTypeEntity;
5959

60-
@ManyToOne(fetch = FetchType.LAZY)
61-
@JoinColumn(name = "category_id", nullable = false)
62-
CtfChallengeCategoryEntity ctfChallengeCategoryEntity;
60+
@Builder.Default
61+
@OneToMany(mappedBy = "challenge", cascade = CascadeType.REMOVE)
62+
List<CtfChallengeHasCtfChallengeCategoryEntity> ctfChallengeHasCtfChallengeCategoryList = new ArrayList<>();
6363

6464
@Column(nullable = false)
6565
@Setter
@@ -90,4 +90,8 @@ public class CtfChallengeEntity {
9090
@PrimaryKeyJoinColumn
9191
@Setter
9292
CtfDynamicChallengeInfoEntity dynamicChallengeInfoEntity;
93+
94+
public void addCtfChallengeHasCtfChallengeCategory(CtfChallengeHasCtfChallengeCategoryEntity ctfChallengeHasCtfChallengeCategoryEntity) {
95+
this.getCtfChallengeHasCtfChallengeCategoryList().add(ctfChallengeHasCtfChallengeCategoryEntity);
96+
}
9397
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package keeper.project.homepage.ctf.entity;
2+
3+
import java.io.Serializable;
4+
import javax.persistence.Entity;
5+
import javax.persistence.FetchType;
6+
import javax.persistence.Id;
7+
import javax.persistence.IdClass;
8+
import javax.persistence.JoinColumn;
9+
import javax.persistence.ManyToOne;
10+
import javax.persistence.Table;
11+
import lombok.AllArgsConstructor;
12+
import lombok.Builder;
13+
import lombok.Getter;
14+
import lombok.NoArgsConstructor;
15+
16+
@Builder
17+
@Entity
18+
@Getter
19+
@NoArgsConstructor
20+
@AllArgsConstructor
21+
@IdClass(CtfChallengeHasCtfChallengeCategoryEntityPK.class) // 정의한 idclass 주입
22+
@Table(name = "ctf_challenge_has_ctf_challenge_category")
23+
public class CtfChallengeHasCtfChallengeCategoryEntity implements Serializable {
24+
25+
@Id
26+
@ManyToOne(targetEntity = CtfChallengeEntity.class, fetch = FetchType.LAZY)
27+
@JoinColumn(name = "ctf_challenge_id")
28+
private CtfChallengeEntity challenge;
29+
30+
@Id
31+
@ManyToOne(targetEntity = CtfChallengeCategoryEntity.class, fetch = FetchType.LAZY)
32+
@JoinColumn(name = "ctf_challenge_category_id")
33+
private CtfChallengeCategoryEntity category;
34+
35+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package keeper.project.homepage.ctf.entity;
2+
3+
import java.io.Serializable;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.EqualsAndHashCode;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
10+
@Getter
11+
@EqualsAndHashCode
12+
@NoArgsConstructor
13+
@AllArgsConstructor
14+
@Builder
15+
public class CtfChallengeHasCtfChallengeCategoryEntityPK implements Serializable {
16+
17+
private Long challenge;
18+
private Long category;
19+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package keeper.project.homepage.ctf.repository;
2+
3+
import keeper.project.homepage.ctf.entity.CtfChallengeHasCtfChallengeCategoryEntity;
4+
import keeper.project.homepage.ctf.entity.CtfChallengeHasCtfChallengeCategoryEntityPK;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
7+
public interface CtfChallengeHasCtfChallengeCategoryRepository extends
8+
JpaRepository<CtfChallengeHasCtfChallengeCategoryEntity, CtfChallengeHasCtfChallengeCategoryEntityPK> {
9+
10+
}

src/main/java/keeper/project/homepage/ctf/service/CtfAdminService.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
import java.util.List;
99
import javax.servlet.http.HttpServletRequest;
1010
import keeper.project.homepage.ctf.dto.CtfChallengeAdminDto;
11+
import keeper.project.homepage.ctf.dto.CtfChallengeCategoryDto;
1112
import keeper.project.homepage.ctf.dto.CtfContestAdminDto;
1213
import keeper.project.homepage.ctf.dto.CtfDynamicChallengeInfoDto;
1314
import keeper.project.homepage.ctf.dto.CtfProbMakerDto;
1415
import keeper.project.homepage.ctf.dto.CtfSubmitLogDto;
1516
import keeper.project.homepage.ctf.entity.CtfChallengeCategoryEntity;
1617
import keeper.project.homepage.ctf.entity.CtfChallengeEntity;
18+
import keeper.project.homepage.ctf.entity.CtfChallengeHasCtfChallengeCategoryEntity;
1719
import keeper.project.homepage.ctf.entity.CtfChallengeTypeEntity;
1820
import keeper.project.homepage.ctf.entity.CtfContestEntity;
1921
import keeper.project.homepage.ctf.entity.CtfDynamicChallengeInfoEntity;
@@ -24,6 +26,7 @@
2426
import keeper.project.homepage.ctf.exception.CustomCtfChallengeNotFoundException;
2527
import keeper.project.homepage.ctf.exception.CustomCtfTypeNotFoundException;
2628
import keeper.project.homepage.ctf.repository.CtfChallengeCategoryRepository;
29+
import keeper.project.homepage.ctf.repository.CtfChallengeHasCtfChallengeCategoryRepository;
2730
import keeper.project.homepage.ctf.repository.CtfChallengeRepository;
2831
import keeper.project.homepage.ctf.repository.CtfChallengeTypeRepository;
2932
import keeper.project.homepage.ctf.repository.CtfContestRepository;
@@ -63,6 +66,8 @@ public class CtfAdminService {
6366
private final CtfContestRepository ctfContestRepository;
6467
private final CtfTeamRepository ctfTeamRepository;
6568
private final CtfChallengeCategoryRepository ctfChallengeCategoryRepository;
69+
70+
private final CtfChallengeHasCtfChallengeCategoryRepository ctfChallengeHasCtfChallengeCategoryRepository;
6671
private final CtfSubmitLogRepository ctfSubmitLogRepository;
6772
private final CtfChallengeTypeRepository ctfChallengeTypeRepository;
6873
private final CtfChallengeRepository challengeRepository;
@@ -111,6 +116,8 @@ public CtfProbMakerDto designateProbMaker(CtfProbMakerDto probMakerDto) {
111116
@Transactional
112117
public CtfChallengeAdminDto createChallenge(CtfChallengeAdminDto challengeAdminDto) {
113118
CtfChallengeEntity newChallenge = createChallengeEntity(challengeAdminDto);
119+
120+
setChallengeCategory(newChallenge, challengeAdminDto);
114121
if (ctfUtilService.isTypeDynamic(newChallenge)) {
115122
trySetDynamicInfoInChallenge(newChallenge, challengeAdminDto);
116123
}
@@ -317,14 +324,32 @@ private Long getCtfId(CtfChallengeEntity challenge) {
317324
private CtfChallengeEntity createChallengeEntityWithFileEntity(
318325
CtfChallengeAdminDto challengeAdminDto, FileEntity fileEntity) {
319326
CtfContestEntity contest = getCtfContestEntity(challengeAdminDto.getContestId());
320-
CtfChallengeCategoryEntity category = getCategoryEntity(challengeAdminDto);
327+
321328
CtfChallengeTypeEntity type = getTypeEntity(challengeAdminDto);
322329
MemberEntity creator = authService.getMemberEntityWithJWT();
330+
323331
CtfChallengeEntity challenge = challengeAdminDto
324-
.toEntity(contest, type, category, fileEntity, creator);
332+
.toEntity(contest, type, fileEntity, creator);
333+
325334
return challengeRepository.save(challenge);
326335
}
327336

337+
private void setChallengeCategory(CtfChallengeEntity challenge,
338+
CtfChallengeAdminDto challengeAdminDto) {
339+
List<CtfChallengeCategoryEntity> ctfChallengeCategoryEntityList = challengeAdminDto.getCategories()
340+
.stream()
341+
.map(CtfChallengeCategoryDto::toEntity).toList();
342+
343+
for (CtfChallengeCategoryEntity ctfChallengeCategory : ctfChallengeCategoryEntityList) {
344+
challenge.addCtfChallengeHasCtfChallengeCategory(ctfChallengeHasCtfChallengeCategoryRepository
345+
.save(CtfChallengeHasCtfChallengeCategoryEntity
346+
.builder()
347+
.challenge(challenge)
348+
.category(ctfChallengeCategory)
349+
.build()));
350+
}
351+
}
352+
328353
private CtfChallengeEntity createChallengeEntity(CtfChallengeAdminDto challengeAdminDto) {
329354
return createChallengeEntityWithFileEntity(challengeAdminDto, null);
330355
}
@@ -335,9 +360,10 @@ private CtfChallengeTypeEntity getTypeEntity(CtfChallengeAdminDto challengeAdmin
335360
.orElseThrow(CustomCtfTypeNotFoundException::new);
336361
}
337362

338-
private CtfChallengeCategoryEntity getCategoryEntity(CtfChallengeAdminDto challengeAdminDto) {
363+
private CtfChallengeCategoryEntity getCategoryEntity(
364+
CtfChallengeCategoryDto ctfChallengeCategoryDto) {
339365
return ctfChallengeCategoryRepository
340-
.findById(challengeAdminDto.getCategory().getId())
366+
.findById(ctfChallengeCategoryDto.getId())
341367
.orElseThrow(CustomCtfCategoryNotFoundException::new);
342368
}
343369

0 commit comments

Comments
 (0)