Skip to content

Commit 9321083

Browse files
committed
feat: Added API version checks, Cleanup.
1 parent e95fe28 commit 9321083

File tree

3 files changed

+26
-31
lines changed

3 files changed

+26
-31
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/util/BeanMapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.google.firebase.firestore.ThrowOnExtraProperties;
2626

2727
import java.lang.reflect.AccessibleObject;
28+
import java.lang.reflect.AnnotatedElement;
2829
import java.lang.reflect.Field;
2930
import java.lang.reflect.Type;
3031
import java.lang.reflect.TypeVariable;
@@ -116,7 +117,7 @@ static String propertyName(Field field) {
116117
return annotatedName != null? annotatedName : field.getName();
117118
}
118119

119-
static String annotatedName(AccessibleObject obj) {
120+
static String annotatedName(AnnotatedElement obj) {
120121
if (obj.isAnnotationPresent(PropertyName.class)) {
121122
PropertyName annotation = obj.getAnnotation(PropertyName.class);
122123
return annotation.value();

firebase-firestore/src/main/java/com/google/firebase/firestore/util/CustomClassMapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.concurrent.ConcurrentMap;
3838

3939
import android.net.Uri;
40+
import android.os.Build;
4041
import com.google.common.collect.Sets;
4142
import com.google.firebase.Timestamp;
4243
import com.google.firebase.firestore.Blob;
@@ -374,7 +375,7 @@ private static <T> BeanMapper<T> loadOrCreateBeanMapperForClass(Class<T> clazz)
374375
@SuppressWarnings("unchecked")
375376
BeanMapper<T> mapper = (BeanMapper<T>) mappers.get(clazz);
376377
if (mapper == null) {
377-
if (isRecordType(clazz)) {
378+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isRecordType(clazz)) {
378379
mapper = new RecordMapper<>(clazz);
379380
} else {
380381
mapper = new PojoBeanMapper<>(clazz);

firebase-firestore/src/main/java/com/google/firebase/firestore/util/RecordMapper.java

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@
2020
import java.lang.reflect.Field;
2121
import java.lang.reflect.InvocationTargetException;
2222
import java.lang.reflect.Method;
23+
import java.lang.reflect.Parameter;
2324
import java.lang.reflect.Type;
2425
import java.lang.reflect.TypeVariable;
2526
import java.util.ArrayList;
2627
import java.util.HashMap;
2728
import java.util.HashSet;
28-
import java.util.List;
2929
import java.util.Map;
3030
import java.util.Set;
3131
import java.util.logging.Logger;
3232

33+
import android.os.Build;
34+
import androidx.annotation.RequiresApi;
3335
import com.google.firebase.firestore.FieldValue;
3436

3537

@@ -51,22 +53,33 @@ class RecordMapper<T> extends BeanMapper<T> {
5153
private final Constructor<T> constructor;
5254
private final Map<String, Integer> constructorParamIndexes = new HashMap<>();
5355

56+
@RequiresApi(api = Build.VERSION_CODES.O)
5457
RecordMapper(Class<T> clazz) {
5558
super(clazz);
5659

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];
5867

59-
Field[] recordComponents = clazz.getDeclaredFields();
68+
Parameter[] recordComponents = constructor.getParameters();
6069
if (recordComponents.length == 0) {
6170
throw new RuntimeException("No properties to serialize found on class " + clazz.getName());
6271
}
6372

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);
7083
}
7184
}
7285

@@ -141,26 +154,6 @@ T deserialize(
141154
}
142155
}
143156

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-
164157
private static Method getAccessor(Class<?> clazz, Field recordComponent) {
165158
try {
166159
Method accessor = clazz.getDeclaredMethod(recordComponent.getName(), CLASSES_ARRAY_TYPE);

0 commit comments

Comments
 (0)