Proper deserialization of MinecraftVersionList to keep elements sorted

This commit is contained in:
Marc Baloup 2023-10-18 23:22:57 +02:00
parent a24eab67b6
commit c7b33132a9
2 changed files with 56 additions and 0 deletions

View File

@ -1,5 +1,18 @@
package fr.pandacube.lib.core.mc_version;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.bind.TreeTypeAdapter;
import com.google.gson.reflect.TypeToken;
import fr.pandacube.lib.core.json.Json;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -14,6 +27,10 @@ public record MinecraftVersionList(
Map<String, Integer> protocolOfVersion,
Map<Integer, List<String>> versionsOfProtocol
) {
static {
Json.registerTypeAdapterFactory(MinecraftVersionListAdapter.FACTORY);
}
/**
* Creates an empty {@link MinecraftVersionList}.
*/
@ -32,4 +49,35 @@ public record MinecraftVersionList(
versions.add(versionId);
versions.sort(MinecraftVersionUtil::compareVersions);
}
/**
* Gson Adapter that ensure the data in {@link MinecraftVersionList} is sorted correctly when deserializing.
*/
public static class MinecraftVersionListAdapter implements JsonSerializer<MinecraftVersionList>, JsonDeserializer<MinecraftVersionList> {
public static final TypeAdapterFactory FACTORY = TreeTypeAdapter.newTypeHierarchyFactory(MinecraftVersionList.class, new MinecraftVersionListAdapter());
private static final TypeToken<Map<String, Integer>> MAP_STR_INT_TYPE = new TypeToken<>() { };
private static final TypeToken<Map<Integer, List<String>>> MAP_INT_LIST_STRING_TYPE = new TypeToken<>() { };
@Override
public MinecraftVersionList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (!(json instanceof JsonObject jsonObj))
throw new JsonParseException("Expected JsonObject, got " + json.getClass().getSimpleName() + ".");
MinecraftVersionList mvList = new MinecraftVersionList();
mvList.protocolOfVersion.putAll(context.deserialize(jsonObj.get("protocolOfVersion"), MAP_STR_INT_TYPE.getType()));
mvList.versionsOfProtocol.putAll(context.deserialize(jsonObj.get("versionsOfProtocol"), MAP_INT_LIST_STRING_TYPE.getType()));
for (List<String> versionLists : mvList.versionsOfProtocol.values()) {
versionLists.sort(MinecraftVersionUtil::compareVersions);
}
return mvList;
}
@Override
public JsonElement serialize(MinecraftVersionList src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.add("protocolOfVersion", context.serialize(src.protocolOfVersion));
obj.add("versionsOfProtocol", context.serialize(src.versionsOfProtocol));
return obj;
}
}
}

View File

@ -216,6 +216,14 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
return displayOptimizedListOfVersions(List.of(this), finalWordSeparator);
}
public String getFirstVersion() {
return versions.get(0);
}
public String getLastVersion() {
return versions.get(versions.size() - 1);
}
@Override
public boolean equals(Object o) {
return o instanceof ProtocolVersion pv && protocolVersionNumber == pv.protocolVersionNumber;