Skip to content

Commit 97655d7

Browse files
committed
Bad Pageable description in Page<DumbBuzModel> description. Fixes #1215.
1 parent 5908c8e commit 97655d7

File tree

15 files changed

+487
-17
lines changed

15 files changed

+487
-17
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/core/Constants.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ public final class Constants {
8080
*/
8181
public static final String SPRINGDOC_DEPRECATING_CONVERTER_ENABLED = "springdoc.model-converters.deprecating-converter.enabled";
8282

83+
/**
84+
* The constant SPRINGDOC_PAGEABLE_CONVERTER_ENABLED.
85+
*/
86+
public static final String SPRINGDOC_PAGEABLE_CONVERTER_ENABLED = "springdoc.model-converters.pageable-converter.enabled";
87+
8388
/**
8489
* The constant SPRINGDOC_SCHEMA_RESOLVE_PROPERTIES.
8590
*/

springdoc-openapi-common/src/main/java/org/springdoc/core/DelegatingMethodParameter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public static MethodParameter[] customize(String[] pNames, MethodParameter[] par
103103
List<MethodParameter> explodedParameters = new ArrayList<>();
104104
for (int i = 0; i < parameters.length; ++i) {
105105
MethodParameter p = parameters[i];
106-
Class<?> paramClass = AdditionalModelsConverter.getReplacement(p.getParameterType());
106+
Class<?> paramClass = AdditionalModelsConverter.getParameterObjectReplacement(p.getParameterType());
107107

108108
if (!MethodParameterPojoExtractor.isSimpleType(paramClass) && (p.hasParameterAnnotation(ParameterObject.class) || AnnotatedElementUtils.isAnnotated(paramClass, ParameterObject.class))) {
109109
MethodParameterPojoExtractor.extractFrom(paramClass).forEach(methodParameter -> {

springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfigProperties.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,11 @@ public static class ModelConverters {
646646
*/
647647
private DeprecatingConverter deprecatingConverter = new DeprecatingConverter();
648648

649+
/**
650+
* The Pageable converter.
651+
*/
652+
private PageableConverter pageableConverter = new PageableConverter();
653+
649654
/**
650655
* Gets deprecating converter.
651656
*
@@ -664,6 +669,24 @@ public void setDeprecatingConverter(DeprecatingConverter deprecatingConverter) {
664669
this.deprecatingConverter = deprecatingConverter;
665670
}
666671

672+
/**
673+
* Gets pageable converter.
674+
*
675+
* @return the pageable converter
676+
*/
677+
public PageableConverter getPageableConverter() {
678+
return pageableConverter;
679+
}
680+
681+
/**
682+
* Sets pageable converter.
683+
*
684+
* @param pageableConverter the pageable converter
685+
*/
686+
public void setPageableConverter(PageableConverter pageableConverter) {
687+
this.pageableConverter = pageableConverter;
688+
}
689+
667690
/**
668691
* The type Deprecating converter.
669692
* @author bnasslashen
@@ -693,6 +716,36 @@ public void setEnabled(boolean enabled) {
693716
this.enabled = enabled;
694717
}
695718
}
719+
720+
/**
721+
* The type Deprecating converter.
722+
* @author bnasslashen
723+
*/
724+
public static class PageableConverter {
725+
726+
/**
727+
* The Enabled.
728+
*/
729+
private boolean enabled;
730+
731+
/**
732+
* Is enabled boolean.
733+
*
734+
* @return the boolean
735+
*/
736+
public boolean isEnabled() {
737+
return enabled;
738+
}
739+
740+
/**
741+
* Sets enabled.
742+
*
743+
* @param enabled the enabled
744+
*/
745+
public void setEnabled(boolean enabled) {
746+
this.enabled = enabled;
747+
}
748+
}
696749
}
697750

698751
/**

springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springdoc.core.converters.AdditionalModelsConverter;
3838
import org.springdoc.core.converters.FileSupportConverter;
3939
import org.springdoc.core.converters.ModelConverterRegistrar;
40+
import org.springdoc.core.converters.PageableOpenAPIConverter;
4041
import org.springdoc.core.converters.PolymorphicModelConverter;
4142
import org.springdoc.core.converters.PropertyCustomizingConverter;
4243
import org.springdoc.core.converters.ResponseSupportConverter;
@@ -75,6 +76,7 @@
7576

7677
import static org.springdoc.core.Constants.SPRINGDOC_DEPRECATING_CONVERTER_ENABLED;
7778
import static org.springdoc.core.Constants.SPRINGDOC_ENABLED;
79+
import static org.springdoc.core.Constants.SPRINGDOC_PAGEABLE_CONVERTER_ENABLED;
7880
import static org.springdoc.core.Constants.SPRINGDOC_SCHEMA_RESOLVE_PROPERTIES;
7981
import static org.springdoc.core.Constants.SPRINGDOC_SHOW_ACTUATOR;
8082
import static org.springdoc.core.SpringDocUtils.getConfig;
@@ -168,6 +170,19 @@ SchemaPropertyDeprecatingConverter schemaPropertyDeprecatingConverter() {
168170
return new SchemaPropertyDeprecatingConverter();
169171
}
170172

173+
/**
174+
* Pageable open api converter pageable open api converter.
175+
*
176+
* @return the pageable open api converter
177+
*/
178+
@Bean
179+
@ConditionalOnMissingBean
180+
@ConditionalOnProperty(name = SPRINGDOC_PAGEABLE_CONVERTER_ENABLED, matchIfMissing = true)
181+
@Lazy(false)
182+
PageableOpenAPIConverter pageableOpenAPIConverter() {
183+
return new PageableOpenAPIConverter();
184+
}
185+
171186
/**
172187
* Polymorphic model converter polymorphic model converter.
173188
*

springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocUtils.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,5 +288,16 @@ public SpringDocUtils disableReplacement(Class source) {
288288
return this;
289289
}
290290

291+
/**
292+
* Replace the ParameterObject with the target class.
293+
*
294+
* @param source the source
295+
* @param target the target
296+
* @return the spring doc utils
297+
*/
298+
public SpringDocUtils replaceParameterObjectWithClass(Class source, Class target) {
299+
AdditionalModelsConverter.replaceParameterObjectWithClass(source, target);
300+
return this;
301+
}
291302
}
292303

springdoc-openapi-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ public class AdditionalModelsConverter implements ModelConverter {
4747
*/
4848
private static final Map<Class, Schema> modelToSchemaMap = new HashMap<>();
4949

50+
/**
51+
* The constant paramObjectReplacementMap.
52+
*/
53+
private static final Map<Class, Class> paramObjectReplacementMap = new HashMap<>();
54+
5055
/**
5156
* Replace with class.
5257
*
@@ -67,14 +72,24 @@ public static void replaceWithSchema(Class source, Schema target) {
6772
modelToSchemaMap.put(source, target);
6873
}
6974

75+
/**
76+
* Replace ParameterObject with class.
77+
*
78+
* @param source the source
79+
* @param target the target
80+
*/
81+
public static void replaceParameterObjectWithClass(Class source, Class target) {
82+
paramObjectReplacementMap.put(source, target);
83+
}
84+
7085
/**
7186
* Gets replacement.
7287
*
7388
* @param clazz the clazz
7489
* @return the replacement
7590
*/
76-
public static Class getReplacement(Class clazz) {
77-
return modelToClassMap.getOrDefault(clazz, clazz);
91+
public static Class getParameterObjectReplacement(Class clazz) {
92+
return paramObjectReplacementMap.getOrDefault(clazz, clazz);
7893
}
7994

8095
/**
@@ -83,10 +98,18 @@ public static Class getReplacement(Class clazz) {
8398
* @param clazz the clazz
8499
*/
85100
public static void disableReplacement(Class clazz) {
86-
if(modelToClassMap.containsKey(clazz))
101+
if (modelToClassMap.containsKey(clazz))
87102
modelToClassMap.remove(clazz);
88103
}
89104

105+
/**
106+
* Resolve schema.
107+
*
108+
* @param type the type
109+
* @param context the context
110+
* @param chain the chain
111+
* @return the schema
112+
*/
90113
@Override
91114
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
92115
JavaType javaType = Json.mapper().constructType(type.getType());
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
*
3+
* *
4+
* * * Copyright 2019-2020 the original author or authors.
5+
* * *
6+
* * * Licensed under the Apache License, Version 2.0 (the "License");
7+
* * * you may not use this file except in compliance with the License.
8+
* * * You may obtain a copy of the License at
9+
* * *
10+
* * * https://www.apache.org/licenses/LICENSE-2.0
11+
* * *
12+
* * * Unless required by applicable law or agreed to in writing, software
13+
* * * distributed under the License is distributed on an "AS IS" BASIS,
14+
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* * * See the License for the specific language governing permissions and
16+
* * * limitations under the License.
17+
* *
18+
*
19+
*/
20+
21+
package org.springdoc.core.converters;
22+
23+
import java.util.Iterator;
24+
25+
import com.fasterxml.jackson.databind.JavaType;
26+
import io.swagger.v3.core.converter.AnnotatedType;
27+
import io.swagger.v3.core.converter.ModelConverter;
28+
import io.swagger.v3.core.converter.ModelConverterContext;
29+
import io.swagger.v3.core.util.Json;
30+
import io.swagger.v3.oas.models.media.Schema;
31+
import org.apache.commons.lang3.StringUtils;
32+
import org.springdoc.core.converters.models.Pageable;
33+
34+
/**
35+
* The Pageable Type models converter.
36+
* @author bnasslahsen
37+
*/
38+
public class PageableOpenAPIConverter implements ModelConverter {
39+
40+
/**
41+
* The constant PAGEABLE_TO_REPLACE.
42+
*/
43+
private static final String PAGEABLE_TO_REPLACE = "org.springframework.data.domain.Pageable";
44+
45+
/**
46+
* The constant PAGE_REQUEST_TO_REPLACE.
47+
*/
48+
private static final String PAGE_REQUEST_TO_REPLACE = "org.springframework.data.domain.PageRequest";
49+
50+
/**
51+
* The constant PAGEABLE.
52+
*/
53+
private static final AnnotatedType PAGEABLE = new AnnotatedType(Pageable.class).resolveAsRef(true);
54+
55+
/**
56+
* Resolve schema.
57+
*
58+
* @param type the type
59+
* @param context the context
60+
* @param chain the chain
61+
* @return the schema
62+
*/
63+
@Override
64+
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
65+
JavaType javaType = Json.mapper().constructType(type.getType());
66+
if (javaType != null) {
67+
Class<?> cls = javaType.getRawClass();
68+
if (PAGEABLE_TO_REPLACE.equals(cls.getCanonicalName()) || PAGE_REQUEST_TO_REPLACE.equals(cls.getCanonicalName())) {
69+
if (!type.isSchemaProperty())
70+
type = PAGEABLE;
71+
else
72+
type.name(cls.getSimpleName() + StringUtils.capitalize(type.getParent().getType()));
73+
}
74+
}
75+
return (chain.hasNext()) ? chain.next().resolve(type, context, chain) : null;
76+
}
77+
78+
}

springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/SpringDocDataRestConfiguration.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@
8484
public class SpringDocDataRestConfiguration {
8585

8686
static {
87-
getConfig().replaceWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
88-
.replaceWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
87+
getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
88+
.replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
8989
}
9090

91+
9192
/**
9293
* Delegating method parameter customizer delegating method parameter customizer.
9394
*
@@ -153,7 +154,7 @@ QuerydslPredicateOperationCustomizer queryDslQuerydslPredicateOperationCustomize
153154
static class SpringRepositoryRestResourceProviderConfiguration {
154155

155156
static {
156-
getConfig().replaceWithClass(DefaultedPageable.class, DefaultPageable.class)
157+
getConfig().replaceParameterObjectWithClass(DefaultedPageable.class, DefaultPageable.class)
157158
.addRequestWrapperToIgnore(RootResourceInformation.class, PersistentEntityResourceAssembler.class, ETag.class, Sort.class)
158159
.addResponseWrapperToIgnore(RootResourceInformation.class);
159160
}
@@ -175,7 +176,7 @@ static class SpringRepositoryRestResourceProviderConfiguration {
175176
SpringRepositoryRestResourceProvider springRepositoryRestResourceProvider(ResourceMappings mappings,
176177
Repositories repositories, Associations associations, ApplicationContext applicationContext,
177178
DataRestRouterOperationService dataRestRouterOperationService, PersistentEntities persistentEntities,
178-
ObjectMapper mapper,SpringDocDataRestUtils springDocDataRestUtils) {
179+
ObjectMapper mapper, SpringDocDataRestUtils springDocDataRestUtils) {
179180
return new SpringRepositoryRestResourceProvider(mappings, repositories, associations, applicationContext,
180181
dataRestRouterOperationService, persistentEntities, mapper, springDocDataRestUtils);
181182
}
@@ -225,7 +226,7 @@ DataRestOperationService dataRestOperationBuilder(DataRestRequestService dataRes
225226
@Bean
226227
@ConditionalOnMissingBean
227228
DataRestRequestService dataRestRequestBuilder(LocalVariableTableParameterNameDiscoverer localSpringDocParameterNameDiscoverer, GenericParameterService parameterBuilder,
228-
RequestBodyService requestBodyService, AbstractRequestService requestBuilder,SpringDocDataRestUtils springDocDataRestUtils) {
229+
RequestBodyService requestBodyService, AbstractRequestService requestBuilder, SpringDocDataRestUtils springDocDataRestUtils) {
229230
return new DataRestRequestService(localSpringDocParameterNameDiscoverer, parameterBuilder,
230231
requestBodyService, requestBuilder, springDocDataRestUtils);
231232
}

springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app14/SpringDocApp14Test.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353
public class SpringDocApp14Test extends AbstractSpringDocTest {
5454

5555
static {
56-
getConfig().replaceWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
57-
.replaceWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
56+
getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
57+
.replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
5858
}
5959

6060

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app27;
20+
21+
import java.util.List;
22+
23+
import javax.validation.constraints.NotNull;
24+
25+
import org.springframework.data.domain.Pageable;
26+
import org.springframework.http.ResponseEntity;
27+
import org.springframework.web.bind.annotation.GetMapping;
28+
import org.springframework.web.bind.annotation.RestController;
29+
30+
@RestController
31+
public class HelloController {
32+
33+
@GetMapping(value = "/search", produces = { "application/xml", "application/json" })
34+
public ResponseEntity<List<PersonDTO>> getAllPets(@NotNull Pageable pageable) {
35+
return null;
36+
}
37+
38+
}

0 commit comments

Comments
 (0)