diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 87c782b044..e6866b5a8f 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -162,6 +162,12 @@ javax.validation validation-api + + + org.modelmapper + modelmapper + ${modelmapper.version} + @@ -259,6 +265,7 @@ 5.2.4 18.0 2.2.4 + 2.3.2 diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java b/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java new file mode 100644 index 0000000000..7684c43648 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java @@ -0,0 +1,20 @@ +package com.baeldung.modelmapper; + +import org.modelmapper.ModelMapper; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class PostApplication { + + public static void main(String[] args) { + SpringApplication.run(PostApplication.class, args); + } + + @Bean + public ModelMapper modelMapper() { + return new ModelMapper(); + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java b/spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java new file mode 100644 index 0000000000..c0cbca5220 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java @@ -0,0 +1,91 @@ +package com.baeldung.modelmapper.controller; + +import java.text.ParseException; +import java.util.List; +import java.util.stream.Collectors; + +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.baeldung.modelmapper.dto.PostDto; +import com.baeldung.modelmapper.model.Post; +import com.baeldung.modelmapper.service.IPostService; +import com.baeldung.modelmapper.service.IUserService; + +@Controller +public class PostRestController { + + @Autowired + private IPostService postService; + + @Autowired + private IUserService userService; + + @Autowired + private ModelMapper modelMapper; + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public List getPosts( + @PathVariable("page") int page, + @PathVariable("size") int size, + @PathVariable("sortDir") String sortDir, + @PathVariable("sort") String sort) { + + List posts = postService.getPostsList(page, size, sortDir, sort); + return posts.stream() + .map(post -> convertToDto(post)) + .collect(Collectors.toList()); + } + + @RequestMapping(method = RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + @ResponseBody + public PostDto createPost(@RequestBody PostDto postDto) throws ParseException { + Post post = convertToEntity(postDto); + Post postCreated = postService.createPost(post); + return convertToDto(postCreated); + } + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + @ResponseBody + public PostDto getPost(@PathVariable("id") Long id) { + return convertToDto(postService.getPostById(id)); + } + + @RequestMapping(value = "/{id}", method = RequestMethod.PUT) + @ResponseStatus(HttpStatus.OK) + public void updatePost(@RequestBody PostDto postDto) throws ParseException { + Post post = convertToEntity(postDto); + postService.updatePost(post); + } + + + private PostDto convertToDto(Post post) { + PostDto postDto = modelMapper.map(post, PostDto.class); + postDto.setSubmissionDate(post.getSubmissionDate(), + userService.getCurrentUser().getPreference().getTimezone()); + return postDto; + } + + private Post convertToEntity(PostDto postDto) throws ParseException { + Post post = modelMapper.map(postDto, Post.class); + post.setSubmissionDate(postDto.getSubmissionDateConverted( + userService.getCurrentUser().getPreference().getTimezone())); + + if (postDto.getId() != null) { + Post oldPost = postService.getPostById(postDto.getId()); + post.setRedditID(oldPost.getRedditID()); + post.setSent(oldPost.isSent()); + } + return post; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/dto/PostDto.java b/spring-boot/src/main/java/com/baeldung/modelmapper/dto/PostDto.java new file mode 100644 index 0000000000..6fe2b23888 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/dto/PostDto.java @@ -0,0 +1,71 @@ +package com.baeldung.modelmapper.dto; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class PostDto { + + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + + private Long id; + + private String title; + + private String url; + + private String date; + + private UserDto user; + + public Date getSubmissionDateConverted(String timezone) throws ParseException { + dateFormat.setTimeZone(TimeZone.getTimeZone(timezone)); + return dateFormat.parse(this.date); + } + + public void setSubmissionDate(Date date, String timezone) { + dateFormat.setTimeZone(TimeZone.getTimeZone(timezone)); + this.date = dateFormat.format(date); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public UserDto getUser() { + return user; + } + + public void setUser(UserDto user) { + this.user = user; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/dto/UserDto.java b/spring-boot/src/main/java/com/baeldung/modelmapper/dto/UserDto.java new file mode 100644 index 0000000000..23110ecbaa --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/dto/UserDto.java @@ -0,0 +1,14 @@ +package com.baeldung.modelmapper.dto; + +public class UserDto { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/Post.java b/spring-boot/src/main/java/com/baeldung/modelmapper/model/Post.java new file mode 100644 index 0000000000..be65ce34a2 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/model/Post.java @@ -0,0 +1,98 @@ +package com.baeldung.modelmapper.model; + +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Post { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String title; + + private String url; + + private String date; + + private String redditID; + + private Date submissionDate; + + private boolean sent; + + private String userName; + + public Post() { + + } + + public boolean isSent() { + return sent; + } + + public void setSent(boolean sent) { + this.sent = sent; + } + + public String getRedditID() { + return redditID; + } + + public void setRedditID(String redditID) { + this.redditID = redditID; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public Date getSubmissionDate() { + return submissionDate; + } + + public void setSubmissionDate(Date submissionDate) { + this.submissionDate = submissionDate; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/Preference.java b/spring-boot/src/main/java/com/baeldung/modelmapper/model/Preference.java new file mode 100644 index 0000000000..0ab5b1eddf --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/model/Preference.java @@ -0,0 +1,32 @@ +package com.baeldung.modelmapper.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Preference { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String timezone; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/User.java b/spring-boot/src/main/java/com/baeldung/modelmapper/model/User.java new file mode 100644 index 0000000000..a458b26f4a --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/model/User.java @@ -0,0 +1,44 @@ +package com.baeldung.modelmapper.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Entity +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + @OneToOne + Preference preference; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Preference getPreference() { + return preference; + } + + public void setPreference(Preference preference) { + this.preference = preference; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java b/spring-boot/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java new file mode 100644 index 0000000000..fc3f5733c3 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java @@ -0,0 +1,21 @@ +package com.baeldung.modelmapper.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; + +import com.baeldung.modelmapper.model.Post; +import com.baeldung.modelmapper.model.User; + +public interface PostRepository extends JpaRepository, PagingAndSortingRepository { + + @Query("select u from Post u where u.userName=:userName") + Page findByUser(@Param("userName") String userName, Pageable pageReq); + + default Page findByUser(User user, Pageable pageReq) { + return findByUser(user.getName(), pageReq); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/IPostService.java b/spring-boot/src/main/java/com/baeldung/modelmapper/service/IPostService.java new file mode 100644 index 0000000000..0182a0da41 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/service/IPostService.java @@ -0,0 +1,17 @@ +package com.baeldung.modelmapper.service; + +import java.util.List; + +import com.baeldung.modelmapper.model.Post; + +public interface IPostService { + + List getPostsList(int page, int size, String sortDir, String sort); + + void updatePost(Post post); + + Post createPost(Post post); + + Post getPostById(Long id); + +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/IUserService.java b/spring-boot/src/main/java/com/baeldung/modelmapper/service/IUserService.java new file mode 100644 index 0000000000..79934114c1 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/service/IUserService.java @@ -0,0 +1,9 @@ +package com.baeldung.modelmapper.service; + +import com.baeldung.modelmapper.model.User; + +public interface IUserService { + + User getCurrentUser(); + +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/PostService.java b/spring-boot/src/main/java/com/baeldung/modelmapper/service/PostService.java new file mode 100644 index 0000000000..5980c30837 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/service/PostService.java @@ -0,0 +1,47 @@ +package com.baeldung.modelmapper.service; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; + +import com.baeldung.modelmapper.model.Post; +import com.baeldung.modelmapper.repository.PostRepository; + +@Service +public class PostService implements IPostService { + + @Autowired + private PostRepository postRepository; + + @Autowired + private IUserService userService; + + @Override + public List getPostsList(int page, int size, String sortDir, String sort) { + + PageRequest pageReq + = PageRequest.of(page, size, Sort.Direction.fromString(sortDir), sort); + + Page posts = postRepository.findByUser(userService.getCurrentUser(), pageReq); + return posts.getContent(); + } + + @Override + public void updatePost(Post post) { + postRepository.save(post); + } + + @Override + public Post createPost(Post post) { + return postRepository.save(post); + } + + @Override + public Post getPostById(Long id) { + return postRepository.getOne(id); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/UserService.java b/spring-boot/src/main/java/com/baeldung/modelmapper/service/UserService.java new file mode 100644 index 0000000000..e445f836a4 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/modelmapper/service/UserService.java @@ -0,0 +1,25 @@ +package com.baeldung.modelmapper.service; + +import org.springframework.stereotype.Service; + +import com.baeldung.modelmapper.model.Preference; +import com.baeldung.modelmapper.model.User; + +@Service +public class UserService implements IUserService { + + @Override + public User getCurrentUser() { + + Preference preference = new Preference(); + preference.setId(1L); + preference.setTimezone("Asia/Calcutta"); + + User user = new User(); + user.setId(1L); + user.setName("Micheal"); + user.setPreference(preference); + + return user; + } +} \ No newline at end of file diff --git a/spring-boot/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java b/spring-boot/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java new file mode 100644 index 0000000000..34ec4db783 --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.modelmapper; + +import static org.junit.Assert.assertEquals; +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import org.junit.Test; +import org.modelmapper.ModelMapper; + +import com.baeldung.modelmapper.dto.PostDto; +import com.baeldung.modelmapper.model.Post; + +public class PostDtoUnitTest { + + private ModelMapper modelMapper = new ModelMapper(); + + @Test + public void whenConvertPostEntityToPostDto_thenCorrect() { + Post post = new Post(); + post.setId(Long.valueOf(1)); + post.setTitle(randomAlphabetic(6)); + post.setUrl("www.test.com"); + + PostDto postDto = modelMapper.map(post, PostDto.class); + assertEquals(post.getId(), postDto.getId()); + assertEquals(post.getTitle(), postDto.getTitle()); + assertEquals(post.getUrl(), postDto.getUrl()); + } + + @Test + public void whenConvertPostDtoToPostEntity_thenCorrect() { + PostDto postDto = new PostDto(); + postDto.setId(Long.valueOf(1)); + postDto.setTitle(randomAlphabetic(6)); + postDto.setUrl("www.test.com"); + + Post post = modelMapper.map(postDto, Post.class); + assertEquals(postDto.getId(), post.getId()); + assertEquals(postDto.getTitle(), post.getTitle()); + assertEquals(postDto.getUrl(), post.getUrl()); + } +} \ No newline at end of file