add setting and getting config in json format#540
add setting and getting config in json format#540ayyhimself wants to merge 2 commits intoJava-Discord:mainfrom
Conversation
danthe1st
left a comment
There was a problem hiding this comment.
I have yet to test this but here's my initial review.
src/main/java/net/discordjug/javabot/data/config/GuildConfig.java
Outdated
Show resolved
Hide resolved
src/main/java/net/discordjug/javabot/data/config/GuildConfig.java
Outdated
Show resolved
Hide resolved
src/main/java/net/discordjug/javabot/data/config/ReflectionUtils.java
Outdated
Show resolved
Hide resolved
src/main/java/net/discordjug/javabot/data/config/ReflectionUtils.java
Outdated
Show resolved
Hide resolved
src/main/java/net/discordjug/javabot/systems/configuration/SetConfigSubcommand.java
Outdated
Show resolved
Hide resolved
| @@ -22,19 +23,6 @@ | |||
| public class ReflectionUtils { | |||
| private static final Map<Class<?>, Function<String, Object>> propertyTypeParsers = new HashMap<>(); | |||
There was a problem hiding this comment.
I think this line can be removed as well.
| } | ||
| field.set(parent, parser.apply(s)); | ||
| public static Object set(@NotNull Field field, @NotNull Object parent, @NotNull String s) throws IllegalAccessException { | ||
| Object value = GsonUtils.fromJson(s, field.getType()); |
There was a problem hiding this comment.
I also noticed another bug. When I try to set message rules (which is a List) using /config set moderationConfig.messageRules, it sets the field to a List containing LinkedTreeMaps despite the field being a List<MessageRule>. This can lead to ClassCastExceptions like the following:
java.lang.ClassCastException: class com.google.gson.internal.LinkedTreeMap cannot be cast to class net.discordjug.javabot.data.config.guild.MessageRule (com.google.gson.internal.LinkedTreeMap and net.discordjug.javabot.data.config.guild.MessageRule are in unnamed module of loader 'app')
at net.discordjug.javabot.listener.filter.MessageRuleFilter.processMessage(MessageRuleFilter.java:49)
at net.discordjug.javabot.listener.filter.MessageFilterHandler.onMessageReceived(MessageFilterHandler.java:50)
at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:660)
at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:89)
at net.dv8tion.jda.internal.hooks.EventManagerProxy.handleInternally(EventManagerProxy.java:76)
at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:63)
at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:180)
at net.dv8tion.jda.internal.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:126)
at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:39)
at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:933)
at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:823)
at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:806)
at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:977)
at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385)
at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276)
at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996)
at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755)
at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108)
at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64)
at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45)
The reason for this is that calling Field#getType on the List<MessageRule> field yields the erased type hence gson doesn't know what to deserialize to. I think this can be fixed by doing something similar to:
Object value = GsonUtils.fromJson(s, field.getGenericType());and
public static Object fromJson(@NotNull String json, Type type) {
return gson.fromJson(json, type);
}| if (resolved == null) { | ||
| return Responses.error(event, "Config `%s` not found", property); | ||
| } | ||
| String json = GsonUtils.toJson(resolved); |
There was a problem hiding this comment.
When setting the config to invalid JSON, I am getting the following exception:
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected ':' at line 7 column 4 path $.sdfdfsdfs
See https://github.com/google/gson/blob/main/Troubleshooting.md#malformed-json
at com.google.gson.Gson.fromJson(Gson.java:1385)
at com.google.gson.Gson.fromJson(Gson.java:1260)
at com.google.gson.Gson.fromJson(Gson.java:1170)
at com.google.gson.Gson.fromJson(Gson.java:1107)
at net.discordjug.javabot.util.GsonUtils.fromJson(GsonUtils.java:24)
at net.discordjug.javabot.data.config.ReflectionUtils.set(ReflectionUtils.java:121)
at net.discordjug.javabot.data.config.GuildConfig.lambda$1(GuildConfig.java:160)
at java.base/java.util.Optional.ifPresent(Optional.java:178)
at net.discordjug.javabot.data.config.GuildConfig.set(GuildConfig.java:158)
at net.discordjug.javabot.systems.configuration.SetConfigSubcommand.handleModal(SetConfigSubcommand.java:81)
at xyz.dynxsty.dih4jda.InteractionHandler.lambda$onModalInteraction$27(InteractionHandler.java:788)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1825)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1817)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:511)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1450)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2019)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)
Caused by: com.google.gson.stream.MalformedJsonException: Expected ':' at line 7 column 4 path $.sdfdfsdfs
See https://github.com/google/gson/blob/main/Troubleshooting.md#malformed-json
at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1817)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:659)
at com.google.gson.stream.JsonReader.skipValue(JsonReader.java:1396)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:517)
at com.google.gson.Gson.fromJson(Gson.java:1359)
... 16 more
changes
/config get displays the object in json format
/config set displays the object in json format and accepts json format
removed old way of displaying objects
gson registered as a bean
very amazing pr