Add lists support

This commit is contained in:
Andrea Cavalli 2021-06-20 02:27:51 +02:00
parent 84cf90947e
commit 37e8d9ae8a
1 changed files with 49 additions and 4 deletions

View File

@ -6,11 +6,14 @@ import com.squareup.moshi.JsonReader;
import com.squareup.moshi.JsonReader.Options;
import com.squareup.moshi.JsonWriter;
import com.squareup.moshi.Moshi;
import com.squareup.moshi.Types;
import dev.zacsweers.moshix.records.RecordsJsonAdapterFactory;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@ -28,9 +31,11 @@ public abstract class MoshiPolymorphic<OBJ> {
private final boolean useGetters;
private boolean initialized = false;
private Moshi abstractMoshi;
private final Map<Class<?>, JsonAdapter<OBJ>> abstractClassesSerializers = new ConcurrentHashMap<>();
private final Map<Class<?>, JsonAdapter<OBJ>> concreteClassesSerializers = new ConcurrentHashMap<>();
private final Map<Class<?>, JsonAdapter<?>> extraClassesSerializers = new ConcurrentHashMap<>();
private final Map<Type, JsonAdapter<OBJ>> abstractClassesSerializers = new ConcurrentHashMap<>();
private final Map<Type, JsonAdapter<List<OBJ>>> abstractListClassesSerializers = new ConcurrentHashMap<>();
private final Map<Type, JsonAdapter<OBJ>> concreteClassesSerializers = new ConcurrentHashMap<>();
private final Map<Type, JsonAdapter<List<OBJ>>> concreteListClassesSerializers = new ConcurrentHashMap<>();
private final Map<Type, JsonAdapter<?>> extraClassesSerializers = new ConcurrentHashMap<>();
private final Map<String, JsonAdapter<OBJ>> customAdapters = new ConcurrentHashMap<>();
public MoshiPolymorphic() {
@ -61,6 +66,9 @@ public abstract class MoshiPolymorphic<OBJ> {
if (!extraClassesSerializers.containsKey(declaredClass)) {
abstractMoshiBuilder.add(declaredClass, adapter);
abstractClassesSerializers.put(declaredClass, adapter);
abstractListClassesSerializers.put(Types.newParameterizedType(List.class, declaredClass),
new ListValueAdapter<>(adapter)
);
}
customAdapters.put(name, adapter);
}
@ -71,6 +79,9 @@ public abstract class MoshiPolymorphic<OBJ> {
if (!extraClassesSerializers.containsKey(declaredClass)
&& !abstractClassesSerializers.containsKey(declaredClass)) {
concreteClassesSerializers.put(declaredClass, adapter);
concreteListClassesSerializers.put(Types.newParameterizedType(List.class, declaredClass),
new ListValueAdapter<>(adapter)
);
abstractMoshiBuilder.add(declaredClass, adapter);
}
customAdapters.put(name, adapter);
@ -96,7 +107,9 @@ public abstract class MoshiPolymorphic<OBJ> {
initialize();
extraClassesSerializers.forEach(moshiBuilder::add);
abstractClassesSerializers.forEach(moshiBuilder::add);
abstractListClassesSerializers.forEach(moshiBuilder::add);
concreteClassesSerializers.forEach(moshiBuilder::add);
concreteListClassesSerializers.forEach(moshiBuilder::add);
return moshiBuilder;
}
@ -234,7 +247,7 @@ public abstract class MoshiPolymorphic<OBJ> {
while (jsonReader.hasNext()) {
var nameId = jsonReader.selectName(names);
if (nameId >= 0 && nameId < this.declaredFields.length) {
var fieldValue = abstractMoshi.adapter(declaredFields[nameId].getType()).fromJson(jsonReader);
var fieldValue = abstractMoshi.adapter(declaredFields[nameId].getGenericType()).fromJson(jsonReader);
if (instantiateUsingStaticOf) {
fields[nameId] = fieldValue;
} else {
@ -288,6 +301,38 @@ public abstract class MoshiPolymorphic<OBJ> {
}
}
private static class ListValueAdapter<T> extends JsonAdapter<List<T>> {
private final JsonAdapter<T> valueAdapter;
public ListValueAdapter(JsonAdapter<T> valueAdapter) {
this.valueAdapter = valueAdapter;
}
@Nullable
@Override
public List<T> fromJson(@NotNull JsonReader jsonReader) throws IOException {
jsonReader.beginArray();
var result = new ArrayList<T>();
result.add(valueAdapter.fromJson(jsonReader));
jsonReader.endArray();
return Collections.unmodifiableList(result);
}
@Override
public void toJson(@NotNull JsonWriter jsonWriter, @Nullable List<T> ts) throws IOException {
if (ts == null) {
jsonWriter.nullValue();
} else {
jsonWriter.beginArray();
for (T value : ts) {
valueAdapter.toJson(jsonWriter.valueSink(), value);
}
jsonWriter.endArray();
}
}
}
private static String fixType(String nextString) {
return nextString.replaceAll("[^a-zA-Z0-9]", "");
}