Skip to content

Commit 02121fc

Browse files
committed
Redunant(wrong) direction appended to @PageableDefault. Fixes #2152
1 parent 3b589bf commit 02121fc

File tree

3 files changed

+149
-7
lines changed

3 files changed

+149
-7
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/DataRestDelegatingMethodParameterCustomizer.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424

2525
import java.lang.annotation.Annotation;
2626
import java.lang.reflect.Field;
27-
import java.util.ArrayList;
27+
import java.util.Arrays;
2828
import java.util.List;
2929
import java.util.Objects;
3030
import java.util.Optional;
31+
import java.util.regex.Pattern;
32+
import java.util.stream.Collectors;
3133

3234
import com.fasterxml.jackson.core.JsonProcessingException;
3335
import io.swagger.v3.core.util.ObjectMapperFactory;
@@ -805,11 +807,7 @@ private String getArrayDefaultValue(String parameterName, PageableDefault pageab
805807
if ("sort".equals(parameterName)) {
806808
DefaultSort defaultSort = getDefaultSort(pageableDefault, sortDefault);
807809
if (defaultSort != null && ArrayUtils.isNotEmpty(defaultSort.properties)) {
808-
List<String> sortValues = new ArrayList<>();
809-
for (String sortValue : defaultSort.properties) {
810-
String sortStr = String.join(",", sortValue, defaultSort.direction.name());
811-
sortValues.add(sortStr);
812-
}
810+
final List<String> sortValues = defaultSort.getEffectiveProperties();
813811
try {
814812
defaultValue = ObjectMapperFactory.buildStrictGenericObjectMapper().writeValueAsString(sortValues);
815813
}
@@ -881,6 +879,13 @@ private boolean isRepositoryRestConfigurationPresent() {
881879
}
882880

883881
private static class DefaultSort {
882+
883+
private static final String DIRECTION_GROUP = Arrays.stream(Sort.Direction.values()).map(Enum::name).collect(Collectors.joining("|"));
884+
885+
private static final String DIRECTED_REGEXP = "\\w+(\\.\\w+)*,\\s*(" + DIRECTION_GROUP + ')';
886+
887+
private static final Pattern DIRECTED_PATTERN = Pattern.compile(DIRECTED_REGEXP, Pattern.CASE_INSENSITIVE);
888+
884889
private final Sort.Direction direction;
885890

886891
private final String[] properties;
@@ -889,5 +894,16 @@ private static class DefaultSort {
889894
this.direction = direction;
890895
this.properties = properties;
891896
}
897+
898+
List<String> getEffectiveProperties() {
899+
return Arrays.stream(properties)
900+
.map(p -> {
901+
if (DIRECTED_PATTERN.matcher(p).matches()) {
902+
return p;
903+
}
904+
return p + ',' + direction.name();
905+
})
906+
.collect(Collectors.toList());
907+
}
892908
}
893-
}
909+
}

springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/app13/HelloController.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,20 @@ public String getPatientList3(@PageableDefault(size = 100)
5757
@ParameterObject Pageable pageable) {
5858
return "bla";
5959
}
60+
61+
@GetMapping("/test4")
62+
public String getPatientList4(@PageableDefault(100)
63+
@ParameterObject Pageable pageable) {
64+
return "bla";
65+
}
66+
67+
@GetMapping("/test5")
68+
public void read(
69+
@PageableDefault(sort = {
70+
"some,desc",
71+
"other,asc",
72+
"another.that,desc"
73+
})
74+
@ParameterObject final Pageable pageable) {
75+
}
6076
}

springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/app13.json

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,116 @@
1111
}
1212
],
1313
"paths": {
14+
"/test5": {
15+
"get": {
16+
"tags": [
17+
"hello-controller"
18+
],
19+
"operationId": "read",
20+
"parameters": [
21+
{
22+
"name": "page",
23+
"in": "query",
24+
"description": "Zero-based page index (0..N)",
25+
"required": false,
26+
"schema": {
27+
"minimum": 0,
28+
"type": "integer",
29+
"default": 0
30+
}
31+
},
32+
{
33+
"name": "size",
34+
"in": "query",
35+
"description": "The size of the page to be returned",
36+
"required": false,
37+
"schema": {
38+
"minimum": 1,
39+
"type": "integer",
40+
"default": 10
41+
}
42+
},
43+
{
44+
"name": "sort",
45+
"in": "query",
46+
"description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
47+
"required": false,
48+
"schema": {
49+
"type": "array",
50+
"items": {
51+
"type": "string"
52+
},
53+
"default": [
54+
"some,desc",
55+
"other,asc",
56+
"another.that,desc"
57+
]
58+
}
59+
}
60+
],
61+
"responses": {
62+
"200": {
63+
"description": "OK"
64+
}
65+
}
66+
}
67+
},
68+
"/test4": {
69+
"get": {
70+
"tags": [
71+
"hello-controller"
72+
],
73+
"operationId": "getPatientList4",
74+
"parameters": [
75+
{
76+
"name": "page",
77+
"in": "query",
78+
"description": "Zero-based page index (0..N)",
79+
"required": false,
80+
"schema": {
81+
"minimum": 0,
82+
"type": "integer",
83+
"default": 0
84+
}
85+
},
86+
{
87+
"name": "size",
88+
"in": "query",
89+
"description": "The size of the page to be returned",
90+
"required": false,
91+
"schema": {
92+
"minimum": 1,
93+
"type": "integer",
94+
"default": 100
95+
}
96+
},
97+
{
98+
"name": "sort",
99+
"in": "query",
100+
"description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
101+
"required": false,
102+
"schema": {
103+
"type": "array",
104+
"items": {
105+
"type": "string"
106+
}
107+
}
108+
}
109+
],
110+
"responses": {
111+
"200": {
112+
"description": "OK",
113+
"content": {
114+
"application/hal+json": {
115+
"schema": {
116+
"type": "string"
117+
}
118+
}
119+
}
120+
}
121+
}
122+
}
123+
},
14124
"/test3": {
15125
"get": {
16126
"tags": [

0 commit comments

Comments
 (0)