2626
2727package org.springdoc.core.configuration
2828
29- import io.swagger.v3.oas.annotations.Parameter
3029import org.springdoc.core.converters.KotlinInlineClassUnwrappingConverter
30+ import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer
3131import org.springdoc.core.customizers.KotlinDeprecatedPropertyCustomizer
32- import org.springdoc.core.customizers.ParameterCustomizer
32+ import org.springdoc.core.extractor.DelegatingMethodParameter
3333import org.springdoc.core.providers.ObjectMapperProvider
3434import org.springdoc.core.utils.Constants
35- import org.springdoc.core.utils.SchemaUtils
3635import org.springdoc.core.utils.SpringDocUtils
3736import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
3837import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
@@ -43,14 +42,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
4342import org.springframework.context.annotation.Bean
4443import org.springframework.context.annotation.Configuration
4544import org.springframework.context.annotation.Lazy
46- import org.springframework.core.KotlinDetector
47- import org.springframework.core.MethodParameter
48- import org.springframework.core.annotation.AnnotatedElementUtils
49- import org.springframework.web.bind.annotation.RequestParam
50- import org.springframework.web.bind.annotation.ValueConstants
5145import kotlin.coroutines.Continuation
52- import kotlin.reflect.KParameter
53- import kotlin.reflect.jvm.kotlinFunction
46+ import kotlin.reflect.full.primaryConstructor
5447
5548/* *
5649 * The type Spring doc kotlin configuration.
@@ -76,60 +69,21 @@ class SpringDocKotlinConfiguration() {
7669 .addDeprecatedType(Deprecated ::class .java)
7770 }
7871
79- /* *
80- * Kotlin springdoc-openapi ParameterCustomizer.
81- * deprecated as not anymore required, use [SchemaUtils.fieldNullable]
82- *
83- * @return the nullable Kotlin Request Parameter Customizer
84- * @see SchemaUtils.fieldNullable()
85- */
86- @Deprecated(" Deprecated since 2.8.7" , level = DeprecationLevel .ERROR )
87- fun nullableKotlinRequestParameterCustomizer (): ParameterCustomizer {
88- return ParameterCustomizer { parameterModel, methodParameter ->
89- if (parameterModel == null ) return @ParameterCustomizer null
90- if (KotlinDetector .isKotlinReflectPresent() && KotlinDetector .isKotlinType(
91- methodParameter.parameterType
92- )
93- ) {
94- val kParameter = methodParameter.toKParameter()
95- if (kParameter != null ) {
96- val parameterDoc = AnnotatedElementUtils .findMergedAnnotation(
97- AnnotatedElementUtils .forAnnotations(* methodParameter.parameterAnnotations),
98- Parameter ::class .java
99- )
100- val requestParam = AnnotatedElementUtils .findMergedAnnotation(
101- AnnotatedElementUtils .forAnnotations(* methodParameter.parameterAnnotations),
102- RequestParam ::class .java
103- )
104- // Swagger @Parameter annotation takes precedence
105- if (parameterDoc != null && parameterDoc.required)
106- parameterModel.required = parameterDoc.required
107- // parameter is not required if a default value is provided in @RequestParam
108- else if (requestParam != null && requestParam.defaultValue != ValueConstants .DEFAULT_NONE )
109- parameterModel.required = false
110- else {
111- val isJavaNullableAnnotationPresent =
112- methodParameter.parameterAnnotations.any {
113- it.annotationClass.qualifiedName == " jakarta.annotation.Nullable"
114- }
115- parameterModel.required =
116- kParameter.type.isMarkedNullable == false && ! isJavaNullableAnnotationPresent
117- }
118- }
119- }
120- return @ParameterCustomizer parameterModel
72+ @Bean
73+ @ConditionalOnProperty(
74+ name = [Constants .SPRINGDOC_NULLABLE_REQUEST_PARAMETER_ENABLED ],
75+ matchIfMissing = true
76+ )
77+ @Lazy(false )
78+ fun kotlinDefaultsInParamObjects (): DelegatingMethodParameterCustomizer =
79+ DelegatingMethodParameterCustomizer { _, mp ->
80+ val kProp = mp.containingClass.kotlin.primaryConstructor
81+ ?.parameters
82+ ?.firstOrNull { it.name == mp.parameterName }
83+ if (kProp?.isOptional == true )
84+ (mp as DelegatingMethodParameter ).isNotRequired = true
12185 }
122- }
123-
124- private fun MethodParameter.toKParameter (): KParameter ? {
125- // ignore return type, see org.springframework.core.MethodParameter.getParameterIndex
126- if (parameterIndex == - 1 ) return null
127- val kotlinFunction = method?.kotlinFunction ? : return null
128- // The first parameter of the kotlin function is the "this" reference and not needed here.
129- // See also kotlin.reflect.KCallable.getParameters
130- return kotlinFunction.parameters[parameterIndex + 1 ]
131- }
132-
86+
13387 @ConditionalOnClass(name = [" kotlin.reflect.full.KClasses" ])
13488 class KotlinReflectDependingConfiguration {
13589
0 commit comments