10
10
import java .util .Collections ;
11
11
import java .util .HashSet ;
12
12
import java .util .List ;
13
+ import java .util .Map ;
13
14
import java .util .Objects ;
15
+ import java .util .Optional ;
16
+ import java .util .OptionalDouble ;
17
+ import java .util .OptionalInt ;
18
+ import java .util .OptionalLong ;
14
19
import java .util .Set ;
15
20
import java .util .stream .Stream ;
16
21
17
22
import io .swagger .v3 .oas .annotations .Parameter ;
18
23
import org .apache .commons .lang3 .ArrayUtils ;
19
24
20
25
import org .springframework .core .MethodParameter ;
21
- import org .springframework .lang .NonNull ;
22
26
import org .springframework .lang .Nullable ;
23
27
24
28
class MethodParameterPojoExtractor {
25
- private static final Set <Class <?>> SIMPLE_TYPES ;
26
- private static final Set <Class <?>> COLLECTION_TYPES ;
27
-
28
- static {
29
- Set <Class <?>> simpleTypes = new HashSet <>();
30
- simpleTypes .add (boolean .class );
31
- simpleTypes .add (char .class );
32
- simpleTypes .add (byte .class );
33
- simpleTypes .add (short .class );
34
- simpleTypes .add (int .class );
35
- simpleTypes .add (long .class );
36
- simpleTypes .add (float .class );
37
- simpleTypes .add (double .class );
38
-
39
- simpleTypes .add (Boolean .class );
40
- simpleTypes .add (Character .class );
41
- simpleTypes .add (Byte .class );
42
- simpleTypes .add (Short .class );
43
- simpleTypes .add (Integer .class );
44
- simpleTypes .add (Long .class );
45
- simpleTypes .add (Float .class );
46
- simpleTypes .add (Double .class );
47
-
48
- simpleTypes .add (CharSequence .class );
49
- simpleTypes .add (Number .class );
50
-
51
- SIMPLE_TYPES = Collections .unmodifiableSet (simpleTypes );
52
-
53
- Set <Class <?>> collectionTypes = new HashSet <>();
54
- collectionTypes .add (Iterable .class );
55
-
56
- COLLECTION_TYPES = Collections .unmodifiableSet (collectionTypes );
29
+ static Stream <MethodParameter > extractFrom (Class <?> clazz ) {
30
+ return extractFrom (clazz , "" );
57
31
}
58
32
59
- private static final Nullable NULLABLE_ANNOTATION = new Nullable () {
60
- @ Override
61
- public Class <? extends Annotation > annotationType () {
62
- return Nullable .class ;
63
- }
64
- };
65
-
66
- @ NonNull
67
- static Stream <MethodParameter > extractFrom (Class <?> clazz ) {
33
+ private static Stream <MethodParameter > extractFrom (Class <?> clazz , String fieldNamePrefix ) {
68
34
return allFieldsOf (clazz ).stream ()
69
- .flatMap (f -> fromGetterOfField (clazz , f ))
35
+ .flatMap (f -> fromGetterOfField (clazz , f , fieldNamePrefix ))
70
36
.filter (Objects ::nonNull );
71
37
}
72
38
73
- private static Stream <MethodParameter > fromGetterOfField (Class <?> paramClass , Field field ) {
39
+ private static Stream <MethodParameter > fromGetterOfField (Class <?> paramClass , Field field , String fieldNamePrefix ) {
40
+ if (isSimpleType (field .getType ())) {
41
+ return fromSimpleClass (paramClass , field , fieldNamePrefix );
42
+ }
43
+ else {
44
+ return extractFrom (field .getType (), fieldNamePrefix + field .getName () + "." );
45
+ }
46
+ }
47
+
48
+ private static Stream <MethodParameter > fromSimpleClass (Class <?> paramClass , Field field , String fieldNamePrefix ) {
49
+ Annotation [] fieldAnnotations = field .getDeclaredAnnotations ();
50
+ if (isOptional (field )) {
51
+ fieldAnnotations = ArrayUtils .add (fieldAnnotations , NULLABLE_ANNOTATION );
52
+ }
74
53
try {
75
- Annotation [] filedAnnotations = field .getDeclaredAnnotations ();
76
- Parameter parameter = field .getAnnotation (Parameter .class );
77
- if (parameter != null && !parameter .required ()) {
78
- filedAnnotations = ArrayUtils .add (filedAnnotations , NULLABLE_ANNOTATION );
79
- }
80
- Annotation [] filedAnnotationsNew = filedAnnotations ;
54
+ Annotation [] finalFieldAnnotations = fieldAnnotations ;
81
55
return Stream .of (Introspector .getBeanInfo (paramClass ).getPropertyDescriptors ())
82
56
.filter (d -> d .getName ().equals (field .getName ()))
83
57
.map (PropertyDescriptor ::getReadMethod )
84
58
.filter (Objects ::nonNull )
85
59
.map (method -> new MethodParameter (method , -1 ))
86
- .map (param -> new DelegatingMethodParameter (param , field .getName (), filedAnnotationsNew ));
60
+ .map (param -> new DelegatingMethodParameter (param , fieldNamePrefix + field .getName (), finalFieldAnnotations ));
87
61
}
88
62
catch (IntrospectionException e ) {
89
63
return Stream .of ();
90
64
}
91
65
}
92
66
67
+ private static boolean isOptional (Field field ) {
68
+ Parameter parameter = field .getAnnotation (Parameter .class );
69
+ return parameter == null || !parameter .required ();
70
+ }
71
+
93
72
private static List <Field > allFieldsOf (Class <?> clazz ) {
94
73
List <Field > fields = new ArrayList <>();
95
74
do {
@@ -98,4 +77,37 @@ private static List<Field> allFieldsOf(Class<?> clazz) {
98
77
} while (clazz != null );
99
78
return fields ;
100
79
}
80
+
81
+ private static boolean isSimpleType (Class <?> clazz ) {
82
+ if (clazz .isPrimitive ()) return true ;
83
+ if (clazz .isArray ()) return true ;
84
+ if (clazz .isEnum ()) return true ;
85
+ return SIMPLE_TYPES .stream ().anyMatch (c -> c .isAssignableFrom (clazz ));
86
+ }
87
+
88
+ private static final Nullable NULLABLE_ANNOTATION = new Nullable () {
89
+ @ Override
90
+ public Class <? extends Annotation > annotationType () {
91
+ return Nullable .class ;
92
+ }
93
+ };
94
+
95
+ private static final Set <Class <?>> SIMPLE_TYPES ;
96
+
97
+ static {
98
+ Set <Class <?>> simpleTypes = new HashSet <>();
99
+ simpleTypes .add (Boolean .class );
100
+ simpleTypes .add (Character .class );
101
+ simpleTypes .add (Number .class );
102
+ simpleTypes .add (CharSequence .class );
103
+ simpleTypes .add (Optional .class );
104
+ simpleTypes .add (OptionalInt .class );
105
+ simpleTypes .add (OptionalLong .class );
106
+ simpleTypes .add (OptionalDouble .class );
107
+
108
+ simpleTypes .add (Map .class );
109
+ simpleTypes .add (Iterable .class );
110
+
111
+ SIMPLE_TYPES = Collections .unmodifiableSet (simpleTypes );
112
+ }
101
113
}
0 commit comments