diff --git a/build.gradle b/build.gradle index 90c26f32..ef5ee2fe 100644 --- a/build.gradle +++ b/build.gradle @@ -111,6 +111,9 @@ dependencies { // Utils shadowed 'io.vavr:vavr:0.10.4' shadowed 'org.glassfish.hk2:hk2-locator:3.0.3' + shadowed('org.glassfish.hk2:hk2-inhabitant-generator:3.0.3') { + exclude group: 'org.apache.maven', module: 'maven-core' + } shadowed('com.dumptruckman.minecraft:Logging:1.1.1') { exclude group: 'junit', module: 'junit' } diff --git a/src/main/java/org/mvplugins/multiverse/core/MultiverseCore.java b/src/main/java/org/mvplugins/multiverse/core/MultiverseCore.java index 87385267..43b1b23e 100644 --- a/src/main/java/org/mvplugins/multiverse/core/MultiverseCore.java +++ b/src/main/java/org/mvplugins/multiverse/core/MultiverseCore.java @@ -8,10 +8,8 @@ package org.mvplugins.multiverse.core; import java.io.File; -import java.lang.annotation.Annotation; import java.util.List; import java.util.logging.Logger; -import java.util.stream.Collectors; import com.dumptruckman.minecraft.util.Logging; import io.vavr.control.Try; @@ -20,13 +18,10 @@ import jakarta.inject.Provider; import me.main__.util.SerializationConfig.SerializationConfig; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; -import org.glassfish.hk2.api.MultiException; -import org.glassfish.hk2.api.ServiceHandle; -import org.glassfish.hk2.api.ServiceLocator; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.core.anchor.AnchorManager; @@ -39,7 +34,8 @@ import org.mvplugins.multiverse.core.config.MVCoreConfig; import org.mvplugins.multiverse.core.destination.DestinationsProvider; import org.mvplugins.multiverse.core.economy.MVEconomist; import org.mvplugins.multiverse.core.inject.InjectableListener; -import org.mvplugins.multiverse.core.inject.PluginInjection; +import org.mvplugins.multiverse.core.inject.PluginServiceLocator; +import org.mvplugins.multiverse.core.inject.PluginServiceLocatorFactory; import org.mvplugins.multiverse.core.placeholders.MultiverseCorePlaceholders; import org.mvplugins.multiverse.core.utils.TestingMode; import org.mvplugins.multiverse.core.utils.metrics.MetricsConfigurator; @@ -54,7 +50,9 @@ import org.mvplugins.multiverse.core.world.config.SpawnLocation; public class MultiverseCore extends JavaPlugin implements MVCore { private static final int PROTOCOL = 50; - private ServiceLocator serviceLocator; + private PluginServiceLocatorFactory serviceLocatorFactory; + private PluginServiceLocator serviceLocator; + @Inject private Provider configProvider; @Inject @@ -150,12 +148,12 @@ public class MultiverseCore extends JavaPlugin implements MVCore { } private void initializeDependencyInjection() { - serviceLocator = PluginInjection.createServiceLocator(new MultiverseCorePluginBinder(this)) - .andThenTry(locator -> { - PluginInjection.enable(this, locator); - }) + serviceLocatorFactory = new PluginServiceLocatorFactory(); + serviceLocator = serviceLocatorFactory.init() + .flatMap(ignore -> serviceLocatorFactory.registerPlugin(new MultiverseCorePluginBinder(this))) + .flatMap(PluginServiceLocator::enable) .getOrElseThrow(exception -> { - Logging.severe("Failed to initialize dependency injection"); + Logging.severe("Failed to initialize dependency injection!"); getServer().getPluginManager().disablePlugin(this); return new RuntimeException(exception); }); @@ -163,9 +161,13 @@ public class MultiverseCore extends JavaPlugin implements MVCore { private void shutdownDependencyInjection() { if (serviceLocator != null) { - PluginInjection.disable(this, serviceLocator); + serviceLocator.disable(); serviceLocator = null; } + if (serviceLocatorFactory != null) { + serviceLocatorFactory.shutdown(); + serviceLocatorFactory = null; + } } private boolean shouldShowConfig() { @@ -207,10 +209,8 @@ public class MultiverseCore extends JavaPlugin implements MVCore { */ private void registerCommands() { Try.of(() -> commandManagerProvider.get()) - .andThenTry(commandManager -> { - serviceLocator.getAllServices(MultiverseCommand.class) - .forEach(commandManager::registerCommand); - }) + .andThenTry(commandManager -> serviceLocator.getAllServices(MultiverseCommand.class) + .forEach(commandManager::registerCommand)) .onFailure(e -> { Logging.severe("Failed to register commands"); e.printStackTrace(); @@ -222,9 +222,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore { */ private void setUpLocales() { Try.of(() -> commandManagerProvider.get()) - .andThen(commandManager -> { - commandManager.usePerIssuerLocale(true, true); - }) + .andThen(commandManager -> commandManager.usePerIssuerLocale(true, true)) .mapTry(commandManager -> pluginLocalesProvider.get()) .andThen(pluginLocales -> { pluginLocales.addFileResClassLoader(this); @@ -282,7 +280,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore { private void loadPlaceholderApiIntegration() { if (configProvider.get().isRegisterPapiHook() && getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) { - Try.run(() -> serviceLocator.createAndInitialize(MultiverseCorePlaceholders.class)) + Try.run(() -> serviceLocator.getService(MultiverseCorePlaceholders.class)) .onFailure(e -> { Logging.severe("Failed to load PlaceholderAPI integration."); e.printStackTrace(); @@ -330,6 +328,22 @@ public class MultiverseCore extends JavaPlugin implements MVCore { return authors.toString(); } + /** + * {@inheritDoc} + */ + @Override + public PluginServiceLocatorFactory getServiceLocatorFactory() { + return serviceLocatorFactory; + } + + /** + * {@inheritDoc} + */ + @Override + public PluginServiceLocator getServiceLocator() { + return serviceLocator; + } + /** * {@inheritDoc} */ @@ -371,46 +385,6 @@ public class MultiverseCore extends JavaPlugin implements MVCore { && anchorManagerProvider.get().saveAnchors(); } - /** - * Gets the best service from this plugin that implements the given contract or has the given implementation. - * - * @param contractOrImpl The contract or concrete implementation to get the best instance of - * @param qualifiers The set of qualifiers that must match this service definition - * @param The type of the contract to get - * @return An instance of the contract or impl if it is a service and is already instantiated, null otherwise - * @throws MultiException if there was an error during service lookup - */ - @Nullable - public T getService(@NotNull Class contractOrImpl, Annotation... qualifiers) throws MultiException { - var handle = serviceLocator.getServiceHandle(contractOrImpl, qualifiers); - if (handle != null && handle.isActive()) { - return handle.getService(); - } - return null; - } - - /** - * Gets all services from this plugin that implement the given contract or have the given implementation and have - * the provided qualifiers. - * - * @param contractOrImpl The contract or concrete implementation to get the best instance of - * @param qualifiers The set of qualifiers that must match this service definition - * @param The type of the contract to get - * @return A list of services implementing this contract or concrete implementation. May not return null, but may - * return an empty list. - * @throws MultiException if there was an error during service lookup - */ - @NotNull - public List getAllServices( - @NotNull Class contractOrImpl, - Annotation... qualifiers) throws MultiException { - var handles = serviceLocator.getAllServiceHandles(contractOrImpl, qualifiers); - return handles.stream() - .filter(ServiceHandle::isActive) - .map(ServiceHandle::getService) - .collect(Collectors.toList()); - } - /** * This is for unit testing ONLY. Do not use this constructor. * diff --git a/src/main/java/org/mvplugins/multiverse/core/api/MVCore.java b/src/main/java/org/mvplugins/multiverse/core/api/MVCore.java index 7c267f80..872463be 100644 --- a/src/main/java/org/mvplugins/multiverse/core/api/MVCore.java +++ b/src/main/java/org/mvplugins/multiverse/core/api/MVCore.java @@ -7,6 +7,9 @@ package org.mvplugins.multiverse.core.api; +import org.mvplugins.multiverse.core.inject.PluginServiceLocator; +import org.mvplugins.multiverse.core.inject.PluginServiceLocatorFactory; + /** * Multiverse 2 Core API *

@@ -14,6 +17,13 @@ package org.mvplugins.multiverse.core.api; */ public interface MVCore extends MVPlugin { + /** + * Gets the {@link PluginServiceLocatorFactory} used to create {@link PluginServiceLocator}s. + * + * @return The {@link PluginServiceLocatorFactory} + */ + PluginServiceLocatorFactory getServiceLocatorFactory(); + /** * Saves all configs. * diff --git a/src/main/java/org/mvplugins/multiverse/core/api/MVPlugin.java b/src/main/java/org/mvplugins/multiverse/core/api/MVPlugin.java index ef65b600..e988ee57 100644 --- a/src/main/java/org/mvplugins/multiverse/core/api/MVPlugin.java +++ b/src/main/java/org/mvplugins/multiverse/core/api/MVPlugin.java @@ -7,6 +7,8 @@ package org.mvplugins.multiverse.core.api; +import org.mvplugins.multiverse.core.inject.PluginServiceLocator; + /** * This interface is implemented by every official Multiverse-plugin. */ @@ -33,4 +35,11 @@ public interface MVPlugin { * @return The readable authors-{@link String} */ String getAuthors(); + + /** + * Gets the {@link PluginServiceLocator} for this plugin. + * + * @return The {@link PluginServiceLocator} + */ + PluginServiceLocator getServiceLocator(); } diff --git a/src/main/java/org/mvplugins/multiverse/core/inject/PluginInjection.java b/src/main/java/org/mvplugins/multiverse/core/inject/PluginInjection.java deleted file mode 100644 index 4a7f3911..00000000 --- a/src/main/java/org/mvplugins/multiverse/core/inject/PluginInjection.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.mvplugins.multiverse.core.inject; - -import io.vavr.control.Try; -import org.bukkit.plugin.Plugin; -import org.glassfish.hk2.api.DynamicConfigurationService; -import org.glassfish.hk2.api.ServiceLocator; -import org.glassfish.hk2.api.ServiceLocatorFactory; -import org.glassfish.hk2.internal.ServiceLocatorFactoryImpl; -import org.glassfish.hk2.utilities.ClasspathDescriptorFileFinder; -import org.glassfish.hk2.utilities.ServiceLocatorUtilities; -import org.jetbrains.annotations.NotNull; - -import org.mvplugins.multiverse.core.inject.binder.JavaPluginBinder; -import org.mvplugins.multiverse.core.inject.binder.PluginBinder; -import org.mvplugins.multiverse.core.inject.binder.ServerBinder; - -/** - * Provides methods to set up dependency injection for plugins. - *
- * This class is a wrapper around the HK2 dependency injection library. It provides methods to create a service locators - * for plugins and to perform injection tasks on plugin instances on enable and disable. - */ -public final class PluginInjection { - - /** - * Creates a {@link ServiceLocator} for the given plugin binder. - *
- * The service locator is populated with the plugin instance and all dependencies that are bound in the - * {@link PluginBinder} of the plugin. Plugins must implement their own {@link PluginBinder} to use this class. - * {@link JavaPluginBinder} is provided as a convenience for plugins that extend - * {@link org.bukkit.plugin.java.JavaPlugin}. - * - * @param pluginBinder The plugin binder for the plugin. - * @return A {@link ServiceLocator} for the plugin. - */ - @NotNull - public static Try createServiceLocator(@NotNull PluginBinder pluginBinder) { - var factory = new ServiceLocatorFactoryImpl(); - - return createSystemServiceLocator(factory) - .flatMap(systemLocator -> createServerServiceLocator(factory, systemLocator)) - .flatMap(serverLocator -> new PluginInjection(pluginBinder, factory, serverLocator).load()); - } - - /** - * Performs necessary steps to enable dependency injection for the given plugin. - *
- * This method will inject all dependencies into the plugin instance and call the {@code @PostConstruct} methods. - * - * @param plugin The plugin to enable dependency injection for. - * @param pluginServiceLocator The service locator for the plugin. - */ - public static void enable(@NotNull Plugin plugin, @NotNull ServiceLocator pluginServiceLocator) { - pluginServiceLocator.inject(plugin); - pluginServiceLocator.postConstruct(plugin); - } - - /** - * Performs necessary steps to disable dependency injection for the given plugin. - *
- * This method will call the {@code @PreDestroy} methods and shutdown the service locator. - * - * @param plugin The plugin to disable dependency injection for. - * @param pluginServiceLocator The service locator for the plugin. - */ - public static void disable(@NotNull Plugin plugin, @NotNull ServiceLocator pluginServiceLocator) { - pluginServiceLocator.preDestroy(plugin); - pluginServiceLocator.shutdown(); - } - - private final PluginBinder pluginBinder; - private final Plugin plugin; - private final ServiceLocator pluginServiceLocator; - - private PluginInjection( - @NotNull PluginBinder pluginBinder, - @NotNull ServiceLocatorFactory serviceLocatorFactory, - @NotNull ServiceLocator serverServiceLocator) { - this.pluginBinder = pluginBinder; - plugin = pluginBinder.getPlugin(); - pluginServiceLocator = serviceLocatorFactory.create(plugin.getName(), serverServiceLocator); - } - - private Try load() { - return Try.runRunnable(() -> ServiceLocatorUtilities.bind(pluginServiceLocator, pluginBinder)) - .flatMap(ignored -> populatePluginServiceLocator(pluginServiceLocator, plugin)); - } - - @NotNull - private static Try createServerServiceLocator( - @NotNull ServiceLocatorFactory serviceLocatorFactory, - @NotNull ServiceLocator systemServiceLocator) { - return Try.of(() -> serviceLocatorFactory.create("server", systemServiceLocator)) - .andThenTry(locator -> ServiceLocatorUtilities.bind(locator, new ServerBinder())); - } - - @NotNull - private static Try createSystemServiceLocator( - @NotNull ServiceLocatorFactory serviceLocatorFactory) { - ServiceLocator serviceLocator = serviceLocatorFactory.create("system"); - - return Try.of(() -> serviceLocator.getService(DynamicConfigurationService.class)) - .mapTry(dynamicConfigurationService -> { - dynamicConfigurationService.getPopulator().populate(); - return serviceLocator; - }); - } - - @NotNull - private static Try populatePluginServiceLocator( - @NotNull ServiceLocator serviceLocator, - @NotNull Plugin plugin) { - return Try.of(() -> serviceLocator.getService(DynamicConfigurationService.class)) - .mapTry(dynamicConfigurationService -> { - dynamicConfigurationService.getPopulator().populate(new ClasspathDescriptorFileFinder( - plugin.getClass().getClassLoader(), - plugin.getName())); - return serviceLocator; - }); - } -} diff --git a/src/main/java/org/mvplugins/multiverse/core/inject/PluginServiceLocator.java b/src/main/java/org/mvplugins/multiverse/core/inject/PluginServiceLocator.java new file mode 100644 index 00000000..d09872fb --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/core/inject/PluginServiceLocator.java @@ -0,0 +1,148 @@ +package org.mvplugins.multiverse.core.inject; + +import io.vavr.control.Try; +import org.bukkit.plugin.Plugin; +import org.glassfish.hk2.api.DynamicConfigurationService; +import org.glassfish.hk2.api.MultiException; +import org.glassfish.hk2.api.ServiceHandle; +import org.glassfish.hk2.api.ServiceLocator; +import org.glassfish.hk2.utilities.ClasspathDescriptorFileFinder; +import org.glassfish.hk2.utilities.ServiceLocatorUtilities; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mvplugins.multiverse.core.inject.binder.PluginBinder; + +import java.lang.annotation.Annotation; +import java.util.List; +import java.util.stream.Collectors; + +public class PluginServiceLocator { + + private final PluginBinder pluginBinder; + private final ServiceLocator serviceLocator; + + PluginServiceLocator(@NotNull PluginBinder pluginBinder, @NotNull ServiceLocator serviceLocator) { + this.pluginBinder = pluginBinder; + this.serviceLocator = serviceLocator; + } + + @NotNull + public Try enable() { + return bindPlugin() + .flatMap(ignore -> populateServices()) + .flatMap(ignore -> injectPlugin()) + .mapTry(ignore -> this); + } + + public void disable() { + serviceLocator.preDestroy(pluginBinder.getPlugin()); + } + + @NotNull + private Try bindPlugin() { + return Try.of(() -> { + ServiceLocatorUtilities.bind(serviceLocator, pluginBinder); + return null; + }); + } + + @NotNull + private Try populateServices() { + Plugin plugin = pluginBinder.getPlugin(); + return Try.of(() -> serviceLocator.getService(DynamicConfigurationService.class)) + .mapTry(dynamicConfigurationService -> { + dynamicConfigurationService.getPopulator().populate(new ClasspathDescriptorFileFinder( + plugin.getClass().getClassLoader(), + plugin.getName()) + ); + return null; + }); + } + + @NotNull + private Try injectPlugin() { + return Try.of(() -> { + serviceLocator.inject(pluginBinder.getPlugin()); + serviceLocator.postConstruct(pluginBinder.getPlugin()); + return null; + }); + } + + /** + * Gets the best service from this plugin that implements the given contract or has the given implementation. + * Service will be instantiated if it is not already instantiated. + * + * @param contractOrImpl The contract or concrete implementation to get the best instance of + * @param qualifiers The set of qualifiers that must match this service definition + * @param The type of the contract to get + * @return An instance of the contract or impl if it is a service, null otherwise + * @throws MultiException + */ + @Nullable + public T getService(@NotNull Class contractOrImpl, Annotation... qualifiers) throws MultiException { + return serviceLocator.getService(contractOrImpl, qualifiers); + } + + /** + * Gets the best active service from this plugin that implements the given contract or has the given implementation. + * + * @param contractOrImpl The contract or concrete implementation to get the best instance of + * @param qualifiers The set of qualifiers that must match this service definition + * @param The type of the contract to get + * @return An instance of the contract or impl if it is a service and is already instantiated, null otherwise + * @throws MultiException if there was an error during service lookup + */ + @Nullable + public T getActiveService(@NotNull Class contractOrImpl, Annotation... qualifiers) throws MultiException { + var handle = serviceLocator.getServiceHandle(contractOrImpl, qualifiers); + if (handle != null && handle.isActive()) { + return handle.getService(); + } + return null; + } + + /** + * Gets all services from this plugin that implement the given contract or have the given implementation and have + * the provided qualifiers. Services will be instantiated if it is not already instantiated. + * + * @param contractOrImpl The contract or concrete implementation to get the best instance of + * @param qualifiers The set of qualifiers that must match this service definition + * @param The type of the contract to get + * @return A list of services implementing this contract or concrete implementation. May not return null, but may + * return an empty list. + * @throws MultiException if there was an error during service lookup + */ + @NotNull + public List getAllServices( + @NotNull Class contractOrImpl, + Annotation... qualifiers) throws MultiException { + return serviceLocator.getAllServices(contractOrImpl, qualifiers); + } + + /** + * Gets all services from this plugin that implement the given contract or have the given implementation and have + * the provided qualifiers. + * + * @param contractOrImpl The contract or concrete implementation to get the best instance of + * @param qualifiers The set of qualifiers that must match this service definition + * @param The type of the contract to get + * @return A list of services already instantiated implementing this contract or concrete implementation. + * May not return null, but may return an empty list. + * @throws MultiException if there was an error during service lookup + */ + @NotNull + public List getAllActiveServices( + @NotNull Class contractOrImpl, + Annotation... qualifiers) throws MultiException { + var handles = serviceLocator.getAllServiceHandles(contractOrImpl, qualifiers); + return handles.stream() + .filter(ServiceHandle::isActive) + .map(ServiceHandle::getService) + .collect(Collectors.toList()); + } + + @NotNull + ServiceLocator getServiceLocator() { + return serviceLocator; + } +} diff --git a/src/main/java/org/mvplugins/multiverse/core/inject/PluginServiceLocatorFactory.java b/src/main/java/org/mvplugins/multiverse/core/inject/PluginServiceLocatorFactory.java new file mode 100644 index 00000000..53405628 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/core/inject/PluginServiceLocatorFactory.java @@ -0,0 +1,75 @@ +package org.mvplugins.multiverse.core.inject; + +import io.vavr.control.Try; +import org.bukkit.plugin.Plugin; +import org.glassfish.hk2.api.DynamicConfigurationService; +import org.glassfish.hk2.api.ServiceLocator; +import org.glassfish.hk2.api.ServiceLocatorFactory; +import org.glassfish.hk2.internal.ServiceLocatorFactoryImpl; +import org.glassfish.hk2.utilities.ServiceLocatorUtilities; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.mvplugins.multiverse.core.inject.binder.PluginBinder; +import org.mvplugins.multiverse.core.inject.binder.ServerBinder; + +public class PluginServiceLocatorFactory { + + private final ServiceLocatorFactory serviceLocatorFactory; + private ServiceLocator baseServiceLocator; + + public PluginServiceLocatorFactory() { + this.serviceLocatorFactory = new ServiceLocatorFactoryImpl(); + } + + @NotNull + public Try init() { + return createSystemServiceLocator() + .flatMap(this::createServerServiceLocator) + .mapTry(locator -> { + baseServiceLocator = locator; + return null; + }); + } + + public void shutdown() { + baseServiceLocator.shutdown(); + } + + @NotNull + private Try createSystemServiceLocator() { + return Try.of(() -> serviceLocatorFactory.create("system")) + .mapTry(systemServiceLocator -> { + systemServiceLocator.getService(DynamicConfigurationService.class) + .getPopulator() + .populate(); + return systemServiceLocator; + }); + } + + @NotNull + private Try createServerServiceLocator(@NotNull ServiceLocator systemServiceLocator) { + return Try.of(() -> serviceLocatorFactory.create("server", systemServiceLocator)) + .mapTry(locator -> { + ServiceLocatorUtilities.bind(locator, new ServerBinder()); + return locator; + }); + } + + public Try registerPlugin(@NotNull PluginBinder pluginBinder) { + return createPluginServiceLocator(pluginBinder, baseServiceLocator); + } + + public Try registerPlugin( + @NotNull PluginBinder pluginBinder, + @NotNull PluginServiceLocator parentServiceLocator) { + return createPluginServiceLocator(pluginBinder, parentServiceLocator.getServiceLocator()); + } + + private Try createPluginServiceLocator( + @NotNull PluginBinder pluginBinder, + @Nullable ServiceLocator parentServiceLocator) { + return Try.of(() -> new PluginServiceLocator( + pluginBinder, + serviceLocatorFactory.create(pluginBinder.getPlugin().getName(), parentServiceLocator))); + } +} diff --git a/src/main/java/org/mvplugins/multiverse/core/world/config/WorldConfigNodes.java b/src/main/java/org/mvplugins/multiverse/core/world/config/WorldConfigNodes.java index 6e0fd5f0..f1336909 100644 --- a/src/main/java/org/mvplugins/multiverse/core/world/config/WorldConfigNodes.java +++ b/src/main/java/org/mvplugins/multiverse/core/world/config/WorldConfigNodes.java @@ -28,7 +28,7 @@ public class WorldConfigNodes { private LoadedMultiverseWorld world = null; WorldConfigNodes(@NotNull MultiverseCore multiverseCore) { - this.enforcementHandler = multiverseCore.getService(EnforcementHandler.class); + this.enforcementHandler = multiverseCore.getServiceLocator().getActiveService(EnforcementHandler.class); } LoadedMultiverseWorld getWorld() { diff --git a/src/test/java/org/mvplugins/multiverse/core/TestWithMockBukkit.kt b/src/test/java/org/mvplugins/multiverse/core/TestWithMockBukkit.kt index ed978c1d..6521180c 100644 --- a/src/test/java/org/mvplugins/multiverse/core/TestWithMockBukkit.kt +++ b/src/test/java/org/mvplugins/multiverse/core/TestWithMockBukkit.kt @@ -2,6 +2,7 @@ package org.mvplugins.multiverse.core import be.seeseemelk.mockbukkit.MockBukkit import be.seeseemelk.mockbukkit.ServerMock +import org.mvplugins.multiverse.core.inject.PluginServiceLocator import org.mvplugins.multiverse.core.utils.TestingMode import kotlin.test.AfterTest import kotlin.test.BeforeTest @@ -13,12 +14,14 @@ abstract class TestWithMockBukkit { protected lateinit var server: ServerMock protected lateinit var multiverseCore: MultiverseCore + protected lateinit var serviceLocator : PluginServiceLocator @BeforeTest fun setUpMockBukkit() { TestingMode.enable() server = MockBukkit.mock() multiverseCore = MockBukkit.load(MultiverseCore::class.java) + serviceLocator = multiverseCore.serviceLocator } @AfterTest diff --git a/src/test/java/org/mvplugins/multiverse/core/commandtools/LocalizationTest.kt b/src/test/java/org/mvplugins/multiverse/core/commandtools/LocalizationTest.kt index a8327b9f..eed48b04 100644 --- a/src/test/java/org/mvplugins/multiverse/core/commandtools/LocalizationTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/commandtools/LocalizationTest.kt @@ -23,8 +23,8 @@ class LocalizationTest : TestWithMockBukkit() { @BeforeTest fun setUpLocale() { - locales = assertNotNull(multiverseCore.getService(PluginLocales::class.java)) - commandManager = assertNotNull(multiverseCore.getService(MVCommandManager::class.java)) + locales = assertNotNull(serviceLocator.getActiveService(PluginLocales::class.java)) + commandManager = assertNotNull(serviceLocator.getActiveService(MVCommandManager::class.java)) } @Nested diff --git a/src/test/java/org/mvplugins/multiverse/core/config/ConfigTest.kt b/src/test/java/org/mvplugins/multiverse/core/config/ConfigTest.kt index becb8953..aaa6e403 100644 --- a/src/test/java/org/mvplugins/multiverse/core/config/ConfigTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/config/ConfigTest.kt @@ -12,7 +12,7 @@ class ConfigTest : TestWithMockBukkit() { @BeforeTest fun setUp() { - config = multiverseCore.getService(MVCoreConfig::class.java).takeIf { it != null } ?: run { + config = serviceLocator.getActiveService(MVCoreConfig::class.java).takeIf { it != null } ?: run { throw IllegalStateException("MVCoreConfig is not available as a service") } val defaultConfig = getResourceAsText("/default_config.yml") diff --git a/src/test/java/org/mvplugins/multiverse/core/inject/InjectionTest.kt b/src/test/java/org/mvplugins/multiverse/core/inject/InjectionTest.kt index 0029b1c4..15c00dce 100644 --- a/src/test/java/org/mvplugins/multiverse/core/inject/InjectionTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/inject/InjectionTest.kt @@ -17,90 +17,91 @@ import org.mvplugins.multiverse.core.teleportation.SimpleLocationManipulation import org.mvplugins.multiverse.core.teleportation.TeleportQueue import org.mvplugins.multiverse.core.utils.metrics.MetricsConfigurator import org.mvplugins.multiverse.core.world.WorldManager +import org.mvplugins.multiverse.core.world.config.WorldsConfigManager import kotlin.test.* class InjectionTest : TestWithMockBukkit() { @Test fun `AnchorManager is available as a service`() { - assertNotNull(multiverseCore.getService(AnchorManager::class.java)) + assertNotNull(serviceLocator.getActiveService(AnchorManager::class.java)) } @Test fun `AsyncSafetyTeleporter is available as a service`() { - assertNotNull(multiverseCore.getService(AsyncSafetyTeleporter::class.java)) + assertNotNull(serviceLocator.getActiveService(AsyncSafetyTeleporter::class.java)) } @Test fun `BlockSafety is available as a service`() { - assertNotNull(multiverseCore.getService(BlockSafety::class.java)) - assertNotNull(multiverseCore.getService(SimpleBlockSafety::class.java)) + assertNotNull(serviceLocator.getActiveService(BlockSafety::class.java)) + assertNotNull(serviceLocator.getActiveService(SimpleBlockSafety::class.java)) } @Test fun `MVCommandManager is available as a service`() { - assertNotNull(multiverseCore.getService(MVCommandManager::class.java)) + assertNotNull(serviceLocator.getActiveService(MVCommandManager::class.java)) } @Test fun `MVEconomist is available as a service`() { - assertNotNull(multiverseCore.getService(MVEconomist::class.java)) + assertNotNull(serviceLocator.getActiveService(MVEconomist::class.java)) } @Test fun `LocationManipulation is available as a service`() { - assertNotNull(multiverseCore.getService(LocationManipulation::class.java)) - assertNotNull(multiverseCore.getService(SimpleLocationManipulation::class.java)) + assertNotNull(serviceLocator.getActiveService(LocationManipulation::class.java)) + assertNotNull(serviceLocator.getActiveService(SimpleLocationManipulation::class.java)) } @Test fun `TeleportQueue is available as a service`() { - assertNotNull(multiverseCore.getService(TeleportQueue::class.java)) + assertNotNull(serviceLocator.getActiveService(TeleportQueue::class.java)) } @Test fun `MVWorldManager is available as a service`() { - assertNotNull(multiverseCore.getService(WorldManager::class.java)) + assertNotNull(serviceLocator.getActiveService(WorldManager::class.java)) } @Test fun `MVEntityListener is available as a service`() { - assertNotNull(multiverseCore.getService(MVEntityListener::class.java)) + assertNotNull(serviceLocator.getActiveService(MVEntityListener::class.java)) } @Test fun `MVPlayerListener is available as a service`() { - assertNotNull(multiverseCore.getService(MVPlayerListener::class.java)) + assertNotNull(serviceLocator.getActiveService(MVPlayerListener::class.java)) } @Test fun `MVChatListener is available as a service`() { - assertNotNull(multiverseCore.getService(MVChatListener::class.java)) + assertNotNull(serviceLocator.getActiveService(MVChatListener::class.java)) } @Test fun `MVPortalListener is available as a service`() { - assertNotNull(multiverseCore.getService(MVPortalListener::class.java)) + assertNotNull(serviceLocator.getActiveService(MVPortalListener::class.java)) } @Test fun `MVWeatherListener is available as a service`() { - assertNotNull(multiverseCore.getService(MVWeatherListener::class.java)) + assertNotNull(serviceLocator.getActiveService(MVWeatherListener::class.java)) } @Test fun `MVWorldListener is available as a service`() { - assertNotNull(multiverseCore.getService(MVWorldListener::class.java)) + assertNotNull(serviceLocator.getActiveService(MVWorldListener::class.java)) } @Test fun `MVCoreConfig is available as a service`() { - assertNotNull(multiverseCore.getService(MVCoreConfig::class.java)) + assertNotNull(serviceLocator.getActiveService(MVCoreConfig::class.java)) } @Test fun `Commands are available as services`() { - val commands = multiverseCore.getAllServices(MultiverseCommand::class.java) + val commands = serviceLocator.getAllActiveServices(MultiverseCommand::class.java) // TODO: come up with a better way to test this like via actually testing the effect of calling each command // TODO: comment this until all commands are done // assertEquals(18, commands.size) @@ -108,7 +109,7 @@ class InjectionTest : TestWithMockBukkit() { @Test fun `Destinations are available as services`() { - val destinations = multiverseCore.getAllServices(Destination::class.java) + val destinations = serviceLocator.getAllActiveServices(Destination::class.java) // TODO: come up with a better way to test this like via actually testing the effect of using each destination assertEquals(6, destinations.size) } @@ -116,11 +117,11 @@ class InjectionTest : TestWithMockBukkit() { @Test fun `MetricsConfigurator is not available as a service`() { // Also making sure this is not loaded automatically since it's supposed to be disabled during tests - assertNull(multiverseCore.getService(MetricsConfigurator::class.java)) + assertNull(serviceLocator.getActiveService(MetricsConfigurator::class.java)) } @Test fun `PluginLocales is available as a service`() { - assertNotNull(multiverseCore.getService(PluginLocales::class.java)) + assertNotNull(serviceLocator.getActiveService(PluginLocales::class.java)) } } diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt index 1648bf23..407b6342 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt @@ -23,7 +23,7 @@ class WorldConfigMangerTest : TestWithMockBukkit() { assertNotNull(defaultConfig) File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds2.yml").absolutePathString()).writeText(defaultConfig) - worldConfigManager = multiverseCore.getService(WorldsConfigManager::class.java).takeIf { it != null } ?: run { + worldConfigManager = serviceLocator.getActiveService(WorldsConfigManager::class.java).takeIf { it != null } ?: run { throw IllegalStateException("WorldsConfigManager is not available as a service") } } diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt index bef9ad6b..86c63575 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt @@ -19,7 +19,7 @@ class WorldConfigTest : TestWithMockBukkit() { assertNotNull(defaultConfig) File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds2.yml").absolutePathString()).writeText(defaultConfig) - worldConfigManager = multiverseCore.getService(WorldsConfigManager::class.java).takeIf { it != null } ?: run { + worldConfigManager = serviceLocator.getActiveService(WorldsConfigManager::class.java).takeIf { it != null } ?: run { throw IllegalStateException("WorldsConfigManager is not available as a service") } assertTrue(worldConfigManager.load().isSuccess) diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt index 52cdb3e2..b735f383 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldManagerTest.kt @@ -13,7 +13,7 @@ class WorldManagerTest : TestWithMockBukkit() { @BeforeTest fun setUp() { - worldManager = multiverseCore.getService(WorldManager::class.java).takeIf { it != null } ?: run { + worldManager = serviceLocator.getActiveService(WorldManager::class.java).takeIf { it != null } ?: run { throw IllegalStateException("WorldManager is not available as a service") } worldManager.createWorld(CreateWorldOptions.worldName("world"))