Skip to content

Commit 6572880

Browse files
committed
DATACMNS-1820 - Moves PageabeExecutionUtils to o.s.data.support.
This avoids module cycles when it is used from a template. The old version is still there, deprecated and delegates to the new version. Original pull request: #472.
1 parent 0902fe8 commit 6572880

File tree

3 files changed

+192
-21
lines changed

3 files changed

+192
-21
lines changed

src/main/java/org/springframework/data/repository/support/PageableExecutionUtils.java

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
import java.util.function.LongSupplier;
2020

2121
import org.springframework.data.domain.Page;
22-
import org.springframework.data.domain.PageImpl;
2322
import org.springframework.data.domain.Pageable;
24-
import org.springframework.util.Assert;
2523

2624
/**
2725
* Support for query execution using {@link Pageable}. Using {@link PageableExecutionUtils} assumes that data queries
@@ -30,8 +28,11 @@
3028
* @author Mark Paluch
3129
* @author Oliver Gierke
3230
* @author Christoph Strobl
31+
* @author Jens Schauder
3332
* @since 1.13
33+
* @deprecated since 2.4. Use {@link org.springframework.data.support.PageableExecutionUtils} instead
3434
*/
35+
@Deprecated
3536
public abstract class PageableExecutionUtils {
3637

3738
private PageableExecutionUtils() {}
@@ -47,24 +48,6 @@ private PageableExecutionUtils() {}
4748
* @return the {@link Page}.
4849
*/
4950
public static <T> Page<T> getPage(List<T> content, Pageable pageable, LongSupplier totalSupplier) {
50-
51-
Assert.notNull(content, "Content must not be null!");
52-
Assert.notNull(pageable, "Pageable must not be null!");
53-
Assert.notNull(totalSupplier, "TotalSupplier must not be null!");
54-
55-
if (pageable.isUnpaged() || pageable.getOffset() == 0) {
56-
57-
if (pageable.isUnpaged() || pageable.getPageSize() > content.size()) {
58-
return new PageImpl<>(content, pageable, content.size());
59-
}
60-
61-
return new PageImpl<>(content, pageable, totalSupplier.getAsLong());
62-
}
63-
64-
if (content.size() != 0 && pageable.getPageSize() > content.size()) {
65-
return new PageImpl<>(content, pageable, pageable.getOffset() + content.size());
66-
}
67-
68-
return new PageImpl<>(content, pageable, totalSupplier.getAsLong());
51+
return org.springframework.data.support.PageableExecutionUtils.getPage(content, pageable, totalSupplier);
6952
}
7053
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 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.support;
17+
18+
import java.util.List;
19+
import java.util.function.LongSupplier;
20+
21+
import org.springframework.data.domain.Page;
22+
import org.springframework.data.domain.PageImpl;
23+
import org.springframework.data.domain.Pageable;
24+
import org.springframework.util.Assert;
25+
26+
/**
27+
* Support for query execution using {@link Pageable}. Using {@link PageableExecutionUtils} assumes that data queries
28+
* are cheaper than {@code COUNT} queries and so some cases can take advantage of optimizations.
29+
*
30+
* @author Mark Paluch
31+
* @author Oliver Gierke
32+
* @author Christoph Strobl
33+
* @author Jens Schauder
34+
* @since 2.4
35+
*/
36+
public abstract class PageableExecutionUtils {
37+
38+
private PageableExecutionUtils() {}
39+
40+
/**
41+
* Constructs a {@link Page} based on the given {@code content}, {@link Pageable} and {@link Supplier} applying
42+
* optimizations. The construction of {@link Page} omits a count query if the total can be determined based on the
43+
* result size and {@link Pageable}.
44+
*
45+
* @param content must not be {@literal null}.
46+
* @param pageable must not be {@literal null}.
47+
* @param totalSupplier must not be {@literal null}.
48+
* @return the {@link Page}.
49+
*/
50+
public static <T> Page<T> getPage(List<T> content, Pageable pageable, LongSupplier totalSupplier) {
51+
52+
Assert.notNull(content, "Content must not be null!");
53+
Assert.notNull(pageable, "Pageable must not be null!");
54+
Assert.notNull(totalSupplier, "TotalSupplier must not be null!");
55+
56+
if (pageable.isUnpaged() || pageable.getOffset() == 0) {
57+
58+
if (pageable.isUnpaged() || pageable.getPageSize() > content.size()) {
59+
return new PageImpl<>(content, pageable, content.size());
60+
}
61+
62+
return new PageImpl<>(content, pageable, totalSupplier.getAsLong());
63+
}
64+
65+
if (content.size() != 0 && pageable.getPageSize() > content.size()) {
66+
return new PageImpl<>(content, pageable, pageable.getOffset() + content.size());
67+
}
68+
69+
return new PageImpl<>(content, pageable, totalSupplier.getAsLong());
70+
}
71+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright 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.support;
17+
18+
import static java.util.Collections.*;
19+
import static org.assertj.core.api.Assertions.*;
20+
import static org.mockito.Mockito.*;
21+
22+
import java.util.Arrays;
23+
import java.util.function.LongSupplier;
24+
25+
import org.junit.jupiter.api.Test;
26+
import org.junit.jupiter.api.extension.ExtendWith;
27+
import org.mockito.Mock;
28+
import org.mockito.junit.jupiter.MockitoExtension;
29+
import org.springframework.data.domain.Page;
30+
import org.springframework.data.domain.PageRequest;
31+
import org.springframework.data.domain.Pageable;
32+
33+
/**
34+
* Unit tests for {@link PageableExecutionUtils}.
35+
*
36+
* @author Mark Paluch
37+
* @author Oliver Gierke
38+
* @author Jens Schauder
39+
*/
40+
@ExtendWith(MockitoExtension.class)
41+
class PageableExecutionUtilsUnitTests {
42+
43+
@Mock LongSupplier totalSupplierMock;
44+
45+
@Test // DATAMCNS-884
46+
void firstPageRequestIsLessThanOneFullPageDoesNotRequireTotal() {
47+
48+
Page<Integer> page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), PageRequest.of(0, 10),
49+
totalSupplierMock);
50+
51+
assertThat(page).contains(1, 2, 3);
52+
assertThat(page.getTotalElements()).isEqualTo(3L);
53+
verifyNoInteractions(totalSupplierMock);
54+
}
55+
56+
@Test // DATAMCNS-884
57+
void noPageableRequestDoesNotRequireTotal() {
58+
59+
Page<Integer> page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), Pageable.unpaged(), totalSupplierMock);
60+
61+
assertThat(page).contains(1, 2, 3);
62+
assertThat(page.getTotalElements()).isEqualTo(3L);
63+
64+
verifyNoInteractions(totalSupplierMock);
65+
}
66+
67+
@Test // DATAMCNS-884
68+
void subsequentPageRequestIsLessThanOneFullPageDoesNotRequireTotal() {
69+
70+
Page<Integer> page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), PageRequest.of(5, 10),
71+
totalSupplierMock);
72+
73+
assertThat(page).contains(1, 2, 3);
74+
assertThat(page.getTotalElements()).isEqualTo(53L);
75+
76+
verifyNoInteractions(totalSupplierMock);
77+
}
78+
79+
@Test // DATAMCNS-884
80+
void firstPageRequestHitsUpperBoundRequiresTotal() {
81+
82+
doReturn(4L).when(totalSupplierMock).getAsLong();
83+
84+
Page<Integer> page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), PageRequest.of(0, 3),
85+
totalSupplierMock);
86+
87+
assertThat(page).contains(1, 2, 3);
88+
assertThat(page.getTotalElements()).isEqualTo(4L);
89+
90+
verify(totalSupplierMock).getAsLong();
91+
}
92+
93+
@Test // DATAMCNS-884
94+
void subsequentPageRequestHitsUpperBoundRequiresTotal() {
95+
96+
doReturn(7L).when(totalSupplierMock).getAsLong();
97+
98+
Page<Integer> page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), PageRequest.of(1, 3),
99+
totalSupplierMock);
100+
101+
assertThat(page).contains(1, 2, 3);
102+
assertThat(page.getTotalElements()).isEqualTo(7L);
103+
104+
verify(totalSupplierMock).getAsLong();
105+
}
106+
107+
@Test // DATAMCNS-884
108+
void subsequentPageRequestWithoutResultRequiresRequireTotal() {
109+
110+
doReturn(7L).when(totalSupplierMock).getAsLong();
111+
Page<Integer> page = PageableExecutionUtils.getPage(emptyList(), PageRequest.of(5, 10), totalSupplierMock);
112+
113+
assertThat(page.getTotalElements()).isEqualTo(7L);
114+
115+
verify(totalSupplierMock).getAsLong();
116+
}
117+
}

0 commit comments

Comments
 (0)