Merge branch '835-integrate-jalu-injector' of https://github.com/AuthMe-Team/AuthMeReloaded
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import ch.jalu.injector.Injector;
|
||||
import ch.jalu.injector.InjectorBuilder;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.api.API;
|
||||
import fr.xephi.authme.api.NewAPI;
|
||||
@@ -16,7 +18,6 @@ import fr.xephi.authme.datasource.MySQL;
|
||||
import fr.xephi.authme.datasource.SQLite;
|
||||
import fr.xephi.authme.hooks.BungeeCordMessage;
|
||||
import fr.xephi.authme.hooks.PluginHooks;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.initialization.MetricsStarter;
|
||||
import fr.xephi.authme.listener.AuthMeBlockListener;
|
||||
@@ -110,7 +111,7 @@ public class AuthMe extends JavaPlugin {
|
||||
private PluginHooks pluginHooks;
|
||||
private SpawnLoader spawnLoader;
|
||||
private BukkitService bukkitService;
|
||||
private AuthMeServiceInitializer initializer;
|
||||
private Injector injector;
|
||||
private GeoLiteAPI geoLiteApi;
|
||||
|
||||
/**
|
||||
@@ -224,20 +225,20 @@ public class AuthMe extends JavaPlugin {
|
||||
MigrationService.changePlainTextToSha256(newSettings, database, new SHA256());
|
||||
|
||||
// Injector initialization
|
||||
initializer = new AuthMeServiceInitializer("fr.xephi.authme");
|
||||
injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create();
|
||||
|
||||
// Register elements of the Bukkit / JavaPlugin environment
|
||||
initializer.register(AuthMe.class, this);
|
||||
initializer.register(Server.class, getServer());
|
||||
initializer.register(PluginManager.class, getServer().getPluginManager());
|
||||
initializer.register(BukkitScheduler.class, getServer().getScheduler());
|
||||
initializer.provide(DataFolder.class, getDataFolder());
|
||||
injector.register(AuthMe.class, this);
|
||||
injector.register(Server.class, getServer());
|
||||
injector.register(PluginManager.class, getServer().getPluginManager());
|
||||
injector.register(BukkitScheduler.class, getServer().getScheduler());
|
||||
injector.provide(DataFolder.class, getDataFolder());
|
||||
|
||||
// Register elements we instantiate manually
|
||||
initializer.register(NewSetting.class, newSettings);
|
||||
initializer.register(DataSource.class, database);
|
||||
injector.register(NewSetting.class, newSettings);
|
||||
injector.register(DataSource.class, database);
|
||||
|
||||
instantiateServices(initializer);
|
||||
instantiateServices(injector);
|
||||
|
||||
// Set up Metrics
|
||||
MetricsStarter.setupMetrics(this, newSettings);
|
||||
@@ -256,7 +257,7 @@ public class AuthMe extends JavaPlugin {
|
||||
reloadSupportHook();
|
||||
|
||||
// Register event listeners
|
||||
registerEventListeners(initializer);
|
||||
registerEventListeners(injector);
|
||||
// Start Email recall task if needed
|
||||
scheduleRecallEmailTask();
|
||||
|
||||
@@ -276,25 +277,25 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
// Purge on start if enabled
|
||||
PurgeService purgeService = initializer.get(PurgeService.class);
|
||||
PurgeService purgeService = injector.getSingleton(PurgeService.class);
|
||||
purgeService.runAutoPurge();
|
||||
}
|
||||
|
||||
protected void instantiateServices(AuthMeServiceInitializer initializer) {
|
||||
protected void instantiateServices(Injector injector) {
|
||||
// Some statically injected things
|
||||
initializer.register(PlayerCache.class, PlayerCache.getInstance());
|
||||
injector.register(PlayerCache.class, PlayerCache.getInstance());
|
||||
|
||||
messages = initializer.get(Messages.class);
|
||||
permsMan = initializer.get(PermissionsManager.class);
|
||||
bukkitService = initializer.get(BukkitService.class);
|
||||
pluginHooks = initializer.get(PluginHooks.class);
|
||||
passwordSecurity = initializer.get(PasswordSecurity.class);
|
||||
spawnLoader = initializer.get(SpawnLoader.class);
|
||||
commandHandler = initializer.get(CommandHandler.class);
|
||||
management = initializer.get(Management.class);
|
||||
geoLiteApi = initializer.get(GeoLiteAPI.class);
|
||||
initializer.get(NewAPI.class);
|
||||
initializer.get(API.class);
|
||||
messages = injector.getSingleton(Messages.class);
|
||||
permsMan = injector.getSingleton(PermissionsManager.class);
|
||||
bukkitService = injector.getSingleton(BukkitService.class);
|
||||
pluginHooks = injector.getSingleton(PluginHooks.class);
|
||||
passwordSecurity = injector.getSingleton(PasswordSecurity.class);
|
||||
spawnLoader = injector.getSingleton(SpawnLoader.class);
|
||||
commandHandler = injector.getSingleton(CommandHandler.class);
|
||||
management = injector.getSingleton(Management.class);
|
||||
geoLiteApi = injector.getSingleton(GeoLiteAPI.class);
|
||||
injector.getSingleton(NewAPI.class);
|
||||
injector.getSingleton(API.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -316,27 +317,27 @@ public class AuthMe extends JavaPlugin {
|
||||
/**
|
||||
* Register all event listeners.
|
||||
*/
|
||||
protected void registerEventListeners(AuthMeServiceInitializer initializer) {
|
||||
protected void registerEventListeners(Injector injector) {
|
||||
// Get the plugin manager instance
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
|
||||
// Register event listeners
|
||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener.class), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMeBlockListener.class), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMeEntityListener.class), this);
|
||||
pluginManager.registerEvents(initializer.get(AuthMeServerListener.class), this);
|
||||
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener.class), this);
|
||||
pluginManager.registerEvents(injector.getSingleton(AuthMeBlockListener.class), this);
|
||||
pluginManager.registerEvents(injector.getSingleton(AuthMeEntityListener.class), this);
|
||||
pluginManager.registerEvents(injector.getSingleton(AuthMeServerListener.class), this);
|
||||
|
||||
// Try to register 1.6 player listeners
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerEditBookEvent");
|
||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener16.class), this);
|
||||
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener16.class), this);
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
// Try to register 1.8 player listeners
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerInteractAtEntityEvent");
|
||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener18.class), this);
|
||||
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener18.class), this);
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
@@ -365,8 +366,8 @@ public class AuthMe extends JavaPlugin {
|
||||
private void setupBungeeCordHook() {
|
||||
if (newSettings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
Messenger messenger = Bukkit.getMessenger();
|
||||
messenger.registerOutgoingPluginChannel(plugin, "BungeeCord");
|
||||
messenger.registerIncomingPluginChannel(plugin, "BungeeCord", initializer.get(BungeeCordMessage.class));
|
||||
messenger.registerOutgoingPluginChannel(this, "BungeeCord");
|
||||
messenger.registerIncomingPluginChannel(this, "BungeeCord", injector.getSingleton(BungeeCordMessage.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,9 +421,9 @@ public class AuthMe extends JavaPlugin {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Save player data
|
||||
BukkitService bukkitService = initializer.getIfAvailable(BukkitService.class);
|
||||
LimboCache limboCache = initializer.getIfAvailable(LimboCache.class);
|
||||
AuthGroupHandler authGroupHandler = initializer.getIfAvailable(AuthGroupHandler.class);
|
||||
BukkitService bukkitService = injector.getIfAvailable(BukkitService.class);
|
||||
LimboCache limboCache = injector.getIfAvailable(LimboCache.class);
|
||||
AuthGroupHandler authGroupHandler = injector.getIfAvailable(AuthGroupHandler.class);
|
||||
|
||||
if (bukkitService != null && limboCache != null) {
|
||||
Collection<? extends Player> players = bukkitService.getOnlinePlayers();
|
||||
@@ -579,7 +580,7 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
if (newSettings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)
|
||||
&& !newSettings.getProperty(RestrictionSettings.NO_TELEPORT)) {
|
||||
PlayerDataStorage playerDataStorage = initializer.getIfAvailable(PlayerDataStorage.class);
|
||||
PlayerDataStorage playerDataStorage = injector.getIfAvailable(PlayerDataStorage.class);
|
||||
if (playerDataStorage != null && !playerDataStorage.hasData(player)) {
|
||||
playerDataStorage.saveData(player);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import ch.jalu.injector.Injector;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.command.help.HelpProvider;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
@@ -37,12 +37,12 @@ public class CommandHandler {
|
||||
private Map<Class<? extends ExecutableCommand>, ExecutableCommand> commands = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public CommandHandler(AuthMeServiceInitializer initializer, CommandMapper commandMapper,
|
||||
public CommandHandler(Injector injector, CommandMapper commandMapper,
|
||||
PermissionsManager permissionsManager, HelpProvider helpProvider) {
|
||||
this.commandMapper = commandMapper;
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.helpProvider = helpProvider;
|
||||
initializeCommands(initializer, commandMapper.getCommandClasses());
|
||||
initializeCommands(injector, commandMapper.getCommandClasses());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,12 +90,13 @@ public class CommandHandler {
|
||||
/**
|
||||
* Initialize all required ExecutableCommand objects.
|
||||
*
|
||||
* @param injector the injector
|
||||
* @param commandClasses the classes to instantiate
|
||||
*/
|
||||
private void initializeCommands(AuthMeServiceInitializer initializer,
|
||||
private void initializeCommands(Injector injector,
|
||||
Set<Class<? extends ExecutableCommand>> commandClasses) {
|
||||
for (Class<? extends ExecutableCommand> clazz : commandClasses) {
|
||||
commands.put(clazz, initializer.newInstance(clazz));
|
||||
commands.put(clazz, injector.newInstance(clazz));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import ch.jalu.injector.Injector;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
@@ -11,7 +12,6 @@ import fr.xephi.authme.converter.RoyalAuthConverter;
|
||||
import fr.xephi.authme.converter.SqliteToSql;
|
||||
import fr.xephi.authme.converter.vAuthConverter;
|
||||
import fr.xephi.authme.converter.xAuthConverter;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -31,7 +31,7 @@ public class ConverterCommand implements ExecutableCommand {
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Inject
|
||||
private AuthMeServiceInitializer initializer;
|
||||
private Injector injector;
|
||||
|
||||
@Override
|
||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||
@@ -46,7 +46,7 @@ public class ConverterCommand implements ExecutableCommand {
|
||||
}
|
||||
|
||||
// Get the proper converter instance
|
||||
final Converter converter = initializer.newInstance(jobType.getConverterClass());
|
||||
final Converter converter = injector.newInstance(jobType.getConverterClass());
|
||||
|
||||
// Run the convert job
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import ch.jalu.injector.Injector;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.initialization.Reloadable;
|
||||
import fr.xephi.authme.initialization.SettingsDependent;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -23,7 +26,7 @@ public class ReloadCommand implements ExecutableCommand {
|
||||
private AuthMe plugin;
|
||||
|
||||
@Inject
|
||||
private AuthMeServiceInitializer initializer;
|
||||
private Injector injector;
|
||||
|
||||
@Inject
|
||||
private NewSetting settings;
|
||||
@@ -44,7 +47,7 @@ public class ReloadCommand implements ExecutableCommand {
|
||||
ConsoleLogger.info("Note: cannot change database type during /authme reload");
|
||||
sender.sendMessage("Note: cannot change database type during /authme reload");
|
||||
}
|
||||
initializer.performReloadOnServices();
|
||||
performReloadOnServices();
|
||||
commandService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage("Error occurred during reload of AuthMe: aborting");
|
||||
@@ -52,4 +55,16 @@ public class ReloadCommand implements ExecutableCommand {
|
||||
plugin.stopOrUnload();
|
||||
}
|
||||
}
|
||||
|
||||
private void performReloadOnServices() {
|
||||
Collection<Reloadable> reloadables = injector.retrieveAllOfType(Reloadable.class);
|
||||
for (Reloadable reloadable : reloadables) {
|
||||
reloadable.reload();
|
||||
}
|
||||
|
||||
Collection<SettingsDependent> settingsDependents = injector.retrieveAllOfType(SettingsDependent.class);
|
||||
for (SettingsDependent dependent : settingsDependents) {
|
||||
dependent.reload(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.hooks;
|
||||
|
||||
import ch.jalu.injector.annotations.NoFieldScan;
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
@@ -17,6 +18,7 @@ import java.io.File;
|
||||
/**
|
||||
* Hooks into third-party plugins and allows to perform actions on them.
|
||||
*/
|
||||
@NoFieldScan
|
||||
public class PluginHooks {
|
||||
|
||||
private final PluginManager pluginManager;
|
||||
|
||||
@@ -1,288 +0,0 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Dependency injector of AuthMe: initializes and injects services and tasks.
|
||||
* <p>
|
||||
* Only constructor and field injection are supported, indicated with the JSR330
|
||||
* {@link javax.inject.Inject @Inject} annotation.
|
||||
* <p>
|
||||
* {@link PostConstruct @PostConstruct} methods are recognized and invoked upon
|
||||
* instantiation. Note that the parent classes are <i>not</i> scanned for such methods.
|
||||
*/
|
||||
public class AuthMeServiceInitializer {
|
||||
|
||||
private final Set<String> ALLOWED_PACKAGES;
|
||||
private final Map<Class<?>, Object> objects;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param allowedPackages list of allowed packages. Only classes whose package
|
||||
* starts with any of the given entries will be instantiated
|
||||
*/
|
||||
public AuthMeServiceInitializer(String... allowedPackages) {
|
||||
ALLOWED_PACKAGES = ImmutableSet.copyOf(allowedPackages);
|
||||
objects = new HashMap<>();
|
||||
objects.put(getClass(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves or instantiates an object of the given type.
|
||||
*
|
||||
* @param clazz the class to retrieve the value for
|
||||
* @param <T> the class' type
|
||||
* @return object of the class' type
|
||||
*/
|
||||
public <T> T get(Class<T> clazz) {
|
||||
return get(clazz, new HashSet<Class<?>>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an object with a custom class (supertype). Use this for example to specify a
|
||||
* concrete implementation of an interface or an abstract class.
|
||||
*
|
||||
* @param clazz the class to register the object for
|
||||
* @param object the object
|
||||
* @param <T> the class' type
|
||||
*/
|
||||
public <T> void register(Class<? super T> clazz, T object) {
|
||||
if (objects.containsKey(clazz)) {
|
||||
throw new IllegalStateException("There is already an object present for " + clazz);
|
||||
}
|
||||
Preconditions.checkNotNull(object);
|
||||
objects.put(clazz, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate an annotation with a value.
|
||||
*
|
||||
* @param annotation the annotation
|
||||
* @param value the value
|
||||
*/
|
||||
public void provide(Class<? extends Annotation> annotation, Object value) {
|
||||
if (objects.containsKey(annotation)) {
|
||||
throw new IllegalStateException("Annotation @" + annotation.getClass().getSimpleName()
|
||||
+ " already registered");
|
||||
}
|
||||
Preconditions.checkNotNull(value);
|
||||
objects.put(annotation, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the given class and does <i>not</i> keep track of it afterwards,
|
||||
* unlike {@link #get(Class)} (singleton scope).
|
||||
*
|
||||
* @param clazz the class to instantiate
|
||||
* @param <T> the class' type
|
||||
* @return new instance of class T
|
||||
*/
|
||||
public <T> T newInstance(Class<T> clazz) {
|
||||
return instantiate(clazz, new HashSet<Class<?>>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the given class if available. This simply returns the instance if present and
|
||||
* otherwise {@code null}. Calling this method will not instantiate anything.
|
||||
*
|
||||
* @param clazz the class to retrieve the instance for
|
||||
* @param <T> the class' type
|
||||
* @return instance or null if none available
|
||||
*/
|
||||
public <T> T getIfAvailable(Class<T> clazz) {
|
||||
if (Annotation.class.isAssignableFrom(clazz)) {
|
||||
throw new UnsupportedOperationException("Annotations may not be retrieved in this way!");
|
||||
}
|
||||
return clazz.cast(objects.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the given class by retrieving it or by instantiating it if not yet present.
|
||||
*
|
||||
* @param clazz the class to retrieve a value for
|
||||
* @param traversedClasses the list of traversed classes
|
||||
* @param <T> the class' type
|
||||
* @return instance or associated value (for annotations)
|
||||
*/
|
||||
private <T> T get(Class<T> clazz, Set<Class<?>> traversedClasses) {
|
||||
if (Annotation.class.isAssignableFrom(clazz)) {
|
||||
throw new UnsupportedOperationException("Cannot retrieve annotated elements in this way!");
|
||||
} else if (objects.containsKey(clazz)) {
|
||||
return clazz.cast(objects.get(clazz));
|
||||
}
|
||||
|
||||
// First time we come across clazz, need to instantiate it. Validate that we can do so
|
||||
validatePackage(clazz);
|
||||
validateInstantiable(clazz);
|
||||
|
||||
// Add the clazz to the list of traversed classes in a new Set, so each path we take has its own Set.
|
||||
traversedClasses = new HashSet<>(traversedClasses);
|
||||
traversedClasses.add(clazz);
|
||||
T object = instantiate(clazz, traversedClasses);
|
||||
storeObject(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a reload on all applicable instances which are registered.
|
||||
* Requires that the {@link NewSetting settings} instance be registered.
|
||||
* <p>
|
||||
* Note that the order in which these classes are reloaded is not guaranteed.
|
||||
*/
|
||||
public void performReloadOnServices() {
|
||||
NewSetting settings = (NewSetting) objects.get(NewSetting.class);
|
||||
if (settings == null) {
|
||||
throw new IllegalStateException("Settings instance is null");
|
||||
}
|
||||
for (Object object : objects.values()) {
|
||||
if (object instanceof SettingsDependent) {
|
||||
((SettingsDependent) object).reload(settings);
|
||||
}
|
||||
|
||||
if (object instanceof Reloadable) {
|
||||
((Reloadable) object).reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates the given class by locating its @Inject elements and retrieving
|
||||
* or instantiating the required instances.
|
||||
*
|
||||
* @param clazz the class to instantiate
|
||||
* @param traversedClasses collection of classes already traversed
|
||||
* @param <T> the class' type
|
||||
* @return the instantiated object
|
||||
*/
|
||||
private <T> T instantiate(Class<T> clazz, Set<Class<?>> traversedClasses) {
|
||||
Injection<T> injection = InjectionHelper.getInjection(clazz);
|
||||
if (injection == null) {
|
||||
throw new IllegalStateException("Did not find injection method for " + clazz + ". Make sure you have "
|
||||
+ "a constructor with @Inject or fields with @Inject. Fields with @Inject require "
|
||||
+ "the default constructor");
|
||||
}
|
||||
|
||||
validateInjectionHasNoCircularDependencies(injection.getDependencies(), traversedClasses);
|
||||
Object[] dependencies = resolveDependencies(injection, traversedClasses);
|
||||
T object = injection.instantiateWith(dependencies);
|
||||
executePostConstructMethod(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the dependencies for the given class instantiation, i.e. returns a collection that satisfy
|
||||
* the class' dependencies by retrieving elements or instantiating them where necessary.
|
||||
*
|
||||
* @param injection the injection parameters
|
||||
* @param traversedClasses collection of traversed classes
|
||||
* @return array with the parameters to use in the constructor
|
||||
*/
|
||||
private Object[] resolveDependencies(Injection<?> injection, Set<Class<?>> traversedClasses) {
|
||||
Class<?>[] dependencies = injection.getDependencies();
|
||||
Class<?>[] annotations = injection.getDependencyAnnotations();
|
||||
Object[] values = new Object[dependencies.length];
|
||||
for (int i = 0; i < dependencies.length; ++i) {
|
||||
if (annotations[i] == null) {
|
||||
values[i] = get(dependencies[i], traversedClasses);
|
||||
} else {
|
||||
Object value = objects.get(annotations[i]);
|
||||
if (value == null) {
|
||||
throw new IllegalStateException("Value for field with @" + annotations[i].getSimpleName()
|
||||
+ " must be registered beforehand");
|
||||
}
|
||||
values[i] = value;
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given object with its class as key. Throws an exception if the key already has
|
||||
* a value associated to it.
|
||||
*
|
||||
* @param object the object to store
|
||||
*/
|
||||
private void storeObject(Object object) {
|
||||
if (objects.containsKey(object.getClass())) {
|
||||
throw new IllegalStateException("There is already an object present for " + object.getClass());
|
||||
}
|
||||
Preconditions.checkNotNull(object);
|
||||
objects.put(object.getClass(), object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that none of the dependencies' types are present in the given collection
|
||||
* of traversed classes. This prevents circular dependencies.
|
||||
*
|
||||
* @param dependencies the dependencies of the class
|
||||
* @param traversedClasses the collection of traversed classes
|
||||
*/
|
||||
private static void validateInjectionHasNoCircularDependencies(Class<?>[] dependencies,
|
||||
Set<Class<?>> traversedClasses) {
|
||||
for (Class<?> clazz : dependencies) {
|
||||
if (traversedClasses.contains(clazz)) {
|
||||
throw new IllegalStateException("Found cyclic dependency - already traversed '" + clazz
|
||||
+ "' (full traversal list: " + traversedClasses + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the package of a parameter type to ensure that it is part of the allowed packages.
|
||||
* This ensures that we don't try to instantiate things that are beyond our reach in case some
|
||||
* external parameter type has not been registered.
|
||||
*
|
||||
* @param clazz the class to validate
|
||||
*/
|
||||
private void validatePackage(Class<?> clazz) {
|
||||
if (clazz.getPackage() == null) {
|
||||
throw new IllegalStateException("Primitive types must be provided explicitly (or use an annotation).");
|
||||
}
|
||||
String packageName = clazz.getPackage().getName();
|
||||
for (String allowedPackage : ALLOWED_PACKAGES) {
|
||||
if (packageName.startsWith(allowedPackage)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Class " + clazz + " with package " + packageName + " is outside of the "
|
||||
+ "allowed packages. It must be provided explicitly or the package must be passed to the constructor.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an object's method annotated with {@link PostConstruct} if present.
|
||||
* Throws an exception if there are multiple such methods, or if the method is static.
|
||||
*
|
||||
* @param object the object to execute the post construct method for
|
||||
*/
|
||||
private static void executePostConstructMethod(Object object) {
|
||||
Method postConstructMethod = InjectionHelper.getAndValidatePostConstructMethod(object.getClass());
|
||||
if (postConstructMethod != null) {
|
||||
try {
|
||||
postConstructMethod.setAccessible(true);
|
||||
postConstructMethod.invoke(object);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new UnsupportedOperationException("Error executing @PostConstruct method", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateInstantiable(Class<?> clazz) {
|
||||
if (clazz.isEnum() || clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
|
||||
throw new IllegalStateException("Class " + clazz.getSimpleName() + " cannot be instantiated");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.listener.protocollib;
|
||||
|
||||
import ch.jalu.injector.annotations.NoFieldScan;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
@@ -11,6 +12,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@NoFieldScan
|
||||
public class ProtocolLibService implements SettingsDependent {
|
||||
|
||||
/* Packet Adapters */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package fr.xephi.authme.security;
|
||||
|
||||
import ch.jalu.injector.Injector;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.events.PasswordEncryptionEvent;
|
||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
||||
import fr.xephi.authme.initialization.Reloadable;
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
@@ -28,7 +28,7 @@ public class PasswordSecurity implements Reloadable {
|
||||
private PluginManager pluginManager;
|
||||
|
||||
@Inject
|
||||
private AuthMeServiceInitializer initializer;
|
||||
private Injector injector;
|
||||
|
||||
private HashAlgorithm algorithm;
|
||||
private boolean supportOldAlgorithm;
|
||||
@@ -155,7 +155,7 @@ public class PasswordSecurity implements Reloadable {
|
||||
if (HashAlgorithm.CUSTOM.equals(algorithm) || HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
||||
return null;
|
||||
}
|
||||
return initializer.newInstance(algorithm.getClazz());
|
||||
return injector.newInstance(algorithm.getClazz());
|
||||
}
|
||||
|
||||
private void hashPasswordForNewAlgorithm(String password, String playerName) {
|
||||
|
||||
Reference in New Issue
Block a user