Skip to content

Commit 116730c

Browse files
committed
Polishing.
Imports, Javadoc, ticket references in test cases. Removed the need for MethodParameterAware… flavors of the ResourceAssemblers by keeping the MethodParameter reference in the original assemblers in the first place. Extracted common Pageable MethodParameter lookup code into PageableMethodParameterUtils. Related ticket: #1307.
1 parent 70f21bd commit 116730c

11 files changed

+327
-422
lines changed

Diff for: src/main/java/org/springframework/data/web/MethodParameterAwarePagedResourcesAssembler.java

-56
This file was deleted.

Diff for: src/main/java/org/springframework/data/web/MethodParameterAwareSlicedResourcesAssembler.java

-55
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright 2023 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.web;
17+
18+
import java.lang.reflect.Method;
19+
import java.util.List;
20+
21+
import org.apache.commons.logging.Log;
22+
import org.apache.commons.logging.LogFactory;
23+
import org.springframework.beans.factory.annotation.Qualifier;
24+
import org.springframework.core.MethodParameter;
25+
import org.springframework.core.log.LogMessage;
26+
import org.springframework.data.domain.Pageable;
27+
import org.springframework.hateoas.server.core.MethodParameters;
28+
import org.springframework.lang.Nullable;
29+
30+
/**
31+
* Utility methods to obtain a {@link MethodParameter} of type {@link Pageable} with the same {@link Qualifier}.
32+
*
33+
* @author Oliver Drotbohm
34+
* @since 3.1
35+
* @soundtrack The Intersphere - Wanderer (https://www.youtube.com/watch?v=Sp_VyFBbDPA)
36+
*/
37+
class PageableMethodParameterUtils {
38+
39+
private static final Log logger = LogFactory.getLog(PageableMethodParameterUtils.class);
40+
41+
private static final String SUPERFLOUS_QUALIFIER = "Found qualified %s parameter, but a unique unqualified %s parameter; Using that one, but you might want to check your controller method configuration";
42+
private static final String PARAMETER_AMBIGUITY = "Discovered multiple parameters of type Pageable but no qualifier annotations to disambiguate";
43+
44+
/**
45+
* Returns finds the {@link MethodParameter} for a {@link Pageable} instance matching the given
46+
* {@link MethodParameter} requesting a {@link PagedResourcesAssembler}.
47+
*
48+
* @param parameter must not be {@literal null}.
49+
* @return can be {@literal null}.
50+
*/
51+
@Nullable
52+
static MethodParameter findMatchingPageableParameter(MethodParameter parameter) {
53+
54+
Method method = parameter.getMethod();
55+
56+
if (method == null) {
57+
throw new IllegalArgumentException(String.format("Could not obtain method from parameter %s", parameter));
58+
}
59+
60+
MethodParameters parameters = MethodParameters.of(method);
61+
List<MethodParameter> pageableParameters = parameters.getParametersOfType(Pageable.class);
62+
Qualifier assemblerQualifier = parameter.getParameterAnnotation(Qualifier.class);
63+
64+
if (pageableParameters.isEmpty()) {
65+
return null;
66+
}
67+
68+
if (pageableParameters.size() == 1) {
69+
70+
MethodParameter pageableParameter = pageableParameters.get(0);
71+
MethodParameter matchingParameter = returnIfQualifiersMatch(pageableParameter, assemblerQualifier);
72+
73+
if (matchingParameter == null) {
74+
logger.info(LogMessage.format(SUPERFLOUS_QUALIFIER, PagedResourcesAssembler.class.getSimpleName(),
75+
Pageable.class.getName()));
76+
}
77+
78+
return pageableParameter;
79+
}
80+
81+
if (assemblerQualifier == null) {
82+
throw new IllegalStateException(PARAMETER_AMBIGUITY);
83+
}
84+
85+
for (MethodParameter pageableParameter : pageableParameters) {
86+
87+
MethodParameter matchingParameter = returnIfQualifiersMatch(pageableParameter, assemblerQualifier);
88+
89+
if (matchingParameter != null) {
90+
return matchingParameter;
91+
}
92+
}
93+
94+
throw new IllegalStateException(PARAMETER_AMBIGUITY);
95+
}
96+
97+
@Nullable
98+
private static MethodParameter returnIfQualifiersMatch(MethodParameter pageableParameter,
99+
@Nullable Qualifier assemblerQualifier) {
100+
101+
if (assemblerQualifier == null) {
102+
return pageableParameter;
103+
}
104+
105+
Qualifier pageableParameterQualifier = pageableParameter.getParameterAnnotation(Qualifier.class);
106+
107+
return pageableParameterQualifier != null
108+
? pageableParameterQualifier.value().equals(assemblerQualifier.value()) ? pageableParameter : null
109+
: null;
110+
}
111+
}

Diff for: src/main/java/org/springframework/data/web/PagedResourcesAssembler.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public class PagedResourcesAssembler<T> implements RepresentationModelAssembler<
5858
private final EmbeddedWrappers wrappers = new EmbeddedWrappers(false);
5959

6060
private boolean forceFirstAndLastRels = false;
61+
private @Nullable MethodParameter parameter;
6162

6263
/**
6364
* Creates a new {@link PagedResourcesAssembler} using the given {@link PageableHandlerMethodArgumentResolver} and
@@ -69,9 +70,15 @@ public class PagedResourcesAssembler<T> implements RepresentationModelAssembler<
6970
*/
7071
public PagedResourcesAssembler(@Nullable HateoasPageableHandlerMethodArgumentResolver resolver,
7172
@Nullable UriComponents baseUri) {
73+
this(resolver, Optional.ofNullable(baseUri), null);
74+
}
75+
76+
private PagedResourcesAssembler(@Nullable HateoasPageableHandlerMethodArgumentResolver resolver,
77+
Optional<UriComponents> baseUri, @Nullable MethodParameter parameter) {
7278

7379
this.pageableResolver = resolver == null ? new HateoasPageableHandlerMethodArgumentResolver() : resolver;
74-
this.baseUri = Optional.ofNullable(baseUri);
80+
this.baseUri = baseUri;
81+
this.parameter = parameter;
7582
}
7683

7784
/**
@@ -87,6 +94,17 @@ public void setForceFirstAndLastRels(boolean forceFirstAndLastRels) {
8794
this.forceFirstAndLastRels = forceFirstAndLastRels;
8895
}
8996

97+
/**
98+
* Creates a new {@link PagedResourcesAssembler} with the given reference {@link MethodParameter}.
99+
*
100+
* @param parameter can be {@literal null}.
101+
* @return will never be {@literal null}.
102+
* @since 3.1
103+
*/
104+
public PagedResourcesAssembler<T> withParameter(@Nullable MethodParameter parameter) {
105+
return new PagedResourcesAssembler<>(pageableResolver, baseUri, parameter);
106+
}
107+
90108
@Override
91109
public PagedModel<EntityModel<T>> toModel(Page<T> entity) {
92110
return toModel(entity, EntityModel::of);
@@ -267,7 +285,7 @@ private UriTemplate getUriTemplate(Optional<Link> baseLink) {
267285
private Link createLink(UriTemplate base, Pageable pageable, LinkRelation relation) {
268286

269287
UriComponentsBuilder builder = fromUri(base.expand());
270-
pageableResolver.enhance(builder, getMethodParameter(), pageable);
288+
pageableResolver.enhance(builder, parameter, pageable);
271289

272290
return Link.of(UriTemplate.of(builder.build().toString()), relation);
273291
}
@@ -278,8 +296,10 @@ private Link createLink(UriTemplate base, Pageable pageable, LinkRelation relati
278296
*
279297
* @return
280298
* @since 1.7
299+
* @deprecated since 3.1, rather set up the instance with {@link #withParameter(MethodParameter)}.
281300
*/
282301
@Nullable
302+
@Deprecated(since = "3.1", forRemoval = true)
283303
protected MethodParameter getMethodParameter() {
284304
return null;
285305
}

0 commit comments

Comments
 (0)