diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ae1dbcb --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + "configurations": [ + { + "type": "java", + "name": "Spring Boot-DemoApplication", + "request": "launch", + "cwd": "${workspaceFolder}", + "mainClass": "com.example.demo.DemoApplication", + "projectName": "demo", + "args": "--populate", + "envFile": "${workspaceFolder}/.env" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 7b016a8..e012065 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "java.compile.nullAnalysis.mode": "automatic" + "java.compile.nullAnalysis.mode": "automatic", + "java.configuration.updateBuildConfiguration": "interactive" } \ No newline at end of file diff --git a/demo/build.gradle b/demo/build.gradle index 89528ee..b7867b9 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -18,6 +18,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' + implementation 'org.modelmapper:modelmapper:3.2.0' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/demo/src/main/java/com/example/demo/ApiController.java b/demo/src/main/java/com/example/demo/ApiController.java deleted file mode 100644 index 48b1010..0000000 --- a/demo/src/main/java/com/example/demo/ApiController.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.example.demo; - -import java.util.ArrayList; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -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.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - - -@RestController -@RequestMapping("/member") -public class ApiController { - private final ArrayList members= new ArrayList<>(); - private final Logger log = LoggerFactory.getLogger(ApiController.class); - - @PostMapping - public Member postMember(@RequestBody Member member) { - members.add(member); - return member; - } - - @GetMapping - public List getMembers() { - return members; - } - - @GetMapping("/{id}") - public Member getMember(@PathVariable(name = "id") int id) { - return members.get(id); - } - - @PutMapping("/{id}") - public Member putMember(@RequestBody Member member, @PathVariable(name = "id") int id) { - members.set(id, member); - return member; - } - - @DeleteMapping("/{id}") - public Member delete(@RequestParam(name = "id") int id) { - Member usr = members.get(id); - members.remove(id); - return usr; - } - -} diff --git a/demo/src/main/java/com/example/demo/DemoApplication.java b/demo/src/main/java/com/example/demo/DemoApplication.java index 64b538a..592c646 100644 --- a/demo/src/main/java/com/example/demo/DemoApplication.java +++ b/demo/src/main/java/com/example/demo/DemoApplication.java @@ -1,13 +1,59 @@ package com.example.demo; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.example.demo.users.model.UserEntity; +import com.example.demo.users.service.UserService; +import com.example.demo.groups.model.GroupEntity; +import com.example.demo.groups.service.GroupService; +import com.example.demo.members.model.MemberEntity; +import com.example.demo.members.service.MemberService; + @SpringBootApplication -public class DemoApplication { +public class DemoApplication implements CommandLineRunner { + private final Logger log = LoggerFactory.getLogger(DemoApplication.class); + + private final UserService userService; + private final GroupService groupService; + private final MemberService memberService; + + public DemoApplication(UserService userService, GroupService groupService, MemberService memberService) { + this.userService = userService; + this.groupService = groupService; + this.memberService = memberService; + } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } + @Override + public void run(String... args) throws Exception { + if (args.length > 0 && Objects.equals("--populate", args[0])) { + + log.info("Create default users values"); + + final var user1 = userService.create(new UserEntity(null, "Oleja123", "bebrus@mail.ru", "1234")); + final var user2 = userService.create(new UserEntity(null, "Vk1d2004", "berus@mail.ru", "4321")); + + log.info("Create default groups values"); + + final var group1 = groupService.create(new GroupEntity(null,user1, "1")); + final var group2 = groupService.create(new GroupEntity(null,user2, "2")); + final var group3 = groupService.create(new GroupEntity(null,user1, "3")); + + log.info("Create default members values"); + + final var member1 = memberService.create(new MemberEntity(null, group1, "mem1", "handle1", "expert")); + final var member2 = memberService.create(new MemberEntity(null, group1, "mem2", "handle2", "expert")); + final var member3 = memberService.create(new MemberEntity(null, group2,"mem3", "handle3", "expert")); + + } + } } diff --git a/demo/src/main/java/com/example/demo/Member.java b/demo/src/main/java/com/example/demo/Member.java deleted file mode 100644 index 5d3a9e3..0000000 --- a/demo/src/main/java/com/example/demo/Member.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.demo; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class Member { - private String name, handle; - private int groupId; - - @JsonCreator - public Member( - @JsonProperty(value = "name") String name, - @JsonProperty(value = "handle") String handle, - @JsonProperty(value = "groupId") int groupId ) { - this.name = name; - this.handle = handle; - this.groupId = groupId; - } - - public String getName(){ - return name; - } - - public String getHandle(){ - return handle; - } - - public int getGroupId(){ - return groupId; - } -} diff --git a/demo/src/main/java/com/example/demo/core/configuration/Constants.java b/demo/src/main/java/com/example/demo/core/configuration/Constants.java new file mode 100644 index 0000000..918cbf2 --- /dev/null +++ b/demo/src/main/java/com/example/demo/core/configuration/Constants.java @@ -0,0 +1,7 @@ +package com.example.demo.core.configuration; + +public class Constants { + public static final String API_URL = "/api/1.0"; + private Constants() { + } +} diff --git a/demo/src/main/java/com/example/demo/core/configuration/MapperConfiguration.java b/demo/src/main/java/com/example/demo/core/configuration/MapperConfiguration.java new file mode 100644 index 0000000..a5ad6f3 --- /dev/null +++ b/demo/src/main/java/com/example/demo/core/configuration/MapperConfiguration.java @@ -0,0 +1,13 @@ +package com.example.demo.core.configuration; + +import org.modelmapper.ModelMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MapperConfiguration { + @Bean + ModelMapper modelMapper() { + return new ModelMapper(); + } +} diff --git a/demo/src/main/java/com/example/demo/WebConfig.java b/demo/src/main/java/com/example/demo/core/configuration/WebConfiguration.java similarity index 80% rename from demo/src/main/java/com/example/demo/WebConfig.java rename to demo/src/main/java/com/example/demo/core/configuration/WebConfiguration.java index 058e1dd..762e85a 100644 --- a/demo/src/main/java/com/example/demo/WebConfig.java +++ b/demo/src/main/java/com/example/demo/core/configuration/WebConfiguration.java @@ -1,4 +1,4 @@ -package com.example.demo; +package com.example.demo.core.configuration; import org.springframework.context.annotation.Configuration; import org.springframework.lang.NonNull; @@ -6,10 +6,10 @@ import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration -public class WebConfig implements WebMvcConfigurer { +public class WebConfiguration implements WebMvcConfigurer { @Override public void addCorsMappings(@NonNull CorsRegistry registry) { registry.addMapping("/**") .allowedMethods("GET", "POST", "PUT", "DELETE"); } -} \ No newline at end of file +} diff --git a/demo/src/main/java/com/example/demo/core/error/NotFoundException.java b/demo/src/main/java/com/example/demo/core/error/NotFoundException.java new file mode 100644 index 0000000..586af3c --- /dev/null +++ b/demo/src/main/java/com/example/demo/core/error/NotFoundException.java @@ -0,0 +1,7 @@ +package com.example.demo.core.error; + +public class NotFoundException extends RuntimeException { + public NotFoundException(Long id) { + super(String.format("Entity with id [%s] is not found or not exists", id)); + } +} diff --git a/demo/src/main/java/com/example/demo/core/model/BaseEntity.java b/demo/src/main/java/com/example/demo/core/model/BaseEntity.java new file mode 100644 index 0000000..674ddfb --- /dev/null +++ b/demo/src/main/java/com/example/demo/core/model/BaseEntity.java @@ -0,0 +1,20 @@ +package com.example.demo.core.model; + +public abstract class BaseEntity { + protected Long id; + + protected BaseEntity() { + } + + protected BaseEntity(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/demo/src/main/java/com/example/demo/core/repository/CommonRepository.java b/demo/src/main/java/com/example/demo/core/repository/CommonRepository.java new file mode 100644 index 0000000..85e1e6d --- /dev/null +++ b/demo/src/main/java/com/example/demo/core/repository/CommonRepository.java @@ -0,0 +1,17 @@ +package com.example.demo.core.repository; + +import java.util.List; + +public interface CommonRepository { + List getAll(); + + E get(T id); + + E create(E entity); + + E update(E entity); + + E delete(E entity); + + void deleteAll(); +} diff --git a/demo/src/main/java/com/example/demo/core/repository/MapRepository.java b/demo/src/main/java/com/example/demo/core/repository/MapRepository.java new file mode 100644 index 0000000..163cafb --- /dev/null +++ b/demo/src/main/java/com/example/demo/core/repository/MapRepository.java @@ -0,0 +1,57 @@ +package com.example.demo.core.repository; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import com.example.demo.core.model.BaseEntity; + +public abstract class MapRepository implements CommonRepository { + private final Map entities = new TreeMap<>(); + private Long lastId = 0L; + + protected MapRepository() { + } + + @Override + public List getAll() { + return entities.values().stream().toList(); + } + + @Override + public E get(Long id) { + return entities.get(id); + } + + @Override + public E create(E entity) { + lastId++; + entity.setId(lastId); + entities.put(lastId, entity); + return entity; + } + + @Override + public E update(E entity) { + if (get(entity.getId()) == null) { + return null; + } + entities.put(entity.getId(), entity); + return entity; + } + + @Override + public E delete(E entity) { + if (get(entity.getId()) == null) { + return null; + } + entities.remove(entity.getId()); + return entity; + } + + @Override + public void deleteAll() { + lastId = 0L; + entities.clear(); + } +} \ No newline at end of file diff --git a/demo/src/main/java/com/example/demo/groups/api/GroupController.java b/demo/src/main/java/com/example/demo/groups/api/GroupController.java new file mode 100644 index 0000000..f3624ea --- /dev/null +++ b/demo/src/main/java/com/example/demo/groups/api/GroupController.java @@ -0,0 +1,71 @@ +package com.example.demo.groups.api; + +import java.util.List; + +import org.modelmapper.ModelMapper; +import org.springframework.boot.autoconfigure.security.SecurityProperties.User; +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.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.example.demo.core.configuration.Constants; +import com.example.demo.groups.model.GroupEntity; +import com.example.demo.groups.service.GroupService; +import com.example.demo.users.service.UserService; + +import jakarta.validation.Valid; + +@RestController +@RequestMapping(Constants.API_URL + "/group") +public class GroupController { + private final GroupService groupService; + private final UserService userService; + private final ModelMapper modelMapper; + + public GroupController(GroupService groupService, UserService userService, ModelMapper modelMapper) { + this.groupService = groupService; + this.userService = userService; + this.modelMapper = modelMapper; + } + + private GroupDto toDto(GroupEntity entity) { + return modelMapper.map(entity, GroupDto.class); + } + + private GroupEntity toEntity(GroupDto dto) { + final GroupEntity entity = modelMapper.map(dto, GroupEntity.class); + entity.setUser(userService.get(dto.getUserId())); + return entity; + } + + @GetMapping + public List getAll(@RequestParam(name = "userId", defaultValue = "0") Long userId) { + return groupService.getAll(userId).stream().map(this::toDto).toList(); + } + + @GetMapping("/{id}") + public GroupDto get(@PathVariable(name = "id") Long id) { + return toDto(groupService.get(id)); + } + + @PostMapping + public GroupDto create(@RequestBody @Valid GroupDto dto) { + return toDto(groupService.create(toEntity(dto))); + } + + @PutMapping("/{id}") + public GroupDto update(@PathVariable(name = "id") Long id, @RequestBody GroupDto dto) { + return toDto(groupService.update(id, toEntity(dto))); + } + + @DeleteMapping("/{id}") + public GroupDto delete(@PathVariable(name = "id") Long id) { + return toDto(groupService.delete(id)); + } +} diff --git a/demo/src/main/java/com/example/demo/groups/api/GroupDto.java b/demo/src/main/java/com/example/demo/groups/api/GroupDto.java new file mode 100644 index 0000000..afe811b --- /dev/null +++ b/demo/src/main/java/com/example/demo/groups/api/GroupDto.java @@ -0,0 +1,40 @@ +package com.example.demo.groups.api; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +public class GroupDto { + private Long id; + @NotNull + @Min(1) + private Long userId; + @NotNull + private String name; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/demo/src/main/java/com/example/demo/groups/model/GroupEntity.java b/demo/src/main/java/com/example/demo/groups/model/GroupEntity.java new file mode 100644 index 0000000..a554744 --- /dev/null +++ b/demo/src/main/java/com/example/demo/groups/model/GroupEntity.java @@ -0,0 +1,54 @@ +package com.example.demo.groups.model; + +import java.util.Objects; + +import com.example.demo.core.model.BaseEntity; +import com.example.demo.users.model.UserEntity; + +public class GroupEntity extends BaseEntity { + private UserEntity user; + private String name; + + public GroupEntity() { + super(); + } + + public GroupEntity(Long id, UserEntity user, String name) { + super(id); + this.user = user; + this.name = name; + } + + public UserEntity getUser() { + return user; + } + + public void setUser(UserEntity user) { + this.user = user; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return Objects.hash(id, name, user); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + final GroupEntity other = (GroupEntity) obj; + return Objects.equals(other.getId(), id) + && Objects.equals(other.getName(), name) + && Objects.equals(other.getUser(), user); + } +} diff --git a/demo/src/main/java/com/example/demo/groups/repository/GroupRepository.java b/demo/src/main/java/com/example/demo/groups/repository/GroupRepository.java new file mode 100644 index 0000000..3be9e0f --- /dev/null +++ b/demo/src/main/java/com/example/demo/groups/repository/GroupRepository.java @@ -0,0 +1,10 @@ +package com.example.demo.groups.repository; + +import org.springframework.stereotype.Repository; + +import com.example.demo.core.repository.MapRepository; +import com.example.demo.groups.model.GroupEntity; + +@Repository +public class GroupRepository extends MapRepository { +} diff --git a/demo/src/main/java/com/example/demo/groups/service/GroupService.java b/demo/src/main/java/com/example/demo/groups/service/GroupService.java new file mode 100644 index 0000000..4d06899 --- /dev/null +++ b/demo/src/main/java/com/example/demo/groups/service/GroupService.java @@ -0,0 +1,51 @@ +package com.example.demo.groups.service; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import com.example.demo.core.error.NotFoundException; +import com.example.demo.groups.model.GroupEntity; +import com.example.demo.groups.repository.GroupRepository; +import com.example.demo.users.model.UserEntity; + +@Service +public class GroupService { + private final GroupRepository repository; + + public GroupService(GroupRepository repository) { + this.repository = repository; + } + + public List getAll(Long userId) { + if (Objects.equals(userId, 0L)) { + return repository.getAll(); + } + return repository.getAll().stream() + .filter(item -> item.getUser().getId().equals(userId)) + .toList(); + } + + public GroupEntity get(Long id) { + return Optional.ofNullable(repository.get(id)) + .orElseThrow(() -> new NotFoundException(id)); + } + + public GroupEntity create(GroupEntity entity) { + return repository.create(entity); + } + + public GroupEntity update(Long id, GroupEntity entity) { + final GroupEntity existsEntity = get(id); + existsEntity.setName(entity.getName()); + existsEntity.setUser(entity.getUser()); + return repository.update(existsEntity); + } + + public GroupEntity delete(Long id) { + final GroupEntity existsEntity = get(id); + return repository.delete(existsEntity); + } +} diff --git a/demo/src/main/java/com/example/demo/members/api/MemberController.java b/demo/src/main/java/com/example/demo/members/api/MemberController.java new file mode 100644 index 0000000..0f4f76e --- /dev/null +++ b/demo/src/main/java/com/example/demo/members/api/MemberController.java @@ -0,0 +1,70 @@ +package com.example.demo.members.api; + +import java.util.List; + +import org.modelmapper.ModelMapper; +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.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.example.demo.core.configuration.Constants; +import com.example.demo.members.model.MemberEntity; +import com.example.demo.members.service.MemberService; +import com.example.demo.groups.service.GroupService; + +import jakarta.validation.Valid; + +@RestController +@RequestMapping(Constants.API_URL + "/member") +public class MemberController { + private final MemberService memberService; + private final GroupService groupService; + private final ModelMapper modelMapper; + + public MemberController(MemberService memberService, GroupService groupService, ModelMapper modelMapper) { + this.memberService = memberService; + this.groupService = groupService; + this.modelMapper = modelMapper; + } + + private MemberDto toDto(MemberEntity entity) { + return modelMapper.map(entity, MemberDto.class); + } + + private MemberEntity toEntity(MemberDto dto) { + final MemberEntity entity = modelMapper.map(dto, MemberEntity.class); + entity.setGroup(groupService.get(dto.getGroupId())); + return entity; + } + + @GetMapping + public List getAll(@RequestParam(name = "groupId", defaultValue = "0") Long groupId) { + return memberService.getAll(groupId).stream().map(this::toDto).toList(); + } + + @GetMapping("/{id}") + public MemberDto get(@PathVariable(name = "id") Long id) { + return toDto(memberService.get(id)); + } + + @PostMapping + public MemberDto create(@RequestBody @Valid MemberDto dto) { + return toDto(memberService.create(toEntity(dto))); + } + + @PutMapping("/{id}") + public MemberDto update(@PathVariable(name = "id") Long id, @RequestBody MemberDto dto) { + return toDto(memberService.update(id, toEntity(dto))); + } + + @DeleteMapping("/{id}") + public MemberDto delete(@PathVariable(name = "id") Long id) { + return toDto(memberService.delete(id)); + } +} diff --git a/demo/src/main/java/com/example/demo/members/api/MemberDto.java b/demo/src/main/java/com/example/demo/members/api/MemberDto.java new file mode 100644 index 0000000..625d5cc --- /dev/null +++ b/demo/src/main/java/com/example/demo/members/api/MemberDto.java @@ -0,0 +1,61 @@ +package com.example.demo.members.api; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +public class MemberDto { + private Long id; + @NotNull + @Min(1) + private Long groupId; + @NotNull + private String name; + @NotNull + private String handle; + @NotNull + private String rank; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getGroupId() { + return groupId; + } + + public void setGroupId(Long groupId) { + this.groupId = groupId; + } + + public String getHandle() { + return handle; + } + + public void setHandle(String handle) { + this.handle = handle; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRank() { + return rank; + } + + public void setRank(String rank) { + this.rank = rank; + } + +} diff --git a/demo/src/main/java/com/example/demo/members/model/MemberEntity.java b/demo/src/main/java/com/example/demo/members/model/MemberEntity.java new file mode 100644 index 0000000..d0e0a6d --- /dev/null +++ b/demo/src/main/java/com/example/demo/members/model/MemberEntity.java @@ -0,0 +1,74 @@ +package com.example.demo.members.model; + +import java.util.Objects; + +import com.example.demo.core.model.BaseEntity; +import com.example.demo.groups.model.GroupEntity; + +public class MemberEntity extends BaseEntity { + private GroupEntity group; + private String name, handle, rank; + + public MemberEntity() { + super(); + } + + public MemberEntity(Long id, GroupEntity group, String name, String handle, String rank) { + super(id); + this.group = group; + this.name = name; + this.handle = handle; + this.rank = rank; + } + + public GroupEntity getGroup() { + return group; + } + + public void setGroup(GroupEntity group) { + this.group = group; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHandle() { + return handle; + } + + public void setHandle(String handle) { + this.handle = handle; + } + + public String getRank() { + return rank; + } + + public void setRank(String rank) { + this.rank = rank; + } + + @Override + public int hashCode() { + return Objects.hash(id, group, name, handle, rank); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + final MemberEntity other = (MemberEntity) obj; + return Objects.equals(other.getId(), id) + && Objects.equals(other.getGroup(), group) + && Objects.equals(other.getName(), name) + && Objects.equals(other.getHandle(), handle) + && Objects.equals(other.getRank(), rank); + } +} \ No newline at end of file diff --git a/demo/src/main/java/com/example/demo/members/repository/MemberRepository.java b/demo/src/main/java/com/example/demo/members/repository/MemberRepository.java new file mode 100644 index 0000000..8bdb143 --- /dev/null +++ b/demo/src/main/java/com/example/demo/members/repository/MemberRepository.java @@ -0,0 +1,10 @@ +package com.example.demo.members.repository; + +import org.springframework.stereotype.Repository; + +import com.example.demo.core.repository.MapRepository; +import com.example.demo.members.model.MemberEntity; + +@Repository +public class MemberRepository extends MapRepository { +} diff --git a/demo/src/main/java/com/example/demo/members/service/MemberService.java b/demo/src/main/java/com/example/demo/members/service/MemberService.java new file mode 100644 index 0000000..5443d30 --- /dev/null +++ b/demo/src/main/java/com/example/demo/members/service/MemberService.java @@ -0,0 +1,52 @@ +package com.example.demo.members.service; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import com.example.demo.core.error.NotFoundException; +import com.example.demo.members.model.MemberEntity; +import com.example.demo.members.repository.MemberRepository; + +@Service +public class MemberService { + private final MemberRepository repository; + + public MemberService(MemberRepository repository) { + this.repository = repository; + } + + public List getAll(Long groupId) { + if (Objects.equals(groupId, 0L)) { + return repository.getAll(); + } + return repository.getAll().stream() + .filter(item -> item.getGroup().getId().equals(groupId)) + .toList(); + } + + public MemberEntity get(Long id) { + return Optional.ofNullable(repository.get(id)) + .orElseThrow(() -> new NotFoundException(id)); + } + + public MemberEntity create(MemberEntity entity) { + return repository.create(entity); + } + + public MemberEntity update(Long id, MemberEntity entity) { + final MemberEntity existsEntity = get(id); + existsEntity.setGroup(entity.getGroup()); + existsEntity.setName(entity.getName()); + existsEntity.setHandle(entity.getHandle()); + existsEntity.setRank(entity.getRank()); + return repository.update(existsEntity); + } + + public MemberEntity delete(Long id) { + final MemberEntity existsEntity = get(id); + return repository.delete(existsEntity); + } +} diff --git a/demo/src/main/java/com/example/demo/users/api/UserController.java b/demo/src/main/java/com/example/demo/users/api/UserController.java new file mode 100644 index 0000000..1d00e35 --- /dev/null +++ b/demo/src/main/java/com/example/demo/users/api/UserController.java @@ -0,0 +1,64 @@ +package com.example.demo.users.api; + +import java.util.List; + +import org.modelmapper.ModelMapper; +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.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.example.demo.core.configuration.Constants; +import com.example.demo.users.model.UserEntity; +import com.example.demo.users.service.UserService; + +import jakarta.validation.Valid; + +@RestController +@RequestMapping(Constants.API_URL + "/user") +public class UserController { + private final UserService userService; + private final ModelMapper modelMapper; + + public UserController(UserService userService, ModelMapper modelMapper) { + this.userService = userService; + this.modelMapper = modelMapper; + } + + private UserDto toDto(UserEntity entity) { + return modelMapper.map(entity, UserDto.class); + } + + private UserEntity toEntity(UserDto dto) { + return modelMapper.map(dto, UserEntity.class); + } + + @GetMapping + public List getAll() { + return userService.getAll().stream().map(this::toDto).toList(); + } + + @GetMapping("/{id}") + public UserDto get(@PathVariable(name = "id") Long id) { + return toDto(userService.get(id)); + } + + @PostMapping + public UserDto create(@RequestBody @Valid UserDto dto) { + return toDto(userService.create(toEntity(dto))); + } + + @PutMapping("/{id}") + public UserDto update(@PathVariable(name = "id") Long id, @RequestBody UserDto dto) { + return toDto(userService.update(id, toEntity(dto))); + } + + @DeleteMapping("/{id}") + public UserDto delete(@PathVariable(name = "id") Long id) { + return toDto(userService.delete(id)); + } +} diff --git a/demo/src/main/java/com/example/demo/users/api/UserDto.java b/demo/src/main/java/com/example/demo/users/api/UserDto.java new file mode 100644 index 0000000..8ce8172 --- /dev/null +++ b/demo/src/main/java/com/example/demo/users/api/UserDto.java @@ -0,0 +1,49 @@ +package com.example.demo.users.api; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +public class UserDto { + private Long id; + @NotNull + private String handle; + @NotNull + private String email; + @NotNull + private String password; + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getHandle() { + return handle; + } + + public void setHandle(String handle) { + this.handle = handle; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/demo/src/main/java/com/example/demo/users/model/UserEntity.java b/demo/src/main/java/com/example/demo/users/model/UserEntity.java new file mode 100644 index 0000000..3a1ee38 --- /dev/null +++ b/demo/src/main/java/com/example/demo/users/model/UserEntity.java @@ -0,0 +1,65 @@ +package com.example.demo.users.model; +import java.util.Objects; + + +import com.example.demo.core.model.BaseEntity; + +import jakarta.validation.OverridesAttribute; + +public class UserEntity extends BaseEntity{ + private String handle, email, password; + + public UserEntity(){ + super(); + } + + public UserEntity(Long id, String handle, String email, String password) { + super(id); + this.handle = handle; + this.email = email; + this.password = password; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getHandle() { + return handle; + } + + public void setHandle(String handle) { + this.handle = handle; + } + + @Override + public int hashCode() { + return Objects.hash(id, handle, email, password); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + final UserEntity other = (UserEntity) obj; + return Objects.equals(other.getId(), id) + && Objects.equals(other.getHandle(), handle) + && Objects.equals(other.getEmail(), email) + && Objects.equals(other.getPassword(), password); + } + +} diff --git a/demo/src/main/java/com/example/demo/users/repository/UserRepository.java b/demo/src/main/java/com/example/demo/users/repository/UserRepository.java new file mode 100644 index 0000000..fa4b654 --- /dev/null +++ b/demo/src/main/java/com/example/demo/users/repository/UserRepository.java @@ -0,0 +1,10 @@ +package com.example.demo.users.repository; + +import org.springframework.stereotype.Repository; + +import com.example.demo.core.repository.MapRepository; +import com.example.demo.users.model.UserEntity; + +@Repository +public class UserRepository extends MapRepository { +} diff --git a/demo/src/main/java/com/example/demo/users/service/UserService.java b/demo/src/main/java/com/example/demo/users/service/UserService.java new file mode 100644 index 0000000..44559bc --- /dev/null +++ b/demo/src/main/java/com/example/demo/users/service/UserService.java @@ -0,0 +1,46 @@ +package com.example.demo.users.service; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import com.example.demo.core.error.NotFoundException; +import com.example.demo.users.model.UserEntity; +import com.example.demo.users.repository.UserRepository; + +@Service +public class UserService { + private final UserRepository repository; + + public UserService(UserRepository repository) { + this.repository = repository; + } + + public List getAll() { + return repository.getAll(); + } + + public UserEntity get(Long id) { + return Optional.ofNullable(repository.get(id)) + .orElseThrow(() -> new NotFoundException(id)); + } + + public UserEntity create(UserEntity entity) { + return repository.create(entity); + } + + public UserEntity update(Long id, UserEntity entity) { + final UserEntity existsEntity = get(id); + existsEntity.setEmail(entity.getEmail()); + existsEntity.setHandle(entity.getHandle()); + existsEntity.setPassword(entity.getPassword()); + return repository.update(existsEntity); + } + + public UserEntity delete(Long id) { + final UserEntity existsEntity = get(id); + return repository.delete(existsEntity); + } +}