diff --git a/data/db.mv.db b/data/db.mv.db index d6e4cd9..06af13a 100644 Binary files a/data/db.mv.db and b/data/db.mv.db differ diff --git a/src/main/java/ru/ulstu/controller/NewsController.java b/src/main/java/ru/ulstu/controller/NewsController.java index 111a1ca..34e8ba3 100644 --- a/src/main/java/ru/ulstu/controller/NewsController.java +++ b/src/main/java/ru/ulstu/controller/NewsController.java @@ -6,6 +6,7 @@ package ru.ulstu.controller; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -14,14 +15,21 @@ import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import ru.ulstu.model.News; +import ru.ulstu.model.OffsetablePageRequest; import ru.ulstu.service.NewsService; import javax.validation.Valid; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; @Controller @RequestMapping("news") public class NewsController { + private final static int DEFAULT_PAGE_SIZE = 10; private final NewsService newsService; public NewsController(NewsService newsService) { @@ -29,8 +37,21 @@ public class NewsController { } @GetMapping("/news") - public String index(Model model) { - model.addAttribute("news", newsService.getAll()); + public String listNews(Model model, + @RequestParam Optional page, + @RequestParam Optional size) { + int currentPage = page.orElse(1); + int pageSize = size.orElse(DEFAULT_PAGE_SIZE); + + Page newsPage = newsService.getNews(new OffsetablePageRequest(currentPage - 1, pageSize)); + model.addAttribute("news", newsPage); + int totalPages = newsPage.getTotalPages(); + if (totalPages > 0) { + List pageNumbers = IntStream.rangeClosed(1, totalPages) + .boxed() + .collect(Collectors.toList()); + model.addAttribute("pageNumbers", pageNumbers); + } return "news"; } diff --git a/src/main/java/ru/ulstu/model/OffsetablePageRequest.java b/src/main/java/ru/ulstu/model/OffsetablePageRequest.java new file mode 100644 index 0000000..c715296 --- /dev/null +++ b/src/main/java/ru/ulstu/model/OffsetablePageRequest.java @@ -0,0 +1,93 @@ +package ru.ulstu.model; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +import java.io.Serializable; + +public class OffsetablePageRequest implements Pageable, Serializable { + private final int offset; + private final int count; + private final Sort sort; + + public OffsetablePageRequest(int page, long pageSize) { + this(pageSize * page, pageSize, Sort.by("id")); + } + + public OffsetablePageRequest(long offset, long count, Sort sort) { + if (offset < 0) { + throw new IllegalArgumentException("Offset value must not be less than zero!"); + } + if (count < 1) { + throw new IllegalArgumentException("Count value must not be less than one!"); + } + this.offset = (int) offset; + this.count = (int) count; + this.sort = sort; + } + + @Override + public Sort getSort() { + return sort; + } + + @Override + public int getPageSize() { + return count; + } + + @Override + public int getPageNumber() { + return offset / count; + } + + @Override + public long getOffset() { + return offset; + } + + @Override + public boolean hasPrevious() { + return offset > 0; + } + + @Override + public Pageable next() { + return new OffsetablePageRequest(getOffset() + getPageSize(), getPageSize(), getSort()); + } + + @Override + public Pageable previousOrFirst() { + return hasPrevious() ? previous() : first(); + } + + public Pageable previous() { + return getOffset() == 0 ? this : new OffsetablePageRequest(getOffset() - getPageSize(), getPageSize(), getSort()); + } + + @Override + public Pageable first() { + return new OffsetablePageRequest(0, getPageSize(), getSort()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final OffsetablePageRequest other = (OffsetablePageRequest) obj; + return this.offset == other.offset && this.count == other.count; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + offset; + result = prime * result + count; + return result; + } +} diff --git a/src/main/java/ru/ulstu/repository/NewsRepository.java b/src/main/java/ru/ulstu/repository/NewsRepository.java index 6bd607a..f7f4fcf 100644 --- a/src/main/java/ru/ulstu/repository/NewsRepository.java +++ b/src/main/java/ru/ulstu/repository/NewsRepository.java @@ -1,5 +1,7 @@ package ru.ulstu.repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import ru.ulstu.model.News; @@ -7,4 +9,6 @@ import java.util.List; public interface NewsRepository extends JpaRepository { List findFirst3ByOrderByDateDesc(); + + Page findByOrderByDateDesc(Pageable pageable); } diff --git a/src/main/java/ru/ulstu/service/NewsService.java b/src/main/java/ru/ulstu/service/NewsService.java index 3f743f0..f49dbdd 100644 --- a/src/main/java/ru/ulstu/service/NewsService.java +++ b/src/main/java/ru/ulstu/service/NewsService.java @@ -1,5 +1,7 @@ package ru.ulstu.service; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import ru.ulstu.model.News; import ru.ulstu.repository.NewsRepository; @@ -50,4 +52,8 @@ public class NewsService { public List getLast() { return newsRepository.findFirst3ByOrderByDateDesc(); } + + public Page getNews(Pageable pageable) { + return newsRepository.findByOrderByDateDesc(pageable); + } } diff --git a/src/main/resources/public/css/main.css b/src/main/resources/public/css/main.css index 9b299ad..bbdc26e 100644 --- a/src/main/resources/public/css/main.css +++ b/src/main/resources/public/css/main.css @@ -31,4 +31,25 @@ .link-dark, .link-dark:visited, .link-dark:focus, .link-dark:any-link { color: black; -} \ No newline at end of file +} + +.pagination { + display: inline-block; +} + +.pagination a { + color: black; + float: left; + padding: 5px 5px; + text-decoration: none; +} + +.pagination a.active { + background-color: gray; + color: white; + border-radius: 2px; +} + +footer { + height: 50px; +} diff --git a/src/main/resources/templates/admin.html b/src/main/resources/templates/admin.html index f37ada4..22e05cf 100644 --- a/src/main/resources/templates/admin.html +++ b/src/main/resources/templates/admin.html @@ -7,7 +7,7 @@ diff --git a/src/main/resources/templates/default.html b/src/main/resources/templates/default.html index 3146bbf..99f7ed0 100644 --- a/src/main/resources/templates/default.html +++ b/src/main/resources/templates/default.html @@ -64,6 +64,7 @@
+
\ No newline at end of file diff --git a/src/main/resources/templates/news.html b/src/main/resources/templates/news.html index 1f6edf8..3b444e5 100644 --- a/src/main/resources/templates/news.html +++ b/src/main/resources/templates/news.html @@ -36,5 +36,15 @@ class="news-date">
+ + +