Skip to content

Commit adf6690

Browse files
committed
Support Spring Data Sort and @SortDefault fixes springdoc#1702, springdoc#1668
1 parent 6be3b7d commit adf6690

File tree

9 files changed

+377
-532
lines changed

9 files changed

+377
-532
lines changed

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

+4
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ public final class Constants {
388388
*/
389389
public static final String LINKS_SCHEMA_CUSTOMISER = "linksSchemaCustomiser";
390390

391+
/**
392+
* The constant SPRINGDOC_SORT_CONVERTER_ENABLED.
393+
*/
394+
public static final String SPRINGDOC_SORT_CONVERTER_ENABLED = "springdoc.model-converters.sort-converter.enabled";
391395
/**
392396
* Instantiates a new Constants.
393397
*/

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

+55
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.util.ArrayList;
2626
import java.util.List;
2727

28+
import org.springdoc.core.SpringDocConfigProperties.ModelConverters.SortConverter;
29+
2830
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2931
import org.springframework.boot.context.properties.ConfigurationProperties;
3032
import org.springframework.context.annotation.Configuration;
@@ -179,6 +181,29 @@ public class SpringDocConfigProperties {
179181
*/
180182
private ModelConverters modelConverters = new ModelConverters();
181183

184+
/**
185+
* The Sort converter.
186+
*/
187+
private SortConverter sortConverter = new SortConverter();
188+
189+
/**
190+
* Gets sort converter.
191+
*
192+
* @return the sort converter
193+
*/
194+
public SortConverter getSortConverter() {
195+
return sortConverter;
196+
}
197+
198+
/**
199+
* Sets sort converter.
200+
*
201+
* @param sortConverter the sort converter
202+
*/
203+
public void setSortConverter(SortConverter sortConverter) {
204+
this.sortConverter = sortConverter;
205+
}
206+
182207
/**
183208
* Is show spring cloud functions boolean.
184209
*
@@ -772,6 +797,36 @@ public void setPolymorphicConverter(PolymorphicConverter polymorphicConverter) {
772797
this.polymorphicConverter = polymorphicConverter;
773798
}
774799

800+
/**
801+
* The type Sort converter.
802+
* @author daniel-shuy
803+
*/
804+
public static class SortConverter {
805+
806+
/**
807+
* The Enabled.
808+
*/
809+
private boolean enabled;
810+
811+
/**
812+
* Is enabled boolean.
813+
*
814+
* @return the boolean
815+
*/
816+
public boolean isEnabled() {
817+
return enabled;
818+
}
819+
820+
/**
821+
* Sets enabled.
822+
*
823+
* @param enabled the enabled
824+
*/
825+
public void setEnabled(boolean enabled) {
826+
this.enabled = enabled;
827+
}
828+
}
829+
775830
/**
776831
* The type Deprecating converter.
777832
* @author bnasslashen

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

+39
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import java.util.Map;
3131
import java.util.Optional;
3232

33+
import static org.springdoc.core.Constants.SPRINGDOC_SORT_CONVERTER_ENABLED;
34+
import org.springframework.data.domain.Sort;
3335
import com.fasterxml.jackson.databind.node.ObjectNode;
3436
import io.swagger.v3.core.converter.ModelConverter;
3537
import io.swagger.v3.oas.annotations.Hidden;
@@ -47,6 +49,7 @@
4749
import org.springdoc.core.converters.PropertyCustomizingConverter;
4850
import org.springdoc.core.converters.ResponseSupportConverter;
4951
import org.springdoc.core.converters.SchemaPropertyDeprecatingConverter;
52+
import org.springdoc.core.converters.SortOpenAPIConverter;
5053
import org.springdoc.core.customizers.ActuatorOpenApiCustomizer;
5154
import org.springdoc.core.customizers.ActuatorOperationCustomizer;
5255
import org.springdoc.core.customizers.DataRestDelegatingMethodParameterCustomizer;
@@ -609,4 +612,40 @@ CloudFunctionProvider springCloudFunctionProvider(Optional<FunctionCatalog> func
609612
ObjectMapperProvider springDocObjectMapperProvider(SpringDocConfigProperties springDocConfigProperties){
610613
return new ObjectMapperProvider(springDocConfigProperties);
611614
}
615+
616+
/**
617+
* The type Spring doc sort configuration.
618+
*/
619+
@ConditionalOnClass(Sort.class)
620+
static class SpringDocSortConfiguration {
621+
622+
/**
623+
* Sort open api converter.
624+
*
625+
* @param objectMapperProvider the object mapper provider
626+
* @return the sort open api converter
627+
*/
628+
@Bean
629+
@ConditionalOnMissingBean
630+
@ConditionalOnProperty(name = SPRINGDOC_SORT_CONVERTER_ENABLED, matchIfMissing = true)
631+
@Lazy(false)
632+
SortOpenAPIConverter sortOpenAPIConverter(ObjectMapperProvider objectMapperProvider) {
633+
getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Sort.class, org.springdoc.core.converters.models.Sort.class);
634+
return new SortOpenAPIConverter(objectMapperProvider);
635+
}
636+
637+
/**
638+
* Delegating method parameter customizer delegating method parameter customizer.
639+
*
640+
* @param optionalSpringDataWebPropertiesProvider the optional spring data web properties
641+
* @param optionalRepositoryRestConfiguration the optional repository rest configuration
642+
* @return the delegating method parameter customizer
643+
*/
644+
@Bean
645+
@ConditionalOnMissingBean
646+
@Lazy(false)
647+
DelegatingMethodParameterCustomizer delegatingMethodParameterCustomizer(Optional<SpringDataWebPropertiesProvider> optionalSpringDataWebPropertiesProvider, Optional<RepositoryRestConfigurationProvider> optionalRepositoryRestConfiguration) {
648+
return new DataRestDelegatingMethodParameterCustomizer(optionalSpringDataWebPropertiesProvider, optionalRepositoryRestConfiguration);
649+
}
650+
}
612651
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,85 @@
1-
package org.springdoc.core.converters;/**
2-
* @author bnasslahsen
3-
*/public class SortOpenAPIConverter {
4-
}
1+
package org.springdoc.core.converters;
2+
3+
/*
4+
*
5+
* *
6+
* * *
7+
* * * * Copyright 2019-2022 the original author or authors.
8+
* * * *
9+
* * * * Licensed under the Apache License, Version 2.0 (the "License");
10+
* * * * you may not use this file except in compliance with the License.
11+
* * * * You may obtain a copy of the License at
12+
* * * *
13+
* * * * https://www.apache.org/licenses/LICENSE-2.0
14+
* * * *
15+
* * * * Unless required by applicable law or agreed to in writing, software
16+
* * * * distributed under the License is distributed on an "AS IS" BASIS,
17+
* * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* * * * See the License for the specific language governing permissions and
19+
* * * * limitations under the License.
20+
* * *
21+
* *
22+
*
23+
*/
24+
import java.util.Iterator;
25+
26+
import com.fasterxml.jackson.databind.JavaType;
27+
import io.swagger.v3.core.converter.AnnotatedType;
28+
import io.swagger.v3.core.converter.ModelConverter;
29+
import io.swagger.v3.core.converter.ModelConverterContext;
30+
import io.swagger.v3.oas.models.media.Schema;
31+
import org.apache.commons.lang3.StringUtils;
32+
import org.springdoc.core.converters.models.Sort;
33+
import org.springdoc.core.providers.ObjectMapperProvider;
34+
35+
/**
36+
* The Spring Data Sort type model converter.
37+
* @author daniel-shuy
38+
*/
39+
public class SortOpenAPIConverter implements ModelConverter {
40+
41+
private static final String SORT_TO_REPLACE = "org.springframework.data.domain.Sort";
42+
43+
/**
44+
* The constant SORT.
45+
*/
46+
private static final AnnotatedType SORT = new AnnotatedType(Sort.class).resolveAsRef(true);
47+
48+
/**
49+
* The Spring doc object mapper.
50+
*/
51+
private final ObjectMapperProvider springDocObjectMapper;
52+
53+
/**
54+
* Instantiates a new Sort open api converter.
55+
*
56+
* @param springDocObjectMapper the spring doc object mapper
57+
*/
58+
public SortOpenAPIConverter(ObjectMapperProvider springDocObjectMapper) {
59+
this.springDocObjectMapper = springDocObjectMapper;
60+
}
61+
62+
/**
63+
* Resolve schema.
64+
*
65+
* @param type the type
66+
* @param context the context
67+
* @param chain the chain
68+
* @return the schema
69+
*/
70+
@Override
71+
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
72+
JavaType javaType = springDocObjectMapper.jsonMapper().constructType(type.getType());
73+
if (javaType != null) {
74+
Class<?> cls = javaType.getRawClass();
75+
if (SORT_TO_REPLACE.equals(cls.getCanonicalName())) {
76+
if (!type.isSchemaProperty())
77+
type = SORT;
78+
else
79+
type.name(cls.getSimpleName() + StringUtils.capitalize(type.getParent().getType()));
80+
}
81+
}
82+
return (chain.hasNext()) ? chain.next().resolve(type, context, chain) : null;
83+
}
84+
85+
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,107 @@
1-
package org.springdoc.core.converters.models;/**
2-
* @author bnasslahsen
3-
*/public class Sort {
4-
}
1+
package org.springdoc.core.converters.models;
2+
3+
/*
4+
*
5+
* *
6+
* * *
7+
* * * * Copyright 2019-2022 the original author or authors.
8+
* * * *
9+
* * * * Licensed under the Apache License, Version 2.0 (the "License");
10+
* * * * you may not use this file except in compliance with the License.
11+
* * * * You may obtain a copy of the License at
12+
* * * *
13+
* * * * https://www.apache.org/licenses/LICENSE-2.0
14+
* * * *
15+
* * * * Unless required by applicable law or agreed to in writing, software
16+
* * * * distributed under the License is distributed on an "AS IS" BASIS,
17+
* * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* * * * See the License for the specific language governing permissions and
19+
* * * * limitations under the License.
20+
* * *
21+
* *
22+
*
23+
*/
24+
25+
import java.util.List;
26+
import java.util.Objects;
27+
28+
import io.swagger.v3.oas.annotations.Parameter;
29+
import io.swagger.v3.oas.annotations.media.ArraySchema;
30+
import io.swagger.v3.oas.annotations.media.Schema;
31+
32+
/**
33+
* The Sort type.
34+
* @author daniel-shuy
35+
*/
36+
public class Sort {
37+
38+
/**
39+
* The Sort.
40+
*/
41+
@Parameter(description = "Sorting criteria in the format: property,(asc|desc). "
42+
+ "Default sort order is ascending. " + "Multiple sort criteria are supported."
43+
, name = "sort"
44+
, array = @ArraySchema(schema = @Schema(type = "string")))
45+
private List<String> sort;
46+
47+
/**
48+
* Instantiates a new Sort.
49+
*
50+
* @param sort the sort
51+
*/
52+
public Sort(List<String> sort) {
53+
this.sort = sort;
54+
}
55+
56+
/**
57+
* Gets sort.
58+
*
59+
* @return the sort
60+
*/
61+
public List<String> getSort() {
62+
return sort;
63+
}
64+
65+
/**
66+
* Sets sort.
67+
*
68+
* @param sort the sort
69+
*/
70+
public void setSort(List<String> sort) {
71+
if (sort == null) {
72+
this.sort.clear();
73+
}
74+
else {
75+
this.sort = sort;
76+
}
77+
}
78+
79+
/**
80+
* Add sort.
81+
*
82+
* @param sort the sort
83+
*/
84+
public void addSort(String sort) {
85+
this.sort.add(sort);
86+
}
87+
88+
@Override
89+
public boolean equals(Object o) {
90+
if (this == o) return true;
91+
if (o == null || getClass() != o.getClass()) return false;
92+
Sort sort = (Sort) o;
93+
return Objects.equals(this.sort, sort.sort);
94+
}
95+
96+
@Override
97+
public int hashCode() {
98+
return Objects.hash(sort);
99+
}
100+
101+
@Override
102+
public String toString() {
103+
return "Sort{" +
104+
"sort=" + sort +
105+
'}';
106+
}
107+
}

0 commit comments

Comments
 (0)