From 44a55d3962e96fa46c06a5d11ccac85be6e29ba3 Mon Sep 17 00:00:00 2001 From: Arnold Alejo Nunag Date: Fri, 9 Oct 2020 15:21:12 +0800 Subject: [PATCH] Move from GSON to Jackson, cleanup code warnings, move to javax.annotation annotations --- build.gradle | 4 +- gradle.properties | 2 +- .../java/sciwhiz12/janitor/BotStartup.java | 4 +- .../java/sciwhiz12/janitor/GuildStorage.java | 6 +- .../commands/moderation/BanCommand.java | 2 +- .../commands/moderation/KickCommand.java | 2 +- .../commands/moderation/NoteCommand.java | 7 +- .../commands/moderation/UnwarnCommand.java | 5 +- .../commands/moderation/WarnListCommand.java | 3 - .../commands/util/ModerationHelper.java | 2 +- .../sciwhiz12/janitor/config/BotConfig.java | 2 +- .../janitor/moderation/notes/NoteEntry.java | 69 ++++++++++-------- .../janitor/moderation/notes/NoteStorage.java | 49 +++++++------ .../moderation/warns/WarningEntry.java | 72 ++++++++++--------- .../moderation/warns/WarningStorage.java | 49 +++++++------ .../sciwhiz12/janitor/msg/MessageBuilder.java | 1 - .../sciwhiz12/janitor/msg/Moderation.java | 2 +- .../sciwhiz12/janitor/msg/Translations.java | 14 ++-- .../sciwhiz12/janitor/storage/IStorage.java | 5 +- .../janitor/storage/JsonStorage.java | 33 +++++---- .../janitor/utils/StringReaderUtil.java | 2 - .../java/sciwhiz12/janitor/utils/Util.java | 4 +- 22 files changed, 179 insertions(+), 160 deletions(-) diff --git a/build.gradle b/build.gradle index be5573d..ac8d7b6 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,9 @@ dependencies { implementation group: 'com.electronwill.night-config', name: 'toml', version: nightconfig_version implementation group: 'net.sf.jopt-simple', name: 'jopt-simple', version: jopt_version implementation group: 'com.google.guava', name: 'guava', version: guava_version - implementation group: 'com.google.code.gson', name: 'gson', version: gson_version + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jackson_version + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jackson_version + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jackson_version implementation group: 'org.apache.logging.log4j', name: 'log4j-to-slf4j', version: log4j_bridge_version implementation group: 'ch.qos.logback', name: 'logback-classic', version: logback_version implementation group: 'com.mojang', name: 'brigadier', version: brigadier_version diff --git a/gradle.properties b/gradle.properties index 5124242..90fffd0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ jda_version=4.2.0_207 nightconfig_version=3.6.3 jopt_version=6.0-alpha-3 guava_version=29.0-jre -gson_version=2.8.6 +jackson_version=2.11.2 log4j_bridge_version=2.13.3 logback_version=1.3.0-alpha5 brigadier_version=1.0.17 diff --git a/src/main/java/sciwhiz12/janitor/BotStartup.java b/src/main/java/sciwhiz12/janitor/BotStartup.java index 3dcfb0a..633d314 100644 --- a/src/main/java/sciwhiz12/janitor/BotStartup.java +++ b/src/main/java/sciwhiz12/janitor/BotStartup.java @@ -1,5 +1,6 @@ package sciwhiz12.janitor; +import com.google.common.base.Preconditions; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.OnlineStatus; import net.dv8tion.jda.api.entities.Activity; @@ -12,7 +13,6 @@ import sciwhiz12.janitor.config.BotOptions; import java.util.EnumSet; -import static com.google.common.base.Preconditions.checkArgument; import static sciwhiz12.janitor.Logging.JANITOR; public class BotStartup { @@ -21,7 +21,7 @@ public class BotStartup { BotOptions options = new BotOptions(args); BotConfig config = new BotConfig(options); - checkArgument(!config.getToken().isEmpty(), "Supply a client token through config or command line"); + Preconditions.checkArgument(!config.getToken().isEmpty(), "Supply a client token through config or command line"); JANITOR.info("Building bot instance and connecting to Discord..."); diff --git a/src/main/java/sciwhiz12/janitor/GuildStorage.java b/src/main/java/sciwhiz12/janitor/GuildStorage.java index 9c98f7b..abeac53 100644 --- a/src/main/java/sciwhiz12/janitor/GuildStorage.java +++ b/src/main/java/sciwhiz12/janitor/GuildStorage.java @@ -1,8 +1,6 @@ package sciwhiz12.janitor; import com.google.common.base.Preconditions; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import net.dv8tion.jda.api.entities.Guild; import sciwhiz12.janitor.storage.IStorage; @@ -19,8 +17,6 @@ import java.util.function.Supplier; import static java.nio.file.StandardOpenOption.*; public class GuildStorage { - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().serializeNulls().create(); - private final JanitorBot bot; private final Path mainFolder; private final Map> guildStorage = new IdentityHashMap<>(); @@ -35,9 +31,9 @@ public class GuildStorage { return bot; } + @SuppressWarnings("unchecked") public T getOrCreate(Guild guild, String key, Supplier defaultSupplier) { final Map storageMap = guildStorage.computeIfAbsent(guild, g -> new HashMap<>()); - //noinspection unchecked return (T) storageMap.computeIfAbsent(key, k -> load(guild, key, defaultSupplier.get())); } diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/BanCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/BanCommand.java index 172fc39..322210d 100644 --- a/src/main/java/sciwhiz12/janitor/commands/moderation/BanCommand.java +++ b/src/main/java/sciwhiz12/janitor/commands/moderation/BanCommand.java @@ -8,7 +8,6 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import org.checkerframework.checker.nullness.qual.Nullable; import sciwhiz12.janitor.commands.BaseCommand; import sciwhiz12.janitor.commands.CommandRegistry; import sciwhiz12.janitor.commands.util.ModerationHelper; @@ -16,6 +15,7 @@ import sciwhiz12.janitor.commands.util.ModerationHelper; import java.util.EnumSet; import java.util.List; import java.util.Objects; +import javax.annotation.Nullable; import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger; import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/KickCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/KickCommand.java index bbcb852..91e3e05 100644 --- a/src/main/java/sciwhiz12/janitor/commands/moderation/KickCommand.java +++ b/src/main/java/sciwhiz12/janitor/commands/moderation/KickCommand.java @@ -8,7 +8,6 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import org.checkerframework.checker.nullness.qual.Nullable; import sciwhiz12.janitor.commands.BaseCommand; import sciwhiz12.janitor.commands.CommandRegistry; import sciwhiz12.janitor.commands.util.CommandHelper; @@ -17,6 +16,7 @@ import sciwhiz12.janitor.commands.util.ModerationHelper; import java.util.EnumSet; import java.util.List; import java.util.Objects; +import javax.annotation.Nullable; import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/NoteCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/NoteCommand.java index dca1e23..0e4c13c 100644 --- a/src/main/java/sciwhiz12/janitor/commands/moderation/NoteCommand.java +++ b/src/main/java/sciwhiz12/janitor/commands/moderation/NoteCommand.java @@ -9,7 +9,6 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import org.checkerframework.checker.nullness.qual.Nullable; import sciwhiz12.janitor.commands.BaseCommand; import sciwhiz12.janitor.commands.CommandRegistry; import sciwhiz12.janitor.moderation.notes.NoteEntry; @@ -22,6 +21,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Predicate; +import javax.annotation.Nullable; import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger; import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; @@ -160,10 +160,9 @@ public class NoteCommand extends BaseCommand { case PERFORMER: { predicate = predicate.and(e -> e.getValue().getPerformer().getIdLong() == performer.getIdLong()); } + case NONE: {} } - final OffsetDateTime dateTime = OffsetDateTime.now(); - if (!performer.hasPermission(NOTE_PERMISSION)) channel.sendMessage( messages().MODERATION.ERRORS.performerInsufficientPermissions(performer, NOTE_PERMISSION).build(getBot())) @@ -188,8 +187,6 @@ public class NoteCommand extends BaseCommand { final Guild guild = ctx.getSource().getGuild(); final Member performer = Objects.requireNonNull(ctx.getSource().getMember()); - final OffsetDateTime dateTime = OffsetDateTime.now(); - if (!performer.hasPermission(NOTE_PERMISSION)) channel.sendMessage( messages().MODERATION.ERRORS.performerInsufficientPermissions(performer, NOTE_PERMISSION).build(getBot())) diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/UnwarnCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/UnwarnCommand.java index 86d4a61..b03b1d0 100644 --- a/src/main/java/sciwhiz12/janitor/commands/moderation/UnwarnCommand.java +++ b/src/main/java/sciwhiz12/janitor/commands/moderation/UnwarnCommand.java @@ -8,15 +8,14 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import org.checkerframework.checker.nullness.qual.Nullable; import sciwhiz12.janitor.commands.BaseCommand; import sciwhiz12.janitor.commands.CommandRegistry; import sciwhiz12.janitor.moderation.warns.WarningEntry; import sciwhiz12.janitor.moderation.warns.WarningStorage; -import java.time.OffsetDateTime; import java.util.EnumSet; import java.util.Objects; +import javax.annotation.Nullable; import static sciwhiz12.janitor.commands.util.CommandHelper.argument; import static sciwhiz12.janitor.commands.util.CommandHelper.literal; @@ -52,8 +51,6 @@ public class UnwarnCommand extends BaseCommand { final Member performer = Objects.requireNonNull(ctx.getSource().getMember()); int caseID = IntegerArgumentType.getInteger(ctx, "caseId"); - final OffsetDateTime dateTime = OffsetDateTime.now(); - if (!performer.hasPermission(WARN_PERMISSION)) channel.sendMessage( messages().MODERATION.ERRORS.performerInsufficientPermissions(performer, WARN_PERMISSION).build(getBot())) diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/WarnListCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/WarnListCommand.java index 18799d3..edc61ab 100644 --- a/src/main/java/sciwhiz12/janitor/commands/moderation/WarnListCommand.java +++ b/src/main/java/sciwhiz12/janitor/commands/moderation/WarnListCommand.java @@ -14,7 +14,6 @@ import sciwhiz12.janitor.commands.CommandRegistry; import sciwhiz12.janitor.moderation.warns.WarningEntry; import sciwhiz12.janitor.moderation.warns.WarningStorage; -import java.time.OffsetDateTime; import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -88,8 +87,6 @@ public class WarnListCommand extends BaseCommand { predicate = predicate.and(e -> e.getValue().getPerformer().getIdLong() == mod.getIdLong()); } - final OffsetDateTime dateTime = OffsetDateTime.now(); - if (!performer.hasPermission(WARN_PERMISSION)) channel.sendMessage( messages().MODERATION.ERRORS.performerInsufficientPermissions(performer, WARN_PERMISSION).build(getBot())) diff --git a/src/main/java/sciwhiz12/janitor/commands/util/ModerationHelper.java b/src/main/java/sciwhiz12/janitor/commands/util/ModerationHelper.java index 14ea445..0895ece 100644 --- a/src/main/java/sciwhiz12/janitor/commands/util/ModerationHelper.java +++ b/src/main/java/sciwhiz12/janitor/commands/util/ModerationHelper.java @@ -4,11 +4,11 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; -import org.checkerframework.checker.nullness.qual.Nullable; import java.time.Instant; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; +import javax.annotation.Nullable; import static sciwhiz12.janitor.utils.Util.nameFor; diff --git a/src/main/java/sciwhiz12/janitor/config/BotConfig.java b/src/main/java/sciwhiz12/janitor/config/BotConfig.java index 8c73d3b..4d5a487 100644 --- a/src/main/java/sciwhiz12/janitor/config/BotConfig.java +++ b/src/main/java/sciwhiz12/janitor/config/BotConfig.java @@ -4,11 +4,11 @@ import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.file.FileNotFoundAction; import com.electronwill.nightconfig.core.file.FileWatcher; import com.electronwill.nightconfig.toml.TomlFormat; -import org.checkerframework.checker.nullness.qual.Nullable; import java.io.IOException; import java.nio.file.Path; import java.util.Optional; +import javax.annotation.Nullable; import static sciwhiz12.janitor.Logging.CONFIG; import static sciwhiz12.janitor.Logging.JANITOR; diff --git a/src/main/java/sciwhiz12/janitor/moderation/notes/NoteEntry.java b/src/main/java/sciwhiz12/janitor/moderation/notes/NoteEntry.java index 5d79756..94ded43 100644 --- a/src/main/java/sciwhiz12/janitor/moderation/notes/NoteEntry.java +++ b/src/main/java/sciwhiz12/janitor/moderation/notes/NoteEntry.java @@ -1,18 +1,19 @@ package sciwhiz12.janitor.moderation.notes; -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.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; import net.dv8tion.jda.api.entities.User; import sciwhiz12.janitor.JanitorBot; -import java.lang.reflect.Type; +import java.io.IOException; import java.time.OffsetDateTime; import java.util.Objects; +import java.util.function.Supplier; public class NoteEntry { private final User performer; @@ -59,32 +60,42 @@ public class NoteEntry { return Objects.hash(getPerformer(), getTarget(), getDateTime(), getContents()); } - public static class Serializer implements JsonDeserializer, JsonSerializer { - private final JanitorBot bot; + public static class Serializer extends StdSerializer { + private static final long serialVersionUID = 1L; - public Serializer(JanitorBot bot) { + public Serializer() { + super(NoteEntry.class); + } + + @Override + public void serialize(NoteEntry value, JsonGenerator gen, SerializerProvider provider) throws IOException { + gen.writeStartObject(); + gen.writeNumberField("performer", value.getPerformer().getIdLong()); + gen.writeNumberField("target", value.getTarget().getIdLong()); + gen.writeStringField("dateTime", value.getDateTime().toString()); + gen.writeStringField("contents", value.getContents()); + gen.writeEndObject(); + } + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + private final Supplier bot; + + public Deserializer(Supplier bot) { + super(NoteEntry.class); this.bot = bot; } @Override - public NoteEntry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - final JsonObject obj = json.getAsJsonObject(); - final User performer = bot.getDiscord().retrieveUserById(obj.get("performer").getAsLong()).complete(); - final User target = bot.getDiscord().retrieveUserById(obj.get("target").getAsLong()).complete(); - final OffsetDateTime dateTime = OffsetDateTime.parse(obj.get("dateTime").getAsString()); - final String reason = obj.get("contents").getAsString(); - return new NoteEntry(performer, target, dateTime, reason); - } - - @Override - public JsonElement serialize(NoteEntry src, Type typeOfSrc, JsonSerializationContext context) { - final JsonObject obj = new JsonObject(); - obj.addProperty("performer", src.getPerformer().getId()); - obj.addProperty("target", src.getTarget().getId()); - obj.addProperty("dateTime", src.getDateTime().toString()); - obj.addProperty("contents", src.getContents()); - return obj; + public NoteEntry deserialize(JsonParser p, DeserializationContext ctx) throws IOException { + final JsonNode obj = ctx.readTree(p); + User performer = bot.get().getDiscord().retrieveUserById(obj.get("performer").asLong()).complete(); + User target = bot.get().getDiscord().retrieveUserById(obj.get("target").asLong()).complete(); + OffsetDateTime dateTime = OffsetDateTime.parse(obj.get("dateTime").asText()); + String contents = obj.get("contents").asText(); + return new NoteEntry(performer, target, dateTime, contents); } } } diff --git a/src/main/java/sciwhiz12/janitor/moderation/notes/NoteStorage.java b/src/main/java/sciwhiz12/janitor/moderation/notes/NoteStorage.java index c82d205..3101432 100644 --- a/src/main/java/sciwhiz12/janitor/moderation/notes/NoteStorage.java +++ b/src/main/java/sciwhiz12/janitor/moderation/notes/NoteStorage.java @@ -1,40 +1,36 @@ package sciwhiz12.janitor.moderation.notes; import com.electronwill.nightconfig.core.utils.ObservedMap; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.node.ObjectNode; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.User; -import org.checkerframework.checker.nullness.qual.Nullable; import sciwhiz12.janitor.GuildStorage; import sciwhiz12.janitor.JanitorBot; import sciwhiz12.janitor.storage.JsonStorage; -import java.lang.reflect.Type; +import java.io.IOException; import java.util.HashMap; import java.util.Map; +import javax.annotation.Nullable; public class NoteStorage extends JsonStorage { - private static final Type NOTE_MAP_TYPE = new TypeToken>() {}.getType(); + private static final TypeReference> NOTE_MAP_TYPE = new TypeReference<>() {}; public static final String STORAGE_KEY = "notes"; public static NoteStorage get(GuildStorage storage, Guild guild) { return storage.getOrCreate(guild, STORAGE_KEY, () -> new NoteStorage(storage.getBot())); } - private final Gson gson; private final JanitorBot bot; private int lastID = 1; private final Map notes = new ObservedMap<>(new HashMap<>(), this::markDirty); public NoteStorage(JanitorBot bot) { this.bot = bot; - this.gson = new GsonBuilder() - .registerTypeAdapter(NoteEntry.class, new NoteEntry.Serializer(bot)) - .create(); } public JanitorBot getBot() { @@ -52,8 +48,8 @@ public class NoteStorage extends JsonStorage { return notes.get(noteID); } - public NoteEntry removeNote(int noteID) { - return notes.remove(noteID); + public void removeNote(int noteID) { + notes.remove(noteID); } public int getAmountOfNotes(User target) { @@ -67,18 +63,27 @@ public class NoteStorage extends JsonStorage { } @Override - public JsonElement save() { - JsonObject obj = new JsonObject(); - obj.addProperty("lastNoteID", lastID); - obj.add("notes", gson.toJsonTree(notes)); + protected void initialize(ObjectMapper mapper) { + super.initialize(mapper); + mapper.registerModule( + new SimpleModule() + .addSerializer(NoteEntry.class, new NoteEntry.Serializer()) + .addDeserializer(NoteEntry.class, new NoteEntry.Deserializer(this::getBot)) + ); + } + + @Override + public JsonNode save(ObjectMapper mapper) { + final ObjectNode obj = mapper.createObjectNode(); + obj.put("lastNoteID", lastID); + obj.set("notes", mapper.valueToTree(notes)); return obj; } @Override - public void load(JsonElement in) { - final JsonObject obj = in.getAsJsonObject(); - lastID = obj.get("lastNoteID").getAsInt(); - final Map loaded = gson.fromJson(obj.get("notes"), NOTE_MAP_TYPE); + public void load(JsonNode in, ObjectMapper mapper) throws IOException { + lastID = in.get("lastNoteID").asInt(); + final Map loaded = mapper.readerFor(NOTE_MAP_TYPE).readValue(in.get("notes")); notes.clear(); notes.putAll(loaded); } diff --git a/src/main/java/sciwhiz12/janitor/moderation/warns/WarningEntry.java b/src/main/java/sciwhiz12/janitor/moderation/warns/WarningEntry.java index e136c77..2623c2d 100644 --- a/src/main/java/sciwhiz12/janitor/moderation/warns/WarningEntry.java +++ b/src/main/java/sciwhiz12/janitor/moderation/warns/WarningEntry.java @@ -1,18 +1,19 @@ package sciwhiz12.janitor.moderation.warns; -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.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; import net.dv8tion.jda.api.entities.User; import sciwhiz12.janitor.JanitorBot; -import java.lang.reflect.Type; +import java.io.IOException; import java.time.OffsetDateTime; import java.util.Objects; +import java.util.function.Supplier; import javax.annotation.Nullable; public class WarningEntry { @@ -62,35 +63,42 @@ public class WarningEntry { return Objects.hash(getPerformer(), getWarned(), getDateTime(), getReason()); } - public static class Serializer implements JsonDeserializer, JsonSerializer { - private final JanitorBot bot; + public static class Serializer extends StdSerializer { + private static final long serialVersionUID = 1L; - public Serializer(JanitorBot bot) { + public Serializer() { + super(WarningEntry.class); + } + + @Override + public void serialize(WarningEntry value, JsonGenerator gen, SerializerProvider provider) throws IOException { + gen.writeStartObject(); + gen.writeNumberField("performer", value.getPerformer().getIdLong()); + gen.writeNumberField("warned", value.getWarned().getIdLong()); + gen.writeStringField("dateTime", value.getDateTime().toString()); + gen.writeStringField("reason", value.getReason()); + gen.writeEndObject(); + } + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + private final Supplier bot; + + public Deserializer(Supplier bot) { + super(WarningEntry.class); this.bot = bot; } @Override - public WarningEntry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - final JsonObject obj = json.getAsJsonObject(); - final User warned = bot.getDiscord().retrieveUserById(obj.get("warned").getAsLong()).complete(); - final User performer = bot.getDiscord().retrieveUserById(obj.get("performer").getAsLong()).complete(); - final OffsetDateTime dateTime = OffsetDateTime.parse(obj.get("dateTime").getAsString()); - @Nullable - final String reason = obj.has("reason") ? obj.get("reason").getAsString() : null; - return new WarningEntry(warned, performer, dateTime, reason); - } - - @Override - public JsonElement serialize(WarningEntry src, Type typeOfSrc, JsonSerializationContext context) { - final JsonObject obj = new JsonObject(); - obj.addProperty("warned", src.getWarned().getId()); - obj.addProperty("performer", src.getPerformer().getId()); - obj.addProperty("dateTime", src.getDateTime().toString()); - if (src.getReason() != null) { - obj.addProperty("reason", src.getReason()); - } - return obj; + public WarningEntry deserialize(JsonParser p, DeserializationContext ctx) throws IOException { + final JsonNode obj = ctx.readTree(p); + User performer = bot.get().getDiscord().retrieveUserById(obj.get("performer").asLong()).complete(); + User warned = bot.get().getDiscord().retrieveUserById(obj.get("warned").asLong()).complete(); + OffsetDateTime dateTime = OffsetDateTime.parse(obj.get("dateTime").asText()); + String contents = obj.get("reason").asText(); + return new WarningEntry(performer, warned, dateTime, contents); } } } diff --git a/src/main/java/sciwhiz12/janitor/moderation/warns/WarningStorage.java b/src/main/java/sciwhiz12/janitor/moderation/warns/WarningStorage.java index b540c34..9dc21ab 100644 --- a/src/main/java/sciwhiz12/janitor/moderation/warns/WarningStorage.java +++ b/src/main/java/sciwhiz12/janitor/moderation/warns/WarningStorage.java @@ -1,39 +1,35 @@ package sciwhiz12.janitor.moderation.warns; import com.electronwill.nightconfig.core.utils.ObservedMap; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.node.ObjectNode; import net.dv8tion.jda.api.entities.Guild; -import org.checkerframework.checker.nullness.qual.Nullable; import sciwhiz12.janitor.GuildStorage; import sciwhiz12.janitor.JanitorBot; import sciwhiz12.janitor.storage.JsonStorage; -import java.lang.reflect.Type; +import java.io.IOException; import java.util.HashMap; import java.util.Map; +import javax.annotation.Nullable; public class WarningStorage extends JsonStorage { - private static final Type WARNING_MAP_TYPE = new TypeToken>() {}.getType(); + private static final TypeReference> WARNING_MAP_TYPE = new TypeReference<>() {}; public static final String STORAGE_KEY = "warnings"; public static WarningStorage get(GuildStorage storage, Guild guild) { return storage.getOrCreate(guild, STORAGE_KEY, () -> new WarningStorage(storage.getBot())); } - private final Gson gson; private final JanitorBot bot; private int lastID = 1; private final Map warnings = new ObservedMap<>(new HashMap<>(), this::markDirty); public WarningStorage(JanitorBot bot) { this.bot = bot; - this.gson = new GsonBuilder() - .registerTypeAdapter(WarningEntry.class, new WarningEntry.Serializer(bot)) - .create(); } public JanitorBot getBot() { @@ -51,8 +47,8 @@ public class WarningStorage extends JsonStorage { return warnings.get(caseID); } - public WarningEntry removeWarning(int caseID) { - return warnings.remove(caseID); + public void removeWarning(int caseID) { + warnings.remove(caseID); } public Map getWarnings() { @@ -60,18 +56,27 @@ public class WarningStorage extends JsonStorage { } @Override - public JsonElement save() { - JsonObject obj = new JsonObject(); - obj.addProperty("lastCaseID", lastID); - obj.add("warnings", gson.toJsonTree(warnings)); + protected void initialize(ObjectMapper mapper) { + super.initialize(mapper); + mapper.registerModule( + new SimpleModule() + .addSerializer(WarningEntry.class, new WarningEntry.Serializer()) + .addDeserializer(WarningEntry.class, new WarningEntry.Deserializer(this::getBot)) + ); + } + + @Override + public JsonNode save(ObjectMapper mapper) { + final ObjectNode obj = mapper.createObjectNode(); + obj.put("lastCaseID", lastID); + obj.set("warnings", mapper.valueToTree(warnings)); return obj; } @Override - public void load(JsonElement in) { - final JsonObject obj = in.getAsJsonObject(); - lastID = obj.get("lastCaseID").getAsInt(); - final Map loaded = gson.fromJson(obj.get("warnings"), WARNING_MAP_TYPE); + public void load(JsonNode in, ObjectMapper mapper) throws IOException { + lastID = in.get("lastCaseID").asInt(); + final Map loaded = mapper.convertValue(in.get("warnings"), WARNING_MAP_TYPE); warnings.clear(); warnings.putAll(loaded); } diff --git a/src/main/java/sciwhiz12/janitor/msg/MessageBuilder.java b/src/main/java/sciwhiz12/janitor/msg/MessageBuilder.java index 0a4fe73..1c4fb86 100644 --- a/src/main/java/sciwhiz12/janitor/msg/MessageBuilder.java +++ b/src/main/java/sciwhiz12/janitor/msg/MessageBuilder.java @@ -25,7 +25,6 @@ public class MessageBuilder { this(new EmbedBuilder(), new HashMap<>()); } - @SuppressWarnings("CopyConstructorMissesField") public MessageBuilder(MessageBuilder copy) { this(new EmbedBuilder(copy.embedBuilder), new HashMap<>(copy.substitutions)); } diff --git a/src/main/java/sciwhiz12/janitor/msg/Moderation.java b/src/main/java/sciwhiz12/janitor/msg/Moderation.java index 3fe302b..b4ea21d 100644 --- a/src/main/java/sciwhiz12/janitor/msg/Moderation.java +++ b/src/main/java/sciwhiz12/janitor/msg/Moderation.java @@ -3,7 +3,6 @@ package sciwhiz12.janitor.msg; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; -import org.checkerframework.checker.nullness.qual.Nullable; import sciwhiz12.janitor.moderation.notes.NoteEntry; import sciwhiz12.janitor.moderation.warns.WarningEntry; @@ -12,6 +11,7 @@ import java.time.ZoneOffset; import java.util.EnumSet; import java.util.Map; import java.util.stream.Collectors; +import javax.annotation.Nullable; import static java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME; diff --git a/src/main/java/sciwhiz12/janitor/msg/Translations.java b/src/main/java/sciwhiz12/janitor/msg/Translations.java index 5dda90d..0101dd3 100644 --- a/src/main/java/sciwhiz12/janitor/msg/Translations.java +++ b/src/main/java/sciwhiz12/janitor/msg/Translations.java @@ -1,13 +1,11 @@ package sciwhiz12.janitor.msg; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.io.Resources; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; import sciwhiz12.janitor.JanitorBot; import java.io.InputStreamReader; -import java.lang.reflect.Type; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; @@ -18,13 +16,13 @@ import static sciwhiz12.janitor.Logging.JANITOR; import static sciwhiz12.janitor.Logging.TRANSLATIONS; public class Translations { - private static final Gson GSON = new GsonBuilder().create(); private static final String DEFAULT_TRANSLATIONS_RESOURCE = "english.json"; - private static final Type MAP_TYPE = new TypeToken>() {}.getType(); + private static final TypeReference> MAP_TYPE = new TypeReference<>() {}; private final JanitorBot bot; private final Path translationsFile; private final Map translations = new HashMap<>(); + private final ObjectMapper jsonMapper = new ObjectMapper(); public Translations(JanitorBot bot, Path translationsFile) { this.bot = bot; @@ -40,7 +38,7 @@ public class Translations { } try { JANITOR.debug(TRANSLATIONS, "Loading translations from file {}", translationsFile); - Map trans = GSON.fromJson(Files.newBufferedReader(translationsFile), MAP_TYPE); + Map trans = jsonMapper.readValue(Files.newBufferedReader(translationsFile), MAP_TYPE); translations.clear(); translations.putAll(trans); JANITOR.info(TRANSLATIONS, "Loaded {} translations from file {}", translations.size(), translationsFile); @@ -55,7 +53,7 @@ public class Translations { try { JANITOR.debug(TRANSLATIONS, "Loading default english translations"); // noinspection UnstableApiUsage - Map trans = GSON.fromJson( + Map trans = jsonMapper.readValue( new InputStreamReader(Resources.getResource(DEFAULT_TRANSLATIONS_RESOURCE).openStream()), MAP_TYPE); translations.clear(); diff --git a/src/main/java/sciwhiz12/janitor/storage/IStorage.java b/src/main/java/sciwhiz12/janitor/storage/IStorage.java index 6ee78c8..655a775 100644 --- a/src/main/java/sciwhiz12/janitor/storage/IStorage.java +++ b/src/main/java/sciwhiz12/janitor/storage/IStorage.java @@ -1,5 +1,6 @@ package sciwhiz12.janitor.storage; +import java.io.IOException; import java.io.Reader; import java.io.Writer; @@ -7,7 +8,7 @@ public interface IStorage { boolean dirty(); - void write(Writer output); + void write(Writer output) throws IOException; - void read(Reader input); + void read(Reader input) throws IOException; } diff --git a/src/main/java/sciwhiz12/janitor/storage/JsonStorage.java b/src/main/java/sciwhiz12/janitor/storage/JsonStorage.java index f0a8013..5763234 100644 --- a/src/main/java/sciwhiz12/janitor/storage/JsonStorage.java +++ b/src/main/java/sciwhiz12/janitor/storage/JsonStorage.java @@ -1,30 +1,35 @@ package sciwhiz12.janitor.storage; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import java.io.IOException; import java.io.Reader; import java.io.Writer; public abstract class JsonStorage extends AbstractStorage { - public static final Gson GSON = new GsonBuilder() - .serializeNulls() - .setPrettyPrinting() - .create(); + protected final ObjectMapper jsonMapper = new ObjectMapper() + .enable(SerializationFeature.INDENT_OUTPUT) + .enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); - public abstract JsonElement save(); + protected JsonStorage() { + initialize(jsonMapper); + } - public abstract void load(JsonElement object); + protected void initialize(ObjectMapper mapper) {} + + public abstract JsonNode save(ObjectMapper mapper); + + public abstract void load(JsonNode object, ObjectMapper mapper) throws IOException; @Override - public void write(Writer input) { - GSON.toJson(save(), input); + public void write(Writer input) throws IOException { + jsonMapper.writeTree(jsonMapper.createGenerator(input), save(jsonMapper)); } @Override - public void read(Reader input) { - load(JsonParser.parseReader(input)); + public void read(Reader input) throws IOException { + load(jsonMapper.readTree(input), jsonMapper); } } diff --git a/src/main/java/sciwhiz12/janitor/utils/StringReaderUtil.java b/src/main/java/sciwhiz12/janitor/utils/StringReaderUtil.java index a20b0cc..99bb739 100644 --- a/src/main/java/sciwhiz12/janitor/utils/StringReaderUtil.java +++ b/src/main/java/sciwhiz12/janitor/utils/StringReaderUtil.java @@ -37,8 +37,6 @@ public class StringReaderUtil { } private static final char SYNTAX_ESCAPE = '\\'; - private static final char SYNTAX_DOUBLE_QUOTE = '"'; - private static final char SYNTAX_SINGLE_QUOTE = '\''; public static String readStringUntil(StringReader reader, char terminator) throws CommandSyntaxException { final StringBuilder result = new StringBuilder(); boolean escaped = false; diff --git a/src/main/java/sciwhiz12/janitor/utils/Util.java b/src/main/java/sciwhiz12/janitor/utils/Util.java index 57ec9aa..fe22818 100644 --- a/src/main/java/sciwhiz12/janitor/utils/Util.java +++ b/src/main/java/sciwhiz12/janitor/utils/Util.java @@ -55,8 +55,8 @@ public class Util { return user.getName().concat("#").concat(user.getDiscriminator()); } - public static BiConsumer handle(final Consumer success, - final Consumer exceptionally) { + public static BiConsumer handle(final Consumer success, + final Consumer exceptionally) { return (suc, ex) -> { if (ex == null) { success.accept(suc);