This commit is contained in:
Andrea Cavalli 2022-02-21 00:59:11 +01:00
parent d1b4fe6a96
commit 255829fe2f
1 changed files with 22 additions and 15 deletions

View File

@ -11,16 +11,17 @@ import dev.zacsweers.moshix.records.RecordsJsonAdapterFactory;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -191,19 +192,25 @@ public abstract class MoshiPolymorphic<OBJ> {
private final String adapterName; private final String adapterName;
private final Options names; private final Options names;
private final Class<?> declaredClass; private final Class<?> declaredClass;
private final Field[] declaredFields; private final List<Field> declaredFields;
private final Function<T, Object>[] fieldGetters; private final Function<T, Object>[] fieldGetters;
private NormalValueAdapter(String adapterName, Class<?> declaredClass) { private NormalValueAdapter(String adapterName, Class<?> declaredClass) {
try { try {
this.adapterName = adapterName; this.adapterName = adapterName;
this.declaredClass = declaredClass; this.declaredClass = declaredClass;
var declaredFields = new ArrayList<>(List.of(declaredClass.getDeclaredFields())); this.declaredFields = Arrays
declaredFields.removeIf(field -> shouldIgnoreField(field.getName())); .stream(declaredClass.getDeclaredFields())
this.declaredFields = declaredFields.toArray(Field[]::new); .filter(field -> {
String[] fieldNames = new String[this.declaredFields.length]; var modifiers = field.getModifiers();
return !Modifier.isStatic(modifiers)
&& !Modifier.isTransient(modifiers)
&& !shouldIgnoreField(field.getName());
})
.collect(Collectors.toList());
String[] fieldNames = new String[this.declaredFields.size()];
//noinspection unchecked //noinspection unchecked
this.fieldGetters = new Function[this.declaredFields.length]; this.fieldGetters = new Function[this.declaredFields.size()];
int i = 0; int i = 0;
for (Field declaredField : this.declaredFields) { for (Field declaredField : this.declaredFields) {
fieldNames[i] = declaredField.getName(); fieldNames[i] = declaredField.getName();
@ -258,7 +265,7 @@ public abstract class MoshiPolymorphic<OBJ> {
Object instance; Object instance;
Object[] fields; Object[] fields;
if (instantiateUsingStaticOf) { if (instantiateUsingStaticOf) {
fields = new Object[declaredFields.length]; fields = new Object[declaredFields.size()];
instance = null; instance = null;
} else { } else {
fields = null; fields = null;
@ -268,12 +275,12 @@ public abstract class MoshiPolymorphic<OBJ> {
jsonReader.beginObject(); jsonReader.beginObject();
while (jsonReader.hasNext()) { while (jsonReader.hasNext()) {
var nameId = jsonReader.selectName(names); var nameId = jsonReader.selectName(names);
if (nameId >= 0 && nameId < this.declaredFields.length) { if (nameId >= 0 && nameId < this.declaredFields.size()) {
var fieldValue = abstractMoshi.adapter(declaredFields[nameId].getGenericType()).fromJson(jsonReader); var fieldValue = abstractMoshi.adapter(declaredFields.get(nameId).getGenericType()).fromJson(jsonReader);
if (instantiateUsingStaticOf) { if (instantiateUsingStaticOf) {
fields[nameId] = fieldValue; fields[nameId] = fieldValue;
} else { } else {
declaredFields[nameId].set(instance, fieldValue); declaredFields.get(nameId).set(instance, fieldValue);
} }
} else { } else {
String keyName = jsonReader.nextName(); String keyName = jsonReader.nextName();
@ -283,9 +290,9 @@ public abstract class MoshiPolymorphic<OBJ> {
jsonReader.endObject(); jsonReader.endObject();
if (instantiateUsingStaticOf) { if (instantiateUsingStaticOf) {
Class[] params = new Class[declaredFields.length]; Class[] params = new Class[declaredFields.size()];
for (int i = 0; i < declaredFields.length; i++) { for (int i = 0; i < declaredFields.size(); i++) {
params[i] = declaredFields[i].getType(); params[i] = declaredFields.get(i).getType();
} }
instance = declaredClass.getMethod("of", params).invoke(null, fields); instance = declaredClass.getMethod("of", params).invoke(null, fields);
} }