mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2024-11-15 15:15:38 +01:00
Add PluginService and InjectionFeature loading.
This commit is contained in:
parent
b40ded9806
commit
9f650d683d
@ -0,0 +1,33 @@
|
||||
package com.onarandombox.MultiverseCore.inject;
|
||||
|
||||
import org.glassfish.hk2.api.ServiceLocator;
|
||||
import org.jvnet.hk2.annotations.Contract;
|
||||
|
||||
/**
|
||||
* Marker interface for injection features.
|
||||
* <br/>
|
||||
* Injection features are used to extend the functionality of the {@link PluginInjection} class. They are only used
|
||||
* internally and should not be implemented by plugins.
|
||||
*/
|
||||
@Contract
|
||||
public interface InjectionFeature {
|
||||
|
||||
/**
|
||||
* Called prior to the eager loading of {@link PluginService}s.
|
||||
* <br/>
|
||||
* It's possible that performing injection in feature related services will cause {@link PluginService} instances to
|
||||
* be created.
|
||||
*
|
||||
* @param pluginServiceLocator The service locator for the plugin.
|
||||
*/
|
||||
default void preServicesCreation(ServiceLocator pluginServiceLocator) {}
|
||||
|
||||
/**
|
||||
* Called after the eager loading of {@link PluginService}s.
|
||||
* <br/>
|
||||
* All {@link PluginService} instances should be created by this point.
|
||||
*
|
||||
* @param pluginServiceLocator The service locator for the plugin.
|
||||
*/
|
||||
default void postServicesCreation(ServiceLocator pluginServiceLocator) {}
|
||||
}
|
@ -3,10 +3,10 @@ package com.onarandombox.MultiverseCore.inject;
|
||||
import com.onarandombox.MultiverseCore.inject.binder.JavaPluginBinder;
|
||||
import com.onarandombox.MultiverseCore.inject.binder.PluginBinder;
|
||||
import com.onarandombox.MultiverseCore.inject.binder.ServerBinder;
|
||||
import io.vavr.control.Option;
|
||||
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.ServiceLocator;
|
||||
import org.glassfish.hk2.api.ServiceLocatorFactory;
|
||||
import org.glassfish.hk2.internal.ServiceLocatorFactoryImpl;
|
||||
@ -14,6 +14,8 @@ import org.glassfish.hk2.utilities.ClasspathDescriptorFileFinder;
|
||||
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides methods to set up dependency injection for plugins.
|
||||
* <br/>
|
||||
@ -36,9 +38,16 @@ public final class PluginInjection {
|
||||
@NotNull
|
||||
public static Try<ServiceLocator> createServiceLocator(@NotNull PluginBinder<?> pluginBinder) {
|
||||
var factory = new ServiceLocatorFactoryImpl();
|
||||
return createServerServiceLocator(factory)
|
||||
.map(locator -> new PluginInjection(factory, locator))
|
||||
.flatMap(pluginInjection -> pluginInjection.load(pluginBinder));
|
||||
|
||||
var systemServiceLocator = createSystemServiceLocator(factory);
|
||||
|
||||
var features = systemServiceLocator
|
||||
.mapTry(locator -> locator.getAllServices(InjectionFeature.class));
|
||||
|
||||
return systemServiceLocator
|
||||
.flatMap(systemLocator -> createServerServiceLocator(factory, systemLocator))
|
||||
.map(serverLocator -> new PluginInjection(pluginBinder, factory, serverLocator))
|
||||
.flatMap(pluginInjection -> features.flatMap(pluginInjection::load));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,34 +76,39 @@ public final class PluginInjection {
|
||||
pluginServiceLocator.shutdown();
|
||||
}
|
||||
|
||||
private final ServiceLocatorFactory serviceLocatorFactory;
|
||||
private final ServiceLocator serverServiceLocator;
|
||||
private final PluginBinder<?> pluginBinder;
|
||||
private final Plugin plugin;
|
||||
private final ServiceLocator pluginServiceLocator;
|
||||
|
||||
private PluginInjection(
|
||||
@NotNull PluginBinder<?> pluginBinder,
|
||||
@NotNull ServiceLocatorFactory serviceLocatorFactory,
|
||||
@NotNull ServiceLocator serverServiceLocator
|
||||
) {
|
||||
this.serviceLocatorFactory = serviceLocatorFactory;
|
||||
this.serverServiceLocator = serverServiceLocator;
|
||||
this.pluginBinder = pluginBinder;
|
||||
plugin = pluginBinder.getPlugin();
|
||||
pluginServiceLocator = serviceLocatorFactory.create(plugin.getName(), serverServiceLocator);
|
||||
}
|
||||
|
||||
private Try<ServiceLocator> load(@NotNull PluginBinder<?> pluginBinder) {
|
||||
var plugin = pluginBinder.getPlugin();
|
||||
private Try<ServiceLocator> load(List<InjectionFeature> features) {
|
||||
return Try.runRunnable(() -> ServiceLocatorUtilities.bind(pluginServiceLocator, pluginBinder))
|
||||
.flatMap(ignored -> populatePluginServiceLocator(pluginServiceLocator, plugin))
|
||||
.andThenTry(() -> loadAncillaryServices(features));
|
||||
}
|
||||
|
||||
return Option.of(serviceLocatorFactory.create(plugin.getName(), serverServiceLocator))
|
||||
.toTry()
|
||||
.andThenTry(pluginServiceLocator -> ServiceLocatorUtilities.bind(pluginServiceLocator, pluginBinder))
|
||||
.flatMap(pluginServiceLocator -> populatePluginServiceLocator(pluginServiceLocator, plugin));
|
||||
private void loadAncillaryServices(List<InjectionFeature> features) throws MultiException {
|
||||
features.forEach(feature -> feature.preServicesCreation(pluginServiceLocator));
|
||||
pluginServiceLocator.getAllServices(PluginService.class);
|
||||
features.forEach(feature -> feature.postServicesCreation(pluginServiceLocator));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Try<ServiceLocator> createServerServiceLocator(
|
||||
@NotNull ServiceLocatorFactory serviceLocatorFactory
|
||||
@NotNull ServiceLocatorFactory serviceLocatorFactory,
|
||||
@NotNull ServiceLocator systemServiceLocator
|
||||
) {
|
||||
return createSystemServiceLocator(serviceLocatorFactory)
|
||||
.map(systemServiceLocator -> serviceLocatorFactory.create("server", systemServiceLocator))
|
||||
.andThenTry(serverServiceLocator ->
|
||||
ServiceLocatorUtilities.bind(serverServiceLocator, new ServerBinder()));
|
||||
return Try.of(() -> serviceLocatorFactory.create("server", systemServiceLocator))
|
||||
.andThenTry(locator -> ServiceLocatorUtilities.bind(locator, new ServerBinder()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -0,0 +1,11 @@
|
||||
package com.onarandombox.MultiverseCore.inject;
|
||||
|
||||
import org.jvnet.hk2.annotations.Contract;
|
||||
|
||||
/**
|
||||
* Marker interface for plugin services.
|
||||
* <br/>
|
||||
* Implementations of this interface will be eagerly loaded when injection is initialized for the owning plugin.
|
||||
*/
|
||||
@Contract
|
||||
public interface PluginService { }
|
Loading…
Reference in New Issue
Block a user