20
20
import java .lang .reflect .Field ;
21
21
import java .lang .reflect .InvocationTargetException ;
22
22
import java .lang .reflect .Method ;
23
+ import java .lang .reflect .Parameter ;
23
24
import java .lang .reflect .Type ;
24
25
import java .lang .reflect .TypeVariable ;
25
26
import java .util .ArrayList ;
26
27
import java .util .HashMap ;
27
28
import java .util .HashSet ;
28
- import java .util .List ;
29
29
import java .util .Map ;
30
30
import java .util .Set ;
31
31
import java .util .logging .Logger ;
32
32
33
+ import android .os .Build ;
34
+ import androidx .annotation .RequiresApi ;
33
35
import com .google .firebase .firestore .FieldValue ;
34
36
35
37
@@ -51,22 +53,33 @@ class RecordMapper<T> extends BeanMapper<T> {
51
53
private final Constructor <T > constructor ;
52
54
private final Map <String , Integer > constructorParamIndexes = new HashMap <>();
53
55
56
+ @ RequiresApi (api = Build .VERSION_CODES .O )
54
57
RecordMapper (Class <T > clazz ) {
55
58
super (clazz );
56
59
57
- constructor = getCanonicalConstructor (clazz );
60
+ Constructor <?>[] constructors = clazz .getConstructors ();
61
+ if (constructors .length != 1 ) {
62
+ throw new RuntimeException ("Record class has custom constructor(s): " + clazz .getName ());
63
+ }
64
+
65
+ //noinspection unchecked
66
+ constructor = (Constructor <T >) constructors [0 ];
58
67
59
- Field [] recordComponents = clazz . getDeclaredFields ();
68
+ Parameter [] recordComponents = constructor . getParameters ();
60
69
if (recordComponents .length == 0 ) {
61
70
throw new RuntimeException ("No properties to serialize found on class " + clazz .getName ());
62
71
}
63
72
64
- for (int i = 0 ; i < recordComponents .length ; i ++) {
65
- Field recordComponent = recordComponents [i ];
66
- String propertyName = propertyName (recordComponent );
67
- constructorParamIndexes .put (propertyName , i );
68
- accessors .put (propertyName , getAccessor (clazz , recordComponent ));
69
- applyFieldAnnotations (recordComponent );
73
+ try {
74
+ for (int i = 0 ; i < recordComponents .length ; i ++) {
75
+ Field field = clazz .getDeclaredField (recordComponents [i ].getName ());
76
+ String propertyName = propertyName (field );
77
+ constructorParamIndexes .put (propertyName , i );
78
+ accessors .put (propertyName , getAccessor (clazz , field ));
79
+ applyFieldAnnotations (field );
80
+ }
81
+ } catch (NoSuchFieldException e ) {
82
+ throw new RuntimeException (e );
70
83
}
71
84
}
72
85
@@ -141,26 +154,6 @@ T deserialize(
141
154
}
142
155
}
143
156
144
- private static <T > Constructor <T > getCanonicalConstructor (Class <T > cls ) {
145
- try {
146
- Class <?>[] paramTypes = getParamTypes (cls );
147
- Constructor <T > constructor = cls .getDeclaredConstructor (paramTypes );
148
- constructor .setAccessible (true );
149
- return constructor ;
150
- } catch (NoSuchMethodException e ) {
151
- throw new IllegalStateException (e );
152
- }
153
- }
154
-
155
- private static <T > Class <?>[] getParamTypes (Class <T > cls ) {
156
- Field [] recordComponents = cls .getDeclaredFields ();
157
- List <Class <?>> types = new ArrayList <>(recordComponents .length );
158
- for (Field element : recordComponents ) {
159
- types .add (element .getType ());
160
- }
161
- return types .toArray (CLASSES_ARRAY_TYPE );
162
- }
163
-
164
157
private static Method getAccessor (Class <?> clazz , Field recordComponent ) {
165
158
try {
166
159
Method accessor = clazz .getDeclaredMethod (recordComponent .getName (), CLASSES_ARRAY_TYPE );
0 commit comments