Skip to content

Commit b432293

Browse files
committed
Collection methods are added to the supported entity methods. Fixes #1105
1 parent d8d99f6 commit b432293

File tree

11 files changed

+349
-456
lines changed

11 files changed

+349
-456
lines changed

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

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ public class DataRestRouterOperationService {
7676
*/
7777
private static final String SEARCH_PATH = AntPathMatcher.DEFAULT_PATH_SEPARATOR + "{search}";
7878

79+
/**
80+
* The constant ID.
81+
*/
82+
private static final String ID = "/{id}";
83+
7984
/**
8085
* The Data rest operation builder.
8186
*/
@@ -161,33 +166,68 @@ private void buildRouterOperationList(List<RouterOperation> routerOperationList,
161166
String subPath, ControllerType controllerType, MethodResourceMapping methodResourceMapping) {
162167
RequestMappingInfo requestMappingInfo = entry.getKey();
163168
HandlerMethod handlerMethod = entry.getValue();
169+
Set<RequestMethod> requestMethodsItem = null;
170+
Set<RequestMethod> requestMethodsCollection = null;
171+
164172
Set<RequestMethod> requestMethods = requestMappingInfo.getMethodsCondition().getMethods();
165-
if (resourceMetadata != null && !controllerType.equals(ControllerType.SEARCH) ) {
173+
if (resourceMetadata != null && !controllerType.equals(ControllerType.SEARCH)) {
166174
HttpMethods httpMethodsItem = resourceMetadata.getSupportedHttpMethods().getMethodsFor(ResourceType.ITEM);
167-
Set<RequestMethod> requestMethodsItem = requestMethods.stream().filter(requestMethod -> httpMethodsItem.contains(HttpMethod.valueOf(requestMethod.toString())))
175+
requestMethodsItem = requestMethods.stream().filter(requestMethod -> httpMethodsItem.contains(HttpMethod.valueOf(requestMethod.toString())))
168176
.collect(Collectors.toSet());
177+
178+
buildRouterOperation(routerOperationList, resourceMetadata, dataRestRepository, openAPI, path,
179+
subPath, controllerType, methodResourceMapping, requestMappingInfo, handlerMethod, requestMethodsItem, ResourceType.ITEM);
180+
169181
if (!ControllerType.PROPERTY.equals(controllerType)) {
170182
HttpMethods httpMethodsCollection = resourceMetadata.getSupportedHttpMethods().getMethodsFor(ResourceType.COLLECTION);
171-
Set<RequestMethod> requestMethodsCollection = requestMethods.stream().filter(requestMethod -> httpMethodsCollection.contains(HttpMethod.valueOf(requestMethod.toString())))
183+
requestMethodsCollection = requestMethods.stream().filter(requestMethod -> httpMethodsCollection.contains(HttpMethod.valueOf(requestMethod.toString())))
172184
.collect(Collectors.toSet());
173-
requestMethodsItem.addAll(requestMethodsCollection);
185+
186+
buildRouterOperation(routerOperationList, resourceMetadata, dataRestRepository, openAPI, path,
187+
subPath, controllerType, methodResourceMapping, requestMappingInfo, handlerMethod, requestMethodsCollection, ResourceType.COLLECTION);
174188
}
175-
requestMethods = requestMethodsItem;
189+
190+
}
191+
else {
192+
buildRouterOperation(routerOperationList, resourceMetadata, dataRestRepository, openAPI, path,
193+
subPath, controllerType, methodResourceMapping, requestMappingInfo, handlerMethod, requestMethods, null);
176194
}
177195

196+
}
178197

179-
for (RequestMethod requestMethod : requestMethods) {
180-
if (!UNDOCUMENTED_REQUEST_METHODS.contains(requestMethod)) {
181-
Set<String> patterns = getActivePatterns(requestMappingInfo);
182-
if (!CollectionUtils.isEmpty(patterns)) {
183-
Map<String, String> regexMap = new LinkedHashMap<>();
184-
String relationName = dataRestRepository.getRelationName();
185-
String operationPath = calculateOperationPath(path, subPath, patterns, regexMap, controllerType, relationName);
186-
buildRouterOperation(routerOperationList, dataRestRepository, openAPI, methodResourceMapping,
187-
handlerMethod, requestMethod, resourceMetadata, operationPath, controllerType);
198+
/**
199+
* Build router operation.
200+
*
201+
* @param routerOperationList the router operation list
202+
* @param resourceMetadata the resource metadata
203+
* @param dataRestRepository the data rest repository
204+
* @param openAPI the open api
205+
* @param path the path
206+
* @param subPath the sub path
207+
* @param controllerType the controller type
208+
* @param methodResourceMapping the method resource mapping
209+
* @param requestMappingInfo the request mapping info
210+
* @param handlerMethod the handler method
211+
* @param requestMethodsCollection the request methods collection
212+
* @param collection the collection
213+
*/
214+
private void buildRouterOperation(List<RouterOperation> routerOperationList, ResourceMetadata resourceMetadata, DataRestRepository dataRestRepository,
215+
OpenAPI openAPI, String path, String subPath, ControllerType controllerType, MethodResourceMapping methodResourceMapping, RequestMappingInfo requestMappingInfo,
216+
HandlerMethod handlerMethod, Set<RequestMethod> requestMethodsCollection, ResourceType collection) {
217+
if (!CollectionUtils.isEmpty(requestMethodsCollection))
218+
for (RequestMethod requestMethod : requestMethodsCollection) {
219+
if (!UNDOCUMENTED_REQUEST_METHODS.contains(requestMethod)) {
220+
Set<String> patterns = getActivePatterns(requestMappingInfo);
221+
if (!CollectionUtils.isEmpty(patterns)) {
222+
Map<String, String> regexMap = new LinkedHashMap<>();
223+
String relationName = dataRestRepository.getRelationName();
224+
String operationPath = calculateOperationPath(path, subPath, patterns, regexMap, controllerType, relationName, collection);
225+
if (operationPath != null)
226+
buildRouterOperation(routerOperationList, dataRestRepository, openAPI, methodResourceMapping,
227+
handlerMethod, requestMethod, resourceMetadata, operationPath, controllerType);
228+
}
188229
}
189230
}
190-
}
191231
}
192232

193233
/**
@@ -199,15 +239,20 @@ private void buildRouterOperationList(List<RouterOperation> routerOperationList,
199239
* @param regexMap the regex map
200240
* @param controllerType the controller type
201241
* @param relationName the relation name
242+
* @param resourceType the resource type
202243
* @return the string
203244
*/
204245
private String calculateOperationPath(String path, String subPath, Set<String> patterns,
205-
Map<String, String> regexMap, ControllerType controllerType, String relationName) {
246+
Map<String, String> regexMap, ControllerType controllerType, String relationName, ResourceType resourceType) {
206247
String operationPath = null;
207248
for (String pattern : patterns) {
208249
operationPath = PathUtils.parsePath(pattern, regexMap);
209250
operationPath = operationPath.replace(REPOSITORY_PATH, path);
210-
if (ControllerType.SEARCH.equals(controllerType))
251+
if (ControllerType.ENTITY.equals(controllerType)) {
252+
if ((ResourceType.ITEM.equals(resourceType) && !operationPath.endsWith(ID)) || (ResourceType.COLLECTION.equals(resourceType) && operationPath.endsWith(ID)))
253+
operationPath = null;
254+
}
255+
else if (ControllerType.SEARCH.equals(controllerType))
211256
operationPath = operationPath.replace(SEARCH_PATH, subPath);
212257
else if (ControllerType.PROPERTY.equals(controllerType))
213258
operationPath = operationPath.replace("{property}", relationName);
@@ -228,9 +273,12 @@ else if (ControllerType.PROPERTY.equals(controllerType))
228273
* @param operationPath the operation path
229274
* @param controllerType the controller type
230275
*/
231-
private void buildRouterOperation(List<RouterOperation> routerOperationList, DataRestRepository dataRestRepository, OpenAPI openAPI,
276+
private void buildRouterOperation
277+
(List<RouterOperation> routerOperationList, DataRestRepository
278+
dataRestRepository, OpenAPI openAPI,
232279
MethodResourceMapping methodResourceMapping, HandlerMethod handlerMethod,
233-
RequestMethod requestMethod, ResourceMetadata resourceMetadata, String operationPath, ControllerType controllerType) {
280+
RequestMethod requestMethod, ResourceMetadata resourceMetadata, String
281+
operationPath, ControllerType controllerType) {
234282
RouterOperation routerOperation = new RouterOperation(operationPath, new RequestMethod[] { requestMethod });
235283
MethodAttributes methodAttributes = new MethodAttributes(springDocConfigProperties.getDefaultConsumesMediaType(), springDocConfigProperties.getDefaultProducesMediaType());
236284
methodAttributes.calculateConsumesProduces(handlerMethod.getMethod());
@@ -249,7 +297,8 @@ private void buildRouterOperation(List<RouterOperation> routerOperationList, Dat
249297
* @param handlerMethodMap the handler method map
250298
* @return the search entry
251299
*/
252-
private Optional<Entry<RequestMappingInfo, HandlerMethod>> getSearchEntry(Map<RequestMappingInfo, HandlerMethod> handlerMethodMap) {
300+
private Optional<Entry<RequestMappingInfo, HandlerMethod>> getSearchEntry
301+
(Map<RequestMappingInfo, HandlerMethod> handlerMethodMap) {
253302
return handlerMethodMap.entrySet().stream().filter(
254303
requestMappingInfoHandlerMethodEntry -> {
255304
RequestMappingInfo requestMappingInfo = requestMappingInfoHandlerMethodEntry.getKey();
@@ -271,7 +320,8 @@ private Optional<Entry<RequestMappingInfo, HandlerMethod>> getSearchEntry(Map<Re
271320
* @param requestMethod the request method
272321
* @return the boolean
273322
*/
274-
private boolean isSearchControllerPresent(RequestMappingInfo requestMappingInfo, HandlerMethod handlerMethod, RequestMethod requestMethod) {
323+
private boolean isSearchControllerPresent(RequestMappingInfo
324+
requestMappingInfo, HandlerMethod handlerMethod, RequestMethod requestMethod) {
275325
if (!UNDOCUMENTED_REQUEST_METHODS.contains(requestMethod)) {
276326
Set<String> patterns = getActivePatterns(requestMappingInfo);
277327
if (!CollectionUtils.isEmpty(patterns)) {

springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app10/CustomerRepository.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323

2424
package test.org.springdoc.api.app10;
2525

26+
import java.util.List;
27+
import java.util.Optional;
28+
2629
import org.springframework.data.domain.Page;
2730
import org.springframework.data.domain.Pageable;
2831
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -55,4 +58,16 @@ public interface CustomerRepository extends CrudRepository<Customer, Long>, JpaS
5558
@Override
5659
@RestResource(exported = false)
5760
void delete(Customer entity);
61+
62+
@Override
63+
@RestResource
64+
List<Customer> findAll();
65+
66+
@Override
67+
@RestResource(exported = false)
68+
Optional<Customer> findById(Long aLong);
69+
70+
@Override
71+
@RestResource(exported = false)
72+
<S extends Customer> S save(S entity);
5873
}

0 commit comments

Comments
 (0)