55
55
import org .apache .commons .lang3 .StringUtils ;
56
56
import org .slf4j .Logger ;
57
57
import org .slf4j .LoggerFactory ;
58
+ import org .springdoc .api .annotations .ParameterObject ;
59
+ import org .springdoc .core .converters .AdditionalModelsConverter ;
58
60
import org .springdoc .core .customizers .DelegatingMethodParameterCustomizer ;
59
61
import org .springdoc .core .providers .ObjectMapperProvider ;
60
62
import org .springdoc .core .providers .WebConversionServiceProvider ;
64
66
import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
65
67
import org .springframework .core .MethodParameter ;
66
68
import org .springframework .core .ResolvableType ;
69
+ import org .springframework .core .annotation .AnnotatedElementUtils ;
67
70
import org .springframework .core .io .Resource ;
68
71
import org .springframework .web .context .request .RequestScope ;
69
72
import org .springframework .web .multipart .MultipartFile ;
@@ -122,6 +125,13 @@ public class GenericParameterService {
122
125
*/
123
126
private final ObjectMapperProvider objectMapperProvider ;
124
127
128
+ /**
129
+ * The constant PARAM_TYPES_TO_IGNORE.
130
+ */
131
+ private final List <Class <?>> PARAM_TYPES_TO_IGNORE = Collections .synchronizedList (new ArrayList <>());
132
+
133
+ private final boolean defaultFlatParamObject ;
134
+
125
135
/**
126
136
* Instantiates a new Generic parameter builder.
127
137
* @param propertyResolverUtils the property resolver utils
@@ -130,13 +140,18 @@ public class GenericParameterService {
130
140
* @param objectMapperProvider the object mapper provider
131
141
*/
132
142
public GenericParameterService (PropertyResolverUtils propertyResolverUtils , Optional <DelegatingMethodParameterCustomizer > optionalDelegatingMethodParameterCustomizer ,
133
- Optional <WebConversionServiceProvider > optionalWebConversionServiceProvider , ObjectMapperProvider objectMapperProvider ) {
143
+ Optional <WebConversionServiceProvider > optionalWebConversionServiceProvider , ObjectMapperProvider objectMapperProvider , boolean defaultFlatParamObject ) {
134
144
this .propertyResolverUtils = propertyResolverUtils ;
135
145
this .optionalDelegatingMethodParameterCustomizer = optionalDelegatingMethodParameterCustomizer ;
136
146
this .optionalWebConversionServiceProvider = optionalWebConversionServiceProvider ;
137
147
this .configurableBeanFactory = propertyResolverUtils .getFactory ();
138
148
this .expressionContext = (configurableBeanFactory != null ? new BeanExpressionContext (configurableBeanFactory , new RequestScope ()) : null );
139
149
this .objectMapperProvider = objectMapperProvider ;
150
+ this .defaultFlatParamObject = defaultFlatParamObject ;
151
+ }
152
+
153
+ protected void addIgnoreType (List <Class <?>> classes ) {
154
+ PARAM_TYPES_TO_IGNORE .addAll (classes );
140
155
}
141
156
142
157
/**
@@ -333,9 +348,9 @@ Schema calculateSchema(Components components, ParameterInfo parameterInfo, Reque
333
348
334
349
if (parameterInfo .getParameterModel () == null || parameterInfo .getParameterModel ().getSchema () == null ) {
335
350
Type type = ReturnTypeParser .getType (methodParameter );
336
- if (type instanceof Class && optionalWebConversionServiceProvider .isPresent ()){
351
+ if (type instanceof Class && optionalWebConversionServiceProvider .isPresent ()) {
337
352
WebConversionServiceProvider webConversionServiceProvider = optionalWebConversionServiceProvider .get ();
338
- if (!MethodParameterPojoExtractor .isSwaggerPrimitiveType ((Class ) type ) && methodParameter .getParameterType ().getAnnotation (io .swagger .v3 .oas .annotations .media .Schema .class )== null )
353
+ if (!MethodParameterPojoExtractor .isSwaggerPrimitiveType ((Class ) type ) && methodParameter .getParameterType ().getAnnotation (io .swagger .v3 .oas .annotations .media .Schema .class ) == null )
339
354
type = webConversionServiceProvider .getSpringConvertedType (methodParameter .getParameterType ());
340
355
}
341
356
schemaN = SpringDocAnnotationsUtils .extractSchema (components , type , jsonView , methodParameter .getParameterAnnotations ());
@@ -566,6 +581,7 @@ public io.swagger.v3.oas.annotations.Parameter generateParameterBySchema(io.swag
566
581
public Class <? extends Annotation > annotationType () {
567
582
return io .swagger .v3 .oas .annotations .Parameter .class ;
568
583
}
584
+
569
585
@ Override
570
586
public String name () {
571
587
return schema .name ();
@@ -652,4 +668,47 @@ public String ref() {
652
668
}
653
669
};
654
670
}
671
+
672
+ /**
673
+ * Customize method parameter [ ].
674
+ *
675
+ * @param pNames the p names
676
+ * @param parameters the parameters
677
+ * @param optionalDelegatingMethodParameterCustomizer the optional delegating method parameter customizer
678
+ * @return the method parameter [ ]
679
+ */
680
+ public MethodParameter [] customize (String [] pNames , MethodParameter [] parameters , Optional <DelegatingMethodParameterCustomizer > optionalDelegatingMethodParameterCustomizer ) {
681
+ List <MethodParameter > explodedParameters = new ArrayList <>();
682
+ for (int i = 0 ; i < parameters .length ; ++i ) {
683
+ MethodParameter p = parameters [i ];
684
+ Class <?> paramClass = AdditionalModelsConverter .getParameterObjectReplacement (p .getParameterType ());
685
+ if (!MethodParameterPojoExtractor .isSimpleType (paramClass ) && (p .hasParameterAnnotation (ParameterObject .class ) || AnnotatedElementUtils .isAnnotated (paramClass , ParameterObject .class ))) {
686
+ MethodParameterPojoExtractor .extractFrom (paramClass ).forEach (methodParameter -> {
687
+ optionalDelegatingMethodParameterCustomizer .ifPresent (customizer -> customizer .customize (p , methodParameter ));
688
+ explodedParameters .add (methodParameter );
689
+ });
690
+ }
691
+ else if (defaultFlatParamObject ) {
692
+ boolean isSimpleType = MethodParameterPojoExtractor .isSimpleType (paramClass );
693
+ boolean hasAnnotation = p .hasParameterAnnotations ();
694
+ boolean shouldFlat = !isSimpleType && !hasAnnotation ;
695
+ if (shouldFlat && PARAM_TYPES_TO_IGNORE .stream ().noneMatch (ignore -> ignore .isAssignableFrom (paramClass ))) {
696
+ MethodParameterPojoExtractor .extractFrom (paramClass ).forEach (methodParameter -> {
697
+ optionalDelegatingMethodParameterCustomizer
698
+ .ifPresent (customizer -> customizer .customize (p , methodParameter ));
699
+ explodedParameters .add (methodParameter );
700
+ });
701
+ }
702
+ else {
703
+ String name = pNames != null ? pNames [i ] : p .getParameterName ();
704
+ explodedParameters .add (new DelegatingMethodParameter (p , name , null , false , false ));
705
+ }
706
+ }
707
+ else {
708
+ String name = pNames != null ? pNames [i ] : p .getParameterName ();
709
+ explodedParameters .add (new DelegatingMethodParameter (p , name , null , false , false ));
710
+ }
711
+ }
712
+ return explodedParameters .toArray (new MethodParameter [0 ]);
713
+ }
655
714
}
0 commit comments