diff options
| author | DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> | 2022-08-24 20:19:24 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-24 20:19:24 +0200 |
| commit | a76b49be6dbeb0be3f88870e33d3e10e0e7f8e1c (patch) | |
| tree | d90eae9c622ba665da79caac9c628e408386ac2f /src/main/java | |
| parent | 87e7c92526ac894525079305932de80f20372679 (diff) | |
| download | OneConfig-a76b49be6dbeb0be3f88870e33d3e10e0e7f8e1c.tar.gz OneConfig-a76b49be6dbeb0be3f88870e33d3e10e0e7f8e1c.tar.bz2 OneConfig-a76b49be6dbeb0be3f88870e33d3e10e0e7f8e1c.zip | |
Gson interface (#109)
* Add gson-interface
* Add gson-interface
* Update license things
Diffstat (limited to 'src/main/java')
10 files changed, 1051 insertions, 7 deletions
diff --git a/src/main/java/cc/polyfrost/oneconfig/config/Config.java b/src/main/java/cc/polyfrost/oneconfig/config/Config.java index eb74d2a..87ade90 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/Config.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/Config.java @@ -34,8 +34,9 @@ import cc.polyfrost.oneconfig.config.data.PageLocation; import cc.polyfrost.oneconfig.config.elements.BasicOption; import cc.polyfrost.oneconfig.config.elements.OptionPage; import cc.polyfrost.oneconfig.config.elements.OptionSubcategory; -import cc.polyfrost.oneconfig.config.gson.NonProfileSpecificExclusionStrategy; -import cc.polyfrost.oneconfig.config.gson.ProfileExclusionStrategy; +import cc.polyfrost.oneconfig.config.gson.exclusion.NonProfileSpecificExclusionStrategy; +import cc.polyfrost.oneconfig.config.gson.exclusion.ProfileExclusionStrategy; +import cc.polyfrost.oneconfig.config.gson.gsoninterface.InterfaceAdapterFactory; import cc.polyfrost.oneconfig.gui.elements.config.ConfigKeyBind; import cc.polyfrost.oneconfig.gui.OneConfigGui; import cc.polyfrost.oneconfig.gui.elements.config.ConfigPageButton; @@ -63,8 +64,18 @@ import java.util.function.Supplier; public class Config { public final transient HashMap<String, BasicOption> optionNames = new HashMap<>(); transient protected final String configFile; - transient protected final Gson gson = new GsonBuilder().setExclusionStrategies(new ProfileExclusionStrategy()).excludeFieldsWithModifiers(Modifier.TRANSIENT).setPrettyPrinting().create(); - transient protected final Gson nonProfileSpecificGson = new GsonBuilder().setExclusionStrategies(new NonProfileSpecificExclusionStrategy()).excludeFieldsWithModifiers(Modifier.TRANSIENT).setPrettyPrinting().create(); + transient protected final Gson gson = new GsonBuilder() + .setExclusionStrategies(new ProfileExclusionStrategy()) + .registerTypeAdapterFactory(new InterfaceAdapterFactory()) + .excludeFieldsWithModifiers(Modifier.TRANSIENT) + .setPrettyPrinting() + .create(); + transient protected final Gson nonProfileSpecificGson = new GsonBuilder() + .setExclusionStrategies(new NonProfileSpecificExclusionStrategy()) + .registerTypeAdapterFactory(new InterfaceAdapterFactory()) + .excludeFieldsWithModifiers(Modifier.TRANSIENT) + .setPrettyPrinting() + .create(); transient protected final HashMap<Field, Object> defaults = new HashMap<>(); transient public Mod mod; public boolean enabled; diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/ExclusionUtils.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/exclusion/ExclusionUtils.java index 031efa6..efad110 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/gson/ExclusionUtils.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/exclusion/ExclusionUtils.java @@ -24,7 +24,7 @@ * <https://polyfrost.cc/legal/oneconfig/additional-terms> */ -package cc.polyfrost.oneconfig.config.gson; +package cc.polyfrost.oneconfig.config.gson.exclusion; public class ExclusionUtils { protected static boolean isSuperClassOf(Class<?> clazz, Class<?> parentClass) { diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/NonProfileSpecificExclusionStrategy.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/exclusion/NonProfileSpecificExclusionStrategy.java index 82dd1c5..ae4e7ac 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/gson/NonProfileSpecificExclusionStrategy.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/exclusion/NonProfileSpecificExclusionStrategy.java @@ -24,7 +24,7 @@ * <https://polyfrost.cc/legal/oneconfig/additional-terms> */ -package cc.polyfrost.oneconfig.config.gson; +package cc.polyfrost.oneconfig.config.gson.exclusion; import cc.polyfrost.oneconfig.config.Config; import cc.polyfrost.oneconfig.config.annotations.Exclude; diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/ProfileExclusionStrategy.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/exclusion/ProfileExclusionStrategy.java index 3f0a97b..e15a6ec 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/gson/ProfileExclusionStrategy.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/exclusion/ProfileExclusionStrategy.java @@ -24,7 +24,7 @@ * <https://polyfrost.cc/legal/oneconfig/additional-terms> */ -package cc.polyfrost.oneconfig.config.gson; +package cc.polyfrost.oneconfig.config.gson.exclusion; import cc.polyfrost.oneconfig.config.Config; import cc.polyfrost.oneconfig.config.annotations.Exclude; diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/GsonContext.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/GsonContext.java new file mode 100644 index 0000000..e27a362 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/GsonContext.java @@ -0,0 +1,123 @@ +package cc.polyfrost.oneconfig.config.gson.gsoninterface; + +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + + * This file contains an adaptation of code from gson-interface + * Project found at <https://github.com/mintern/gson-interface> + * For the avoidance of doubt, this file is still licensed under the terms + * of OneConfig's Licensing. + * + * LICENSE NOTICE FOR ADAPTED CODE + * + * Copyright (C) 2012, Brandon Mintern, EasyESI, Berkeley, CA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither gson-interface nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRANDON MINTERN OR EASYESI BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonIOException; +import com.google.gson.TypeAdapter; +import com.google.gson.internal.bind.JsonTreeReader; +import com.google.gson.internal.bind.JsonTreeWriter; + +import java.io.IOException; +import java.lang.reflect.Type; + +/** + * @author mintern + */ +public class GsonContext<T> { + private final Gson gson; + private final InterfaceAdapterFactory.InterfaceTypeAdapter<T> constructingAdapter; + + public GsonContext(Gson g, InterfaceAdapterFactory.InterfaceTypeAdapter<T> ita) { + gson = g; + constructingAdapter = ita; + } + + public JsonElement toJsonTree(Object obj) { + return gson.toJsonTree(obj); + } + + public JsonElement thisToJsonTree(T obj) throws JsonIOException { + JsonTreeWriter writer = new JsonTreeWriter(); + try { + constructingAdapter.getDelegate().write(writer, obj); + } catch (IOException e) { + throw new JsonIOException(e); + } + return writer.get(); + } + + public <C> C fromJsonTree(JsonElement json, Class<C> type) { + return gson.fromJson(json, type); + } + + public <C> C fromJsonTree(JsonElement json, Type typeOfC) { + return (C) gson.fromJson(json, typeOfC); + } + + public T thisFromJsonTree(JsonElement json) throws JsonIOException { + try { + return constructingAdapter.getDelegate().read(new JsonTreeReader(json)); + } catch (IOException e) { + throw new JsonIOException(e); + } + } + + public <C extends T> C thisFromJsonTree(JsonElement json, Type typeOfC) { + TypeAdapter<C> adapter = constructingAdapter.getNextAdapter(typeOfC); + try { + return adapter.read(new JsonTreeReader(json)); + } catch (IOException e) { + throw new JsonIOException(e); + } + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/InterfaceAdapterFactory.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/InterfaceAdapterFactory.java new file mode 100644 index 0000000..8f7d9d6 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/InterfaceAdapterFactory.java @@ -0,0 +1,192 @@ +package cc.polyfrost.oneconfig.config.gson.gsoninterface; + +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + + * This file contains an adaptation of code from gson-interface + * Project found at <https://github.com/mintern/gson-interface> + * For the avoidance of doubt, this file is still licensed under the terms + * of OneConfig's Licensing. + * + * LICENSE NOTICE FOR ADAPTED CODE + * + * Copyright (C) 2012, Brandon Mintern, EasyESI, Berkeley, CA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither gson-interface nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRANDON MINTERN OR EASYESI BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.google.gson.*; +import com.google.gson.internal.Streams; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * @author mintern + */ +public class InterfaceAdapterFactory implements TypeAdapterFactory { + @Override + public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tt) { + Class<T> rawType = Reflection.classOfType(tt.getRawType()); + boolean serializes = JsonSerialization.class.isAssignableFrom(rawType); + Constructor<JsonDeserializes<T>> deserializerConstructor = null; + Class<JsonDeserializes<T>>[] typeParameters = Reflection.getTypeParameters(rawType, JsonDeserialization.class); + if (typeParameters != null) { + deserializerConstructor = Reflection.getConstructor(typeParameters[0]); + } + if (serializes || deserializerConstructor != null) { + return new InterfaceTypeAdapter(serializes, deserializerConstructor, gson, tt, this); + } + return null; + } + + public static class InterfaceTypeAdapter<T> extends TypeAdapter<T> { + // This map ensures that only one deserializer of each type exists. + private static final Map<Class, JsonDeserializes<?>> deserializerInstances = new HashMap(); + + // Fields set in the constructor + private final boolean selfSerializing; + private final Constructor<JsonDeserializes<T>> deserializerConstructor; + private final Gson gson; + private final TypeToken<T> typeToken; + private final TypeAdapterFactory thisFactory; + + // Adapters that follow this one in the chain for the indicated type + private final Map<Type, TypeAdapter> nextAdapters = new HashMap(); + + // Lazily-initialized fields. Call their corresponding getters in + // order to access them. + private TypeAdapter<T> delegate; + private GsonContext gsonContext; + + private InterfaceTypeAdapter( + boolean serializes, + Constructor<JsonDeserializes<T>> dsc, + Gson g, + TypeToken<T> tt, + TypeAdapterFactory factory) { + selfSerializing = serializes; + if (dsc != null) { + dsc.setAccessible(true); + } + deserializerConstructor = dsc; + gson = g; + typeToken = tt; + thisFactory = factory; + } + + @Override + public void write(JsonWriter writer, T value) throws IOException { + if (!selfSerializing) { + getDelegate().write(writer, value); + } else if (value == null) { + writer.nullValue(); + } else { + JsonElement tree = ((JsonSerialization) value).toJsonTree(gsonContext()); + Streams.write(tree, writer); + } + } + + @Override + public T read(JsonReader reader) throws IOException { + if (deserializerConstructor == null) { + return getDelegate().read(reader); + } + JsonElement json = Streams.parse(reader); + if (json.isJsonNull()) { + return null; + } + return (T) deserializer().fromJsonTree(json, typeToken.getType(), gsonContext()); + } + + synchronized TypeAdapter<T> getDelegate() { + if (delegate == null) { + delegate = gson.getDelegateAdapter(thisFactory, typeToken); + } + return delegate; + } + + private synchronized GsonContext gsonContext() { + if (gsonContext == null) { + gsonContext = new GsonContext(gson, this); + } + return gsonContext; + } + + synchronized <C extends T> TypeAdapter<C> getNextAdapter(Type typeOfC) { + TypeAdapter<C> nextAdapter = nextAdapters.get(typeOfC); + if (nextAdapter == null) { + nextAdapter = gson.getDelegateAdapter(thisFactory, (TypeToken<C>) TypeToken.get(typeOfC)); + nextAdapters.put(typeOfC, nextAdapter); + } + return nextAdapter; + } + + private JsonDeserializes<T> deserializer() { + synchronized (deserializerInstances) { + Class<JsonDeserializes<T>> c = deserializerConstructor.getDeclaringClass(); + JsonDeserializes<T> deserializer = (JsonDeserializes<T>) deserializerInstances.get(c); + if (deserializer == null) { + try { + deserializer = deserializerConstructor.newInstance(); + } catch (Exception e) { + throw new JsonParseException(e); + } + deserializerInstances.put(c, deserializer); + } + return deserializer; + } + } + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonDeserialization.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonDeserialization.java new file mode 100644 index 0000000..436d897 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonDeserialization.java @@ -0,0 +1,63 @@ +package cc.polyfrost.oneconfig.config.gson.gsoninterface; + +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + + * This file contains an adaptation of code from gson-interface + * Project found at <https://github.com/mintern/gson-interface> + * For the avoidance of doubt, this file is still licensed under the terms + * of OneConfig's Licensing. + * + * LICENSE NOTICE FOR ADAPTED CODE + * + * Copyright (C) 2012, Brandon Mintern, EasyESI, Berkeley, CA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither gson-interface nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRANDON MINTERN OR EASYESI BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +public interface JsonDeserialization<D extends JsonDeserializes<? extends JsonDeserialization<D>>> { +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonDeserializes.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonDeserializes.java new file mode 100644 index 0000000..ecdf8e5 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonDeserializes.java @@ -0,0 +1,72 @@ +package cc.polyfrost.oneconfig.config.gson.gsoninterface; + +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + + * This file contains an adaptation of code from gson-interface + * Project found at <https://github.com/mintern/gson-interface> + * For the avoidance of doubt, this file is still licensed under the terms + * of OneConfig's Licensing. + * + * LICENSE NOTICE FOR ADAPTED CODE + * + * Copyright (C) 2012, Brandon Mintern, EasyESI, Berkeley, CA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither gson-interface nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRANDON MINTERN OR EASYESI BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.google.gson.JsonElement; + +import java.lang.reflect.Type; + +/** + * @author mintern + */ +public interface JsonDeserializes<T> { + T fromJsonTree(JsonElement json, Type type, GsonContext<T> context); +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonSerialization.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonSerialization.java new file mode 100644 index 0000000..3cae64d --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/JsonSerialization.java @@ -0,0 +1,70 @@ +package cc.polyfrost.oneconfig.config.gson.gsoninterface; + +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + + * This file contains an adaptation of code from gson-interface + * Project found at <https://github.com/mintern/gson-interface> + * For the avoidance of doubt, this file is still licensed under the terms + * of OneConfig's Licensing. + * + * LICENSE NOTICE FOR ADAPTED CODE + * + * Copyright (C) 2012, Brandon Mintern, EasyESI, Berkeley, CA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither gson-interface nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRANDON MINTERN OR EASYESI BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.google.gson.JsonElement; + +/** + * @author mintern + */ +public interface JsonSerialization<T extends JsonSerialization<T>> { + public JsonElement toJsonTree(GsonContext<T> context); +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/Reflection.java b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/Reflection.java new file mode 100644 index 0000000..ee50b64 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/gson/gsoninterface/Reflection.java @@ -0,0 +1,513 @@ +package cc.polyfrost.oneconfig.config.gson.gsoninterface; + +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + + * This file contains an adaptation of code from gson-interface + * Project found at <https://github.com/mintern/gson-interface> + * For the avoidance of doubt, this file is still licensed under the terms + * of OneConfig's Licensing. + * + * LICENSE NOTICE FOR ADAPTED CODE + * + * Copyright (C) 2012, Brandon Mintern, EasyESI, Berkeley, CA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither gson-interface nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BRANDON MINTERN OR EASYESI BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.lang.reflect.*; +import java.util.ArrayList; +import java.util.EmptyStackException; + +/** + * Provides various static helper methods that add a high-level interface to + * introspection and reflection. + * + * @author mintern + */ +public class Reflection { + /** + * A wrapper for Class.newInstance() that throws an unchecked Exception. + * It also ensures that even private constructors can be called. + * + * @param c the class on which to call newInstance() + * @return the object returned from c.newInstance() + * @throws IllegalArgumentException if there was an exception + * constructing the instance + */ + public static <T> T newInstance(Class<T> c) { + try { + return constructAnyway(c.getDeclaredConstructor()); |
