From 21283b0928366fd3455d7f8083501e9a3229d327 Mon Sep 17 00:00:00 2001 From: Auxilor Date: Thu, 20 Apr 2023 19:19:00 +0100 Subject: [PATCH] Added ExternalDataStoreObjectAdapter --- .../eco/core/data/ExternalDataStore.java | 69 ++++++++++++++++++- .../data/ExternalDataStoreObjectAdapter.java | 69 +++++++++++++++++++ .../eco/internal/data/VersionAdapters.kt | 27 ++++++++ .../eco/internal/spigot/EcoSpigotPlugin.kt | 19 +++++ 4 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStoreObjectAdapter.java create mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/data/VersionAdapters.kt diff --git a/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStore.java b/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStore.java index e4f5eeaa..0e4a51fd 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStore.java +++ b/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStore.java @@ -3,17 +3,26 @@ package com.willfp.eco.core.data; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.function.Supplier; /** * A simple store key-value store for data to be stored outside of plugins. */ +@SuppressWarnings("unchecked") public final class ExternalDataStore { /** * The store. */ - private static final HashMap data = new HashMap<>(); + private static final Map DATA = new HashMap<>(); + + /** + * The store adapters. + */ + private static final List> STORE_ADAPTERS = new ArrayList<>(); /** * Put data into the store. @@ -23,7 +32,29 @@ public final class ExternalDataStore { */ public static void put(@NotNull final String key, @NotNull final Object value) { - data.put(key, value); + doPut(key, value); + } + + /** + * Put data into the store. + * + * @param key The key. + * @param value The value. + * @param The stored type. + */ + private static void doPut(@NotNull final String key, + @NotNull final A value) { + Object storedValue = value; + + for (ExternalDataStoreObjectAdapter unknownAdapter : STORE_ADAPTERS) { + if (unknownAdapter.getAccessedClass().isInstance(value)) { + ExternalDataStoreObjectAdapter adapter = (ExternalDataStoreObjectAdapter) unknownAdapter; + storedValue = adapter.toStoredObject(value); + break; + } + } + + DATA.put(key, storedValue); } /** @@ -37,7 +68,30 @@ public final class ExternalDataStore { @Nullable public static T get(@NotNull final String key, @NotNull final Class clazz) { - Object value = data.get(key); + return doGet(key, clazz); + } + + /** + * Get data from the store. + * + * @param key The key. + * @param clazz The class. + * @param The accessed type. + * @param The stored type. + * @return The value. + */ + @Nullable + private static A doGet(@NotNull final String key, + @NotNull final Class clazz) { + Object value = DATA.get(key); + + for (ExternalDataStoreObjectAdapter unknownAdapter : STORE_ADAPTERS) { + if (unknownAdapter.getStoredClass().isInstance(value) && unknownAdapter.getAccessedClass().equals(clazz)) { + ExternalDataStoreObjectAdapter adapter = (ExternalDataStoreObjectAdapter) unknownAdapter; + value = adapter.toAccessedObject((S) value); + break; + } + } if (clazz.isInstance(value)) { return clazz.cast(value); @@ -79,6 +133,15 @@ public final class ExternalDataStore { return get(key, clazz, defaultValue.get()); } + /** + * Register a new adapter. + * + * @param adapter The adapter. + */ + public static void registerAdapter(@NotNull final ExternalDataStoreObjectAdapter adapter) { + STORE_ADAPTERS.add(adapter); + } + private ExternalDataStore() { throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); } diff --git a/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStoreObjectAdapter.java b/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStoreObjectAdapter.java new file mode 100644 index 00000000..2e6a4fd8 --- /dev/null +++ b/eco-api/src/main/java/com/willfp/eco/core/data/ExternalDataStoreObjectAdapter.java @@ -0,0 +1,69 @@ +package com.willfp.eco.core.data; + +import org.jetbrains.annotations.NotNull; + +/** + * An adapter for objects stored in {@link ExternalDataStore}. + * + * @param The accessed class. + * @param The stored class. + */ +public abstract class ExternalDataStoreObjectAdapter { + /** + * The class that is accessed (read / written). + */ + private final Class accessedClass; + + /** + * The class that is stored internally. + */ + private final Class storedClass; + + /** + * Create a new adapter. + * + * @param accessedClass The class that is accessed (read / written). + * @param storedClass The class that is stored internally. + */ + protected ExternalDataStoreObjectAdapter(@NotNull final Class accessedClass, + @NotNull final Class storedClass) { + this.accessedClass = accessedClass; + this.storedClass = storedClass; + } + + /** + * Convert an object to the stored object. + * + * @param obj The object. + * @return The stored object. + */ + @NotNull + public abstract S toStoredObject(@NotNull final A obj); + + /** + * Convert an object to the accessed object. + * + * @param obj The object. + * @return The accessed object. + */ + @NotNull + public abstract A toAccessedObject(@NotNull final S obj); + + /** + * Get the class that is accessed (read / written). + * + * @return The class. + */ + public Class getAccessedClass() { + return accessedClass; + } + + /** + * Get the class that is stored internally. + * + * @return The class. + */ + public Class getStoredClass() { + return storedClass; + } +} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/data/VersionAdapters.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/data/VersionAdapters.kt new file mode 100644 index 00000000..2ce7417f --- /dev/null +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/data/VersionAdapters.kt @@ -0,0 +1,27 @@ +package com.willfp.eco.internal.data + +import com.willfp.eco.core.data.ExternalDataStoreObjectAdapter +import com.willfp.eco.core.version.Version + +object VersionToStringAdapter: ExternalDataStoreObjectAdapter( + Version::class.java, + String::class.java +) { + override fun toAccessedObject(obj: String): Version = Version(obj) + + override fun toStoredObject(obj: Version): String = obj.toString() +} + +class MavenVersionToStringAdapter( + className: String +): ExternalDataStoreObjectAdapter( + Class.forName(className), + String::class.java +) { + private val constructor = Class.forName(className) + .getConstructor(String::class.java) + + override fun toAccessedObject(obj: String): Any = constructor.newInstance(obj) + + override fun toStoredObject(obj: Any): String = obj.toString() +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt index 105dbc08..48f343da 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt @@ -3,6 +3,7 @@ package com.willfp.eco.internal.spigot import com.willfp.eco.core.Eco import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.Prerequisite +import com.willfp.eco.core.data.ExternalDataStore import com.willfp.eco.core.entities.Entities import com.willfp.eco.core.integrations.IntegrationLoader import com.willfp.eco.core.integrations.afk.AFKManager @@ -19,6 +20,8 @@ import com.willfp.eco.core.items.Items import com.willfp.eco.core.packet.PacketListener import com.willfp.eco.core.particle.Particles import com.willfp.eco.core.price.Prices +import com.willfp.eco.internal.data.MavenVersionToStringAdapter +import com.willfp.eco.internal.data.VersionToStringAdapter import com.willfp.eco.internal.entities.EntityArgParserAdult import com.willfp.eco.internal.entities.EntityArgParserAttackDamage import com.willfp.eco.internal.entities.EntityArgParserAttackSpeed @@ -120,6 +123,7 @@ import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInComplex import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInVanilla import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapedCraftingRecipeStackHandler import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapelessCraftingRecipeStackHandler +import com.willfp.eco.util.ClassUtils import me.TechsCode.UltraEconomy.UltraEconomy import net.kyori.adventure.platform.bukkit.BukkitAudiences import net.milkbowl.vault.economy.Economy @@ -178,6 +182,20 @@ abstract class EcoSpigotPlugin : EcoPlugin() { SegmentParserUseIfPresent.register() CustomItemsManager.registerProviders() + + ExternalDataStore.registerAdapter(VersionToStringAdapter) + // Handle with shadow. + val className = listOf( + "org", + "apache", + "maven", + "artifact", + "versioning", + "DefaultArtifactVersion" + ).joinToString(".") + if (ClassUtils.exists(className)) { + ExternalDataStore.registerAdapter(MavenVersionToStringAdapter(className)) + } } override fun handleEnable() { @@ -270,6 +288,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() { IntegrationLoader("CombatLogX") { val pluginManager = Bukkit.getPluginManager() val combatLogXPlugin = pluginManager.getPlugin("CombatLogX") ?: return@IntegrationLoader + @Suppress("DEPRECATION") val pluginVersion = combatLogXPlugin.description.version if (pluginVersion.startsWith("10")) {