Skip to content

Commit 5908c8e

Browse files
committed
Derive documentation from javadoc. Fixes #38.
1 parent 4ba3bde commit 5908c8e

File tree

688 files changed

+51480
-34
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

688 files changed

+51480
-34
lines changed

pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
<module>springdoc-openapi-groovy</module>
6161
<module>springdoc-openapi-ui</module>
6262
<module>springdoc-openapi-webflux-ui</module>
63+
<module>springdoc-openapi-javadoc</module>
6364
</modules>
6465

6566
<properties>
@@ -76,6 +77,7 @@
7677
<javax.jws-api.version>1.1</javax.jws-api.version>
7778
<jjwt.version>0.9.1</jjwt.version>
7879
<spring-native.version>0.10.1</spring-native.version>
80+
<therapi-runtime-javadoc.version>0.12.0</therapi-runtime-javadoc.version>
7981
</properties>
8082

8183
<dependencyManagement>

springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import org.springdoc.core.ActuatorProvider;
7777
import org.springdoc.core.GenericParameterService;
7878
import org.springdoc.core.GenericResponseService;
79+
import org.springdoc.core.JavadocProvider;
7980
import org.springdoc.core.MethodAttributes;
8081
import org.springdoc.core.OpenAPIService;
8182
import org.springdoc.core.OperationService;
@@ -302,7 +303,7 @@ protected synchronized OpenAPI getOpenApi() {
302303
LOGGER.info("Init duration for springdoc-openapi is: {} ms",
303304
Duration.between(start, Instant.now()).toMillis());
304305
}
305-
else{
306+
else {
306307
LOGGER.debug("Fetching openApi document from cache");
307308
openApi = openAPIService.updateServers(openAPIService.getCachedOpenAPI());
308309
}
@@ -341,6 +342,8 @@ protected void calculatePath(HandlerMethod handlerMethod, RouterOperation router
341342
operationMap = pathItem.readOperationsMap();
342343
}
343344

345+
JavadocProvider javadocProvider = operationParser.getJavadocProvider();
346+
344347
for (RequestMethod requestMethod : requestMethods) {
345348
Operation existingOperation = getExistingOperation(operationMap, requestMethod);
346349
Method method = handlerMethod.getMethod();
@@ -353,6 +356,10 @@ protected void calculatePath(HandlerMethod handlerMethod, RouterOperation router
353356

354357
MethodAttributes methodAttributes = new MethodAttributes(springDocConfigProperties.getDefaultConsumesMediaType(), springDocConfigProperties.getDefaultProducesMediaType(), methodConsumes, methodProduces, headers);
355358
methodAttributes.setMethodOverloaded(existingOperation != null);
359+
//Use the javadoc return if present
360+
if (javadocProvider != null) {
361+
methodAttributes.setJavadocReturn(javadocProvider.getMethodJavadocReturn(handlerMethod.getMethod()));
362+
}
356363

357364
if (reqMappingClass != null) {
358365
methodAttributes.setClassConsumes(reqMappingClass.consumes());
@@ -395,6 +402,13 @@ protected void calculatePath(HandlerMethod handlerMethod, RouterOperation router
395402
ApiResponses apiResponses = responseBuilder.build(components, handlerMethod, operation, methodAttributes);
396403
operation.setResponses(apiResponses);
397404

405+
// get javadoc method description
406+
if (javadocProvider != null) {
407+
String description = javadocProvider.getMethodJavadocDescription(handlerMethod.getMethod());
408+
if (!StringUtils.isEmpty(description) && StringUtils.isEmpty(operation.getDescription()))
409+
operation.setDescription(description);
410+
}
411+
398412
Set<io.swagger.v3.oas.annotations.callbacks.Callback> apiCallbacks = AnnotatedElementUtils.findMergedRepeatableAnnotations(method, io.swagger.v3.oas.annotations.callbacks.Callback.class);
399413

400414
// callbacks
@@ -506,12 +520,12 @@ protected void calculatePath(RouterOperation routerOperation) {
506520
operation.getParameters().stream()
507521
.filter(parameter -> StringUtils.isEmpty(parameter.get$ref()))
508522
.forEach(parameter -> {
509-
if (parameter.getSchema() == null)
510-
parameter.setSchema(new StringSchema());
511-
if (parameter.getIn() == null)
512-
parameter.setIn(ParameterIn.QUERY.toString());
513-
}
514-
);
523+
if (parameter.getSchema() == null)
524+
parameter.setSchema(new StringSchema());
525+
if (parameter.getIn() == null)
526+
parameter.setIn(ParameterIn.QUERY.toString());
527+
}
528+
);
515529
PathItem pathItemObject = buildPathItem(requestMethod, operation, operationPath, paths);
516530
paths.addPathItem(operationPath, pathItemObject);
517531
}
@@ -687,7 +701,7 @@ public static boolean containsResponseBody(HandlerMethod handlerMethod) {
687701
ResponseBody responseBodyAnnotation = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), ResponseBody.class);
688702
if (responseBodyAnnotation == null)
689703
responseBodyAnnotation = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), ResponseBody.class);
690-
return responseBodyAnnotation!=null;
704+
return responseBodyAnnotation != null;
691705
}
692706

693707

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod,
236236
Map<String, io.swagger.v3.oas.annotations.Parameter> parametersDocMap = getApiParameters(handlerMethod.getMethod());
237237
Components components = openAPI.getComponents();
238238

239+
JavadocProvider javadocProvider = operationService.getJavadocProvider();
240+
239241
for (MethodParameter methodParameter : parameters) {
240242
// check if query param
241243
Parameter parameter;
@@ -252,6 +254,7 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod,
252254
if (parameterDoc != null) {
253255
if (parameterDoc.hidden() || parameterDoc.schema().hidden())
254256
continue;
257+
255258
parameter = parameterBuilder.buildParameterFromDoc(parameterDoc, components, methodAttributes.getJsonViewAnnotation());
256259
parameterInfo.setParameterModel(parameter);
257260
}
@@ -261,15 +264,31 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod,
261264
// Merge with the operation parameters
262265
parameter = GenericParameterService.mergeParameter(operationParameters, parameter);
263266
List<Annotation> parameterAnnotations = Arrays.asList(methodParameter.getParameterAnnotations());
264-
if (isValidParameter(parameter))
267+
if (isValidParameter(parameter)) {
268+
// Add param javadoc
269+
if (StringUtils.isBlank(parameter.getDescription()) && javadocProvider != null) {
270+
String paramJavadocDescription = javadocProvider.getParamJavadoc(handlerMethod.getMethod(), pName);
271+
if (!StringUtils.isBlank(paramJavadocDescription)) {
272+
parameter.setDescription(paramJavadocDescription);
273+
}
274+
}
265275
applyBeanValidatorAnnotations(parameter, parameterAnnotations);
276+
}
266277
else if (!RequestMethod.GET.equals(requestMethod)) {
267278
if (operation.getRequestBody() != null)
268279
requestBodyInfo.setRequestBody(operation.getRequestBody());
269280
requestBodyService.calculateRequestBodyInfo(components, methodAttributes,
270281
parameterInfo, requestBodyInfo);
282+
// Add requestBody javadoc
283+
if (StringUtils.isBlank(requestBodyInfo.getRequestBody().getDescription()) && javadocProvider != null) {
284+
String paramJavadocDescription = javadocProvider.getParamJavadoc(handlerMethod.getMethod(), pName);
285+
if (!StringUtils.isBlank(paramJavadocDescription)) {
286+
requestBodyInfo.getRequestBody().setDescription(paramJavadocDescription);
287+
}
288+
}
271289
applyBeanValidatorAnnotations(requestBodyInfo.getRequestBody(), parameterAnnotations, methodParameter.isOptional());
272290
}
291+
273292
customiseParameter(parameter, parameterInfo);
274293
}
275294
}

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ public void buildGenericResponse(Components components, Map<String, Object> find
168168
springDocConfigProperties.getDefaultProducesMediaType(), controllerAdviceInfoApiResponseMap);
169169
//calculate JsonView Annotation
170170
methodAttributes.setJsonViewAnnotation(AnnotatedElementUtils.findMergedAnnotation(method, JsonView.class));
171+
//use the javadoc return if present
172+
if (operationService.getJavadocProvider() != null) {
173+
JavadocProvider javadocProvider = operationService.getJavadocProvider();
174+
methodAttributes.setJavadocReturn(javadocProvider.getMethodJavadocReturn(methodParameter.getMethod()));
175+
}
171176
Map<String, ApiResponse> apiResponses = computeResponseFromDoc(components, methodParameter, apiResponsesOp, methodAttributes);
172177
buildGenericApiResponses(components, methodParameter, apiResponsesOp, methodAttributes);
173178
apiResponses.forEach(controllerAdviceInfoApiResponseMap::put);
@@ -456,7 +461,11 @@ private void buildApiResponses(Components components, MethodParameter methodPara
456461
else if (CollectionUtils.isEmpty(apiResponse.getContent()))
457462
apiResponse.setContent(null);
458463
if (StringUtils.isBlank(apiResponse.getDescription())) {
459-
setDescription(httpCode, apiResponse);
464+
// use javadoc
465+
if (!StringUtils.isBlank(methodAttributes.getJavadocReturn()))
466+
apiResponse.setDescription(methodAttributes.getJavadocReturn());
467+
else
468+
setDescription(httpCode, apiResponse);
460469
}
461470
}
462471
if (apiResponse.getContent() != null
@@ -551,7 +560,7 @@ private Map<String, ApiResponse> getGenericMapResponse(Class<?> beanType) {
551560
private boolean isValidHttpCode(String httpCode, MethodParameter methodParameter) {
552561
boolean result = false;
553562
final Method method = methodParameter.getMethod();
554-
if(method!=null){
563+
if (method != null) {
555564
Set<io.swagger.v3.oas.annotations.responses.ApiResponse> responseSet = getApiResponses(method);
556565
if (isHttpCodePresent(httpCode, responseSet))
557566
result = true;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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;
22+
23+
import java.lang.reflect.Field;
24+
import java.lang.reflect.Method;
25+
26+
/**
27+
* The interface Javadoc provider.
28+
* @author bnasslashen
29+
*/
30+
public interface JavadocProvider {
31+
32+
/**
33+
* Gets method description.
34+
*
35+
* @param method the method
36+
* @return the method description
37+
*/
38+
String getMethodJavadocDescription(Method method);
39+
40+
/**
41+
* Gets method javadoc return.
42+
*
43+
* @param method the method
44+
* @return the method javadoc return
45+
*/
46+
String getMethodJavadocReturn(Method method);
47+
48+
/**
49+
* Gets param javadoc.
50+
*
51+
* @param method the method
52+
* @param name the name
53+
* @return the param javadoc
54+
*/
55+
String getParamJavadoc(Method method, String name);
56+
57+
String getFieldJavadoc(Field field);
58+
}
59+

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ public class MethodAttributes {
107107
*/
108108
private Map<String, ApiResponse> genericMapResponse = new LinkedHashMap<>();
109109

110+
/**
111+
* The javadoc Return.
112+
*/
113+
private String javadocReturn;
114+
110115
/**
111116
* Instantiates a new Method attributes.
112117
*
@@ -420,4 +425,22 @@ public void calculateHeadersForClass(Class<?> declaringClass) {
420425
fillMethods(reqMappingClass.produces(), reqMappingClass.consumes(), reqMappingClass.headers());
421426
}
422427
}
428+
429+
/**
430+
* Gets javadoc return value
431+
*
432+
* @return the javadoc return
433+
*/
434+
public String getJavadocReturn() {
435+
return javadocReturn;
436+
}
437+
438+
/**
439+
* Sets javadoc return value.
440+
*
441+
* @param javadocReturn the javadoc return value
442+
*/
443+
public void setJavadocReturn(String javadocReturn) {
444+
this.javadocReturn = javadocReturn;
445+
}
423446
}

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,21 +86,27 @@ public class OperationService {
8686
*/
8787
private final PropertyResolverUtils propertyResolverUtils;
8888

89+
/**
90+
* The javadoc provider.
91+
*/
92+
private final Optional<JavadocProvider> javadocProvider;
93+
8994
/**
9095
* Instantiates a new Operation builder.
91-
*
9296
* @param parameterBuilder the parameter builder
9397
* @param requestBodyService the request body builder
9498
* @param securityParser the security parser
9599
* @param propertyResolverUtils the property resolver utils
100+
* @param javadocProvider the javadoc provider
96101
*/
97102
public OperationService(GenericParameterService parameterBuilder, RequestBodyService requestBodyService,
98-
SecurityService securityParser, PropertyResolverUtils propertyResolverUtils) {
103+
SecurityService securityParser, PropertyResolverUtils propertyResolverUtils, Optional<JavadocProvider> javadocProvider) {
99104
super();
100105
this.parameterBuilder = parameterBuilder;
101106
this.requestBodyService = requestBodyService;
102107
this.securityParser = securityParser;
103108
this.propertyResolverUtils = propertyResolverUtils;
109+
this.javadocProvider = javadocProvider;
104110
}
105111

106112
/**
@@ -389,7 +395,7 @@ private Optional<ApiResponses> getApiResponses(
389395
setRef(apiResponsesObject, response, apiResponseObject);
390396
continue;
391397
}
392-
setDescription(response, apiResponseObject);
398+
setDescription(response, apiResponseObject, methodAttributes.getJavadocReturn());
393399
setExtensions(response, apiResponseObject);
394400

395401
buildResponseContent(methodAttributes, components, classProduces, methodProduces, apiResponsesOp, response, apiResponseObject);
@@ -460,13 +466,17 @@ private void setLinks(io.swagger.v3.oas.annotations.responses.ApiResponse respon
460466
* Sets description.
461467
*
462468
* @param response the response
469+
* @param response the javadocReturn
463470
* @param apiResponseObject the api response object
464471
*/
465472
private void setDescription(io.swagger.v3.oas.annotations.responses.ApiResponse response,
466-
ApiResponse apiResponseObject) {
473+
ApiResponse apiResponseObject, String javadocReturn) {
467474
if (StringUtils.isNotBlank(response.description())) {
468475
apiResponseObject.setDescription(response.description());
469476
}
477+
else if (StringUtils.isNotBlank(javadocReturn)) {
478+
apiResponseObject.setDescription(javadocReturn);
479+
}
470480
else {
471481
GenericResponseService.setDescription(response.responseCode(), apiResponseObject);
472482
}
@@ -608,4 +618,13 @@ public Operation mergeOperation(Operation operation, Operation operationModel) {
608618
}
609619
return operation;
610620
}
621+
622+
/**
623+
* Gets javadoc provider.
624+
*
625+
* @return the javadoc provider
626+
*/
627+
public JavadocProvider getJavadocProvider() {
628+
return javadocProvider.orElse(null);
629+
}
611630
}

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,6 @@ else if (!componentSchemas.containsKey(entry.getKey())) {
138138
return schemaN;
139139
}
140140

141-
/**
142-
* Extract schema schema.
143-
*
144-
* @param components the components
145-
* @param genericParameterType the generic parameter type
146-
* @param jsonView the json view
147-
* @return the schema
148-
*/
149-
public static Schema extractSchema(Components components, Type genericParameterType, JsonView jsonView) {
150-
return extractSchema(components, genericParameterType, jsonView, null);
151-
}
152-
153141
/**
154142
* Gets content.
155143
*

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,21 +212,22 @@ ModelConverterRegistrar modelConverterRegistrar(Optional<List<ModelConverter>> m
212212
}
213213

214214
/**
215-
* Operation builder operation builder.
215+
* Operation builder operation service.
216216
*
217217
* @param parameterBuilder the parameter builder
218-
* @param requestBodyService the request body builder
218+
* @param requestBodyService the request body service
219219
* @param securityParser the security parser
220220
* @param propertyResolverUtils the property resolver utils
221-
* @return the operation builder
221+
* @param javadocProvider the javadoc provider
222+
* @return the operation service
222223
*/
223224
@Bean
224225
@ConditionalOnWebApplication
225226
@ConditionalOnMissingBean
226227
OperationService operationBuilder(GenericParameterService parameterBuilder, RequestBodyService requestBodyService,
227-
SecurityService securityParser, PropertyResolverUtils propertyResolverUtils) {
228+
SecurityService securityParser, PropertyResolverUtils propertyResolverUtils, Optional<JavadocProvider> javadocProvider) {
228229
return new OperationService(parameterBuilder, requestBodyService,
229-
securityParser, propertyResolverUtils);
230+
securityParser, propertyResolverUtils, javadocProvider);
230231
}
231232

232233
/**

0 commit comments

Comments
 (0)