2626
2727import java .io .IOException ;
2828import java .lang .annotation .Annotation ;
29+ import java .lang .reflect .Field ;
2930import java .lang .reflect .ParameterizedType ;
3031import java .lang .reflect .Type ;
3132import java .lang .reflect .WildcardType ;
3637import java .util .List ;
3738import java .util .Locale ;
3839import java .util .Map ;
40+ import java .util .Objects ;
3941import java .util .Optional ;
4042
4143import com .fasterxml .jackson .annotation .JsonView ;
5557import io .swagger .v3 .oas .models .media .Schema ;
5658import io .swagger .v3 .oas .models .parameters .Parameter ;
5759import org .apache .commons .lang3 .StringUtils ;
60+ import org .apache .commons .lang3 .reflect .FieldUtils ;
5861import org .slf4j .Logger ;
5962import org .slf4j .LoggerFactory ;
6063import org .springdoc .core .customizers .DelegatingMethodParameterCustomizer ;
64+ import org .springdoc .core .extractor .DelegatingMethodParameter ;
6165import org .springdoc .core .extractor .MethodParameterPojoExtractor ;
6266import org .springdoc .core .models .ParameterInfo ;
6367import org .springdoc .core .models .RequestBodyInfo ;
6468import org .springdoc .core .parsers .ReturnTypeParser ;
69+ import org .springdoc .core .providers .JavadocProvider ;
6570import org .springdoc .core .providers .ObjectMapperProvider ;
6671import org .springdoc .core .providers .WebConversionServiceProvider ;
6772import org .springdoc .core .utils .Constants ;
7378import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
7479import org .springframework .core .MethodParameter ;
7580import org .springframework .core .ResolvableType ;
81+ import org .springframework .core .annotation .AnnotatedElementUtils ;
7682import org .springframework .core .io .Resource ;
7783import org .springframework .web .context .request .RequestScope ;
7884import org .springframework .web .multipart .MultipartFile ;
7985import org .springframework .web .multipart .MultipartRequest ;
8086
87+ import static org .springdoc .core .utils .Constants .DOT ;
88+
8189/**
8290 * The type Generic parameter builder.
8391 * @author bnasslahsen, coutin
@@ -131,21 +139,28 @@ public class GenericParameterService {
131139 */
132140 private final ObjectMapperProvider objectMapperProvider ;
133141
142+ /**
143+ * The javadoc provider.
144+ */
145+ private final Optional <JavadocProvider > javadocProviderOptional ;
146+
134147 /**
135148 * Instantiates a new Generic parameter builder.
136149 * @param propertyResolverUtils the property resolver utils
137150 * @param optionalDelegatingMethodParameterCustomizer the optional delegating method parameter customizer
138151 * @param optionalWebConversionServiceProvider the optional web conversion service provider
139152 * @param objectMapperProvider the object mapper provider
153+ * @param javadocProviderOptional the javadoc provider
140154 */
141155 public GenericParameterService (PropertyResolverUtils propertyResolverUtils , Optional <DelegatingMethodParameterCustomizer > optionalDelegatingMethodParameterCustomizer ,
142- Optional <WebConversionServiceProvider > optionalWebConversionServiceProvider , ObjectMapperProvider objectMapperProvider ) {
156+ Optional <WebConversionServiceProvider > optionalWebConversionServiceProvider , ObjectMapperProvider objectMapperProvider , Optional < JavadocProvider > javadocProviderOptional ) {
143157 this .propertyResolverUtils = propertyResolverUtils ;
144158 this .optionalDelegatingMethodParameterCustomizer = optionalDelegatingMethodParameterCustomizer ;
145159 this .optionalWebConversionServiceProvider = optionalWebConversionServiceProvider ;
146160 this .configurableBeanFactory = propertyResolverUtils .getFactory ();
147161 this .expressionContext = (configurableBeanFactory != null ? new BeanExpressionContext (configurableBeanFactory , new RequestScope ()) : null );
148162 this .objectMapperProvider = objectMapperProvider ;
163+ this .javadocProviderOptional = javadocProviderOptional ;
149164 }
150165
151166 /**
@@ -359,6 +374,16 @@ Schema calculateSchema(Components components, ParameterInfo parameterInfo, Reque
359374
360375 if (requestBodyInfo != null ) {
361376 schemaN = calculateRequestBodySchema (components , parameterInfo , requestBodyInfo , schemaN , paramName );
377+ JavadocProvider javadocProvider = javadocProviderOptional .orElse (null );
378+ if (schemaN != null && javadocProvider != null && !isRequestBodyPresent (parameterInfo )) {
379+ String paramJavadocDescription = getParamJavadoc (javadocProvider , methodParameter );
380+ if (schemaN .getProperties () != null && schemaN .getProperties ().containsKey (parameterInfo .getpName ())) {
381+ Map <String , Schema > properties = schemaN .getProperties ();
382+ if (!StringUtils .isBlank (paramJavadocDescription ) && StringUtils .isBlank (properties .get (parameterInfo .getpName ()).getDescription ())) {
383+ properties .get (parameterInfo .getpName ()).setDescription (paramJavadocDescription );
384+ }
385+ }
386+ }
362387 }
363388
364389 return schemaN ;
@@ -666,4 +691,48 @@ public String ref() {
666691 }
667692 };
668693 }
694+
695+ /**
696+ * Gets javadoc provider.
697+ *
698+ * @return the javadoc provider
699+ */
700+ public JavadocProvider getJavadocProvider () {
701+ return javadocProviderOptional .orElse (null );
702+ }
703+
704+ /**
705+ * Is request body present boolean.
706+ *
707+ * @param parameterInfo the parameter info
708+ * @return the boolean
709+ */
710+ public boolean isRequestBodyPresent (ParameterInfo parameterInfo ) {
711+ return parameterInfo .getMethodParameter ().getParameterAnnotation (io .swagger .v3 .oas .annotations .parameters .RequestBody .class ) != null
712+ || parameterInfo .getMethodParameter ().getParameterAnnotation (org .springframework .web .bind .annotation .RequestBody .class ) != null
713+ || AnnotatedElementUtils .findMergedAnnotation (Objects .requireNonNull (parameterInfo .getMethodParameter ().getMethod ()), io .swagger .v3 .oas .annotations .parameters .RequestBody .class ) != null ;
714+ }
715+
716+ /**
717+ * Gets param javadoc.
718+ *
719+ * @param javadocProvider the javadoc provider
720+ * @param methodParameter the method parameter
721+ * @return the param javadoc
722+ */
723+ String getParamJavadoc (JavadocProvider javadocProvider , MethodParameter methodParameter ) {
724+ String pName = methodParameter .getParameterName ();
725+ DelegatingMethodParameter delegatingMethodParameter = (DelegatingMethodParameter ) methodParameter ;
726+ final String paramJavadocDescription ;
727+ if (delegatingMethodParameter .isParameterObject ()) {
728+ String fieldName ; if (StringUtils .isNotEmpty (pName ) && pName .contains (DOT ))
729+ fieldName = StringUtils .substringAfterLast (pName , DOT );
730+ else fieldName = pName ;
731+ Field field = FieldUtils .getDeclaredField (((DelegatingMethodParameter ) methodParameter ).getExecutable ().getDeclaringClass (), fieldName , true );
732+ paramJavadocDescription = javadocProvider .getFieldJavadoc (field );
733+ }
734+ else
735+ paramJavadocDescription = javadocProvider .getParamJavadoc (methodParameter .getMethod (), pName );
736+ return paramJavadocDescription ;
737+ }
669738}
0 commit comments