mirror of
https://github.com/CarmJos/BukkitJSONSerializer.git
synced 2026-06-04 16:48:18 +08:00
feat: A lightweight JSON serializer
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
package cc.carm.lib.bukkit.configuration;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* BukkitJSONSerializer, a lightweight JSON serializer for {@link ConfigurationSerializable} objects.
|
||||
* <li>serialize by {@link #serializeToJSON(ConfigurationSerializable)}</li>
|
||||
* <li>deserialize by {@link #deserializeJSON(String, Class, ConfigurationSerializable)}</li>
|
||||
*
|
||||
* @author CarmJos
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class BukkitJSONSerializer {
|
||||
|
||||
protected static final String TYPE_KEY = ConfigurationSerialization.SERIALIZED_TYPE_KEY;
|
||||
|
||||
protected static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
||||
protected static JsonParser parser = new JsonParser();
|
||||
|
||||
public static void setGson(Gson gson) {
|
||||
BukkitJSONSerializer.gson = gson;
|
||||
}
|
||||
|
||||
public static void setParser(JsonParser parser) {
|
||||
BukkitJSONSerializer.parser = parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a {@link ConfigurationSerializable} object to Map.
|
||||
*
|
||||
* @param value object to serialize.
|
||||
* @param <T> {@link ConfigurationSerializable} object type.
|
||||
* @return Map containing serialized data
|
||||
*/
|
||||
public static <T extends ConfigurationSerializable> Map<String, Object> serializeToMap(T value) {
|
||||
Map<String, Object> values = new LinkedHashMap<>();
|
||||
// First, put tye type key;
|
||||
values.put(TYPE_KEY, ConfigurationSerialization.getAlias(value.getClass()));
|
||||
// Then, put the serialized value
|
||||
value.serialize().forEach((key, sub) -> {
|
||||
if (sub instanceof ConfigurationSerializable) {
|
||||
values.put(key, serializeToMap((ConfigurationSerializable) sub));
|
||||
} else {
|
||||
values.put(key, sub);
|
||||
}
|
||||
});
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a {@link ConfigurationSerializable} object to JSON.
|
||||
*
|
||||
* @param value object to serialize.
|
||||
* @param <T> {@link ConfigurationSerializable} object type.
|
||||
* @return JSON string containing serialized data.
|
||||
*/
|
||||
public static <T extends ConfigurationSerializable> String serializeToJSON(T value) {
|
||||
return gson.toJson(serializeToMap(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a {@link ConfigurationSerializable} object from JSON.
|
||||
*
|
||||
* @param json JSON string to deserialize.
|
||||
* @return Deserialized object.
|
||||
*/
|
||||
@Contract("null->null")
|
||||
public static Object deserializeJSON(@Nullable String json) {
|
||||
return deserializeJSON(json, (ConfigurationSerializable) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a {@link ConfigurationSerializable} object from JSON.
|
||||
*
|
||||
* @param json JSON string to deserialize.
|
||||
* @param defaultValue default value to return if json is null or failed to deserialize.
|
||||
* @return Deserialized object.
|
||||
*/
|
||||
@Contract("_,!null->!null; null,null->null")
|
||||
public static ConfigurationSerializable deserializeJSON(@Nullable String json,
|
||||
@Nullable ConfigurationSerializable defaultValue) {
|
||||
if (json == null) return defaultValue;
|
||||
Map<String, Object> args = jsonToMap(json);
|
||||
|
||||
return Optional.ofNullable((String) args.get(TYPE_KEY))
|
||||
.map(ConfigurationSerialization::getClassByAlias)
|
||||
.map(clazz -> ConfigurationSerialization.deserializeObject(args, clazz))
|
||||
.orElse(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a {@link ConfigurationSerializable} object from Map.
|
||||
*
|
||||
* @param json JSON string to deserialize.
|
||||
* @param typeClazz type of object.
|
||||
* @param <T> {@link ConfigurationSerializable} object type.
|
||||
* @return Deserialized object.
|
||||
*/
|
||||
public static <T extends ConfigurationSerializable> @Nullable T deserializeJSON(@Nullable String json,
|
||||
@NotNull Class<T> typeClazz) {
|
||||
return deserializeJSON(json, typeClazz, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a {@link ConfigurationSerializable} object from Map.
|
||||
*
|
||||
* @param json JSON string to deserialize.
|
||||
* @param typeClazz type of object.
|
||||
* @param defaultValue default value to return if json is null or failed to deserialize.
|
||||
* @param <T> {@link ConfigurationSerializable} object type.
|
||||
* @return Deserialized object.
|
||||
*/
|
||||
@Contract("_,_,!null->!null; null,_,null->null")
|
||||
public static <T extends ConfigurationSerializable> T deserializeJSON(@Nullable String json,
|
||||
@NotNull Class<T> typeClazz,
|
||||
@Nullable T defaultValue) {
|
||||
Object value = deserializeJSON(json, defaultValue);
|
||||
if (!typeClazz.isInstance(value)) return defaultValue;
|
||||
|
||||
return typeClazz.cast(value);
|
||||
}
|
||||
|
||||
protected static Map<String, Object> jsonToMap(String json) {
|
||||
return jsonToMap(parser.parse(json).getAsJsonObject());
|
||||
}
|
||||
|
||||
protected static Map<String, Object> jsonToMap(JsonObject object) {
|
||||
return parseMap(gson.fromJson(object, Map.class));
|
||||
}
|
||||
|
||||
protected static Map<String, Object> parseMap(Map<?, ?> map) {
|
||||
Map<String, Object> args = new LinkedHashMap<>();
|
||||
map.forEach((k, v) -> {
|
||||
String key = (String) k;
|
||||
if (v instanceof Map<?, ?>) {
|
||||
Map<String, Object> sub = parseMap((Map<?, ?>) v);
|
||||
if (sub.containsKey(TYPE_KEY)) {
|
||||
args.put(key, ConfigurationSerialization.deserializeObject(sub));
|
||||
} else {
|
||||
args.put(key, sub);
|
||||
}
|
||||
} else {
|
||||
args.put(key, v);
|
||||
}
|
||||
});
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cc.carm.lib.bukkit.configuration;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface JSONSerializable extends ConfigurationSerializable {
|
||||
|
||||
/**
|
||||
* Serialize this object into a JSON string.
|
||||
*
|
||||
* @return JSON string contains serialized data.
|
||||
*/
|
||||
default @NotNull String serializeToJSON() {
|
||||
return BukkitJSONSerializer.serializeToJSON(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import cc.carm.lib.bukkit.configuration.BukkitJSONSerializer;
|
||||
import cc.carm.lib.bukkit.configuration.JSONSerializable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class demo {
|
||||
|
||||
public static void demoUsage() {
|
||||
|
||||
Location location = new Location(Bukkit.getWorlds().get(0), -100.5, 100, 105.5);
|
||||
|
||||
String serialized = BukkitJSONSerializer.serializeToJSON(location);
|
||||
// serialized -> {"world":"world","x":-100.5,"y":100,"z":105.5,"yaw":0.0,"pitch":0.0}
|
||||
|
||||
Location deserialized = BukkitJSONSerializer.deserializeJSON(serialized, Location.class);
|
||||
|
||||
}
|
||||
|
||||
public static final class SomeValue implements JSONSerializable {
|
||||
|
||||
long time;
|
||||
UUID uuid;
|
||||
|
||||
public SomeValue(long time, UUID uuid) {
|
||||
this.time = time;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("time", time);
|
||||
map.put("uuid", uuid.toString());
|
||||
return map;
|
||||
}
|
||||
|
||||
public static SomeValue deserialize(Map<String, Object> map) {
|
||||
return new SomeValue(
|
||||
(long) map.get("time"),
|
||||
UUID.fromString((String) map.get("uuid"))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user