1 /*
2  * Copyright 2014-2020 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      https://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.springframework.data.domain;
17
18 import lombok.Getter;
19
20 import java.io.Serializable;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.function.Function;
26 import java.util.stream.Collectors;
27
28 import org.springframework.lang.Nullable;
29 import org.springframework.util.Assert;
30
31 /**
32  * A chunk of data restricted by the configured {@link Pageable}.
33  *
34  * @author Oliver Gierke
35  * @author Christoph Strobl
36  * @since 1.8
37  */

38 abstract class Chunk<T> implements Slice<T>, Serializable {
39
40     private static final long serialVersionUID = 867755909294344406L;
41
42     private final List<T> content = new ArrayList<>();
43     private final @Getter Pageable pageable;
44
45     /**
46      * Creates a new {@link Chunk} with the given content and the given governing {@link Pageable}.
47      *
48      * @param content must not be {@literal null}.
49      * @param pageable must not be {@literal null}.
50      */

51     public Chunk(List<T> content, Pageable pageable) {
52
53         Assert.notNull(content, "Content must not be null!");
54         Assert.notNull(pageable, "Pageable must not be null!");
55
56         this.content.addAll(content);
57         this.pageable = pageable;
58     }
59
60     /*
61      * (non-Javadoc)
62      * @see org.springframework.data.domain.Slice#getNumber()
63      */

64     public int getNumber() {
65         return pageable.isPaged() ? pageable.getPageNumber() : 0;
66     }
67
68     /*
69      * (non-Javadoc)
70      * @see org.springframework.data.domain.Slice#getSize()
71      */

72     public int getSize() {
73         return pageable.isPaged() ? pageable.getPageSize() : content.size();
74     }
75
76     /*
77      * (non-Javadoc)
78      * @see org.springframework.data.domain.Slice#getNumberOfElements()
79      */

80     public int getNumberOfElements() {
81         return content.size();
82     }
83
84     /*
85      * (non-Javadoc)
86      * @see org.springframework.data.domain.Slice#hasPrevious()
87      */

88     public boolean hasPrevious() {
89         return getNumber() > 0;
90     }
91
92     /*
93      * (non-Javadoc)
94      * @see org.springframework.data.domain.Slice#isFirst()
95      */

96     public boolean isFirst() {
97         return !hasPrevious();
98     }
99
100     /*
101      * (non-Javadoc)
102      * @see org.springframework.data.domain.Slice#isLast()
103      */

104     public boolean isLast() {
105         return !hasNext();
106     }
107
108     /*
109      * (non-Javadoc)
110      * @see org.springframework.data.domain.Slice#nextPageable()
111      */

112     public Pageable nextPageable() {
113         return hasNext() ? pageable.next() : Pageable.unpaged();
114     }
115
116     /*
117      * (non-Javadoc)
118      * @see org.springframework.data.domain.Slice#previousPageable()
119      */

120     public Pageable previousPageable() {
121         return hasPrevious() ? pageable.previousOrFirst() : Pageable.unpaged();
122     }
123
124     /*
125      * (non-Javadoc)
126      * @see org.springframework.data.domain.Slice#hasContent()
127      */

128     public boolean hasContent() {
129         return !content.isEmpty();
130     }
131
132     /*
133      * (non-Javadoc)
134      * @see org.springframework.data.domain.Slice#getContent()
135      */

136     public List<T> getContent() {
137         return Collections.unmodifiableList(content);
138     }
139
140     /*
141      * (non-Javadoc)
142      * @see org.springframework.data.domain.Slice#getSort()
143      */

144     @Override
145     public Sort getSort() {
146         return pageable.getSort();
147     }
148
149     /*
150      * (non-Javadoc)
151      * @see java.lang.Iterable#iterator()
152      */

153     public Iterator<T> iterator() {
154         return content.iterator();
155     }
156
157     /**
158      * Applies the given {@link Function} to the content of the {@link Chunk}.
159      *
160      * @param converter must not be {@literal null}.
161      * @return
162      */

163     protected <U> List<U> getConvertedContent(Function<? super T, ? extends U> converter) {
164
165         Assert.notNull(converter, "Function must not be null!");
166
167         return this.stream().map(converter::apply).collect(Collectors.toList());
168     }
169
170     /*
171      * (non-Javadoc)
172      * @see java.lang.Object#equals(java.lang.Object)
173      */

174     @Override
175     public boolean equals(@Nullable Object obj) {
176
177         if (this == obj) {
178             return true;
179         }
180
181         if (!(obj instanceof Chunk<?>)) {
182             return false;
183         }
184
185         Chunk<?> that = (Chunk<?>) obj;
186
187         boolean contentEqual = this.content.equals(that.content);
188         boolean pageableEqual = this.pageable.equals(that.pageable);
189
190         return contentEqual && pageableEqual;
191     }
192
193     /*
194      * (non-Javadoc)
195      * @see java.lang.Object#hashCode()
196      */

197     @Override
198     public int hashCode() {
199
200         int result = 17;
201
202         result += 31 * pageable.hashCode();
203         result += 31 * content.hashCode();
204
205         return result;
206     }
207 }
208