Skip to content

Commit d8d99f6

Browse files
committed
Spring Data Rest: Exception while generating api doc with inheritance - NullPointerException: Cannot invoke "String.substring(int)". Fixes #1095
1 parent 60e0512 commit d8d99f6

File tree

24 files changed

+3554
-141
lines changed

24 files changed

+3554
-141
lines changed

Diff for: springdoc-openapi-common/src/main/java/org/springdoc/core/RepositoryRestResourceProvider.java

+7
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,11 @@ public interface RepositoryRestResourceProvider {
3434
*/
3535
Map getHandlerMethods();
3636

37+
/**
38+
* Customize.
39+
*
40+
* @param openAPI the open api
41+
*/
42+
void customize(OpenAPI openAPI);
43+
3744
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ static class SpringRepositoryRestResourceProviderConfiguration {
175175
SpringRepositoryRestResourceProvider springRepositoryRestResourceProvider(ResourceMappings mappings,
176176
Repositories repositories, Associations associations, ApplicationContext applicationContext,
177177
DataRestRouterOperationService dataRestRouterOperationService, PersistentEntities persistentEntities,
178-
ObjectMapper mapper) {
178+
ObjectMapper mapper,SpringDocDataRestUtils springDocDataRestUtils) {
179179
return new SpringRepositoryRestResourceProvider(mappings, repositories, associations, applicationContext,
180-
dataRestRouterOperationService, persistentEntities, mapper);
180+
dataRestRouterOperationService, persistentEntities, mapper, springDocDataRestUtils);
181181
}
182182

183183
/**

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

+21-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.springdoc.data.rest.core.ControllerType;
4242
import org.springdoc.data.rest.core.DataRestRepository;
4343
import org.springdoc.data.rest.core.DataRestRouterOperationService;
44+
import org.springdoc.data.rest.utils.SpringDocDataRestUtils;
4445

4546
import org.springframework.context.ApplicationContext;
4647
import org.springframework.core.annotation.AnnotatedElementUtils;
@@ -151,6 +152,11 @@ public class SpringRepositoryRestResourceProvider implements RepositoryRestResou
151152
*/
152153
private List<HandlerMapping> handlerMappingList;
153154

155+
/**
156+
* The Spring doc data rest utils.
157+
*/
158+
private SpringDocDataRestUtils springDocDataRestUtils;
159+
154160
/**
155161
* Instantiates a new Spring repository rest resource provider.
156162
*
@@ -162,14 +168,17 @@ public class SpringRepositoryRestResourceProvider implements RepositoryRestResou
162168
* @param persistentEntities the persistent entities
163169
* @param mapper the mapper
164170
*/
165-
public SpringRepositoryRestResourceProvider(ResourceMappings mappings, Repositories repositories, Associations associations, ApplicationContext applicationContext, DataRestRouterOperationService dataRestRouterOperationService, PersistentEntities persistentEntities, ObjectMapper mapper) {
171+
public SpringRepositoryRestResourceProvider(ResourceMappings mappings, Repositories repositories,
172+
Associations associations, ApplicationContext applicationContext, DataRestRouterOperationService dataRestRouterOperationService,
173+
PersistentEntities persistentEntities, ObjectMapper mapper, SpringDocDataRestUtils springDocDataRestUtils) {
166174
this.mappings = mappings;
167175
this.repositories = repositories;
168176
this.associations = associations;
169177
this.applicationContext = applicationContext;
170178
this.dataRestRouterOperationService = dataRestRouterOperationService;
171179
this.persistentEntities = persistentEntities;
172180
this.mapper = mapper;
181+
this.springDocDataRestUtils = springDocDataRestUtils;
173182
}
174183

175184

@@ -266,6 +275,17 @@ public Map getHandlerMethods() {
266275
.filter(entry -> !entry.getValue().getBeanType().getName().startsWith(SPRING_DATA_REST_PACKAGE) && AnnotatedElementUtils.hasAnnotation(entry.getValue().getBeanType(), RepositoryRestController.class))
267276
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
268277
}
278+
279+
/**
280+
* Customize.
281+
*
282+
* @param openAPI the open api
283+
*/
284+
@Override
285+
public void customize(OpenAPI openAPI) {
286+
springDocDataRestUtils.customise(openAPI, mappings, persistentEntities);
287+
}
288+
269289
/**
270290
* Gets handler mapping list.
271291
*

Diff for: springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestOperationService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ private Operation buildEntityOperation(HandlerMethod handlerMethod, DataRestRepo
156156
domainType = dataRestRepository.getDomainType();
157157
Operation operation = initOperation(handlerMethod, domainType, requestMethod);
158158
dataRestRequestService.buildParameters(openAPI, handlerMethod, requestMethod, methodAttributes, operation, resourceMetadata, dataRestRepository);
159-
dataRestResponseService.buildEntityResponse(operation, handlerMethod, openAPI, requestMethod, operationPath, domainType, methodAttributes, dataRestRepository, resourceMetadata);
159+
dataRestResponseService.buildEntityResponse(operation, handlerMethod, openAPI, requestMethod, operationPath, methodAttributes, dataRestRepository, resourceMetadata);
160160
tagsBuilder.buildEntityTags(operation, handlerMethod, dataRestRepository);
161161
if (domainType != null)
162162
addOperationDescription(operation, requestMethod, domainType.getSimpleName().toLowerCase(), dataRestRepository);

Diff for: springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestRequestService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ else if (!RequestMethod.GET.equals(requestMethod)) {
233233
requestBuilder.applyBeanValidatorAnnotations(requestBodyInfo.getRequestBody(), parameterAnnotations, methodParameter.isOptional());
234234
operation.setRequestBody(requestBodyInfo.getRequestBody());
235235
Content content = operation.getRequestBody().getContent();
236-
springDocDataRestUtils.enhanceRequestBodyContent(openAPI, resourceMetadata, content, dataRestRepository);
236+
springDocDataRestUtils.buildTextUriContent(content);
237237
operation.getRequestBody().setRequired(true);
238238
}
239239
}

Diff for: springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestResponseService.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public void buildSearchResponse(Operation operation, HandlerMethod handlerMethod
120120
ApiResponse apiResponse = new ApiResponse();
121121
Type returnType = findSearchReturnType(methodResourceMapping, domainType);
122122
Content content = genericResponseService.buildContent(openAPI.getComponents(), methodParameterReturn.getParameterAnnotations(), methodAttributes.getMethodProduces(), null, returnType);
123-
springDocDataRestUtils.enhanceResponseContent(openAPI, resourceMetadata, content, dataRestRepository);
123+
springDocDataRestUtils.buildTextUriContent(content);
124124
apiResponse.setContent(content);
125125
addResponse200(apiResponses, apiResponse);
126126
addResponse404(apiResponses);
@@ -136,19 +136,18 @@ public void buildSearchResponse(Operation operation, HandlerMethod handlerMethod
136136
* @param openAPI the open api
137137
* @param requestMethod the request method
138138
* @param operationPath the operation path
139-
* @param domainType the domain type
140139
* @param methodAttributes the method attributes
141140
* @param dataRestRepository the data rest repository
142141
* @param resourceMetadata the resource metadata
143142
*/
144143
public void buildEntityResponse(Operation operation, HandlerMethod handlerMethod, OpenAPI openAPI, RequestMethod requestMethod,
145-
String operationPath, Class<?> domainType, MethodAttributes methodAttributes, DataRestRepository dataRestRepository, ResourceMetadata resourceMetadata) {
144+
String operationPath, MethodAttributes methodAttributes, DataRestRepository dataRestRepository, ResourceMetadata resourceMetadata) {
146145
MethodParameter methodParameterReturn = handlerMethod.getReturnType();
147146
Type returnType = getType(methodParameterReturn, requestMethod, dataRestRepository, resourceMetadata);
148147
ApiResponses apiResponses = new ApiResponses();
149148
ApiResponse apiResponse = new ApiResponse();
150149
Content content = genericResponseService.buildContent(openAPI.getComponents(), methodParameterReturn.getParameterAnnotations(), methodAttributes.getMethodProduces(), null, returnType);
151-
springDocDataRestUtils.enhanceResponseContent(openAPI, resourceMetadata, content, dataRestRepository);
150+
springDocDataRestUtils.buildTextUriContent(content);
152151
apiResponse.setContent(content);
153152
addResponse(requestMethod, operationPath, apiResponses, apiResponse);
154153
operation.setResponses(apiResponses);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package org.springdoc.data.rest.utils;
2+
3+
import java.util.List;
4+
5+
/**
6+
* The type Entity info.
7+
* @author bnasslashen
8+
*/
9+
public class EntityInfo {
10+
11+
/**
12+
* The Ignored fields.
13+
*/
14+
private List<String> ignoredFields;
15+
16+
/**
17+
* The Associations fields.
18+
*/
19+
private List<String> associationsFields;
20+
21+
/**
22+
* The Domain type.
23+
*/
24+
private Class<?> domainType;
25+
26+
/**
27+
* Gets ignored fields.
28+
*
29+
* @return the ignored fields
30+
*/
31+
public List<String> getIgnoredFields() {
32+
return ignoredFields;
33+
}
34+
35+
/**
36+
* Sets ignored fields.
37+
*
38+
* @param ignoredFields the ignored fields
39+
*/
40+
public void setIgnoredFields(List<String> ignoredFields) {
41+
this.ignoredFields = ignoredFields;
42+
}
43+
44+
/**
45+
* Gets associations fields.
46+
*
47+
* @return the associations fields
48+
*/
49+
public List<String> getAssociationsFields() {
50+
return associationsFields;
51+
}
52+
53+
/**
54+
* Sets associations fields.
55+
*
56+
* @param associationsFields the associations fields
57+
*/
58+
public void setAssociationsFields(List<String> associationsFields) {
59+
this.associationsFields = associationsFields;
60+
}
61+
62+
/**
63+
* Gets domain type.
64+
*
65+
* @return the domain type
66+
*/
67+
public Class<?> getDomainType() {
68+
return domainType;
69+
}
70+
71+
/**
72+
* Sets domain type.
73+
*
74+
* @param domainType the domain type
75+
*/
76+
public void setDomainType(Class<?> domainType) {
77+
this.domainType = domainType;
78+
}
79+
}

0 commit comments

Comments
 (0)