mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-12-25 10:07:35 +01:00
Merge branch 'master' of https://github.com/AuthMe-Team/AuthMeReloaded into 784-purgeservice-architecture
Conflicts: src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java
This commit is contained in:
commit
cf1032d936
7
pom.xml
7
pom.xml
@ -792,6 +792,13 @@
|
|||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Injector -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.jalu</groupId>
|
||||||
|
<artifactId>injector</artifactId>
|
||||||
|
<version>0.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- String comparison library. Used for dynamic help system. -->
|
<!-- String comparison library. Used for dynamic help system. -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.ricecode</groupId>
|
<groupId>net.ricecode</groupId>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package fr.xephi.authme;
|
package fr.xephi.authme;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
|
import ch.jalu.injector.InjectorBuilder;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import fr.xephi.authme.api.API;
|
import fr.xephi.authme.api.API;
|
||||||
import fr.xephi.authme.api.NewAPI;
|
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.datasource.SQLite;
|
||||||
import fr.xephi.authme.hooks.BungeeCordMessage;
|
import fr.xephi.authme.hooks.BungeeCordMessage;
|
||||||
import fr.xephi.authme.hooks.PluginHooks;
|
import fr.xephi.authme.hooks.PluginHooks;
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
|
||||||
import fr.xephi.authme.initialization.DataFolder;
|
import fr.xephi.authme.initialization.DataFolder;
|
||||||
import fr.xephi.authme.initialization.MetricsStarter;
|
import fr.xephi.authme.initialization.MetricsStarter;
|
||||||
import fr.xephi.authme.listener.AuthMeBlockListener;
|
import fr.xephi.authme.listener.AuthMeBlockListener;
|
||||||
@ -110,7 +111,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
private PluginHooks pluginHooks;
|
private PluginHooks pluginHooks;
|
||||||
private SpawnLoader spawnLoader;
|
private SpawnLoader spawnLoader;
|
||||||
private BukkitService bukkitService;
|
private BukkitService bukkitService;
|
||||||
private AuthMeServiceInitializer initializer;
|
private Injector injector;
|
||||||
private GeoLiteAPI geoLiteApi;
|
private GeoLiteAPI geoLiteApi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,20 +225,20 @@ public class AuthMe extends JavaPlugin {
|
|||||||
MigrationService.changePlainTextToSha256(newSettings, database, new SHA256());
|
MigrationService.changePlainTextToSha256(newSettings, database, new SHA256());
|
||||||
|
|
||||||
// Injector initialization
|
// Injector initialization
|
||||||
initializer = new AuthMeServiceInitializer("fr.xephi.authme");
|
injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create();
|
||||||
|
|
||||||
// Register elements of the Bukkit / JavaPlugin environment
|
// Register elements of the Bukkit / JavaPlugin environment
|
||||||
initializer.register(AuthMe.class, this);
|
injector.register(AuthMe.class, this);
|
||||||
initializer.register(Server.class, getServer());
|
injector.register(Server.class, getServer());
|
||||||
initializer.register(PluginManager.class, getServer().getPluginManager());
|
injector.register(PluginManager.class, getServer().getPluginManager());
|
||||||
initializer.register(BukkitScheduler.class, getServer().getScheduler());
|
injector.register(BukkitScheduler.class, getServer().getScheduler());
|
||||||
initializer.provide(DataFolder.class, getDataFolder());
|
injector.provide(DataFolder.class, getDataFolder());
|
||||||
|
|
||||||
// Register elements we instantiate manually
|
// Register elements we instantiate manually
|
||||||
initializer.register(NewSetting.class, newSettings);
|
injector.register(NewSetting.class, newSettings);
|
||||||
initializer.register(DataSource.class, database);
|
injector.register(DataSource.class, database);
|
||||||
|
|
||||||
instantiateServices(initializer);
|
instantiateServices(injector);
|
||||||
|
|
||||||
// Set up Metrics
|
// Set up Metrics
|
||||||
MetricsStarter.setupMetrics(this, newSettings);
|
MetricsStarter.setupMetrics(this, newSettings);
|
||||||
@ -256,7 +257,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
reloadSupportHook();
|
reloadSupportHook();
|
||||||
|
|
||||||
// Register event listeners
|
// Register event listeners
|
||||||
registerEventListeners(initializer);
|
registerEventListeners(injector);
|
||||||
// Start Email recall task if needed
|
// Start Email recall task if needed
|
||||||
scheduleRecallEmailTask();
|
scheduleRecallEmailTask();
|
||||||
|
|
||||||
@ -276,25 +277,25 @@ public class AuthMe extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Purge on start if enabled
|
// Purge on start if enabled
|
||||||
PurgeService purgeService = initializer.get(PurgeService.class);
|
PurgeService purgeService = injector.getSingleton(PurgeService.class);
|
||||||
purgeService.runAutoPurge();
|
purgeService.runAutoPurge();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void instantiateServices(AuthMeServiceInitializer initializer) {
|
protected void instantiateServices(Injector injector) {
|
||||||
// Some statically injected things
|
// Some statically injected things
|
||||||
initializer.register(PlayerCache.class, PlayerCache.getInstance());
|
injector.register(PlayerCache.class, PlayerCache.getInstance());
|
||||||
|
|
||||||
messages = initializer.get(Messages.class);
|
messages = injector.getSingleton(Messages.class);
|
||||||
permsMan = initializer.get(PermissionsManager.class);
|
permsMan = injector.getSingleton(PermissionsManager.class);
|
||||||
bukkitService = initializer.get(BukkitService.class);
|
bukkitService = injector.getSingleton(BukkitService.class);
|
||||||
pluginHooks = initializer.get(PluginHooks.class);
|
pluginHooks = injector.getSingleton(PluginHooks.class);
|
||||||
passwordSecurity = initializer.get(PasswordSecurity.class);
|
passwordSecurity = injector.getSingleton(PasswordSecurity.class);
|
||||||
spawnLoader = initializer.get(SpawnLoader.class);
|
spawnLoader = injector.getSingleton(SpawnLoader.class);
|
||||||
commandHandler = initializer.get(CommandHandler.class);
|
commandHandler = injector.getSingleton(CommandHandler.class);
|
||||||
management = initializer.get(Management.class);
|
management = injector.getSingleton(Management.class);
|
||||||
geoLiteApi = initializer.get(GeoLiteAPI.class);
|
geoLiteApi = injector.getSingleton(GeoLiteAPI.class);
|
||||||
initializer.get(NewAPI.class);
|
injector.getSingleton(NewAPI.class);
|
||||||
initializer.get(API.class);
|
injector.getSingleton(API.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -316,27 +317,27 @@ public class AuthMe extends JavaPlugin {
|
|||||||
/**
|
/**
|
||||||
* Register all event listeners.
|
* Register all event listeners.
|
||||||
*/
|
*/
|
||||||
protected void registerEventListeners(AuthMeServiceInitializer initializer) {
|
protected void registerEventListeners(Injector injector) {
|
||||||
// Get the plugin manager instance
|
// Get the plugin manager instance
|
||||||
PluginManager pluginManager = getServer().getPluginManager();
|
PluginManager pluginManager = getServer().getPluginManager();
|
||||||
|
|
||||||
// Register event listeners
|
// Register event listeners
|
||||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener.class), this);
|
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener.class), this);
|
||||||
pluginManager.registerEvents(initializer.get(AuthMeBlockListener.class), this);
|
pluginManager.registerEvents(injector.getSingleton(AuthMeBlockListener.class), this);
|
||||||
pluginManager.registerEvents(initializer.get(AuthMeEntityListener.class), this);
|
pluginManager.registerEvents(injector.getSingleton(AuthMeEntityListener.class), this);
|
||||||
pluginManager.registerEvents(initializer.get(AuthMeServerListener.class), this);
|
pluginManager.registerEvents(injector.getSingleton(AuthMeServerListener.class), this);
|
||||||
|
|
||||||
// Try to register 1.6 player listeners
|
// Try to register 1.6 player listeners
|
||||||
try {
|
try {
|
||||||
Class.forName("org.bukkit.event.player.PlayerEditBookEvent");
|
Class.forName("org.bukkit.event.player.PlayerEditBookEvent");
|
||||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener16.class), this);
|
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener16.class), this);
|
||||||
} catch (ClassNotFoundException ignore) {
|
} catch (ClassNotFoundException ignore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to register 1.8 player listeners
|
// Try to register 1.8 player listeners
|
||||||
try {
|
try {
|
||||||
Class.forName("org.bukkit.event.player.PlayerInteractAtEntityEvent");
|
Class.forName("org.bukkit.event.player.PlayerInteractAtEntityEvent");
|
||||||
pluginManager.registerEvents(initializer.get(AuthMePlayerListener18.class), this);
|
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener18.class), this);
|
||||||
} catch (ClassNotFoundException ignore) {
|
} catch (ClassNotFoundException ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,8 +366,8 @@ public class AuthMe extends JavaPlugin {
|
|||||||
private void setupBungeeCordHook() {
|
private void setupBungeeCordHook() {
|
||||||
if (newSettings.getProperty(HooksSettings.BUNGEECORD)) {
|
if (newSettings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||||
Messenger messenger = Bukkit.getMessenger();
|
Messenger messenger = Bukkit.getMessenger();
|
||||||
messenger.registerOutgoingPluginChannel(plugin, "BungeeCord");
|
messenger.registerOutgoingPluginChannel(this, "BungeeCord");
|
||||||
messenger.registerIncomingPluginChannel(plugin, "BungeeCord", initializer.get(BungeeCordMessage.class));
|
messenger.registerIncomingPluginChannel(this, "BungeeCord", injector.getSingleton(BungeeCordMessage.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,9 +421,9 @@ public class AuthMe extends JavaPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
// Save player data
|
// Save player data
|
||||||
BukkitService bukkitService = initializer.getIfAvailable(BukkitService.class);
|
BukkitService bukkitService = injector.getIfAvailable(BukkitService.class);
|
||||||
LimboCache limboCache = initializer.getIfAvailable(LimboCache.class);
|
LimboCache limboCache = injector.getIfAvailable(LimboCache.class);
|
||||||
AuthGroupHandler authGroupHandler = initializer.getIfAvailable(AuthGroupHandler.class);
|
AuthGroupHandler authGroupHandler = injector.getIfAvailable(AuthGroupHandler.class);
|
||||||
|
|
||||||
if (bukkitService != null && limboCache != null) {
|
if (bukkitService != null && limboCache != null) {
|
||||||
Collection<? extends Player> players = bukkitService.getOnlinePlayers();
|
Collection<? extends Player> players = bukkitService.getOnlinePlayers();
|
||||||
@ -579,7 +580,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
if (newSettings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)
|
if (newSettings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)
|
||||||
&& !newSettings.getProperty(RestrictionSettings.NO_TELEPORT)) {
|
&& !newSettings.getProperty(RestrictionSettings.NO_TELEPORT)) {
|
||||||
PlayerDataStorage playerDataStorage = initializer.getIfAvailable(PlayerDataStorage.class);
|
PlayerDataStorage playerDataStorage = injector.getIfAvailable(PlayerDataStorage.class);
|
||||||
if (playerDataStorage != null && !playerDataStorage.hasData(player)) {
|
if (playerDataStorage != null && !playerDataStorage.hasData(player)) {
|
||||||
playerDataStorage.saveData(player);
|
playerDataStorage.saveData(player);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package fr.xephi.authme.command;
|
package fr.xephi.authme.command;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
import fr.xephi.authme.AuthMe;
|
import fr.xephi.authme.AuthMe;
|
||||||
import fr.xephi.authme.command.help.HelpProvider;
|
import fr.xephi.authme.command.help.HelpProvider;
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
|
||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.util.StringUtils;
|
import fr.xephi.authme.util.StringUtils;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -37,12 +37,12 @@ public class CommandHandler {
|
|||||||
private Map<Class<? extends ExecutableCommand>, ExecutableCommand> commands = new HashMap<>();
|
private Map<Class<? extends ExecutableCommand>, ExecutableCommand> commands = new HashMap<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CommandHandler(AuthMeServiceInitializer initializer, CommandMapper commandMapper,
|
public CommandHandler(Injector injector, CommandMapper commandMapper,
|
||||||
PermissionsManager permissionsManager, HelpProvider helpProvider) {
|
PermissionsManager permissionsManager, HelpProvider helpProvider) {
|
||||||
this.commandMapper = commandMapper;
|
this.commandMapper = commandMapper;
|
||||||
this.permissionsManager = permissionsManager;
|
this.permissionsManager = permissionsManager;
|
||||||
this.helpProvider = helpProvider;
|
this.helpProvider = helpProvider;
|
||||||
initializeCommands(initializer, commandMapper.getCommandClasses());
|
initializeCommands(injector, commandMapper.getCommandClasses());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,12 +90,13 @@ public class CommandHandler {
|
|||||||
/**
|
/**
|
||||||
* Initialize all required ExecutableCommand objects.
|
* Initialize all required ExecutableCommand objects.
|
||||||
*
|
*
|
||||||
|
* @param injector the injector
|
||||||
* @param commandClasses the classes to instantiate
|
* @param commandClasses the classes to instantiate
|
||||||
*/
|
*/
|
||||||
private void initializeCommands(AuthMeServiceInitializer initializer,
|
private void initializeCommands(Injector injector,
|
||||||
Set<Class<? extends ExecutableCommand>> commandClasses) {
|
Set<Class<? extends ExecutableCommand>> commandClasses) {
|
||||||
for (Class<? extends ExecutableCommand> clazz : 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;
|
package fr.xephi.authme.command.executable.authme;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.command.CommandService;
|
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.SqliteToSql;
|
||||||
import fr.xephi.authme.converter.vAuthConverter;
|
import fr.xephi.authme.converter.vAuthConverter;
|
||||||
import fr.xephi.authme.converter.xAuthConverter;
|
import fr.xephi.authme.converter.xAuthConverter;
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
|
||||||
import fr.xephi.authme.output.MessageKey;
|
import fr.xephi.authme.output.MessageKey;
|
||||||
import fr.xephi.authme.util.BukkitService;
|
import fr.xephi.authme.util.BukkitService;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -31,7 +31,7 @@ public class ConverterCommand implements ExecutableCommand {
|
|||||||
private BukkitService bukkitService;
|
private BukkitService bukkitService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AuthMeServiceInitializer initializer;
|
private Injector injector;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
public void executeCommand(final CommandSender sender, List<String> arguments) {
|
||||||
@ -46,7 +46,7 @@ public class ConverterCommand implements ExecutableCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the proper converter instance
|
// Get the proper converter instance
|
||||||
final Converter converter = initializer.newInstance(jobType.getConverterClass());
|
final Converter converter = injector.newInstance(jobType.getConverterClass());
|
||||||
|
|
||||||
// Run the convert job
|
// Run the convert job
|
||||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
package fr.xephi.authme.command.executable.authme;
|
package fr.xephi.authme.command.executable.authme;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
import fr.xephi.authme.AuthMe;
|
import fr.xephi.authme.AuthMe;
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.command.CommandService;
|
import fr.xephi.authme.command.CommandService;
|
||||||
import fr.xephi.authme.command.ExecutableCommand;
|
import fr.xephi.authme.command.ExecutableCommand;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
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.output.MessageKey;
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
import fr.xephi.authme.settings.NewSetting;
|
||||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +26,7 @@ public class ReloadCommand implements ExecutableCommand {
|
|||||||
private AuthMe plugin;
|
private AuthMe plugin;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AuthMeServiceInitializer initializer;
|
private Injector injector;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private NewSetting settings;
|
private NewSetting settings;
|
||||||
@ -44,7 +47,7 @@ public class ReloadCommand implements ExecutableCommand {
|
|||||||
ConsoleLogger.info("Note: cannot change database type during /authme reload");
|
ConsoleLogger.info("Note: cannot change database type during /authme reload");
|
||||||
sender.sendMessage("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);
|
commandService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
sender.sendMessage("Error occurred during reload of AuthMe: aborting");
|
sender.sendMessage("Error occurred during reload of AuthMe: aborting");
|
||||||
@ -52,4 +55,16 @@ public class ReloadCommand implements ExecutableCommand {
|
|||||||
plugin.stopOrUnload();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,11 +31,13 @@ public class VersionCommand implements ExecutableCommand {
|
|||||||
+ " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
|
+ " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
|
||||||
sender.sendMessage(ChatColor.GOLD + "Developers:");
|
sender.sendMessage(ChatColor.GOLD + "Developers:");
|
||||||
Collection<? extends Player> onlinePlayers = bukkitService.getOnlinePlayers();
|
Collection<? extends Player> onlinePlayers = bukkitService.getOnlinePlayers();
|
||||||
printDeveloper(sender, "Xephi", "xephi59", "Lead Developer", onlinePlayers);
|
printDeveloper(sender, "Alexandre Vanhecke", "xephi59", "Original Author", onlinePlayers);
|
||||||
|
printDeveloper(sender, "Lucas J.", "ljacqu", "Main Developer", onlinePlayers);
|
||||||
|
printDeveloper(sender, "Gnat008", "gnat008", "Developer", onlinePlayers);
|
||||||
printDeveloper(sender, "DNx5", "DNx5", "Developer", onlinePlayers);
|
printDeveloper(sender, "DNx5", "DNx5", "Developer", onlinePlayers);
|
||||||
printDeveloper(sender, "games647", "games647", "Developer", onlinePlayers);
|
printDeveloper(sender, "games647", "games647", "Developer", onlinePlayers);
|
||||||
printDeveloper(sender, "Tim Visee", "timvisee", "Developer", onlinePlayers);
|
printDeveloper(sender, "Tim Visee", "timvisee", "Developer", onlinePlayers);
|
||||||
printDeveloper(sender, "Sgdc3", "sgdc3", "Project manager, Contributor", onlinePlayers);
|
printDeveloper(sender, "Gabriele C.", "sgdc3", "Project manager, Contributor", onlinePlayers);
|
||||||
sender.sendMessage(ChatColor.GOLD + "Website: " + ChatColor.WHITE +
|
sender.sendMessage(ChatColor.GOLD + "Website: " + ChatColor.WHITE +
|
||||||
"http://dev.bukkit.org/bukkit-plugins/authme-reloaded/");
|
"http://dev.bukkit.org/bukkit-plugins/authme-reloaded/");
|
||||||
sender.sendMessage(ChatColor.GOLD + "License: " + ChatColor.WHITE + "GNU GPL v3.0"
|
sender.sendMessage(ChatColor.GOLD + "License: " + ChatColor.WHITE + "GNU GPL v3.0"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package fr.xephi.authme.hooks;
|
package fr.xephi.authme.hooks;
|
||||||
|
|
||||||
|
import ch.jalu.injector.annotations.NoFieldScan;
|
||||||
import com.earth2me.essentials.Essentials;
|
import com.earth2me.essentials.Essentials;
|
||||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
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.
|
* Hooks into third-party plugins and allows to perform actions on them.
|
||||||
*/
|
*/
|
||||||
|
@NoFieldScan
|
||||||
public class PluginHooks {
|
public class PluginHooks {
|
||||||
|
|
||||||
private final PluginManager pluginManager;
|
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;
|
package fr.xephi.authme.listener.protocollib;
|
||||||
|
|
||||||
|
import ch.jalu.injector.annotations.NoFieldScan;
|
||||||
import fr.xephi.authme.AuthMe;
|
import fr.xephi.authme.AuthMe;
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||||
@ -11,6 +12,7 @@ import org.bukkit.entity.Player;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@NoFieldScan
|
||||||
public class ProtocolLibService implements SettingsDependent {
|
public class ProtocolLibService implements SettingsDependent {
|
||||||
|
|
||||||
/* Packet Adapters */
|
/* Packet Adapters */
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package fr.xephi.authme.security;
|
package fr.xephi.authme.security;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.events.PasswordEncryptionEvent;
|
import fr.xephi.authme.events.PasswordEncryptionEvent;
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
|
||||||
import fr.xephi.authme.initialization.Reloadable;
|
import fr.xephi.authme.initialization.Reloadable;
|
||||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||||
@ -28,7 +28,7 @@ public class PasswordSecurity implements Reloadable {
|
|||||||
private PluginManager pluginManager;
|
private PluginManager pluginManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AuthMeServiceInitializer initializer;
|
private Injector injector;
|
||||||
|
|
||||||
private HashAlgorithm algorithm;
|
private HashAlgorithm algorithm;
|
||||||
private boolean supportOldAlgorithm;
|
private boolean supportOldAlgorithm;
|
||||||
@ -155,7 +155,7 @@ public class PasswordSecurity implements Reloadable {
|
|||||||
if (HashAlgorithm.CUSTOM.equals(algorithm) || HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
if (HashAlgorithm.CUSTOM.equals(algorithm) || HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return initializer.newInstance(algorithm.getClazz());
|
return injector.newInstance(algorithm.getClazz());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hashPasswordForNewAlgorithm(String password, String playerName) {
|
private void hashPasswordForNewAlgorithm(String password, String playerName) {
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package fr.xephi.authme;
|
package fr.xephi.authme;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
|
import ch.jalu.injector.InjectorBuilder;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import fr.xephi.authme.api.NewAPI;
|
import fr.xephi.authme.api.NewAPI;
|
||||||
import fr.xephi.authme.command.CommandHandler;
|
import fr.xephi.authme.command.CommandHandler;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
|
||||||
import fr.xephi.authme.initialization.DataFolder;
|
import fr.xephi.authme.initialization.DataFolder;
|
||||||
import fr.xephi.authme.listener.AuthMeBlockListener;
|
import fr.xephi.authme.listener.AuthMeBlockListener;
|
||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
@ -42,7 +43,7 @@ import static org.mockito.Mockito.mock;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration test verifying that all services can be initialized in {@link AuthMe}
|
* Integration test verifying that all services can be initialized in {@link AuthMe}
|
||||||
* with the {@link AuthMeServiceInitializer}.
|
* with the {@link Injector}.
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class AuthMeInitializationTest {
|
public class AuthMeInitializationTest {
|
||||||
@ -97,29 +98,29 @@ public class AuthMeInitializationTest {
|
|||||||
// We only require it right now because of usages of AuthMe#getInstance()
|
// We only require it right now because of usages of AuthMe#getInstance()
|
||||||
ReflectionTestUtils.setField(AuthMe.class, null, "plugin", authMe);
|
ReflectionTestUtils.setField(AuthMe.class, null, "plugin", authMe);
|
||||||
|
|
||||||
AuthMeServiceInitializer initializer = new AuthMeServiceInitializer("fr.xephi.authme");
|
Injector injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create();
|
||||||
initializer.provide(DataFolder.class, dataFolder);
|
injector.provide(DataFolder.class, dataFolder);
|
||||||
initializer.register(Server.class, server);
|
injector.register(Server.class, server);
|
||||||
initializer.register(PluginManager.class, pluginManager);
|
injector.register(PluginManager.class, pluginManager);
|
||||||
|
|
||||||
initializer.register(AuthMe.class, authMe);
|
injector.register(AuthMe.class, authMe);
|
||||||
initializer.register(NewSetting.class, settings);
|
injector.register(NewSetting.class, settings);
|
||||||
initializer.register(DataSource.class, mock(DataSource.class));
|
injector.register(DataSource.class, mock(DataSource.class));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
authMe.instantiateServices(initializer);
|
authMe.instantiateServices(injector);
|
||||||
authMe.registerEventListeners(initializer);
|
authMe.registerEventListeners(injector);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
// Take a few samples and ensure that they are not null
|
// Take a few samples and ensure that they are not null
|
||||||
assertThat(initializer.getIfAvailable(AuthMeBlockListener.class), not(nullValue()));
|
assertThat(injector.getIfAvailable(AuthMeBlockListener.class), not(nullValue()));
|
||||||
assertThat(initializer.getIfAvailable(CommandHandler.class), not(nullValue()));
|
assertThat(injector.getIfAvailable(CommandHandler.class), not(nullValue()));
|
||||||
assertThat(initializer.getIfAvailable(Management.class), not(nullValue()));
|
assertThat(injector.getIfAvailable(Management.class), not(nullValue()));
|
||||||
assertThat(initializer.getIfAvailable(NewAPI.class), not(nullValue()));
|
assertThat(injector.getIfAvailable(NewAPI.class), not(nullValue()));
|
||||||
assertThat(initializer.getIfAvailable(PasswordSecurity.class), not(nullValue()));
|
assertThat(injector.getIfAvailable(PasswordSecurity.class), not(nullValue()));
|
||||||
assertThat(initializer.getIfAvailable(PermissionsManager.class), not(nullValue()));
|
assertThat(injector.getIfAvailable(PermissionsManager.class), not(nullValue()));
|
||||||
assertThat(initializer.getIfAvailable(ProcessSyncPlayerLogin.class), not(nullValue()));
|
assertThat(injector.getIfAvailable(ProcessSyncPlayerLogin.class), not(nullValue()));
|
||||||
assertThat(initializer.getIfAvailable(PurgeService.class), not(nullValue()));
|
assertThat(injector.getIfAvailable(PurgeService.class), not(nullValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package fr.xephi.authme.cache.backup;
|
package fr.xephi.authme.cache.backup;
|
||||||
|
|
||||||
|
import ch.jalu.injector.testing.BeforeInjecting;
|
||||||
|
import ch.jalu.injector.testing.DelayedInjectionRunner;
|
||||||
|
import ch.jalu.injector.testing.InjectDelayed;
|
||||||
import fr.xephi.authme.TestHelper;
|
import fr.xephi.authme.TestHelper;
|
||||||
import fr.xephi.authme.cache.limbo.PlayerData;
|
import fr.xephi.authme.cache.limbo.PlayerData;
|
||||||
import fr.xephi.authme.initialization.DataFolder;
|
import fr.xephi.authme.initialization.DataFolder;
|
||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.runner.BeforeInjecting;
|
|
||||||
import fr.xephi.authme.runner.DelayedInjectionRunner;
|
|
||||||
import fr.xephi.authme.runner.InjectDelayed;
|
|
||||||
import fr.xephi.authme.settings.SpawnLoader;
|
import fr.xephi.authme.settings.SpawnLoader;
|
||||||
import fr.xephi.authme.util.BukkitService;
|
import fr.xephi.authme.util.BukkitService;
|
||||||
import fr.xephi.authme.util.StringUtils;
|
import fr.xephi.authme.util.StringUtils;
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
package fr.xephi.authme.command;
|
package fr.xephi.authme.command;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
|
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
|
||||||
import fr.xephi.authme.command.TestCommandsUtil.TestRegisterCommand;
|
import fr.xephi.authme.command.TestCommandsUtil.TestRegisterCommand;
|
||||||
import fr.xephi.authme.command.TestCommandsUtil.TestUnregisterCommand;
|
import fr.xephi.authme.command.TestCommandsUtil.TestUnregisterCommand;
|
||||||
import fr.xephi.authme.command.help.HelpProvider;
|
import fr.xephi.authme.command.help.HelpProvider;
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
|
||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.runner.BeforeInjecting;
|
|
||||||
import fr.xephi.authme.runner.DelayedInjectionRunner;
|
|
||||||
import fr.xephi.authme.runner.InjectDelayed;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -49,14 +48,13 @@ import static org.mockito.Mockito.verify;
|
|||||||
// Justification: It's more readable to use asList() everywhere in the test when we often generated two lists where one
|
// Justification: It's more readable to use asList() everywhere in the test when we often generated two lists where one
|
||||||
// often consists of only one element, e.g. myMethod(asList("authme"), asList("my", "args"), ...)
|
// often consists of only one element, e.g. myMethod(asList("authme"), asList("my", "args"), ...)
|
||||||
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
|
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
|
||||||
@RunWith(DelayedInjectionRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class CommandHandlerTest {
|
public class CommandHandlerTest {
|
||||||
|
|
||||||
@InjectDelayed
|
|
||||||
private CommandHandler handler;
|
private CommandHandler handler;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private AuthMeServiceInitializer initializer;
|
private Injector injector;
|
||||||
@Mock
|
@Mock
|
||||||
private CommandMapper commandMapper;
|
private CommandMapper commandMapper;
|
||||||
@Mock
|
@Mock
|
||||||
@ -66,23 +64,25 @@ public class CommandHandlerTest {
|
|||||||
|
|
||||||
private Map<Class<? extends ExecutableCommand>, ExecutableCommand> mockedCommands = new HashMap<>();
|
private Map<Class<? extends ExecutableCommand>, ExecutableCommand> mockedCommands = new HashMap<>();
|
||||||
|
|
||||||
@BeforeInjecting
|
@Before
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void initializeCommandMapper() {
|
public void initializeCommandMapper() {
|
||||||
given(commandMapper.getCommandClasses()).willReturn(Sets.newHashSet(
|
given(commandMapper.getCommandClasses()).willReturn(Sets.newHashSet(
|
||||||
ExecutableCommand.class, TestLoginCommand.class, TestRegisterCommand.class, TestUnregisterCommand.class));
|
ExecutableCommand.class, TestLoginCommand.class, TestRegisterCommand.class, TestUnregisterCommand.class));
|
||||||
setInjectorToMockExecutableCommandClasses();
|
setInjectorToMockExecutableCommandClasses();
|
||||||
|
|
||||||
|
handler = new CommandHandler(injector, commandMapper, permissionsManager, helpProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the initializer return a mock when {@link AuthMeServiceInitializer#newInstance(Class)} is invoked
|
* Makes the injector return a mock when {@link Injector#newInstance(Class)} is invoked
|
||||||
* with (a child of) ExecutableCommand.class. The mocks the initializer creates are stored in {@link #mockedCommands}.
|
* with (a child of) ExecutableCommand.class. The mocks the injector creates are stored in {@link #mockedCommands}.
|
||||||
* <p>
|
* <p>
|
||||||
* The {@link CommandMapper} is mocked in {@link #initializeCommandMapper()} to return certain test classes.
|
* The {@link CommandMapper} is mocked in {@link #initializeCommandMapper()} to return certain test classes.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void setInjectorToMockExecutableCommandClasses() {
|
private void setInjectorToMockExecutableCommandClasses() {
|
||||||
given(initializer.newInstance(any(Class.class))).willAnswer(new Answer<Object>() {
|
given(injector.newInstance(any(Class.class))).willAnswer(new Answer<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||||
Class<?> clazz = (Class<?>) invocation.getArguments()[0];
|
Class<?> clazz = (Class<?>) invocation.getArguments()[0];
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package fr.xephi.authme.command;
|
package fr.xephi.authme.command;
|
||||||
|
|
||||||
|
import ch.jalu.injector.testing.BeforeInjecting;
|
||||||
|
import ch.jalu.injector.testing.DelayedInjectionRunner;
|
||||||
|
import ch.jalu.injector.testing.InjectDelayed;
|
||||||
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
|
import fr.xephi.authme.command.TestCommandsUtil.TestLoginCommand;
|
||||||
import fr.xephi.authme.command.TestCommandsUtil.TestRegisterCommand;
|
import fr.xephi.authme.command.TestCommandsUtil.TestRegisterCommand;
|
||||||
import fr.xephi.authme.command.TestCommandsUtil.TestUnregisterCommand;
|
import fr.xephi.authme.command.TestCommandsUtil.TestUnregisterCommand;
|
||||||
import fr.xephi.authme.command.executable.HelpCommand;
|
import fr.xephi.authme.command.executable.HelpCommand;
|
||||||
import fr.xephi.authme.permission.PermissionNode;
|
import fr.xephi.authme.permission.PermissionNode;
|
||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.runner.BeforeInjecting;
|
|
||||||
import fr.xephi.authme.runner.InjectDelayed;
|
|
||||||
import fr.xephi.authme.runner.DelayedInjectionRunner;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package fr.xephi.authme.command.executable.authme;
|
package fr.xephi.authme.command.executable.authme;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
import fr.xephi.authme.TestHelper;
|
import fr.xephi.authme.TestHelper;
|
||||||
import fr.xephi.authme.command.CommandService;
|
import fr.xephi.authme.command.CommandService;
|
||||||
import fr.xephi.authme.converter.RakamakConverter;
|
import fr.xephi.authme.converter.RakamakConverter;
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
|
||||||
import fr.xephi.authme.output.MessageKey;
|
import fr.xephi.authme.output.MessageKey;
|
||||||
import fr.xephi.authme.util.BukkitService;
|
import fr.xephi.authme.util.BukkitService;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -43,7 +43,7 @@ public class ConverterCommandTest {
|
|||||||
private BukkitService bukkitService;
|
private BukkitService bukkitService;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private AuthMeServiceInitializer initializer;
|
private Injector injector;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldHandleUnknownConversionType() {
|
public void shouldHandleUnknownConversionType() {
|
||||||
@ -56,7 +56,7 @@ public class ConverterCommandTest {
|
|||||||
// then
|
// then
|
||||||
verify(commandService).send(sender, MessageKey.ERROR);
|
verify(commandService).send(sender, MessageKey.ERROR);
|
||||||
verifyNoMoreInteractions(commandService);
|
verifyNoMoreInteractions(commandService);
|
||||||
verifyZeroInteractions(initializer);
|
verifyZeroInteractions(injector);
|
||||||
verifyZeroInteractions(bukkitService);
|
verifyZeroInteractions(bukkitService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ public class ConverterCommandTest {
|
|||||||
// given
|
// given
|
||||||
ConverterCommand.ConvertType type = ConverterCommand.ConvertType.RAKAMAK;
|
ConverterCommand.ConvertType type = ConverterCommand.ConvertType.RAKAMAK;
|
||||||
RakamakConverter converter = mock(RakamakConverter.class);
|
RakamakConverter converter = mock(RakamakConverter.class);
|
||||||
given(initializer.newInstance(RakamakConverter.class)).willReturn(converter);
|
given(injector.newInstance(RakamakConverter.class)).willReturn(converter);
|
||||||
CommandSender sender = mock(CommandSender.class);
|
CommandSender sender = mock(CommandSender.class);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -97,8 +97,8 @@ public class ConverterCommandTest {
|
|||||||
// then
|
// then
|
||||||
verify(converter).execute(sender);
|
verify(converter).execute(sender);
|
||||||
verifyNoMoreInteractions(converter);
|
verifyNoMoreInteractions(converter);
|
||||||
verify(initializer).newInstance(type.getConverterClass());
|
verify(injector).newInstance(type.getConverterClass());
|
||||||
verifyNoMoreInteractions(initializer);
|
verifyNoMoreInteractions(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package fr.xephi.authme.command.executable.authme;
|
package fr.xephi.authme.command.executable.authme;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
import fr.xephi.authme.AuthMe;
|
import fr.xephi.authme.AuthMe;
|
||||||
import fr.xephi.authme.TestHelper;
|
import fr.xephi.authme.TestHelper;
|
||||||
import fr.xephi.authme.command.CommandService;
|
import fr.xephi.authme.command.CommandService;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.datasource.DataSourceType;
|
import fr.xephi.authme.datasource.DataSourceType;
|
||||||
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.output.MessageKey;
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
import fr.xephi.authme.settings.NewSetting;
|
||||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||||
@ -19,14 +21,18 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.argThat;
|
import static org.mockito.Matchers.argThat;
|
||||||
import static org.mockito.Matchers.matches;
|
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +48,7 @@ public class ReloadCommandTest {
|
|||||||
private AuthMe authMe;
|
private AuthMe authMe;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private AuthMeServiceInitializer initializer;
|
private Injector injector;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private NewSetting settings;
|
private NewSetting settings;
|
||||||
@ -71,13 +77,19 @@ public class ReloadCommandTest {
|
|||||||
CommandSender sender = mock(CommandSender.class);
|
CommandSender sender = mock(CommandSender.class);
|
||||||
given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL);
|
given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL);
|
||||||
given(dataSource.getType()).willReturn(DataSourceType.MYSQL);
|
given(dataSource.getType()).willReturn(DataSourceType.MYSQL);
|
||||||
|
List<Reloadable> reloadables = Arrays.asList(
|
||||||
|
mock(Reloadable.class), mock(Reloadable.class), mock(Reloadable.class));
|
||||||
|
List<SettingsDependent> dependents = Arrays.asList(
|
||||||
|
mock(SettingsDependent.class), mock(SettingsDependent.class));
|
||||||
|
given(injector.retrieveAllOfType(Reloadable.class)).willReturn(reloadables);
|
||||||
|
given(injector.retrieveAllOfType(SettingsDependent.class)).willReturn(dependents);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
command.executeCommand(sender, Collections.<String>emptyList());
|
command.executeCommand(sender, Collections.<String>emptyList());
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify(settings).reload();
|
verify(settings).reload();
|
||||||
verify(initializer).performReloadOnServices();
|
verifyReloadingCalls(reloadables, dependents);
|
||||||
verify(commandService).send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
|
verify(commandService).send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +97,7 @@ public class ReloadCommandTest {
|
|||||||
public void shouldHandleReloadError() {
|
public void shouldHandleReloadError() {
|
||||||
// given
|
// given
|
||||||
CommandSender sender = mock(CommandSender.class);
|
CommandSender sender = mock(CommandSender.class);
|
||||||
doThrow(IllegalStateException.class).when(initializer).performReloadOnServices();
|
doThrow(IllegalStateException.class).when(injector).retrieveAllOfType(Reloadable.class);
|
||||||
given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL);
|
given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL);
|
||||||
given(dataSource.getType()).willReturn(DataSourceType.MYSQL);
|
given(dataSource.getType()).willReturn(DataSourceType.MYSQL);
|
||||||
|
|
||||||
@ -94,8 +106,8 @@ public class ReloadCommandTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
verify(settings).reload();
|
verify(settings).reload();
|
||||||
verify(initializer).performReloadOnServices();
|
verify(injector).retrieveAllOfType(Reloadable.class);
|
||||||
verify(sender).sendMessage(matches("Error occurred.*"));
|
verify(sender).sendMessage(argThat(containsString("Error occurred")));
|
||||||
verify(authMe).stopOrUnload();
|
verify(authMe).stopOrUnload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,13 +117,24 @@ public class ReloadCommandTest {
|
|||||||
CommandSender sender = mock(CommandSender.class);
|
CommandSender sender = mock(CommandSender.class);
|
||||||
given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL);
|
given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL);
|
||||||
given(dataSource.getType()).willReturn(DataSourceType.SQLITE);
|
given(dataSource.getType()).willReturn(DataSourceType.SQLITE);
|
||||||
|
given(injector.retrieveAllOfType(Reloadable.class)).willReturn(new ArrayList<Reloadable>());
|
||||||
|
given(injector.retrieveAllOfType(SettingsDependent.class)).willReturn(new ArrayList<SettingsDependent>());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
command.executeCommand(sender, Collections.<String>emptyList());
|
command.executeCommand(sender, Collections.<String>emptyList());
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify(settings).reload();
|
verify(settings).reload();
|
||||||
verify(initializer).performReloadOnServices();
|
verify(injector, times(2)).retrieveAllOfType(any(Class.class));
|
||||||
verify(sender).sendMessage(argThat(containsString("cannot change database type")));
|
verify(sender).sendMessage(argThat(containsString("cannot change database type")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void verifyReloadingCalls(List<Reloadable> reloadables, List<SettingsDependent> dependents) {
|
||||||
|
for (Reloadable reloadable : reloadables) {
|
||||||
|
verify(reloadable).reload();
|
||||||
|
}
|
||||||
|
for (SettingsDependent dependent : dependents) {
|
||||||
|
verify(dependent).reload(settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package fr.xephi.authme.converter;
|
package fr.xephi.authme.converter;
|
||||||
|
|
||||||
|
import ch.jalu.injector.testing.DelayedInjectionRunner;
|
||||||
|
import ch.jalu.injector.testing.InjectDelayed;
|
||||||
import fr.xephi.authme.TestHelper;
|
import fr.xephi.authme.TestHelper;
|
||||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.initialization.DataFolder;
|
import fr.xephi.authme.initialization.DataFolder;
|
||||||
import fr.xephi.authme.runner.DelayedInjectionRunner;
|
|
||||||
import fr.xephi.authme.runner.InjectDelayed;
|
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
import fr.xephi.authme.settings.NewSetting;
|
||||||
import fr.xephi.authme.settings.properties.ConverterSettings;
|
import fr.xephi.authme.settings.properties.ConverterSettings;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
@ -1,340 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.samples.AlphaService;
|
|
||||||
import fr.xephi.authme.initialization.samples.BadFieldInjection;
|
|
||||||
import fr.xephi.authme.initialization.samples.BetaManager;
|
|
||||||
import fr.xephi.authme.initialization.samples.CircularClasses;
|
|
||||||
import fr.xephi.authme.initialization.samples.ClassWithAbstractDependency;
|
|
||||||
import fr.xephi.authme.initialization.samples.ClassWithAnnotations;
|
|
||||||
import fr.xephi.authme.initialization.samples.Duration;
|
|
||||||
import fr.xephi.authme.initialization.samples.FieldInjectionWithAnnotations;
|
|
||||||
import fr.xephi.authme.initialization.samples.GammaService;
|
|
||||||
import fr.xephi.authme.initialization.samples.InstantiationFallbackClasses;
|
|
||||||
import fr.xephi.authme.initialization.samples.InvalidClass;
|
|
||||||
import fr.xephi.authme.initialization.samples.InvalidPostConstruct;
|
|
||||||
import fr.xephi.authme.initialization.samples.InvalidStaticFieldInjection;
|
|
||||||
import fr.xephi.authme.initialization.samples.PostConstructTestClass;
|
|
||||||
import fr.xephi.authme.initialization.samples.ProvidedClass;
|
|
||||||
import fr.xephi.authme.initialization.samples.Size;
|
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.hamcrest.Matchers.sameInstance;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for {@link AuthMeServiceInitializer}.
|
|
||||||
*/
|
|
||||||
public class AuthMeServiceInitializerTest {
|
|
||||||
|
|
||||||
private static final String ALLOWED_PACKAGE = "fr.xephi.authme.initialization";
|
|
||||||
|
|
||||||
private AuthMeServiceInitializer initializer;
|
|
||||||
|
|
||||||
// As we test many cases that throw exceptions, we use JUnit's ExpectedException Rule
|
|
||||||
// to make sure that we receive the exception we expect
|
|
||||||
@Rule
|
|
||||||
public ExpectedException expectedException = ExpectedException.none();
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setInitializer() {
|
|
||||||
initializer = new AuthMeServiceInitializer(ALLOWED_PACKAGE);
|
|
||||||
initializer.register(ProvidedClass.class, new ProvidedClass(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldInitializeElements() {
|
|
||||||
// given / when
|
|
||||||
BetaManager betaManager = initializer.get(BetaManager.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(betaManager, not(nullValue()));
|
|
||||||
for (Object o : betaManager.getDependencies()) {
|
|
||||||
assertThat(o, not(nullValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForInvalidPackage() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("outside of the allowed packages");
|
|
||||||
initializer.get(InvalidClass.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForUnregisteredPrimitiveType() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("Primitive types must be provided");
|
|
||||||
initializer.get(int.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldPassValueByAnnotation() {
|
|
||||||
// given
|
|
||||||
int size = 12;
|
|
||||||
long duration = -15482L;
|
|
||||||
initializer.provide(Size.class, size);
|
|
||||||
initializer.provide(Duration.class, duration);
|
|
||||||
|
|
||||||
// when
|
|
||||||
ClassWithAnnotations object = initializer.get(ClassWithAnnotations.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(object, not(nullValue()));
|
|
||||||
assertThat(object.getSize(), equalTo(size));
|
|
||||||
assertThat(object.getDuration(), equalTo(duration));
|
|
||||||
// some sample check to make sure we only have one instance of GammaService
|
|
||||||
assertThat(object.getGammaService(), equalTo(initializer.get(BetaManager.class).getDependencies()[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldRecognizeCircularReferences() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("Found cyclic dependency");
|
|
||||||
initializer.get(CircularClasses.Circular3.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForUnregisteredAnnotation() {
|
|
||||||
// given
|
|
||||||
initializer.provide(Size.class, 4523);
|
|
||||||
|
|
||||||
// when / then
|
|
||||||
expectRuntimeExceptionWith("must be registered beforehand");
|
|
||||||
initializer.get(ClassWithAnnotations.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForFieldInjectionWithoutNoArgsConstructor() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("Did not find injection method");
|
|
||||||
initializer.get(BadFieldInjection.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldInjectFieldsWithAnnotationsProperly() {
|
|
||||||
// given
|
|
||||||
initializer.provide(Size.class, 2809375);
|
|
||||||
initializer.provide(Duration.class, 13095L);
|
|
||||||
|
|
||||||
// when
|
|
||||||
FieldInjectionWithAnnotations result = initializer.get(FieldInjectionWithAnnotations.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(result.getSize(), equalTo(2809375));
|
|
||||||
assertThat(result.getDuration(), equalTo(13095L));
|
|
||||||
assertThat(result.getBetaManager(), not(nullValue()));
|
|
||||||
assertThat(result.getClassWithAnnotations(), not(nullValue()));
|
|
||||||
assertThat(result.getClassWithAnnotations().getGammaService(),
|
|
||||||
equalTo(result.getBetaManager().getDependencies()[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForAnnotationAsKey() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("Cannot retrieve annotated elements in this way");
|
|
||||||
initializer.get(Size.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForSecondRegistration() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("There is already an object present");
|
|
||||||
initializer.register(ProvidedClass.class, new ProvidedClass(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForSecondAnnotationRegistration() {
|
|
||||||
// given
|
|
||||||
initializer.provide(Size.class, 12);
|
|
||||||
|
|
||||||
// when / then
|
|
||||||
expectRuntimeExceptionWith("already registered");
|
|
||||||
initializer.provide(Size.class, -8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForNullValueAssociatedToAnnotation() {
|
|
||||||
// given / when / then
|
|
||||||
expectedException.expect(NullPointerException.class);
|
|
||||||
initializer.provide(Duration.class, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForRegisterWithNull() {
|
|
||||||
// given / when / then
|
|
||||||
expectedException.expect(NullPointerException.class);
|
|
||||||
initializer.register(String.class, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldExecutePostConstructMethod() {
|
|
||||||
// given
|
|
||||||
initializer.provide(Size.class, 15123);
|
|
||||||
|
|
||||||
// when
|
|
||||||
PostConstructTestClass testClass = initializer.get(PostConstructTestClass.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(testClass.wasPostConstructCalled(), equalTo(true));
|
|
||||||
assertThat(testClass.getBetaManager(), not(nullValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForInvalidPostConstructMethod() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("@PostConstruct method may not be static or have any parameters");
|
|
||||||
initializer.get(InvalidPostConstruct.WithParams.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForStaticPostConstructMethod() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("@PostConstruct method may not be static or have any parameters");
|
|
||||||
initializer.get(InvalidPostConstruct.Static.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldForwardExceptionFromPostConstruct() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("Error executing @PostConstruct method");
|
|
||||||
initializer.get(InvalidPostConstruct.ThrowsException.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForMultiplePostConstructMethods() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("Multiple methods with @PostConstruct");
|
|
||||||
initializer.get(InvalidPostConstruct.MultiplePostConstructs.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForPostConstructNotReturningVoid() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("@PostConstruct method must have return type void");
|
|
||||||
initializer.get(InvalidPostConstruct.NotVoidReturnType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForAbstractNonRegisteredDependency() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("cannot be instantiated");
|
|
||||||
initializer.get(ClassWithAbstractDependency.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldInstantiateWithImplementationOfAbstractDependency() {
|
|
||||||
// given
|
|
||||||
ClassWithAbstractDependency.ConcreteDependency concrete = new ClassWithAbstractDependency.ConcreteDependency();
|
|
||||||
initializer.register(ClassWithAbstractDependency.AbstractDependency.class, concrete);
|
|
||||||
|
|
||||||
// when
|
|
||||||
ClassWithAbstractDependency cwad = initializer.get(ClassWithAbstractDependency.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(cwad.getAbstractDependency() == concrete, equalTo(true));
|
|
||||||
assertThat(cwad.getAlphaService(), not(nullValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForAlreadyRegisteredClass() {
|
|
||||||
// given
|
|
||||||
initializer.register(BetaManager.class, new BetaManager());
|
|
||||||
|
|
||||||
// when / then
|
|
||||||
expectRuntimeExceptionWith("There is already an object present");
|
|
||||||
initializer.register(BetaManager.class, new BetaManager());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldCreateNewUntrackedInstance() {
|
|
||||||
// given / when
|
|
||||||
AlphaService singletonScoped = initializer.get(AlphaService.class);
|
|
||||||
AlphaService requestScoped = initializer.newInstance(AlphaService.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(singletonScoped.getProvidedClass(), not(nullValue()));
|
|
||||||
assertThat(singletonScoped.getProvidedClass(), equalTo(requestScoped.getProvidedClass()));
|
|
||||||
assertThat(singletonScoped, not(sameInstance(requestScoped)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForStaticFieldInjection() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("is static but annotated with @Inject");
|
|
||||||
initializer.newInstance(InvalidStaticFieldInjection.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldFallbackToSimpleInstantiationForPlainClass() {
|
|
||||||
// given / when
|
|
||||||
InstantiationFallbackClasses.HasFallbackDependency result =
|
|
||||||
initializer.get(InstantiationFallbackClasses.HasFallbackDependency.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(result, not(nullValue()));
|
|
||||||
assertThat(result.getGammaService(), not(nullValue()));
|
|
||||||
assertThat(result.getFallbackDependency(), not(nullValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldPerformReloadOnApplicableInstances() {
|
|
||||||
// given
|
|
||||||
initializer.provide(Size.class, 12);
|
|
||||||
initializer.provide(Duration.class, -113L);
|
|
||||||
initializer.register(NewSetting.class, mock(NewSetting.class));
|
|
||||||
|
|
||||||
GammaService gammaService = initializer.get(GammaService.class);
|
|
||||||
PostConstructTestClass postConstructTestClass = initializer.get(PostConstructTestClass.class);
|
|
||||||
ProvidedClass providedClass = initializer.get(ProvidedClass.class);
|
|
||||||
initializer.get(ClassWithAnnotations.class);
|
|
||||||
// Assert that no class was somehow reloaded at initialization
|
|
||||||
assertThat(gammaService.getWasReloaded() || postConstructTestClass.getWasReloaded()
|
|
||||||
|| providedClass.getWasReloaded(), equalTo(false));
|
|
||||||
|
|
||||||
// when
|
|
||||||
initializer.performReloadOnServices();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(gammaService.getWasReloaded(), equalTo(true));
|
|
||||||
assertThat(postConstructTestClass.getWasReloaded(), equalTo(true));
|
|
||||||
assertThat(providedClass.getWasReloaded(), equalTo(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldThrowForNullSetting() {
|
|
||||||
// given / when / then
|
|
||||||
expectRuntimeExceptionWith("Settings instance is null");
|
|
||||||
initializer.performReloadOnServices();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldRetrieveExistingInstancesOnly() {
|
|
||||||
// given
|
|
||||||
initializer.get(GammaService.class);
|
|
||||||
|
|
||||||
// when
|
|
||||||
AlphaService alphaService = initializer.getIfAvailable(AlphaService.class);
|
|
||||||
BetaManager betaManager = initializer.getIfAvailable(BetaManager.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
// was initialized because is dependency of GammaService
|
|
||||||
assertThat(alphaService, not(nullValue()));
|
|
||||||
// nothing caused this to be initialized
|
|
||||||
assertThat(betaManager, nullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void expectRuntimeExceptionWith(String message) {
|
|
||||||
expectedException.expect(RuntimeException.class);
|
|
||||||
expectedException.expectMessage(containsString(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.samples.AlphaService;
|
|
||||||
import fr.xephi.authme.initialization.samples.BetaManager;
|
|
||||||
import fr.xephi.authme.initialization.samples.ClassWithAnnotations;
|
|
||||||
import fr.xephi.authme.initialization.samples.Duration;
|
|
||||||
import fr.xephi.authme.initialization.samples.GammaService;
|
|
||||||
import fr.xephi.authme.initialization.samples.InvalidClass;
|
|
||||||
import fr.xephi.authme.initialization.samples.ProvidedClass;
|
|
||||||
import fr.xephi.authme.initialization.samples.Size;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.arrayContaining;
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for {@link ConstructorInjection}.
|
|
||||||
*/
|
|
||||||
public class ConstructorInjectionTest {
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Test
|
|
||||||
public void shouldReturnDependencies() {
|
|
||||||
// given
|
|
||||||
Injection<ClassWithAnnotations> injection = ConstructorInjection.provide(ClassWithAnnotations.class).get();
|
|
||||||
|
|
||||||
// when
|
|
||||||
Class<?>[] dependencies = injection.getDependencies();
|
|
||||||
Class<?>[] annotations = injection.getDependencyAnnotations();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(dependencies, arrayContaining(int.class, GammaService.class, long.class));
|
|
||||||
assertThat(annotations, arrayContaining((Class<?>) Size.class, null, Duration.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldInstantiate() {
|
|
||||||
// given
|
|
||||||
GammaService gammaService = new GammaService(
|
|
||||||
AlphaService.newInstance(new ProvidedClass("")));
|
|
||||||
Injection<ClassWithAnnotations> injection = ConstructorInjection.provide(ClassWithAnnotations.class).get();
|
|
||||||
|
|
||||||
// when
|
|
||||||
ClassWithAnnotations instance = injection.instantiateWith(-112, gammaService, 19L);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(instance, not(nullValue()));
|
|
||||||
assertThat(instance.getSize(), equalTo(-112));
|
|
||||||
assertThat(instance.getGammaService(), equalTo(gammaService));
|
|
||||||
assertThat(instance.getDuration(), equalTo(19L));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = NullPointerException.class)
|
|
||||||
public void shouldThrowForNullValue() {
|
|
||||||
// given
|
|
||||||
Injection<ClassWithAnnotations> injection = ConstructorInjection.provide(ClassWithAnnotations.class).get();
|
|
||||||
|
|
||||||
// when / then
|
|
||||||
injection.instantiateWith(-112, null, 12L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = RuntimeException.class)
|
|
||||||
public void shouldThrowUponInstantiationError() {
|
|
||||||
// given
|
|
||||||
AlphaService alphaService = AlphaService.newInstance(new ProvidedClass(""));
|
|
||||||
Injection<InvalidClass> injection = ConstructorInjection.provide(InvalidClass.class).get();
|
|
||||||
|
|
||||||
// when
|
|
||||||
injection.instantiateWith(alphaService, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldReturnNullForNoConstructorInjection() {
|
|
||||||
// given / when
|
|
||||||
Injection<BetaManager> injection = ConstructorInjection.provide(BetaManager.class).get();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(injection, nullValue());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.samples.AlphaService;
|
|
||||||
import fr.xephi.authme.initialization.samples.BadFieldInjection;
|
|
||||||
import fr.xephi.authme.initialization.samples.BetaManager;
|
|
||||||
import fr.xephi.authme.initialization.samples.ClassWithAnnotations;
|
|
||||||
import fr.xephi.authme.initialization.samples.Duration;
|
|
||||||
import fr.xephi.authme.initialization.samples.FieldInjectionWithAnnotations;
|
|
||||||
import fr.xephi.authme.initialization.samples.GammaService;
|
|
||||||
import fr.xephi.authme.initialization.samples.InvalidStaticFieldInjection;
|
|
||||||
import fr.xephi.authme.initialization.samples.ProvidedClass;
|
|
||||||
import fr.xephi.authme.initialization.samples.Size;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.arrayContaining;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for {@link FieldInjection}.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class FieldInjectionTest {
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Test
|
|
||||||
public void shouldReturnDependencies() {
|
|
||||||
// given
|
|
||||||
FieldInjection<FieldInjectionWithAnnotations> injection =
|
|
||||||
FieldInjection.provide(FieldInjectionWithAnnotations.class).get();
|
|
||||||
|
|
||||||
// when
|
|
||||||
Class<?>[] dependencies = injection.getDependencies();
|
|
||||||
Class<?>[] annotations = injection.getDependencyAnnotations();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(dependencies, arrayContaining(BetaManager.class, int.class, long.class, ClassWithAnnotations.class));
|
|
||||||
assertThat(annotations, arrayContaining((Class<?>) null, Size.class, Duration.class, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldInstantiateClass() {
|
|
||||||
// given
|
|
||||||
FieldInjection<BetaManager> injection = FieldInjection.provide(BetaManager.class).get();
|
|
||||||
ProvidedClass providedClass = new ProvidedClass("");
|
|
||||||
AlphaService alphaService = AlphaService.newInstance(providedClass);
|
|
||||||
GammaService gammaService = new GammaService(alphaService);
|
|
||||||
|
|
||||||
// when
|
|
||||||
BetaManager betaManager = injection.instantiateWith(providedClass, gammaService, alphaService);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(betaManager, not(nullValue()));
|
|
||||||
assertThat(betaManager.getDependencies(), arrayContaining(providedClass, gammaService, alphaService));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldProvideNullForImpossibleFieldInjection() {
|
|
||||||
// given / when
|
|
||||||
FieldInjection<BadFieldInjection> injection = FieldInjection.provide(BadFieldInjection.class).get();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(injection, nullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = RuntimeException.class)
|
|
||||||
public void shouldForwardExceptionDuringInstantiation() {
|
|
||||||
// given
|
|
||||||
FieldInjection<ThrowingConstructor> injection = FieldInjection.provide(ThrowingConstructor.class).get();
|
|
||||||
|
|
||||||
// when / when
|
|
||||||
injection.instantiateWith(new ProvidedClass(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = RuntimeException.class)
|
|
||||||
public void shouldThrowForInvalidFieldValue() {
|
|
||||||
// given
|
|
||||||
ProvidedClass providedClass = new ProvidedClass("");
|
|
||||||
AlphaService alphaService = AlphaService.newInstance(providedClass);
|
|
||||||
GammaService gammaService = new GammaService(alphaService);
|
|
||||||
FieldInjection<BetaManager> injection = FieldInjection.provide(BetaManager.class).get();
|
|
||||||
|
|
||||||
// when / then
|
|
||||||
// Correct order is provided, gamma, alpha
|
|
||||||
injection.instantiateWith(providedClass, alphaService, gammaService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = NullPointerException.class)
|
|
||||||
public void shouldThrowForNullValue() {
|
|
||||||
// given
|
|
||||||
ProvidedClass providedClass = new ProvidedClass("");
|
|
||||||
AlphaService alphaService = AlphaService.newInstance(providedClass);
|
|
||||||
FieldInjection<BetaManager> injection = FieldInjection.provide(BetaManager.class).get();
|
|
||||||
|
|
||||||
// when / then
|
|
||||||
// Correct order is provided, gamma, alpha
|
|
||||||
injection.instantiateWith(providedClass, null, alphaService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = RuntimeException.class)
|
|
||||||
public void shouldThrowForStaticFieldInjection() {
|
|
||||||
// given / when / then
|
|
||||||
FieldInjection.provide(InvalidStaticFieldInjection.class).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldNotReturnFieldInjectionForZeroInjectFields() {
|
|
||||||
// given / when
|
|
||||||
Injection<NoInjectionClass> injection = FieldInjection.provide(NoInjectionClass.class).get();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(injection, nullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private static class ThrowingConstructor {
|
|
||||||
@Inject
|
|
||||||
private ProvidedClass providedClass;
|
|
||||||
|
|
||||||
public ThrowingConstructor() {
|
|
||||||
throw new UnsupportedOperationException("Exception in constructor");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class NoInjectionClass {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.samples.GammaService;
|
|
||||||
import fr.xephi.authme.initialization.samples.InstantiationFallbackClasses;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for {@link InstantiationFallback}.
|
|
||||||
*/
|
|
||||||
public class InstantiationFallbackTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldInstantiateClass() {
|
|
||||||
// given
|
|
||||||
Injection<InstantiationFallbackClasses.FallbackClass> instantiation =
|
|
||||||
InstantiationFallback.provide(InstantiationFallbackClasses.FallbackClass.class).get();
|
|
||||||
|
|
||||||
// when
|
|
||||||
InstantiationFallbackClasses.FallbackClass result = instantiation.instantiateWith();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(result, not(nullValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = RuntimeException.class)
|
|
||||||
public void shouldThrowIfArgumentsAreSupplied() {
|
|
||||||
// given
|
|
||||||
Injection<InstantiationFallbackClasses.FallbackClass> instantiation =
|
|
||||||
InstantiationFallback.provide(InstantiationFallbackClasses.FallbackClass.class).get();
|
|
||||||
|
|
||||||
// when / then
|
|
||||||
instantiation.instantiateWith("some argument");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldReturnNullForClassWithInjectMethod() {
|
|
||||||
// given / when
|
|
||||||
Injection<InstantiationFallbackClasses.InvalidInjectOnMethodClass> instantiation =
|
|
||||||
InstantiationFallback.provide(InstantiationFallbackClasses.InvalidInjectOnMethodClass.class).get();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(instantiation, nullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldReturnNullForMissingNoArgsConstructor() {
|
|
||||||
// given / when
|
|
||||||
Injection<InstantiationFallbackClasses.InvalidFallbackClass> instantiation =
|
|
||||||
InstantiationFallback.provide(InstantiationFallbackClasses.InvalidFallbackClass.class).get();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(instantiation, nullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldReturnNullForDifferentInjectionType() {
|
|
||||||
// given / when
|
|
||||||
Injection<GammaService> instantiation = InstantiationFallback.provide(GammaService.class).get();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(instantiation, nullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldReturnNullForClassWithPostConstruct() {
|
|
||||||
// given / when
|
|
||||||
Injection<InstantiationFallbackClasses.ClassWithPostConstruct> instantiation =
|
|
||||||
InstantiationFallback.provide(InstantiationFallbackClasses.ClassWithPostConstruct.class).get();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(instantiation, nullValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample - class with dependency to ProvidedClass.
|
|
||||||
*/
|
|
||||||
public class AlphaService {
|
|
||||||
|
|
||||||
private ProvidedClass providedClass;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
AlphaService(ProvidedClass providedClass) {
|
|
||||||
this.providedClass = providedClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProvidedClass getProvidedClass() {
|
|
||||||
return providedClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance (for instantiations in tests).
|
|
||||||
*
|
|
||||||
* @param providedClass .
|
|
||||||
* @return created instance
|
|
||||||
*/
|
|
||||||
public static AlphaService newInstance(ProvidedClass providedClass) {
|
|
||||||
return new AlphaService(providedClass);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample class with invalid field injection (requires default constructor).
|
|
||||||
*/
|
|
||||||
public class BadFieldInjection {
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Inject
|
|
||||||
private AlphaService alphaService;
|
|
||||||
|
|
||||||
public BadFieldInjection(BetaManager betaManager) {
|
|
||||||
throw new IllegalStateException("Should never be called");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample - depends on Provided, alpha and gamma.
|
|
||||||
*/
|
|
||||||
public class BetaManager {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ProvidedClass providedClass;
|
|
||||||
@Inject
|
|
||||||
private GammaService gammaService;
|
|
||||||
@Inject
|
|
||||||
private AlphaService alphaService;
|
|
||||||
|
|
||||||
public Object[] getDependencies() {
|
|
||||||
return new Object[]{providedClass, gammaService, alphaService};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Classes with circular dependencies.
|
|
||||||
*/
|
|
||||||
public abstract class CircularClasses {
|
|
||||||
|
|
||||||
public static final class Circular1 {
|
|
||||||
@Inject
|
|
||||||
public Circular1(AlphaService alphaService, Circular3 circular3) {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Circular2 {
|
|
||||||
@Inject
|
|
||||||
public Circular2(Circular1 circular1) {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Circular3 {
|
|
||||||
@Inject
|
|
||||||
public Circular3(Circular2 circular2, BetaManager betaManager) {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test with an abstract class declared as dependency.
|
|
||||||
*/
|
|
||||||
public class ClassWithAbstractDependency {
|
|
||||||
|
|
||||||
private final AlphaService alphaService;
|
|
||||||
private final AbstractDependency abstractDependency;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public ClassWithAbstractDependency(AlphaService as, AbstractDependency ad) {
|
|
||||||
this.alphaService = as;
|
|
||||||
this.abstractDependency = ad;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AlphaService getAlphaService() {
|
|
||||||
return alphaService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractDependency getAbstractDependency() {
|
|
||||||
return abstractDependency;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class AbstractDependency {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class ConcreteDependency extends AbstractDependency {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
public class ClassWithAnnotations {
|
|
||||||
|
|
||||||
private int size;
|
|
||||||
private GammaService gammaService;
|
|
||||||
private long duration;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
ClassWithAnnotations(@Size int size, GammaService gammaService, @Duration long duration) {
|
|
||||||
this.size = size;
|
|
||||||
this.gammaService = gammaService;
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GammaService getGammaService() {
|
|
||||||
return gammaService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDuration() {
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample annotation.
|
|
||||||
*/
|
|
||||||
@Target({ElementType.PARAMETER, ElementType.FIELD})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface Duration {
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample - field injection, including custom annotations.
|
|
||||||
*/
|
|
||||||
public class FieldInjectionWithAnnotations {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private BetaManager betaManager;
|
|
||||||
@Inject
|
|
||||||
@Size
|
|
||||||
private int size;
|
|
||||||
@Duration
|
|
||||||
@Inject
|
|
||||||
private long duration;
|
|
||||||
@Inject
|
|
||||||
protected ClassWithAnnotations classWithAnnotations;
|
|
||||||
|
|
||||||
FieldInjectionWithAnnotations() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public BetaManager getBetaManager() {
|
|
||||||
return betaManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDuration() {
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassWithAnnotations getClassWithAnnotations() {
|
|
||||||
return classWithAnnotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.Reloadable;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample - class dependent on alpha service.
|
|
||||||
*/
|
|
||||||
public class GammaService implements Reloadable {
|
|
||||||
|
|
||||||
private AlphaService alphaService;
|
|
||||||
private boolean wasReloaded;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public GammaService(AlphaService alphaService) {
|
|
||||||
this.alphaService = alphaService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AlphaService getAlphaService() {
|
|
||||||
return alphaService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reload() {
|
|
||||||
wasReloaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getWasReloaded() {
|
|
||||||
return wasReloaded;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample class - tests various situations for the instantiation fallback.
|
|
||||||
*/
|
|
||||||
public abstract class InstantiationFallbackClasses {
|
|
||||||
|
|
||||||
public static final class FallbackClass {
|
|
||||||
// No @Inject annotations, public no-args constructor
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class HasFallbackDependency {
|
|
||||||
@Inject
|
|
||||||
private FallbackClass fallbackClass;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private GammaService gammaService;
|
|
||||||
|
|
||||||
public GammaService getGammaService() {
|
|
||||||
return gammaService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FallbackClass getFallbackDependency() {
|
|
||||||
return fallbackClass;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class InvalidFallbackClass {
|
|
||||||
private InvalidFallbackClass() {
|
|
||||||
// no-args constructor must be public for fallback instantiation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class InvalidInjectOnMethodClass {
|
|
||||||
// We don't support method injection but this should still be detected and an exception returned
|
|
||||||
// Only use instantiation fallback if we're sure there isn't some sort of misconfiguration
|
|
||||||
@Inject
|
|
||||||
public void setGammaService(GammaService gammaService) {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class with @PostConstruct method should never be instantiated by instantiation fallback
|
|
||||||
public static final class ClassWithPostConstruct {
|
|
||||||
@PostConstruct
|
|
||||||
public void postConstructMethod() {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample - invalid class, since Integer parameter type is outside of the allowed package and not annotated.
|
|
||||||
*/
|
|
||||||
public class InvalidClass {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public InvalidClass(AlphaService alphaService, Integer i) {
|
|
||||||
throw new IllegalStateException("Should never be called");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class with invalid @PostConstruct method.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public abstract class InvalidPostConstruct {
|
|
||||||
|
|
||||||
public static final class WithParams {
|
|
||||||
@Inject
|
|
||||||
private AlphaService alphaService;
|
|
||||||
@Inject
|
|
||||||
private ProvidedClass providedClass;
|
|
||||||
|
|
||||||
WithParams() { }
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void invalidPostConstr(BetaManager betaManager) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Static {
|
|
||||||
@Inject
|
|
||||||
Static(BetaManager betaManager) {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public static void invalidMethod() {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class ThrowsException {
|
|
||||||
@Inject
|
|
||||||
private ProvidedClass providedClass;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void throwingPostConstruct() {
|
|
||||||
throw new IllegalStateException("Exception in post construct");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class NotVoidReturnType {
|
|
||||||
@Inject
|
|
||||||
private ProvidedClass providedClass;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public int returnsInt() {
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class MultiplePostConstructs {
|
|
||||||
@Inject
|
|
||||||
private ProvidedClass providedClass;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void postConstruct1() {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
@PostConstruct
|
|
||||||
public void postConstruct2() {
|
|
||||||
// --
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample class - attempted field injection on a static member.
|
|
||||||
*/
|
|
||||||
public class InvalidStaticFieldInjection {
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Inject
|
|
||||||
private ProvidedClass providedClass;
|
|
||||||
@Inject
|
|
||||||
protected static AlphaService alphaService;
|
|
||||||
|
|
||||||
InvalidStaticFieldInjection() { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.SettingsDependent;
|
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample class for testing the execution of @PostConstruct methods.
|
|
||||||
*/
|
|
||||||
public class PostConstructTestClass implements SettingsDependent {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Size
|
|
||||||
private int size;
|
|
||||||
@Inject
|
|
||||||
private BetaManager betaManager;
|
|
||||||
private boolean wasPostConstructCalled = false;
|
|
||||||
private boolean wasReloaded = false;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void postConstructMethod() {
|
|
||||||
wasPostConstructCalled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean wasPostConstructCalled() {
|
|
||||||
return wasPostConstructCalled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BetaManager getBetaManager() {
|
|
||||||
return betaManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reload(NewSetting settings) {
|
|
||||||
if (settings != null) {
|
|
||||||
wasReloaded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getWasReloaded() {
|
|
||||||
return wasReloaded;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.Reloadable;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample - class that is always provided to the initializer beforehand.
|
|
||||||
*/
|
|
||||||
public class ProvidedClass implements Reloadable {
|
|
||||||
|
|
||||||
private boolean wasReloaded = false;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public ProvidedClass() {
|
|
||||||
throw new IllegalStateException("Should never be called (tests always provide this class)");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProvidedClass(String manualConstructor) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reload() {
|
|
||||||
wasReloaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getWasReloaded() {
|
|
||||||
return wasReloaded;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package fr.xephi.authme.initialization.samples;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample annotation.
|
|
||||||
*/
|
|
||||||
@Target({ElementType.PARAMETER, ElementType.FIELD})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface Size {
|
|
||||||
}
|
|
@ -1,11 +1,11 @@
|
|||||||
package fr.xephi.authme.listener;
|
package fr.xephi.authme.listener;
|
||||||
|
|
||||||
|
import ch.jalu.injector.testing.BeforeInjecting;
|
||||||
|
import ch.jalu.injector.testing.DelayedInjectionRunner;
|
||||||
|
import ch.jalu.injector.testing.InjectDelayed;
|
||||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.hooks.PluginHooks;
|
import fr.xephi.authme.hooks.PluginHooks;
|
||||||
import fr.xephi.authme.runner.BeforeInjecting;
|
|
||||||
import fr.xephi.authme.runner.InjectDelayed;
|
|
||||||
import fr.xephi.authme.runner.DelayedInjectionRunner;
|
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
import fr.xephi.authme.settings.NewSetting;
|
||||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
package fr.xephi.authme.runner;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks methods to run before {@link InjectDelayed} fields are instantiated.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface BeforeInjecting {
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
package fr.xephi.authme.runner;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.Injection;
|
|
||||||
import fr.xephi.authme.initialization.InjectionHelper;
|
|
||||||
import org.junit.runner.notification.RunNotifier;
|
|
||||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
|
||||||
import org.junit.runners.model.FrameworkField;
|
|
||||||
import org.junit.runners.model.FrameworkMethod;
|
|
||||||
import org.junit.runners.model.InitializationError;
|
|
||||||
import org.junit.runners.model.Statement;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom JUnit runner which adds support for {@link InjectDelayed} and {@link BeforeInjecting}.
|
|
||||||
* This runner also initializes fields with Mockito's {@link Mock}, {@link org.mockito.Spy} and
|
|
||||||
* {@link org.mockito.InjectMocks}.
|
|
||||||
* <p>
|
|
||||||
* Mockito's {@link Mock} and {@link org.mockito.InjectMocks} are initialized <i>before</i>
|
|
||||||
* {@link org.junit.Before} methods are run. This leaves no possibility to initialize some mock
|
|
||||||
* behavior before {@link org.mockito.InjectMocks} fields get instantiated.
|
|
||||||
* <p>
|
|
||||||
* The runner fills this gap by introducing {@link BeforeInjecting}. At the time these methods
|
|
||||||
* are run Mockito's annotation will have taken effect but not {@link InjectDelayed}. Fields with
|
|
||||||
* this annotation are initialized after {@link BeforeInjecting} methods have been run.
|
|
||||||
* <p>
|
|
||||||
* Additionally, after a field annotated with {@link InjectDelayed} has been initialized, its
|
|
||||||
* {@link javax.annotation.PostConstruct} method will be invoked, if available.
|
|
||||||
* <p>
|
|
||||||
* Important: It is required to declare all dependencies of classes annotated with
|
|
||||||
* {@link InjectDelayed} as {@link Mock} fields. If a dependency is missing, an exception
|
|
||||||
* will be thrown.
|
|
||||||
*/
|
|
||||||
public class DelayedInjectionRunner extends BlockJUnit4ClassRunner {
|
|
||||||
|
|
||||||
public DelayedInjectionRunner(Class<?> clazz) throws InitializationError {
|
|
||||||
super(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Statement withBefores(FrameworkMethod method, Object target, Statement statement) {
|
|
||||||
// Initialize all Mockito annotations
|
|
||||||
MockitoAnnotations.initMocks(target);
|
|
||||||
|
|
||||||
// Call chain normally: let parent handle @Before methods.
|
|
||||||
// Note that the chain of statements will be run from the end to the start,
|
|
||||||
// so @Before will be run AFTER our custom statements below
|
|
||||||
statement = super.withBefores(method, target, statement);
|
|
||||||
|
|
||||||
// Add support for @BeforeInjecting and @InjectDelayed (again, reverse order)
|
|
||||||
statement = withDelayedInjects(target, statement);
|
|
||||||
return withBeforeInjectings(target, statement);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(final RunNotifier notifier) {
|
|
||||||
// add listener that validates framework usage at the end of each test
|
|
||||||
notifier.addListener(new DelayedInjectionRunnerValidator(notifier, getTestClass()));
|
|
||||||
super.run(notifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds a Statement to the chain if @BeforeInjecting methods are present. */
|
|
||||||
private Statement withBeforeInjectings(Object target, Statement statement) {
|
|
||||||
List<FrameworkMethod> beforeInjectings = getTestClass().getAnnotatedMethods(BeforeInjecting.class);
|
|
||||||
return beforeInjectings.isEmpty()
|
|
||||||
? statement
|
|
||||||
: new RunBeforeInjectings(statement, beforeInjectings, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adds a Statement to the chain if @InjectDelayed methods are present.
|
|
||||||
* If fields have been found, the injection for the type is resolved and stored with the necessary dependencies.
|
|
||||||
*/
|
|
||||||
private Statement withDelayedInjects(Object target, Statement statement) {
|
|
||||||
List<FrameworkField> delayedFields = getTestClass().getAnnotatedFields(InjectDelayed.class);
|
|
||||||
if (delayedFields.isEmpty()) {
|
|
||||||
return statement;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PendingInjection> pendingInjections = new ArrayList<>(delayedFields.size());
|
|
||||||
for (FrameworkField field : delayedFields) {
|
|
||||||
pendingInjections.add(new PendingInjection(field.getField(), getInjection(field)));
|
|
||||||
}
|
|
||||||
InjectionResolver injectionResolver = new InjectionResolver(getTestClass(), target);
|
|
||||||
return new RunDelayedInjects(statement, pendingInjections, target, injectionResolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the injection method for the given field's type and ensures an injection method has been found.
|
|
||||||
*
|
|
||||||
* @param field the field to get the injection for
|
|
||||||
* @return the injection
|
|
||||||
*/
|
|
||||||
private static Injection<?> getInjection(FrameworkField field) {
|
|
||||||
final Injection<?> injection = InjectionHelper.getInjection(field.getType());
|
|
||||||
if (injection == null) {
|
|
||||||
throw new IllegalStateException("No injection method available for field '" + field.getName() + "'");
|
|
||||||
}
|
|
||||||
return injection;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package fr.xephi.authme.runner;
|
|
||||||
|
|
||||||
import org.junit.runner.Description;
|
|
||||||
import org.junit.runner.notification.Failure;
|
|
||||||
import org.junit.runner.notification.RunListener;
|
|
||||||
import org.junit.runner.notification.RunNotifier;
|
|
||||||
import org.junit.runners.model.TestClass;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates that {@link DelayedInjectionRunner} is used as intended.
|
|
||||||
*/
|
|
||||||
class DelayedInjectionRunnerValidator extends RunListener {
|
|
||||||
|
|
||||||
private final RunNotifier notifier;
|
|
||||||
private final TestClass testClass;
|
|
||||||
|
|
||||||
public DelayedInjectionRunnerValidator(RunNotifier notifier, TestClass testClass) {
|
|
||||||
this.notifier = notifier;
|
|
||||||
this.testClass = testClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void testFinished(Description description) throws Exception {
|
|
||||||
try {
|
|
||||||
Mockito.validateMockitoUsage();
|
|
||||||
if (!testClass.getAnnotatedFields(InjectMocks.class).isEmpty()) {
|
|
||||||
throw new IllegalStateException("Do not use @InjectMocks with the DelayedInjectionRunner:" +
|
|
||||||
" use @InjectDelayed or change runner");
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
notifier.fireTestFailure(new Failure(description, t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package fr.xephi.authme.runner;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks fields to instantiate with mocks after {@link BeforeInjecting} methods.
|
|
||||||
*
|
|
||||||
* @see DelayedInjectionRunner
|
|
||||||
*/
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface InjectDelayed {
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
package fr.xephi.authme.runner;
|
|
||||||
|
|
||||||
import fr.xephi.authme.ReflectionTestUtils;
|
|
||||||
import fr.xephi.authme.initialization.Injection;
|
|
||||||
import fr.xephi.authme.initialization.InjectionHelper;
|
|
||||||
import org.junit.runners.model.FrameworkField;
|
|
||||||
import org.junit.runners.model.TestClass;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the dependencies of an injection based on the provided {@link TestClass} and {@link #target target}.
|
|
||||||
*/
|
|
||||||
class InjectionResolver {
|
|
||||||
|
|
||||||
private final TestClass testClass;
|
|
||||||
private final Object target;
|
|
||||||
private final Map<Class<?>, Object> mocksByType;
|
|
||||||
|
|
||||||
public InjectionResolver(TestClass testClass, Object target) {
|
|
||||||
this.testClass = testClass;
|
|
||||||
this.target = target;
|
|
||||||
this.mocksByType = gatherAvailableMocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object instantiate(Injection<?> injection) {
|
|
||||||
Object[] dependencies = resolveDependencies(injection);
|
|
||||||
Object object = injection.instantiateWith(dependencies);
|
|
||||||
executePostConstructMethod(object);
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of all objects for the given list of dependencies, retrieved from the given
|
|
||||||
* target's {@link Mock} fields.
|
|
||||||
*
|
|
||||||
* @param injection the injection whose dependencies to gather
|
|
||||||
* @return the resolved dependencies
|
|
||||||
*/
|
|
||||||
private Object[] resolveDependencies(Injection<?> injection) {
|
|
||||||
final Class<?>[] dependencies = injection.getDependencies();
|
|
||||||
final Class<?>[] annotations = injection.getDependencyAnnotations();
|
|
||||||
Object[] resolvedValues = new Object[dependencies.length];
|
|
||||||
for (int i = 0; i < dependencies.length; ++i) {
|
|
||||||
Object dependency = (annotations[i] == null)
|
|
||||||
? resolveDependency(dependencies[i])
|
|
||||||
: resolveAnnotation(annotations[i]);
|
|
||||||
resolvedValues[i] = dependency;
|
|
||||||
}
|
|
||||||
return resolvedValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object resolveDependency(Class<?> clazz) {
|
|
||||||
Object o = mocksByType.get(clazz);
|
|
||||||
if (o == null) {
|
|
||||||
throw new IllegalStateException("No mock found for '" + clazz + "'. "
|
|
||||||
+ "All dependencies of @InjectDelayed must be provided as @Mock fields");
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object resolveAnnotation(Class<?> clazz) {
|
|
||||||
Class<? extends Annotation> annotation = (Class<? extends Annotation>) clazz;
|
|
||||||
List<FrameworkField> matches = testClass.getAnnotatedFields(annotation);
|
|
||||||
if (matches.isEmpty()) {
|
|
||||||
throw new IllegalStateException("No field found with @" + annotation.getSimpleName() + " in test class,"
|
|
||||||
+ "but a dependency in an @InjectDelayed field is using it");
|
|
||||||
} else if (matches.size() > 1) {
|
|
||||||
throw new IllegalStateException("You cannot have multiple fields with @" + annotation.getSimpleName());
|
|
||||||
}
|
|
||||||
return ReflectionTestUtils.getFieldValue(matches.get(0).getField(), target);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the class' PostConstruct method if available. Validates that all rules for
|
|
||||||
* {@link javax.annotation.PostConstruct} are met.
|
|
||||||
*
|
|
||||||
* @param object the object whose PostConstruct method should be run, if available
|
|
||||||
* @see InjectionHelper#getAndValidatePostConstructMethod
|
|
||||||
*/
|
|
||||||
private static void executePostConstructMethod(Object object) {
|
|
||||||
Method postConstructMethod = InjectionHelper.getAndValidatePostConstructMethod(object.getClass());
|
|
||||||
if (postConstructMethod != null) {
|
|
||||||
ReflectionTestUtils.invokeMethod(postConstructMethod, object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Class<?>, Object> gatherAvailableMocks() {
|
|
||||||
List<FrameworkField> availableMocks = testClass.getAnnotatedFields(Mock.class);
|
|
||||||
Map<Class<?>, Object> mocksByType = new HashMap<>();
|
|
||||||
for (FrameworkField frameworkField : availableMocks) {
|
|
||||||
Field field = frameworkField.getField();
|
|
||||||
Object fieldValue = ReflectionTestUtils.getFieldValue(field, target);
|
|
||||||
mocksByType.put(field.getType(), fieldValue);
|
|
||||||
}
|
|
||||||
return mocksByType;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package fr.xephi.authme.runner;
|
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.Injection;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains an injection and the field it's for.
|
|
||||||
*/
|
|
||||||
class PendingInjection {
|
|
||||||
|
|
||||||
private final Field field;
|
|
||||||
private final Injection<?> injection;
|
|
||||||
|
|
||||||
public PendingInjection(Field field, Injection<?> injection) {
|
|
||||||
this.field = field;
|
|
||||||
this.injection = injection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the injection to perform.
|
|
||||||
*
|
|
||||||
* @return the injection
|
|
||||||
*/
|
|
||||||
public Injection<?> getInjection() {
|
|
||||||
return injection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the field the constructed object should be assigned to.
|
|
||||||
*
|
|
||||||
* @return the field in the test class
|
|
||||||
*/
|
|
||||||
public Field getField() {
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package fr.xephi.authme.runner;
|
|
||||||
|
|
||||||
import fr.xephi.authme.ReflectionTestUtils;
|
|
||||||
import org.junit.runners.model.FrameworkMethod;
|
|
||||||
import org.junit.runners.model.Statement;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Statement for running {@link BeforeInjecting} methods. Such methods are run
|
|
||||||
* after Mockito's @Mock, @Spy and @InjectMocks have taken effect,
|
|
||||||
* but before {@link InjectDelayed} fields are handled.
|
|
||||||
*/
|
|
||||||
class RunBeforeInjectings extends Statement {
|
|
||||||
|
|
||||||
private final Statement next;
|
|
||||||
private final List<FrameworkMethod> beforeInjectings;
|
|
||||||
private final Object target;
|
|
||||||
|
|
||||||
public RunBeforeInjectings(Statement next, List<FrameworkMethod> beforeInjectings, Object target) {
|
|
||||||
this.next = next;
|
|
||||||
this.beforeInjectings = beforeInjectings;
|
|
||||||
this.target = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void evaluate() throws Throwable {
|
|
||||||
for (FrameworkMethod method : beforeInjectings) {
|
|
||||||
ReflectionTestUtils.invokeMethod(method.getMethod(), target);
|
|
||||||
}
|
|
||||||
next.evaluate();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package fr.xephi.authme.runner;
|
|
||||||
|
|
||||||
import fr.xephi.authme.ReflectionTestUtils;
|
|
||||||
import org.junit.runners.model.Statement;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Statement for initializing {@link InjectDelayed} fields. These fields are
|
|
||||||
* constructed after {@link BeforeInjecting} and before JUnit's @Before.
|
|
||||||
*/
|
|
||||||
class RunDelayedInjects extends Statement {
|
|
||||||
|
|
||||||
private final Statement next;
|
|
||||||
private final Object target;
|
|
||||||
private List<PendingInjection> pendingInjections;
|
|
||||||
private InjectionResolver injectionResolver;
|
|
||||||
|
|
||||||
public RunDelayedInjects(Statement next, List<PendingInjection> pendingInjections, Object target,
|
|
||||||
InjectionResolver injectionResolver) {
|
|
||||||
this.next = next;
|
|
||||||
this.pendingInjections = pendingInjections;
|
|
||||||
this.target = target;
|
|
||||||
this.injectionResolver = injectionResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void evaluate() throws Throwable {
|
|
||||||
for (PendingInjection pendingInjection : pendingInjections) {
|
|
||||||
if (ReflectionTestUtils.getFieldValue(pendingInjection.getField(), target) != null) {
|
|
||||||
throw new IllegalStateException("Field with @InjectDelayed must be null on startup");
|
|
||||||
}
|
|
||||||
Object object = injectionResolver.instantiate(pendingInjection.getInjection());
|
|
||||||
ReflectionTestUtils.setField(pendingInjection.getField(), target, object);
|
|
||||||
}
|
|
||||||
this.pendingInjections = null;
|
|
||||||
this.injectionResolver = null;
|
|
||||||
next.evaluate();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
package fr.xephi.authme.security;
|
package fr.xephi.authme.security;
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
import ch.jalu.injector.Injector;
|
||||||
|
import ch.jalu.injector.InjectorBuilder;
|
||||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
import fr.xephi.authme.settings.NewSetting;
|
||||||
@ -24,15 +25,15 @@ import static org.mockito.Mockito.mock;
|
|||||||
*/
|
*/
|
||||||
public class HashAlgorithmIntegrationTest {
|
public class HashAlgorithmIntegrationTest {
|
||||||
|
|
||||||
private static AuthMeServiceInitializer initializer;
|
private static Injector injector;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpConfigAndInjector() {
|
public static void setUpConfigAndInjector() {
|
||||||
NewSetting settings = mock(NewSetting.class);
|
NewSetting settings = mock(NewSetting.class);
|
||||||
given(settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND)).willReturn(8);
|
given(settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND)).willReturn(8);
|
||||||
given(settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH)).willReturn(16);
|
given(settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH)).willReturn(16);
|
||||||
initializer = new AuthMeServiceInitializer();
|
injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create();
|
||||||
initializer.register(NewSetting.class, settings);
|
injector.register(NewSetting.class, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -55,7 +56,7 @@ public class HashAlgorithmIntegrationTest {
|
|||||||
// given / when / then
|
// given / when / then
|
||||||
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
||||||
if (!HashAlgorithm.CUSTOM.equals(algorithm) && !HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
if (!HashAlgorithm.CUSTOM.equals(algorithm) && !HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
||||||
EncryptionMethod method = initializer.newInstance(algorithm.getClazz());
|
EncryptionMethod method = injector.newInstance(algorithm.getClazz());
|
||||||
HashedPassword hashedPassword = method.computeHash("pwd", "name");
|
HashedPassword hashedPassword = method.computeHash("pwd", "name");
|
||||||
assertThat("Salt should not be null if method.hasSeparateSalt(), and vice versa. Method: '"
|
assertThat("Salt should not be null if method.hasSeparateSalt(), and vice versa. Method: '"
|
||||||
+ method + "'", StringUtils.isEmpty(hashedPassword.getSalt()), equalTo(!method.hasSeparateSalt()));
|
+ method + "'", StringUtils.isEmpty(hashedPassword.getSalt()), equalTo(!method.hasSeparateSalt()));
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package fr.xephi.authme.security;
|
package fr.xephi.authme.security;
|
||||||
|
|
||||||
|
import ch.jalu.injector.Injector;
|
||||||
|
import ch.jalu.injector.InjectorBuilder;
|
||||||
import fr.xephi.authme.ReflectionTestUtils;
|
import fr.xephi.authme.ReflectionTestUtils;
|
||||||
import fr.xephi.authme.TestHelper;
|
import fr.xephi.authme.TestHelper;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.events.PasswordEncryptionEvent;
|
import fr.xephi.authme.events.PasswordEncryptionEvent;
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
|
||||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||||
import fr.xephi.authme.security.crypts.JOOMLA;
|
import fr.xephi.authme.security.crypts.JOOMLA;
|
||||||
@ -41,7 +42,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class PasswordSecurityTest {
|
public class PasswordSecurityTest {
|
||||||
|
|
||||||
private AuthMeServiceInitializer initializer;
|
private Injector injector;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private NewSetting settings;
|
private NewSetting settings;
|
||||||
@ -79,10 +80,10 @@ public class PasswordSecurityTest {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}).when(pluginManager).callEvent(any(Event.class));
|
}).when(pluginManager).callEvent(any(Event.class));
|
||||||
initializer = new AuthMeServiceInitializer();
|
injector = new InjectorBuilder().addDefaultHandlers("!! impossible package !!").create();
|
||||||
initializer.register(NewSetting.class, settings);
|
injector.register(NewSetting.class, settings);
|
||||||
initializer.register(DataSource.class, dataSource);
|
injector.register(DataSource.class, dataSource);
|
||||||
initializer.register(PluginManager.class, pluginManager);
|
injector.register(PluginManager.class, pluginManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -97,7 +98,7 @@ public class PasswordSecurityTest {
|
|||||||
given(dataSource.getPassword(playerName)).willReturn(password);
|
given(dataSource.getPassword(playerName)).willReturn(password);
|
||||||
given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(true);
|
given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(true);
|
||||||
initSettings(HashAlgorithm.BCRYPT, false);
|
initSettings(HashAlgorithm.BCRYPT, false);
|
||||||
PasswordSecurity security = initializer.newInstance(PasswordSecurity.class);
|
PasswordSecurity security = injector.newInstance(PasswordSecurity.class);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean result = security.comparePassword(clearTextPass, playerName);
|
boolean result = security.comparePassword(clearTextPass, playerName);
|
||||||
@ -120,7 +121,7 @@ public class PasswordSecurityTest {
|
|||||||
given(dataSource.getPassword(playerName)).willReturn(password);
|
given(dataSource.getPassword(playerName)).willReturn(password);
|
||||||
given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false);
|
given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false);
|
||||||
initSettings(HashAlgorithm.CUSTOM, false);
|
initSettings(HashAlgorithm.CUSTOM, false);
|
||||||
PasswordSecurity security = initializer.newInstance(PasswordSecurity.class);
|
PasswordSecurity security = injector.newInstance(PasswordSecurity.class);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean result = security.comparePassword(clearTextPass, playerName);
|
boolean result = security.comparePassword(clearTextPass, playerName);
|
||||||
@ -140,7 +141,7 @@ public class PasswordSecurityTest {
|
|||||||
|
|
||||||
given(dataSource.getPassword(playerName)).willReturn(null);
|
given(dataSource.getPassword(playerName)).willReturn(null);
|
||||||
initSettings(HashAlgorithm.MD5, false);
|
initSettings(HashAlgorithm.MD5, false);
|
||||||
PasswordSecurity security = initializer.newInstance(PasswordSecurity.class);
|
PasswordSecurity security = injector.newInstance(PasswordSecurity.class);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean result = security.comparePassword(clearTextPass, playerName);
|
boolean result = security.comparePassword(clearTextPass, playerName);
|
||||||
@ -168,7 +169,7 @@ public class PasswordSecurityTest {
|
|||||||
given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false);
|
given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false);
|
||||||
given(method.computeHash(clearTextPass, playerLowerCase)).willReturn(newPassword);
|
given(method.computeHash(clearTextPass, playerLowerCase)).willReturn(newPassword);
|
||||||
initSettings(HashAlgorithm.MD5, true);
|
initSettings(HashAlgorithm.MD5, true);
|
||||||
PasswordSecurity security = initializer.newInstance(PasswordSecurity.class);
|
PasswordSecurity security = injector.newInstance(PasswordSecurity.class);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean result = security.comparePassword(clearTextPass, playerName);
|
boolean result = security.comparePassword(clearTextPass, playerName);
|
||||||
@ -193,7 +194,7 @@ public class PasswordSecurityTest {
|
|||||||
given(dataSource.getPassword(playerName)).willReturn(password);
|
given(dataSource.getPassword(playerName)).willReturn(password);
|
||||||
given(method.comparePassword(clearTextPass, password, playerName)).willReturn(false);
|
given(method.comparePassword(clearTextPass, password, playerName)).willReturn(false);
|
||||||
initSettings(HashAlgorithm.MD5, true);
|
initSettings(HashAlgorithm.MD5, true);
|
||||||
PasswordSecurity security = initializer.newInstance(PasswordSecurity.class);
|
PasswordSecurity security = injector.newInstance(PasswordSecurity.class);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean result = security.comparePassword(clearTextPass, playerName);
|
boolean result = security.comparePassword(clearTextPass, playerName);
|
||||||
@ -212,7 +213,7 @@ public class PasswordSecurityTest {
|
|||||||
HashedPassword hashedPassword = new HashedPassword("$T$est#Hash", "__someSalt__");
|
HashedPassword hashedPassword = new HashedPassword("$T$est#Hash", "__someSalt__");
|
||||||
given(method.computeHash(password, usernameLowerCase)).willReturn(hashedPassword);
|
given(method.computeHash(password, usernameLowerCase)).willReturn(hashedPassword);
|
||||||
initSettings(HashAlgorithm.JOOMLA, true);
|
initSettings(HashAlgorithm.JOOMLA, true);
|
||||||
PasswordSecurity security = initializer.newInstance(PasswordSecurity.class);
|
PasswordSecurity security = injector.newInstance(PasswordSecurity.class);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
HashedPassword result = security.computeHash(password, username);
|
HashedPassword result = security.computeHash(password, username);
|
||||||
@ -235,7 +236,7 @@ public class PasswordSecurityTest {
|
|||||||
given(method.computeHash(password, username)).willReturn(hashedPassword);
|
given(method.computeHash(password, username)).willReturn(hashedPassword);
|
||||||
given(method.hasSeparateSalt()).willReturn(true);
|
given(method.hasSeparateSalt()).willReturn(true);
|
||||||
initSettings(HashAlgorithm.XAUTH, false);
|
initSettings(HashAlgorithm.XAUTH, false);
|
||||||
PasswordSecurity security = initializer.newInstance(PasswordSecurity.class);
|
PasswordSecurity security = injector.newInstance(PasswordSecurity.class);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean result = security.comparePassword(password, hashedPassword, username);
|
boolean result = security.comparePassword(password, hashedPassword, username);
|
||||||
@ -251,7 +252,7 @@ public class PasswordSecurityTest {
|
|||||||
public void shouldReloadSettings() {
|
public void shouldReloadSettings() {
|
||||||
// given
|
// given
|
||||||
initSettings(HashAlgorithm.BCRYPT, false);
|
initSettings(HashAlgorithm.BCRYPT, false);
|
||||||
PasswordSecurity passwordSecurity = initializer.newInstance(PasswordSecurity.class);
|
PasswordSecurity passwordSecurity = injector.newInstance(PasswordSecurity.class);
|
||||||
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.MD5);
|
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.MD5);
|
||||||
given(settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH)).willReturn(true);
|
given(settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH)).willReturn(true);
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package fr.xephi.authme.settings;
|
package fr.xephi.authme.settings;
|
||||||
|
|
||||||
|
import ch.jalu.injector.testing.BeforeInjecting;
|
||||||
|
import ch.jalu.injector.testing.DelayedInjectionRunner;
|
||||||
|
import ch.jalu.injector.testing.InjectDelayed;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import fr.xephi.authme.TestHelper;
|
import fr.xephi.authme.TestHelper;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.hooks.PluginHooks;
|
import fr.xephi.authme.hooks.PluginHooks;
|
||||||
import fr.xephi.authme.initialization.DataFolder;
|
import fr.xephi.authme.initialization.DataFolder;
|
||||||
import fr.xephi.authme.runner.BeforeInjecting;
|
|
||||||
import fr.xephi.authme.runner.DelayedInjectionRunner;
|
|
||||||
import fr.xephi.authme.runner.InjectDelayed;
|
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package fr.xephi.authme.util;
|
package fr.xephi.authme.util;
|
||||||
|
|
||||||
|
import ch.jalu.injector.testing.BeforeInjecting;
|
||||||
|
import ch.jalu.injector.testing.DelayedInjectionRunner;
|
||||||
|
import ch.jalu.injector.testing.InjectDelayed;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.output.MessageKey;
|
import fr.xephi.authme.output.MessageKey;
|
||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||||
import fr.xephi.authme.runner.BeforeInjecting;
|
|
||||||
import fr.xephi.authme.runner.DelayedInjectionRunner;
|
|
||||||
import fr.xephi.authme.runner.InjectDelayed;
|
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
import fr.xephi.authme.settings.NewSetting;
|
||||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
|
@ -141,7 +141,7 @@ public class CheckTestMocks implements AutoToolTask {
|
|||||||
Injection<?> injection = InjectionHelper.getInjection(realClass);
|
Injection<?> injection = InjectionHelper.getInjection(realClass);
|
||||||
return injection == null
|
return injection == null
|
||||||
? Collections.<Class<?>>emptySet()
|
? Collections.<Class<?>>emptySet()
|
||||||
: Sets.newHashSet(injection.getDependencies());
|
: Sets.<Class<?>>newHashSet(injection.getDependencies());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isTestClassWithMocks(Class<?> clazz) {
|
private static boolean isTestClassWithMocks(Class<?> clazz) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package tools.hashmethods;
|
package tools.hashmethods;
|
||||||
|
|
||||||
import fr.xephi.authme.initialization.AuthMeServiceInitializer;
|
import ch.jalu.injector.Injector;
|
||||||
|
import ch.jalu.injector.InjectorBuilder;
|
||||||
import fr.xephi.authme.security.HashAlgorithm;
|
import fr.xephi.authme.security.HashAlgorithm;
|
||||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||||
import fr.xephi.authme.security.crypts.HexSaltedMethod;
|
import fr.xephi.authme.security.crypts.HexSaltedMethod;
|
||||||
@ -33,7 +34,7 @@ public class EncryptionMethodInfoGatherer {
|
|||||||
private final static Set<Class<? extends Annotation>> RELEVANT_ANNOTATIONS =
|
private final static Set<Class<? extends Annotation>> RELEVANT_ANNOTATIONS =
|
||||||
newHashSet(HasSalt.class, Recommendation.class, AsciiRestricted.class);
|
newHashSet(HasSalt.class, Recommendation.class, AsciiRestricted.class);
|
||||||
|
|
||||||
private static AuthMeServiceInitializer initializer = createInitializer();
|
private static Injector injector = createInitializer();
|
||||||
|
|
||||||
private Map<HashAlgorithm, MethodDescription> descriptions;
|
private Map<HashAlgorithm, MethodDescription> descriptions;
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ public class EncryptionMethodInfoGatherer {
|
|||||||
|
|
||||||
private static MethodDescription createDescription(HashAlgorithm algorithm) {
|
private static MethodDescription createDescription(HashAlgorithm algorithm) {
|
||||||
Class<? extends EncryptionMethod> clazz = algorithm.getClazz();
|
Class<? extends EncryptionMethod> clazz = algorithm.getClazz();
|
||||||
EncryptionMethod method = initializer.newInstance(clazz);
|
EncryptionMethod method = injector.newInstance(clazz);
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NullPointerException("Method for '" + algorithm + "' is null");
|
throw new NullPointerException("Method for '" + algorithm + "' is null");
|
||||||
}
|
}
|
||||||
@ -138,7 +139,7 @@ public class EncryptionMethodInfoGatherer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static AuthMeServiceInitializer createInitializer() {
|
private static Injector createInitializer() {
|
||||||
NewSetting settings = mock(NewSetting.class);
|
NewSetting settings = mock(NewSetting.class);
|
||||||
// Return the default value for any property
|
// Return the default value for any property
|
||||||
when(settings.getProperty(any(Property.class))).thenAnswer(new Answer<Object>() {
|
when(settings.getProperty(any(Property.class))).thenAnswer(new Answer<Object>() {
|
||||||
@ -149,11 +150,11 @@ public class EncryptionMethodInfoGatherer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// By not passing any "allowed package" to the constructor, the initializer will throw if it needs to
|
// By passing some bogus "package" to the constructor, the injector will throw if it needs to
|
||||||
// instantiate any dependency other than what we provide.
|
// instantiate any dependency other than what we provide.
|
||||||
AuthMeServiceInitializer initializer = new AuthMeServiceInitializer();
|
Injector injector = new InjectorBuilder().addDefaultHandlers("!!No package!!").create();
|
||||||
initializer.register(NewSetting.class, settings);
|
injector.register(NewSetting.class, settings);
|
||||||
return initializer;
|
return injector;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
6
team.txt
6
team.txt
@ -1,14 +1,16 @@
|
|||||||
AuthMe-Team:
|
AuthMe-Team:
|
||||||
|
|
||||||
Active staff:
|
Active staff:
|
||||||
Xephi (Xephi59) - Leader, Main developer
|
ljacqu - Main Developer
|
||||||
DNx5 - Developer
|
DNx5 - Developer
|
||||||
ljacqu - Developer
|
|
||||||
TimVisee - Developer
|
TimVisee - Developer
|
||||||
games647 - Developer
|
games647 - Developer
|
||||||
Gnat008 - Developer
|
Gnat008 - Developer
|
||||||
Gabriele C. (sgdc3) - Project Manager, Contributor
|
Gabriele C. (sgdc3) - Project Manager, Contributor
|
||||||
|
|
||||||
|
Inactive staff:
|
||||||
|
Xephi (Xephi59) - Original developer
|
||||||
|
|
||||||
Retired staff:
|
Retired staff:
|
||||||
Maxetto - Ticket Manager, IT translator
|
Maxetto - Ticket Manager, IT translator
|
||||||
darkwarriors (d4rkwarriors) - Original AuthMeReloaded Author (Inactive)
|
darkwarriors (d4rkwarriors) - Original AuthMeReloaded Author (Inactive)
|
||||||
|
Loading…
Reference in New Issue
Block a user