4646import java .time .ZoneOffset ;
4747import java .util .ArrayList ;
4848import java .util .Arrays ;
49+ import java .util .Collections ;
4950import java .util .HashSet ;
5051import java .util .List ;
5152import java .util .Map ;
5960import java .util .concurrent .atomic .AtomicInteger ;
6061import java .util .concurrent .atomic .AtomicLong ;
6162import java .util .function .Predicate ;
63+ import java .util .stream .Collectors ;
6264import java .util .stream .Stream ;
6365
6466import io .swagger .v3 .core .util .PrimitiveType ;
@@ -153,9 +155,18 @@ Stream<MethodParameter> extractFrom(Class<?> clazz) {
153155 * @return the stream
154156 */
155157 private Stream <MethodParameter > extractFrom (Class <?> clazz , String fieldNamePrefix , boolean parentRequired ) {
158+ Map <String , PropertyDescriptor > propertyDescriptorMap ;
159+ try {
160+ propertyDescriptorMap = Arrays .stream (Introspector .getBeanInfo (clazz ).getPropertyDescriptors ())
161+ .collect (Collectors .toMap (PropertyDescriptor ::getName , pd -> pd , (a , b ) -> a ));
162+ }
163+ catch (IntrospectionException e ) {
164+ propertyDescriptorMap = Collections .emptyMap ();
165+ }
166+ Map <String , PropertyDescriptor > finalPropertyDescriptorMap = propertyDescriptorMap ;
156167 return allFieldsOf (clazz ).stream ()
157168 .filter (field -> !field .getType ().equals (clazz ))
158- .flatMap (f -> fromGetterOfField (clazz , f , fieldNamePrefix , parentRequired ))
169+ .flatMap (f -> fromGetterOfField (clazz , f , fieldNamePrefix , parentRequired , finalPropertyDescriptorMap ))
159170 .filter (Objects ::nonNull );
160171 }
161172
@@ -168,14 +179,14 @@ private Stream<MethodParameter> extractFrom(Class<?> clazz, String fieldNamePref
168179 * @param parentRequired whether the field that holds the class currently being examined was required or optional
169180 * @return the stream
170181 */
171- private Stream <MethodParameter > fromGetterOfField (Class <?> paramClass , Field field , String fieldNamePrefix , boolean parentRequired ) {
182+ private Stream <MethodParameter > fromGetterOfField (Class <?> paramClass , Field field , String fieldNamePrefix , boolean parentRequired , Map < String , PropertyDescriptor > propertyDescriptorMap ) {
172183 Class <?> type = extractType (paramClass , field );
173184
174185 if (Objects .isNull (type ))
175186 return Stream .empty ();
176187
177188 if (isSimpleType (type ))
178- return fromSimpleClass (paramClass , field , fieldNamePrefix , parentRequired );
189+ return fromSimpleClass (paramClass , field , fieldNamePrefix , parentRequired , propertyDescriptorMap );
179190 else {
180191 Parameter parameter = field .getAnnotation (Parameter .class );
181192 Schema schema = field .getAnnotation (Schema .class );
@@ -242,33 +253,28 @@ private static Class<?> extractType(Class<?> paramClass, Field field) {
242253 * @param fieldNamePrefix the field name prefix
243254 * @return the stream
244255 */
245- private Stream <MethodParameter > fromSimpleClass (Class <?> paramClass , Field field , String fieldNamePrefix , boolean parentRequired ) {
256+ private Stream <MethodParameter > fromSimpleClass (Class <?> paramClass , Field field , String fieldNamePrefix , boolean parentRequired , Map < String , PropertyDescriptor > propertyDescriptorMap ) {
246257 Annotation [] fieldAnnotations = field .getDeclaredAnnotations ();
247- try {
248- Parameter parameter = field .getAnnotation (Parameter .class );
249- Schema schema = field .getAnnotation (Schema .class );
250- boolean fieldRequired = this .schemaUtils .fieldRequired (field , schema , parameter );
258+ Parameter parameter = field .getAnnotation (Parameter .class );
259+ Schema schema = field .getAnnotation (Schema .class );
260+ boolean fieldRequired = this .schemaUtils .fieldRequired (field , schema , parameter );
251261
252- boolean paramRequired = parentRequired && fieldRequired ;
253- if (paramClass .getSuperclass () != null && paramClass .isRecord ()) {
254- return Stream .of (paramClass .getRecordComponents ())
255- .filter (d -> d .getName ().equals (field .getName ()))
256- .map (RecordComponent ::getAccessor )
257- .map (method -> new MethodParameter (method , -1 ))
258- .map (methodParameter -> DelegatingMethodParameter .changeContainingClass (methodParameter , paramClass ))
259- .map (param -> new DelegatingMethodParameter (param , fieldNamePrefix + field .getName (), fieldAnnotations , param .getMethodAnnotations (), true , field , !paramRequired ));
260- }
261- else
262- return Stream .of (Introspector .getBeanInfo (paramClass ).getPropertyDescriptors ())
263- .filter (d -> d .getName ().equals (field .getName ()))
264- .map (PropertyDescriptor ::getReadMethod )
265- .filter (Objects ::nonNull )
266- .map (method -> new MethodParameter (method , -1 ))
267- .map (methodParameter -> DelegatingMethodParameter .changeContainingClass (methodParameter , paramClass ))
268- .map (param -> new DelegatingMethodParameter (param , fieldNamePrefix + field .getName (), fieldAnnotations , param .getMethodAnnotations (), true , field , !paramRequired ));
262+ boolean paramRequired = parentRequired && fieldRequired ;
263+ if (paramClass .getSuperclass () != null && paramClass .isRecord ()) {
264+ return Stream .of (paramClass .getRecordComponents ())
265+ .filter (d -> d .getName ().equals (field .getName ()))
266+ .map (RecordComponent ::getAccessor )
267+ .map (method -> new MethodParameter (method , -1 ))
268+ .map (methodParameter -> DelegatingMethodParameter .changeContainingClass (methodParameter , paramClass ))
269+ .map (param -> new DelegatingMethodParameter (param , fieldNamePrefix + field .getName (), fieldAnnotations , param .getMethodAnnotations (), true , field , !paramRequired ));
269270 }
270- catch (IntrospectionException e ) {
271- return Stream .of ();
271+ else {
272+ PropertyDescriptor pd = propertyDescriptorMap .get (field .getName ());
273+ if (pd == null || pd .getReadMethod () == null )
274+ return Stream .of ();
275+ MethodParameter methodParameter = new MethodParameter (pd .getReadMethod (), -1 );
276+ methodParameter = DelegatingMethodParameter .changeContainingClass (methodParameter , paramClass );
277+ return Stream .of (new DelegatingMethodParameter (methodParameter , fieldNamePrefix + field .getName (), fieldAnnotations , methodParameter .getMethodAnnotations (), true , field , !paramRequired ));
272278 }
273279 }
274280
0 commit comments