Skip to content

Commit 16febf1

Browse files
author
bnasslahsen
committed
@RepositoryRestResource Support. Fixes #644.
1 parent fc942ba commit 16febf1

File tree

6 files changed

+109
-93
lines changed

6 files changed

+109
-93
lines changed

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

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -223,29 +223,34 @@ Schema calculateSchema(Components components, ParameterInfo parameterInfo, Reque
223223
schemaN = parameterInfo.getParameterModel().getSchema();
224224

225225
if (requestBodyInfo != null) {
226-
if (schemaN != null && StringUtils.isEmpty(schemaN.getDescription()) && parameterInfo.getParameterModel() != null) {
227-
String description = parameterInfo.getParameterModel().getDescription();
228-
if (schemaN.get$ref() != null && schemaN.get$ref().contains(AnnotationsUtils.COMPONENTS_REF)) {
229-
String key = schemaN.get$ref().substring(21);
230-
Schema existingSchema = components.getSchemas().get(key);
231-
existingSchema.setDescription(description);
232-
}
233-
else
234-
schemaN.setDescription(description);
235-
}
226+
schemaN = calculateRequestBodySchema(components, parameterInfo, requestBodyInfo, schemaN, paramName);
227+
}
236228

237-
if (requestBodyInfo.getMergedSchema() != null) {
238-
requestBodyInfo.getMergedSchema().addProperties(paramName, schemaN);
239-
schemaN = requestBodyInfo.getMergedSchema();
240-
}
241-
else if (schemaN instanceof FileSchema || schemaN instanceof ArraySchema && ((ArraySchema) schemaN).getItems() instanceof FileSchema) {
242-
schemaN = new ObjectSchema().addProperties(paramName, schemaN);
243-
requestBodyInfo.setMergedSchema(schemaN);
229+
return schemaN;
230+
}
231+
232+
private Schema calculateRequestBodySchema(Components components, ParameterInfo parameterInfo, RequestBodyInfo requestBodyInfo, Schema schemaN, String paramName) {
233+
if (schemaN != null && StringUtils.isEmpty(schemaN.getDescription()) && parameterInfo.getParameterModel() != null) {
234+
String description = parameterInfo.getParameterModel().getDescription();
235+
if (schemaN.get$ref() != null && schemaN.get$ref().contains(AnnotationsUtils.COMPONENTS_REF)) {
236+
String key = schemaN.get$ref().substring(21);
237+
Schema existingSchema = components.getSchemas().get(key);
238+
existingSchema.setDescription(description);
244239
}
245240
else
246-
requestBodyInfo.addProperties(paramName, schemaN);
241+
schemaN.setDescription(description);
247242
}
248243

244+
if (requestBodyInfo.getMergedSchema() != null) {
245+
requestBodyInfo.getMergedSchema().addProperties(paramName, schemaN);
246+
schemaN = requestBodyInfo.getMergedSchema();
247+
}
248+
else if (schemaN instanceof FileSchema || schemaN instanceof ArraySchema && ((ArraySchema) schemaN).getItems() instanceof FileSchema) {
249+
schemaN = new ObjectSchema().addProperties(paramName, schemaN);
250+
requestBodyInfo.setMergedSchema(schemaN);
251+
}
252+
else
253+
requestBodyInfo.addProperties(paramName, schemaN);
249254
return schemaN;
250255
}
251256

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

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,7 @@ else if (genericType instanceof ParameterizedType) {
6060
Class<?>[] generics = new Class<?>[parameterizedType.getActualTypeArguments().length];
6161
Type[] typeArguments = parameterizedType.getActualTypeArguments();
6262
ResolvableType contextType = ResolvableType.forClass(contextClass);
63-
for (int i = 0; i < typeArguments.length; i++) {
64-
Type typeArgument = typeArguments[i];
65-
if (typeArgument instanceof TypeVariable) {
66-
ResolvableType resolvedTypeArgument = resolveVariable(
67-
(TypeVariable<?>) typeArgument, contextType);
68-
if (resolvedTypeArgument != ResolvableType.NONE) {
69-
generics[i] = resolvedTypeArgument.resolve();
70-
}
71-
else {
72-
generics[i] = ResolvableType.forType(typeArgument).resolve();
73-
}
74-
}
75-
else {
76-
generics[i] = ResolvableType.forType(typeArgument).resolve();
77-
}
78-
}
63+
findTypeForGenerics(generics, typeArguments, contextType);
7964
Class<?> rawClass = resolvedType.getRawClass();
8065
if (rawClass != null) {
8166
return ResolvableType.forClassWithGenerics(rawClass, generics).getType();
@@ -86,6 +71,25 @@ else if (genericType instanceof ParameterizedType) {
8671
return genericType;
8772
}
8873

74+
static void findTypeForGenerics(Class<?>[] generics, Type[] typeArguments, ResolvableType contextType) {
75+
for (int i = 0; i < typeArguments.length; i++) {
76+
Type typeArgument = typeArguments[i];
77+
if (typeArgument instanceof TypeVariable) {
78+
ResolvableType resolvedTypeArgument = resolveVariable(
79+
(TypeVariable<?>) typeArgument, contextType);
80+
if (resolvedTypeArgument != ResolvableType.NONE) {
81+
generics[i] = resolvedTypeArgument.resolve();
82+
}
83+
else {
84+
generics[i] = ResolvableType.forType(typeArgument).resolve();
85+
}
86+
}
87+
else {
88+
generics[i] = ResolvableType.forType(typeArgument).resolve();
89+
}
90+
}
91+
}
92+
8993
static ResolvableType resolveVariable(TypeVariable<?> typeVariable, ResolvableType contextType) {
9094
ResolvableType resolvedType;
9195
if (contextType.hasGenerics()) {

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

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ public SpringRepositoryRestResourceProvider(ResourceMappings mappings, Repositor
8282
public List<RouterOperation> getRouterOperations(OpenAPI openAPI) {
8383
List<RouterOperation> routerOperationList = new ArrayList<>();
8484
List<HandlerMapping> handlerMappingList = delegatingHandlerMapping.getDelegates();
85-
boolean profileIsDone = false;
8685
for (Class<?> domainType : repositories) {
8786
ResourceMetadata resourceMetadata = mappings.getMetadataFor(domainType);
8887
if (resourceMetadata.isExported()) {
@@ -108,8 +107,6 @@ else if (handlerMapping instanceof BasePathAwareHandlerMapping) {
108107
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1));
109108

110109
findControllers(routerOperationList, handlerMethodMapFiltered, resourceMetadata, domainType, openAPI);
111-
if (profileIsDone)
112-
continue;
113110
handlerMethodMapFiltered = handlerMethodMap.entrySet().stream()
114111
.filter(requestMappingInfoHandlerMethodEntry -> ProfileController.class.equals(requestMappingInfoHandlerMethodEntry
115112
.getValue().getBeanType()) || AlpsController.class.equals(requestMappingInfoHandlerMethodEntry
@@ -120,24 +117,28 @@ else if (handlerMapping instanceof BasePathAwareHandlerMapping) {
120117
}
121118
}
122119
// search
123-
for (HandlerMapping handlerMapping : handlerMappingList) {
124-
if (handlerMapping instanceof RepositoryRestHandlerMapping) {
125-
RepositoryRestHandlerMapping repositoryRestHandlerMapping = (RepositoryRestHandlerMapping) handlerMapping;
126-
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = repositoryRestHandlerMapping.getHandlerMethods();
127-
Map<RequestMappingInfo, HandlerMethod> handlerMethodMapFiltered = handlerMethodMap.entrySet().stream()
128-
.filter(requestMappingInfoHandlerMethodEntry -> REPOSITORY_SERACH_CONTROLLER.equals(requestMappingInfoHandlerMethodEntry
129-
.getValue().getBeanType().getName()))
130-
.filter(controller -> !AbstractOpenApiResource.isHiddenRestControllers(controller.getValue().getBeanType()))
131-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1));
132-
ResourceMetadata metadata = associations.getMetadataFor(domainType);
133-
SearchResourceMappings searchResourceMappings = metadata.getSearchResourceMappings();
134-
if (searchResourceMappings.isExported()) {
135-
findSearchControllers(routerOperationList, handlerMethodMapFiltered, resourceMetadata, domainType, openAPI, searchResourceMappings);
136-
}
120+
findSearchResourceMappings(openAPI, routerOperationList, handlerMappingList, domainType, resourceMetadata);
121+
}
122+
return routerOperationList;
123+
}
124+
125+
private void findSearchResourceMappings(OpenAPI openAPI, List<RouterOperation> routerOperationList, List<HandlerMapping> handlerMappingList, Class<?> domainType, ResourceMetadata resourceMetadata) {
126+
for (HandlerMapping handlerMapping : handlerMappingList) {
127+
if (handlerMapping instanceof RepositoryRestHandlerMapping) {
128+
RepositoryRestHandlerMapping repositoryRestHandlerMapping = (RepositoryRestHandlerMapping) handlerMapping;
129+
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = repositoryRestHandlerMapping.getHandlerMethods();
130+
Map<RequestMappingInfo, HandlerMethod> handlerMethodMapFiltered = handlerMethodMap.entrySet().stream()
131+
.filter(requestMappingInfoHandlerMethodEntry -> REPOSITORY_SERACH_CONTROLLER.equals(requestMappingInfoHandlerMethodEntry
132+
.getValue().getBeanType().getName()))
133+
.filter(controller -> !AbstractOpenApiResource.isHiddenRestControllers(controller.getValue().getBeanType()))
134+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1));
135+
ResourceMetadata metadata = associations.getMetadataFor(domainType);
136+
SearchResourceMappings searchResourceMappings = metadata.getSearchResourceMappings();
137+
if (searchResourceMappings.isExported()) {
138+
findSearchControllers(routerOperationList, handlerMethodMapFiltered, resourceMetadata, domainType, openAPI, searchResourceMappings);
137139
}
138140
}
139141
}
140-
return routerOperationList;
141142
}
142143

143144
private List<RouterOperation> findSearchControllers(List<RouterOperation> routerOperationList,

springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestTagsBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
import io.swagger.v3.oas.models.OpenAPI;
2727
import io.swagger.v3.oas.models.Operation;
2828
import org.springdoc.core.OpenAPIBuilder;
29+
import org.springdoc.data.rest.SpringRepositoryRestResourceProvider;
2930

31+
import org.springframework.data.rest.webmvc.ProfileController;
32+
import org.springframework.data.rest.webmvc.alps.AlpsController;
3033
import org.springframework.web.method.HandlerMethod;
3134

3235
public class DataRestTagsBuilder {
@@ -51,7 +54,10 @@ private void buildTags(Operation operation, OpenAPI openAPI, HandlerMethod handl
5154
Class<?> domainType) {
5255
if (openAPIBuilder.isAutoTagClasses(operation)) {
5356
String tagName = handlerMethod.getBeanType().getSimpleName();
54-
if (domainType != null)
57+
if(SpringRepositoryRestResourceProvider.REPOSITORY_SCHEMA_CONTROLLER.equals(handlerMethod.getBeanType().getName())
58+
|| AlpsController.class.equals(handlerMethod.getBeanType()))
59+
tagName = ProfileController.class.getSimpleName();
60+
else if (domainType != null)
5561
tagName = tagName.replace("Repository", domainType.getSimpleName());
5662
operation.addTagsItem(OpenAPIBuilder.splitCamelCase(tagName));
5763
}

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

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,7 @@
11631163
"/profile/accounts": {
11641164
"get": {
11651165
"tags": [
1166-
"alps-controller"
1166+
"profile-controller"
11671167
],
11681168
"operationId": "descriptor_1",
11691169
"responses": {
@@ -1193,7 +1193,7 @@
11931193
"/profile/customers": {
11941194
"get": {
11951195
"tags": [
1196-
"alps-controller"
1196+
"profile-controller"
11971197
],
11981198
"operationId": "descriptor_2",
11991199
"responses": {
@@ -1327,25 +1327,6 @@
13271327
}
13281328
}
13291329
},
1330-
"CollectionModelAccount": {
1331-
"type": "object",
1332-
"properties": {
1333-
"_embedded": {
1334-
"type": "object",
1335-
"properties": {
1336-
"accounts": {
1337-
"type": "array",
1338-
"items": {
1339-
"$ref": "#/components/schemas/Account"
1340-
}
1341-
}
1342-
}
1343-
},
1344-
"_links": {
1345-
"$ref": "#/components/schemas/Links"
1346-
}
1347-
}
1348-
},
13491330
"Customer": {
13501331
"type": "object",
13511332
"properties": {
@@ -1361,16 +1342,16 @@
13611342
}
13621343
}
13631344
},
1364-
"CollectionModelObject": {
1345+
"CollectionModelAccount": {
13651346
"type": "object",
13661347
"properties": {
13671348
"_embedded": {
13681349
"type": "object",
13691350
"properties": {
1370-
"objects": {
1351+
"accounts": {
13711352
"type": "array",
13721353
"items": {
1373-
"type": "object"
1354+
"$ref": "#/components/schemas/Account"
13741355
}
13751356
}
13761357
}
@@ -1399,6 +1380,25 @@
13991380
}
14001381
}
14011382
},
1383+
"CollectionModelObject": {
1384+
"type": "object",
1385+
"properties": {
1386+
"_embedded": {
1387+
"type": "object",
1388+
"properties": {
1389+
"objects": {
1390+
"type": "array",
1391+
"items": {
1392+
"type": "object"
1393+
}
1394+
}
1395+
}
1396+
},
1397+
"_links": {
1398+
"$ref": "#/components/schemas/Links"
1399+
}
1400+
}
1401+
},
14021402
"RepresentationModelCustomer": {
14031403
"type": "object",
14041404
"properties": {

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@
667667
"/profile/peopleme": {
668668
"get": {
669669
"tags": [
670-
"alps-controller"
670+
"profile-controller"
671671
],
672672
"operationId": "descriptor_1",
673673
"responses": {
@@ -785,6 +785,17 @@
785785
}
786786
}
787787
},
788+
"Person": {
789+
"type": "object",
790+
"properties": {
791+
"firstName": {
792+
"type": "string"
793+
},
794+
"lastName": {
795+
"type": "string"
796+
}
797+
}
798+
},
788799
"CollectionModelPerson": {
789800
"type": "object",
790801
"properties": {
@@ -804,14 +815,17 @@
804815
}
805816
}
806817
},
807-
"Person": {
818+
"EntityModelPerson": {
808819
"type": "object",
809820
"properties": {
810821
"firstName": {
811822
"type": "string"
812823
},
813824
"lastName": {
814825
"type": "string"
826+
},
827+
"_links": {
828+
"$ref": "#/components/schemas/Links"
815829
}
816830
}
817831
},
@@ -834,20 +848,6 @@
834848
}
835849
}
836850
},
837-
"EntityModelPerson": {
838-
"type": "object",
839-
"properties": {
840-
"firstName": {
841-
"type": "string"
842-
},
843-
"lastName": {
844-
"type": "string"
845-
},
846-
"_links": {
847-
"$ref": "#/components/schemas/Links"
848-
}
849-
}
850-
},
851851
"Link": {
852852
"type": "object",
853853
"properties": {

0 commit comments

Comments
 (0)