Skip to content

Commit a0af83d

Browse files
committed
Rename PaginationRequest and ScrollRequest
...to Subrange and ScrollSubrange See gh-620
1 parent d017506 commit a0af83d

File tree

8 files changed

+112
-117
lines changed

8 files changed

+112
-117
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurer.java

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,19 @@
9494
* @author Brian Clozel
9595
* @since 1.0.0
9696
*/
97-
public class AnnotatedControllerConfigurer
98-
implements ApplicationContextAware, InitializingBean, RuntimeWiringConfigurer {
97+
public class AnnotatedControllerConfigurer implements ApplicationContextAware, InitializingBean, RuntimeWiringConfigurer {
98+
99+
private static final ClassLoader classLoader = AnnotatedControllerConfigurer.class.getClassLoader();
100+
101+
private final static boolean springDataPresent = ClassUtils.isPresent(
102+
"org.springframework.data.projection.SpelAwareProxyProjectionFactory", classLoader);
103+
104+
private final static boolean springSecurityPresent = ClassUtils.isPresent(
105+
"org.springframework.security.core.context.SecurityContext", classLoader);
106+
107+
private final static boolean beanValidationPresent = ClassUtils.isPresent(
108+
"jakarta.validation.executable.ExecutableValidator", classLoader);
109+
99110

100111
private final static Log logger = LogFactory.getLog(AnnotatedControllerConfigurer.class);
101112

@@ -111,18 +122,6 @@ public class AnnotatedControllerConfigurer
111122
*/
112123
private static final String SCOPED_TARGET_NAME_PREFIX = "scopedTarget.";
113124

114-
private final static boolean springDataPresent = ClassUtils.isPresent(
115-
"org.springframework.data.projection.SpelAwareProxyProjectionFactory",
116-
AnnotatedControllerConfigurer.class.getClassLoader());
117-
118-
private final static boolean springSecurityPresent = ClassUtils.isPresent(
119-
"org.springframework.security.core.context.SecurityContext",
120-
AnnotatedControllerConfigurer.class.getClassLoader());
121-
122-
private final static boolean beanValidationPresent = ClassUtils.isPresent(
123-
"jakarta.validation.executable.ExecutableValidator",
124-
AnnotatedControllerConfigurer.class.getClassLoader());
125-
126125

127126
private final FormattingConversionService conversionService = new DefaultFormattingConversionService();
128127

@@ -165,10 +164,9 @@ public void addFormatterRegistrar(FormatterRegistrar registrar) {
165164
* results in one of the following:
166165
* <ul>
167166
* <li>If Spring Data is present, and the strategy supports {@code ScrollPosition},
168-
* then {@link ScrollRequestMethodArgumentResolver} is
169-
* configured as a method argument resolver.
170-
* <li>Otherwise {@link PaginationRequestMethodArgumentResolver} is added
171-
* instead.
167+
* then {@link ScrollSubrangeMethodArgumentResolver} is configured as a method
168+
* argument resolver.
169+
* <li>Otherwise {@link SubrangeMethodArgumentResolver} is added.
172170
* </ul>
173171
* @since 1.2
174172
*/
@@ -286,7 +284,7 @@ private HandlerMethodArgumentResolverComposite initArgumentResolvers() {
286284
resolvers.addResolver(new DataFetchingEnvironmentMethodArgumentResolver());
287285
resolvers.addResolver(new DataLoaderMethodArgumentResolver());
288286
if (this.cursorStrategy != null) {
289-
resolvers.addResolver(initPaginationResolver(this.cursorStrategy));
287+
resolvers.addResolver(createSubrangeMethodArgumentResolver(this.cursorStrategy));
290288
}
291289
if (this.sortStrategy != null) {
292290
resolvers.addResolver(new SortMethodArgumentResolver(this.sortStrategy));
@@ -309,14 +307,14 @@ private HandlerMethodArgumentResolverComposite initArgumentResolvers() {
309307
}
310308

311309
@SuppressWarnings("unchecked")
312-
private HandlerMethodArgumentResolver initPaginationResolver(CursorStrategy<?> cursorStrategy) {
310+
private static HandlerMethodArgumentResolver createSubrangeMethodArgumentResolver(CursorStrategy<?> strategy) {
313311
if (springDataPresent) {
314-
if (cursorStrategy.supports(org.springframework.data.domain.ScrollPosition.class)) {
315-
return new ScrollRequestMethodArgumentResolver(
316-
(CursorStrategy<org.springframework.data.domain.ScrollPosition>) cursorStrategy);
312+
if (strategy.supports(org.springframework.data.domain.ScrollPosition.class)) {
313+
return new ScrollSubrangeMethodArgumentResolver(
314+
(CursorStrategy<org.springframework.data.domain.ScrollPosition>) strategy);
317315
}
318316
}
319-
return new PaginationRequestMethodArgumentResolver<>(cursorStrategy);
317+
return new SubrangeMethodArgumentResolver<>(strategy);
320318
}
321319

322320
protected final ApplicationContext obtainApplicationContext() {
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,32 @@
2020
import org.springframework.core.MethodParameter;
2121
import org.springframework.data.domain.ScrollPosition;
2222
import org.springframework.graphql.data.pagination.CursorStrategy;
23-
import org.springframework.graphql.data.query.ScrollRequest;
23+
import org.springframework.graphql.data.query.ScrollSubrange;
2424
import org.springframework.lang.Nullable;
2525

2626

2727
/**
28-
* Subclass of {@link PaginationRequestMethodArgumentResolver} that supports
29-
* {@link ScrollRequest} with cursors converted to {@link ScrollPosition} for
30-
* forward or backward pagination.
28+
* A {@link SubrangeMethodArgumentResolver} that supports {@link ScrollSubrange}
29+
* and {@link ScrollPosition} as cursor.
3130
*
3231
* @author Rossen Stoyanchev
3332
* @since 1.2
3433
*/
35-
public class ScrollRequestMethodArgumentResolver extends PaginationRequestMethodArgumentResolver<ScrollPosition> {
34+
public class ScrollSubrangeMethodArgumentResolver extends SubrangeMethodArgumentResolver<ScrollPosition> {
3635

3736

38-
public ScrollRequestMethodArgumentResolver(CursorStrategy<ScrollPosition> cursorStrategy) {
39-
super(cursorStrategy);
37+
public ScrollSubrangeMethodArgumentResolver(CursorStrategy<ScrollPosition> strategy) {
38+
super(strategy);
4039
}
4140

4241

4342
@Override
4443
public boolean supportsParameter(MethodParameter parameter) {
45-
return parameter.getParameterType().equals(ScrollRequest.class);
44+
return parameter.getParameterType().equals(ScrollSubrange.class);
4645
}
4746

48-
protected ScrollRequest createRequest(@Nullable ScrollPosition position, @Nullable Integer size, boolean forward) {
49-
return new ScrollRequest(position, size, forward);
47+
protected ScrollSubrange createSubrange(@Nullable ScrollPosition pos, @Nullable Integer size, boolean forward) {
48+
return new ScrollSubrange(pos, size, forward);
5049
}
5150

5251
}
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,31 @@
2222
import org.springframework.core.MethodParameter;
2323
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
2424
import org.springframework.graphql.data.pagination.CursorStrategy;
25-
import org.springframework.graphql.data.pagination.PaginationRequest;
25+
import org.springframework.graphql.data.pagination.Subrange;
2626
import org.springframework.lang.Nullable;
2727
import org.springframework.util.Assert;
2828

2929
/**
30-
* Resolver for a method argument of type {@link PaginationRequest} initialized
30+
* Resolver for a method argument of type {@link Subrange} initialized
3131
* from "first", "last", "before", and "after" GraphQL arguments.
3232
*
3333
* @author Rossen Stoyanchev
3434
* @since 1.2
3535
*/
36-
public class PaginationRequestMethodArgumentResolver<P> implements HandlerMethodArgumentResolver {
36+
public class SubrangeMethodArgumentResolver<P> implements HandlerMethodArgumentResolver {
3737

3838
private final CursorStrategy<P> cursorStrategy;
3939

4040

41-
public PaginationRequestMethodArgumentResolver(CursorStrategy<P> cursorStrategy) {
41+
public SubrangeMethodArgumentResolver(CursorStrategy<P> cursorStrategy) {
4242
Assert.notNull(cursorStrategy, "CursorStrategy is required");
4343
this.cursorStrategy = cursorStrategy;
4444
}
4545

4646

4747
@Override
4848
public boolean supportsParameter(MethodParameter parameter) {
49-
return (parameter.getParameterType().equals(PaginationRequest.class) &&
49+
return (parameter.getParameterType().equals(Subrange.class) &&
5050
this.cursorStrategy.supports(parameter.nested().getNestedParameterType()));
5151
}
5252

@@ -56,14 +56,14 @@ public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment
5656
Integer count = environment.getArgument(forward ? "first" : "last");
5757
String cursor = environment.getArgument(forward ? "after" : "before");
5858
P position = (cursor != null ? this.cursorStrategy.fromCursor(cursor) : null);
59-
return createRequest(position, count, forward);
59+
return createSubrange(position, count, forward);
6060
}
6161

6262
/**
63-
* Create the {@code PaginationRequest} instance.
63+
* Allows subclasses to create an extension of {@link Subrange}.
6464
*/
65-
protected PaginationRequest<P> createRequest(@Nullable P position, @Nullable Integer size, boolean forward) {
66-
return new PaginationRequest<>(position, size, forward);
65+
protected Subrange<P> createSubrange(@Nullable P pos, @Nullable Integer size, boolean forward) {
66+
return new Subrange<>(pos, size, forward);
6767
}
6868

6969
}
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
import org.springframework.lang.Nullable;
2323

2424
/**
25-
* Container for a pagination request.
25+
* Container for parameters that limit result elements to a subrange including a
26+
* relative position, number of elements, and direction.
2627
*
2728
* @author Rossen Stoyanchev
2829
* @since 1.2
2930
*/
30-
public class PaginationRequest<P> {
31+
public class Subrange<P> {
3132

3233
@Nullable
3334
private final P position;
@@ -39,39 +40,38 @@ public class PaginationRequest<P> {
3940

4041

4142
/**
42-
* Constructor with the position, count, and direction.
43+
* Constructor with the relative position, count, and direction.
4344
*/
44-
public PaginationRequest(@Nullable P position, @Nullable Integer count, boolean forward) {
45+
public Subrange(@Nullable P position, @Nullable Integer count, boolean forward) {
4546
this.position = position;
4647
this.forward = forward;
4748
this.count = count;
4849
}
4950

5051

5152
/**
52-
* The position of an element relative to which to paginate, decoded from a
53-
* String cursor, e.g. the "before" and "after" arguments from the GraphQL
54-
* Cursor connection spec.
53+
* The position of the result element the subrange is relative to. This is
54+
* decoded from the "before" or "after" input arguments from the GraphQL
55+
* Cursor connection spec via {@link CursorStrategy}.
5556
*/
5657
public Optional<P> position() {
5758
return Optional.ofNullable(this.position);
5859
}
5960

6061
/**
61-
* The number of elements requested, e.g. "first" and "last" N elements
62+
* The number of elements in the subrange based on the "first" and "last"
6263
* arguments from the GraphQL Cursor connection spec.
6364
*/
6465
public Optional<Integer> count() {
6566
return Optional.ofNullable(this.count);
6667
}
6768

6869
/**
69-
* Whether forward or backward pagination is requested, e.g. depending on
70-
* whether "fist" or "last" N elements was sent.
71-
* <p><strong>Note:</strong> This value may not reflect the one originally
72-
* sent by the client. For example, for backward pagination, an offset cursor
73-
* may be adjusted down by the number of requested elements, turning into
74-
* forward pagination.
70+
* Whether the subrange is forward or backward from ths position, depending
71+
* on whether the argument sent "fist" or "last".
72+
* <p><strong>Note:</strong> The direction may not always match the original
73+
* value. For backward pagination, for example, an offset cursor could be
74+
* adjusted down by the count of elements, switching backward to forward.
7575
*/
7676
public boolean forward() {
7777
return this.forward;

spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollRequest.java renamed to spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollSubrange.java

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,43 +23,41 @@
2323
import org.springframework.data.domain.KeysetScrollPosition.Direction;
2424
import org.springframework.data.domain.OffsetScrollPosition;
2525
import org.springframework.data.domain.ScrollPosition;
26-
import org.springframework.graphql.data.pagination.PaginationRequest;
26+
import org.springframework.graphql.data.pagination.Subrange;
2727
import org.springframework.lang.Nullable;
2828

2929
/**
30-
* Container for pagination request with a {@link ScrollPosition} cursor.
30+
* Container for parameters that limit result elements to a subrange including a
31+
* relative {@link ScrollPosition}, number of elements, and direction.
3132
*
32-
* <p>An {@link OffsetScrollPosition} is always used for forward pagination.
33-
* When backward pagination is requested, the offset is adjusted down by the
34-
* requested count, thus turning it into forward pagination.
33+
* <p> For backward pagination, the offset of an {@link OffsetScrollPosition}
34+
* is adjusted to point to the first item in the range by subtracting the count
35+
* from it. Hence, for {@code OffsetScrollPosition} {@link #forward()} is
36+
* always {@code true}.
3537
*
3638
* @author Rossen Stoyanchev
3739
* @since 1.2
3840
*/
39-
public final class ScrollRequest extends PaginationRequest<ScrollPosition> {
41+
public final class ScrollSubrange extends Subrange<ScrollPosition> {
4042

4143

42-
public ScrollRequest(@Nullable ScrollPosition position, @Nullable Integer count, boolean forward) {
43-
super(initPosition(position, count, forward), count,
44-
(position instanceof OffsetScrollPosition || forward));
44+
public ScrollSubrange(@Nullable ScrollPosition pos, @Nullable Integer count, boolean forward) {
45+
super(initPosition(pos, count, forward), count, (pos instanceof OffsetScrollPosition || forward));
4546
}
4647

4748
@Nullable
48-
private static ScrollPosition initPosition(
49-
@Nullable ScrollPosition position, @Nullable Integer count, boolean forward) {
50-
49+
private static ScrollPosition initPosition(@Nullable ScrollPosition pos, @Nullable Integer count, boolean forward) {
5150
if (!forward) {
52-
if (position instanceof OffsetScrollPosition offsetPosition && count != null) {
51+
if (pos instanceof OffsetScrollPosition offsetPosition && count != null) {
5352
long offset = offsetPosition.getOffset();
5453
return OffsetScrollPosition.of(offset > count ? offset - count : 0);
5554
}
56-
else if (position instanceof KeysetScrollPosition keysetPosition) {
55+
else if (pos instanceof KeysetScrollPosition keysetPosition) {
5756
Map<String, Object> keys = keysetPosition.getKeys();
58-
position = KeysetScrollPosition.of(keys, Direction.Backward);
57+
pos = KeysetScrollPosition.of(keys, Direction.Backward);
5958
}
6059
}
61-
62-
return position;
60+
return pos;
6361
}
6462

6563
}

spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import org.springframework.graphql.data.method.annotation.QueryMapping;
3434
import org.springframework.graphql.data.pagination.ConnectionFieldTypeVisitor;
3535
import org.springframework.graphql.data.query.ScrollPositionCursorStrategy;
36-
import org.springframework.graphql.data.query.ScrollRequest;
36+
import org.springframework.graphql.data.query.ScrollSubrange;
3737
import org.springframework.graphql.data.query.WindowConnectionAdapter;
3838
import org.springframework.graphql.execution.ConnectionTypeGenerator;
3939
import org.springframework.stereotype.Controller;
@@ -120,7 +120,7 @@ private ExecutionGraphQlService graphQlService(BiConsumer<AnnotatedControllerCon
120120
AnnotatedControllerConfigurer configurer = new AnnotatedControllerConfigurer();
121121
configurer.setApplicationContext(context);
122122

123-
GraphQlSetup setup = GraphQlSetup.schemaContent(this.SCHEMA).runtimeWiring(configurer);
123+
GraphQlSetup setup = GraphQlSetup.schemaContent(SCHEMA).runtimeWiring(configurer);
124124
consumer.accept(configurer, setup);
125125

126126
configurer.afterPropertiesSet();
@@ -134,9 +134,9 @@ private ExecutionGraphQlService graphQlService(BiConsumer<AnnotatedControllerCon
134134
private static class BookController {
135135

136136
@QueryMapping
137-
public Window<Book> books(ScrollRequest request) {
138-
int offset = (int) ((OffsetScrollPosition) request.position().get()).getOffset();
139-
int count = request.count().get();
137+
public Window<Book> books(ScrollSubrange subrange) {
138+
int offset = (int) ((OffsetScrollPosition) subrange.position().orElse(OffsetScrollPosition.initial())).getOffset();
139+
int count = subrange.count().orElse(5);
140140
List<Book> books = BookSource.books().subList(offset, offset + count);
141141
return Window.from(books, OffsetScrollPosition::of);
142142
}

0 commit comments

Comments
 (0)