diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 812e88e9..b69cd299 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -256,7 +256,7 @@ public class AuthMe extends JavaPlugin { initializer.register(newSettings); initializer.register(messages); initializer.register(DataSource.class, database); - initializer.provide(BaseCommands.class, CommandInitializer.buildCommands()); + initializer.provide(BaseCommands.class, CommandInitializer.buildCommands(initializer)); // Some statically injected things initializer.register(PlayerCache.class, PlayerCache.getInstance()); diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java index 6635545f..14d72f4a 100644 --- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -33,6 +33,7 @@ import fr.xephi.authme.command.executable.login.LoginCommand; import fr.xephi.authme.command.executable.logout.LogoutCommand; import fr.xephi.authme.command.executable.register.RegisterCommand; import fr.xephi.authme.command.executable.unregister.UnregisterCommand; +import fr.xephi.authme.initialization.AuthMeServiceInitializer; import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.PlayerPermission; @@ -53,13 +54,13 @@ public final class CommandInitializer { // Helper class } - public static Set buildCommands() { + public static Set buildCommands(AuthMeServiceInitializer initializer) { // Register the base AuthMe Reloaded command final CommandDescription AUTHME_BASE = CommandDescription.builder() .labels("authme") .description("Main command") .detailedDescription("The main AuthMeReloaded command. The root for all admin commands.") - .executableCommand(new AuthMeCommand()) + .executableCommand(initializer.newInstance(AuthMeCommand.class)) .build(); // Register the register command @@ -71,7 +72,7 @@ public final class CommandInitializer { .withArgument("player", "Player name", false) .withArgument("password", "Password", false) .permissions(OP_ONLY, AdminPermission.REGISTER) - .executableCommand(new RegisterAdminCommand()) + .executableCommand(initializer.newInstance(RegisterAdminCommand.class)) .build(); // Register the unregister command @@ -82,7 +83,7 @@ public final class CommandInitializer { .detailedDescription("Unregister the specified player.") .withArgument("player", "Player name", false) .permissions(OP_ONLY, AdminPermission.UNREGISTER) - .executableCommand(new UnregisterAdminCommand()) + .executableCommand(initializer.newInstance(UnregisterAdminCommand.class)) .build(); // Register the forcelogin command @@ -93,7 +94,7 @@ public final class CommandInitializer { .detailedDescription("Enforce the specified player to login.") .withArgument("player", "Online player name", true) .permissions(OP_ONLY, AdminPermission.FORCE_LOGIN) - .executableCommand(new ForceLoginCommand()) + .executableCommand(initializer.newInstance(ForceLoginCommand.class)) .build(); // Register the changepassword command @@ -105,7 +106,7 @@ public final class CommandInitializer { .withArgument("player", "Player name", false) .withArgument("pwd", "New password", false) .permissions(OP_ONLY, AdminPermission.CHANGE_PASSWORD) - .executableCommand(new ChangePasswordAdminCommand()) + .executableCommand(initializer.newInstance(ChangePasswordAdminCommand.class)) .build(); // Register the last login command @@ -116,7 +117,7 @@ public final class CommandInitializer { .detailedDescription("View the date of the specified players last login.") .withArgument("player", "Player name", true) .permissions(OP_ONLY, AdminPermission.LAST_LOGIN) - .executableCommand(new LastLoginCommand()) + .executableCommand(initializer.newInstance(LastLoginCommand.class)) .build(); // Register the accounts command @@ -127,7 +128,7 @@ public final class CommandInitializer { .detailedDescription("Display all accounts of a player by his player name or IP.") .withArgument("player", "Player name or IP", true) .permissions(OP_ONLY, AdminPermission.ACCOUNTS) - .executableCommand(new AccountsCommand()) + .executableCommand(initializer.newInstance(AccountsCommand.class)) .build(); // Register the getemail command @@ -138,7 +139,7 @@ public final class CommandInitializer { .detailedDescription("Display the email address of the specified player if set.") .withArgument("player", "Player name", true) .permissions(OP_ONLY, AdminPermission.GET_EMAIL) - .executableCommand(new GetEmailCommand()) + .executableCommand(initializer.newInstance(GetEmailCommand.class)) .build(); // Register the setemail command @@ -150,7 +151,7 @@ public final class CommandInitializer { .withArgument("player", "Player name", false) .withArgument("email", "Player email", false) .permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL) - .executableCommand(new SetEmailCommand()) + .executableCommand(initializer.newInstance(SetEmailCommand.class)) .build(); // Register the getip command @@ -161,7 +162,7 @@ public final class CommandInitializer { .detailedDescription("Get the IP address of the specified online player.") .withArgument("player", "Player name", false) .permissions(OP_ONLY, AdminPermission.GET_IP) - .executableCommand(new GetIpCommand()) + .executableCommand(initializer.newInstance(GetIpCommand.class)) .build(); // Register the spawn command @@ -171,7 +172,7 @@ public final class CommandInitializer { .description("Teleport to spawn") .detailedDescription("Teleport to the spawn.") .permissions(OP_ONLY, AdminPermission.SPAWN) - .executableCommand(new SpawnCommand()) + .executableCommand(initializer.newInstance(SpawnCommand.class)) .build(); // Register the setspawn command @@ -181,7 +182,7 @@ public final class CommandInitializer { .description("Change the spawn") .detailedDescription("Change the player's spawn to your current position.") .permissions(OP_ONLY, AdminPermission.SET_SPAWN) - .executableCommand(new SetSpawnCommand()) + .executableCommand(initializer.newInstance(SetSpawnCommand.class)) .build(); // Register the firstspawn command @@ -191,7 +192,7 @@ public final class CommandInitializer { .description("Teleport to first spawn") .detailedDescription("Teleport to the first spawn.") .permissions(OP_ONLY, AdminPermission.FIRST_SPAWN) - .executableCommand(new FirstSpawnCommand()) + .executableCommand(initializer.newInstance(FirstSpawnCommand.class)) .build(); // Register the setfirstspawn command @@ -201,7 +202,7 @@ public final class CommandInitializer { .description("Change the first spawn") .detailedDescription("Change the first player's spawn to your current position.") .permissions(OP_ONLY, AdminPermission.SET_FIRST_SPAWN) - .executableCommand(new SetFirstSpawnCommand()) + .executableCommand(initializer.newInstance(SetFirstSpawnCommand.class)) .build(); // Register the purge command @@ -212,7 +213,7 @@ public final class CommandInitializer { .detailedDescription("Purge old AuthMeReloaded data longer than the specified amount of days ago.") .withArgument("days", "Number of days", false) .permissions(OP_ONLY, AdminPermission.PURGE) - .executableCommand(new PurgeCommand()) + .executableCommand(initializer.newInstance(PurgeCommand.class)) .build(); // Register the purgelastposition command @@ -224,7 +225,7 @@ public final class CommandInitializer { .detailedDescription("Purge the last know position of the specified player or all of them.") .withArgument("player/*", "Player name or * for all players", false) .permissions(OP_ONLY, AdminPermission.PURGE_LAST_POSITION) - .executableCommand(new PurgeLastPositionCommand()) + .executableCommand(initializer.newInstance(PurgeLastPositionCommand.class)) .build(); // Register the purgebannedplayers command @@ -234,7 +235,7 @@ public final class CommandInitializer { .description("Purge banned players data") .detailedDescription("Purge all AuthMeReloaded data for banned players.") .permissions(OP_ONLY, AdminPermission.PURGE_BANNED_PLAYERS) - .executableCommand(new PurgeBannedPlayersCommand()) + .executableCommand(initializer.newInstance(PurgeBannedPlayersCommand.class)) .build(); // Register the switchantibot command @@ -245,7 +246,7 @@ public final class CommandInitializer { .detailedDescription("Switch or toggle the AntiBot mode to the specified state.") .withArgument("mode", "ON / OFF", true) .permissions(OP_ONLY, AdminPermission.SWITCH_ANTIBOT) - .executableCommand(new SwitchAntiBotCommand()) + .executableCommand(initializer.newInstance(SwitchAntiBotCommand.class)) .build(); // Register the reload command @@ -255,7 +256,7 @@ public final class CommandInitializer { .description("Reload plugin") .detailedDescription("Reload the AuthMeReloaded plugin.") .permissions(OP_ONLY, AdminPermission.RELOAD) - .executableCommand(new ReloadCommand()) + .executableCommand(initializer.newInstance(ReloadCommand.class)) .build(); // Register the version command @@ -265,7 +266,7 @@ public final class CommandInitializer { .description("Version info") .detailedDescription("Show detailed information about the installed AuthMeReloaded version, the " + "developers, contributors, and license.") - .executableCommand(new VersionCommand()) + .executableCommand(initializer.newInstance(VersionCommand.class)) .build(); CommandDescription.builder() @@ -276,7 +277,7 @@ public final class CommandInitializer { .withArgument("job", "Conversion job: xauth / crazylogin / rakamak / " + "royalauth / vauth / sqlitetosql", false) .permissions(OP_ONLY, AdminPermission.CONVERTER) - .executableCommand(new ConverterCommand()) + .executableCommand(initializer.newInstance(ConverterCommand.class)) .build(); // Register the base login command @@ -287,7 +288,7 @@ public final class CommandInitializer { .detailedDescription("Command to log in using AuthMeReloaded.") .withArgument("password", "Login password", false) .permissions(ALLOWED, PlayerPermission.LOGIN) - .executableCommand(new LoginCommand()) + .executableCommand(initializer.newInstance(LoginCommand.class)) .build(); // Register the base logout command @@ -297,7 +298,7 @@ public final class CommandInitializer { .description("Logout command") .detailedDescription("Command to logout using AuthMeReloaded.") .permissions(ALLOWED, PlayerPermission.LOGOUT) - .executableCommand(new LogoutCommand()) + .executableCommand(initializer.newInstance(LogoutCommand.class)) .build(); // Register the base register command @@ -309,7 +310,7 @@ public final class CommandInitializer { .withArgument("password", "Password", true) .withArgument("verifyPassword", "Verify password", true) .permissions(ALLOWED, PlayerPermission.REGISTER) - .executableCommand(new RegisterCommand()) + .executableCommand(initializer.newInstance(RegisterCommand.class)) .build(); // Register the base unregister command @@ -320,7 +321,7 @@ public final class CommandInitializer { .detailedDescription("Command to unregister using AuthMeReloaded.") .withArgument("password", "Password", false) .permissions(ALLOWED, PlayerPermission.UNREGISTER) - .executableCommand(new UnregisterCommand()) + .executableCommand(initializer.newInstance(UnregisterCommand.class)) .build(); // Register the base changepassword command @@ -332,7 +333,7 @@ public final class CommandInitializer { .withArgument("oldPassword", "Old Password", false) .withArgument("newPassword", "New Password.", false) .permissions(ALLOWED, PlayerPermission.CHANGE_PASSWORD) - .executableCommand(new ChangePasswordCommand()) + .executableCommand(initializer.newInstance(ChangePasswordCommand.class)) .build(); // Register the base Email command @@ -341,7 +342,7 @@ public final class CommandInitializer { .labels("email", "mail") .description("Email command") .detailedDescription("The AuthMeReloaded Email command base.") - .executableCommand(new EmailBaseCommand()) + .executableCommand(initializer.newInstance(EmailBaseCommand.class)) .build(); // Register the add command @@ -353,7 +354,7 @@ public final class CommandInitializer { .withArgument("email", "Email address", false) .withArgument("verifyEmail", "Email address verification", false) .permissions(ALLOWED, PlayerPermission.ADD_EMAIL) - .executableCommand(new AddEmailCommand()) + .executableCommand(initializer.newInstance(AddEmailCommand.class)) .build(); // Register the change command @@ -365,7 +366,7 @@ public final class CommandInitializer { .withArgument("oldEmail", "Old email address", false) .withArgument("newEmail", "New email address", false) .permissions(ALLOWED, PlayerPermission.CHANGE_EMAIL) - .executableCommand(new ChangeEmailCommand()) + .executableCommand(initializer.newInstance(ChangeEmailCommand.class)) .build(); // Register the recover command @@ -377,7 +378,7 @@ public final class CommandInitializer { "a new password.") .withArgument("email", "Email address", false) .permissions(ALLOWED, PlayerPermission.RECOVER_EMAIL) - .executableCommand(new RecoverEmailCommand()) + .executableCommand(initializer.newInstance(RecoverEmailCommand.class)) .build(); // Register the base captcha command @@ -388,7 +389,7 @@ public final class CommandInitializer { .detailedDescription("Captcha command for AuthMeReloaded.") .withArgument("captcha", "The Captcha", false) .permissions(ALLOWED, PlayerPermission.CAPTCHA) - .executableCommand(new CaptchaCommand()) + .executableCommand(initializer.newInstance(CaptchaCommand.class)) .build(); Set baseCommands = ImmutableSet.of( @@ -401,7 +402,7 @@ public final class CommandInitializer { EMAIL_BASE, CAPTCHA_BASE); - setHelpOnAllBases(baseCommands); + setHelpOnAllBases(baseCommands, initializer); return baseCommands; } @@ -409,9 +410,11 @@ public final class CommandInitializer { * Set the help command on all base commands, e.g. to register /authme help or /register help. * * @param commands The list of base commands to register a help child command on + * @param initializer The service initializer */ - private static void setHelpOnAllBases(Collection commands) { - final HelpCommand helpCommandExecutable = new HelpCommand(); + private static void setHelpOnAllBases(Collection commands, + AuthMeServiceInitializer initializer) { + final HelpCommand helpCommandExecutable = initializer.newInstance(HelpCommand.class); final List helpCommandLabels = Arrays.asList("help", "hlp", "h", "sos", "?"); for (CommandDescription base : commands) { diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java index d3698cfd..ad5bf9b2 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java @@ -3,10 +3,13 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.util.StringUtils; import org.bukkit.command.CommandSender; +import javax.inject.Inject; import java.util.List; /** @@ -14,6 +17,11 @@ import java.util.List; */ public class AccountsCommand implements ExecutableCommand { + @Inject + private DataSource dataSource; + @Inject + private Messages messages; + @Override public void executeCommand(final CommandSender sender, List arguments, final CommandService commandService) { @@ -24,15 +32,15 @@ public class AccountsCommand implements ExecutableCommand { commandService.runTaskAsynchronously(new Runnable() { @Override public void run() { - PlayerAuth auth = commandService.getDataSource().getAuth(playerName.toLowerCase()); + PlayerAuth auth = dataSource.getAuth(playerName.toLowerCase()); if (auth == null) { - commandService.send(sender, MessageKey.UNKNOWN_USER); + messages.send(sender, MessageKey.UNKNOWN_USER); return; } - List accountList = commandService.getDataSource().getAllAuthsByIp(auth.getIp()); + List accountList = dataSource.getAllAuthsByIp(auth.getIp()); if (accountList.isEmpty()) { - commandService.send(sender, MessageKey.USER_NOT_REGISTERED); + messages.send(sender, MessageKey.USER_NOT_REGISTERED); } else if (accountList.size() == 1) { sender.sendMessage("[AuthMe] " + playerName + " is a single account player"); } else { @@ -44,7 +52,7 @@ public class AccountsCommand implements ExecutableCommand { commandService.runTaskAsynchronously(new Runnable() { @Override public void run() { - List accountList = commandService.getDataSource().getAllAuthsByIp(playerName); + List accountList = dataSource.getAllAuthsByIp(playerName); if (accountList.isEmpty()) { sender.sendMessage("[AuthMe] This IP does not exist in the database."); } else if (accountList.size() == 1) { diff --git a/src/main/java/fr/xephi/authme/initialization/AuthMeServiceInitializer.java b/src/main/java/fr/xephi/authme/initialization/AuthMeServiceInitializer.java index b751b32e..e5dddd04 100644 --- a/src/main/java/fr/xephi/authme/initialization/AuthMeServiceInitializer.java +++ b/src/main/java/fr/xephi/authme/initialization/AuthMeServiceInitializer.java @@ -97,6 +97,18 @@ public class AuthMeServiceInitializer { objects.put(annotation, value); } + /** + * Creates a new instance of the given class and does not keep track of it afterwards, + * unlike {@link #get(Class)} (singleton scope). + * + * @param clazz the class to instantiate + * @param the class' type + * @return new instance of class T + */ + public T newInstance(Class clazz) { + return instantiate(clazz, new HashSet>()); + } + /** * Returns an instance of the given class or the value associated with an annotation, * by retrieving it or by instantiating it if not yet present. @@ -120,7 +132,6 @@ public class AuthMeServiceInitializer { traversedClasses = new HashSet<>(traversedClasses); traversedClasses.add(clazz); - System.out.println(Strings.repeat(" ", traversedClasses.size() * 2) + "- Instantiating " + clazz); return instantiate(clazz, traversedClasses); } diff --git a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java index 6e5418d5..7c62377f 100644 --- a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java @@ -1,10 +1,13 @@ package fr.xephi.authme.command; +import fr.xephi.authme.initialization.AuthMeServiceInitializer; import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.util.StringUtils; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Collection; @@ -21,6 +24,9 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Test for {@link CommandInitializer} to guarantee the integrity of the defined commands. @@ -37,7 +43,16 @@ public class CommandInitializerTest { @BeforeClass public static void initializeCommandManager() { - commands = CommandInitializer.buildCommands(); + AuthMeServiceInitializer initializer = mock(AuthMeServiceInitializer.class); + when(initializer.newInstance(any(Class.class))).thenAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) { + Class clazz = (Class) invocation.getArguments()[0]; + return mock(clazz); + } + }); + + commands = CommandInitializer.buildCommands(initializer); } @Test diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java index 5a837280..95124658 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java @@ -4,10 +4,14 @@ import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import org.bukkit.command.CommandSender; -import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; import java.util.Arrays; import java.util.Collections; @@ -22,26 +26,23 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; /** * Test for {@link AccountsCommand}. */ +@RunWith(MockitoJUnitRunner.class) public class AccountsCommandTest { + @InjectMocks private AccountsCommand command; + @Mock private CommandSender sender; + @Mock private CommandService service; + @Mock private DataSource dataSource; - - @Before - public void setUpMocks() { - command = new AccountsCommand(); - sender = mock(CommandSender.class); - dataSource = mock(DataSource.class); - service = mock(CommandService.class); - when(service.getDataSource()).thenReturn(dataSource); - } + @Mock + private Messages messages; @Test public void shouldGetAccountsOfCurrentUser() { @@ -72,7 +73,7 @@ public class AccountsCommandTest { runInnerRunnable(service); // then - verify(service).send(sender, MessageKey.UNKNOWN_USER); + verify(messages).send(sender, MessageKey.UNKNOWN_USER); verify(sender, never()).sendMessage(anyString()); } @@ -88,7 +89,7 @@ public class AccountsCommandTest { runInnerRunnable(service); // then - verify(service).send(sender, MessageKey.USER_NOT_REGISTERED); + verify(messages).send(sender, MessageKey.USER_NOT_REGISTERED); verify(sender, never()).sendMessage(anyString()); } diff --git a/src/tools/commands/CommandPageCreater.java b/src/tools/commands/CommandPageCreater.java index 8d92dbfb..3369b906 100644 --- a/src/tools/commands/CommandPageCreater.java +++ b/src/tools/commands/CommandPageCreater.java @@ -2,7 +2,6 @@ package commands; import fr.xephi.authme.command.CommandArgumentDescription; import fr.xephi.authme.command.CommandDescription; -import fr.xephi.authme.command.CommandInitializer; import fr.xephi.authme.command.CommandPermissions; import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.permission.PermissionNode; @@ -13,6 +12,7 @@ import utils.ToolTask; import utils.ToolsConstants; import java.util.Collection; +import java.util.HashSet; import java.util.Scanner; import java.util.Set; @@ -27,7 +27,8 @@ public class CommandPageCreater implements ToolTask { @Override public void execute(Scanner scanner) { - final Set baseCommands = CommandInitializer.buildCommands(); + // TODO ljacqu 20160427: Fix initialization of commands + final Set baseCommands = new HashSet<>();//CommandInitializer.buildCommands(); NestedTagValue commandTags = new NestedTagValue(); addCommandsInfo(commandTags, baseCommands);