1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package de.kaiserpfalzedv.commons.core.resources;
19
20 import org.eclipse.microprofile.openapi.annotations.media.Schema;
21
22 import com.fasterxml.jackson.annotation.JsonIgnore;
23 import com.fasterxml.jackson.annotation.JsonInclude;
24
25 import de.kaiserpfalzedv.commons.api.resources.Paging;
26 import lombok.AllArgsConstructor;
27 import lombok.Builder;
28 import lombok.EqualsAndHashCode;
29 import lombok.Getter;
30 import lombok.ToString;
31 import lombok.extern.jackson.Jacksonized;
32
33
34
35
36
37
38
39 @Schema(
40 description = "Paging data including calculating next/previous and first/last pages available.",
41 example = "{\n" +
42 " \"start\": 0, \n" +
43 " \"size\": 100, \n" +
44 " \"count\": 83, \n" +
45 " \"total\": 83,\n" +
46 "}",
47 title = "Pagination data for transfer lists"
48 )
49 @Jacksonized
50 @JsonInclude(JsonInclude.Include.NON_ABSENT)
51 @Builder(toBuilder = true)
52 @AllArgsConstructor
53 @Getter
54 @ToString
55 @EqualsAndHashCode
56 public class PagingImpl implements Paging {
57 private static final long serialVersionUID = 0L;
58
59 @Builder.Default
60 private final long start = 0;
61
62 @Builder.Default
63 private final long size = 20;
64
65 private final long count;
66
67 private final long total;
68
69 @Override
70 @JsonIgnore
71 @Schema(hidden = true)
72 public Paging firstPage() {
73 return this.toBuilder()
74 .start(0)
75 .count(this.calculatePageSize(0))
76 .build();
77 }
78
79 @Override
80 @JsonIgnore
81 @Schema(hidden = true)
82 public Paging previousPage() {
83 if (this.start - this.size <= 0) {
84 return this.firstPage();
85 }
86
87 return this.toBuilder()
88 .start(this.start - this.size)
89 .count(this.calculatePageSize(this.start - this.size))
90 .build();
91 }
92
93 @Override
94 @JsonIgnore
95 @Schema(hidden = true)
96 public Paging nextPage() {
97 return this.calculateNextPage(this.start + this.size);
98 }
99
100 @Override
101 @JsonIgnore
102 @Schema(hidden = true)
103 public Paging lastPage() {
104 return this.calculateNextPage(this.total / this.size * this.size);
105 }
106
107 private long calculatePageSize(final long start) {
108 if (start >= this.total) {
109 return 0;
110 }
111
112 if (start + this.size >= this.total) {
113 return this.total - start;
114 }
115
116 return this.size;
117 }
118
119 private Paging calculateNextPage(final long start) {
120 return this.toBuilder()
121 .start(start)
122 .count(this.calculatePageSize(start))
123 .build();
124 }
125 }