From d78b7cc4af29406110f8e0e52a9fc369da776eaa Mon Sep 17 00:00:00 2001 From: ljacqu Date: Fri, 7 Oct 2016 20:12:18 +0200 Subject: [PATCH] #293 Create class for handling message file initialization - Work in progress; more logic can be extracted --- .../command/help/HelpMessagesService.java | 49 ++++++++++----- .../authme/message/MessageFileCopier.java | 63 +++++++++++++++++++ .../fr/xephi/authme/message/Messages.java | 25 ++++---- .../authme/command/help/HelpProviderTest.java | 4 +- .../message/MessagesIntegrationTest.java | 39 +++++------- 5 files changed, 124 insertions(+), 56 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/message/MessageFileCopier.java diff --git a/src/main/java/fr/xephi/authme/command/help/HelpMessagesService.java b/src/main/java/fr/xephi/authme/command/help/HelpMessagesService.java index a42caf86e..92d39a456 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpMessagesService.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpMessagesService.java @@ -4,15 +4,17 @@ import com.google.common.base.CaseFormat; import fr.xephi.authme.command.CommandArgumentDescription; import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandUtils; -import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.Reloadable; +import fr.xephi.authme.message.MessageFileCopier; +import fr.xephi.authme.message.MessageFileCopier.MessageFileData; +import fr.xephi.authme.message.Messages; import fr.xephi.authme.permission.DefaultPermission; -import fr.xephi.authme.util.FileUtils; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import javax.inject.Inject; -import java.io.File; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -26,19 +28,15 @@ public class HelpMessagesService implements Reloadable { private static final String DETAILED_DESCRIPTION_SUFFIX = ".detailedDescription"; private static final String DEFAULT_PERMISSIONS_PATH = "common.defaultPermissions."; - private final File dataFolder; - // FIXME: Make configurable - private String file = "messages/help_en.yml"; + private final MessageFileCopier fileCopier; private FileConfiguration fileConfiguration; + private String defaultFile; + private FileConfiguration defaultConfiguration; @Inject - HelpMessagesService(@DataFolder File dataFolder) { - File messagesFile = new File(dataFolder, "messages/help_en.yml"); - if (!FileUtils.copyFileFromResource(messagesFile, file)) { - throw new IllegalStateException("Could not copy help message"); - } - this.dataFolder = dataFolder; - fileConfiguration = YamlConfiguration.loadConfiguration(messagesFile); + HelpMessagesService(MessageFileCopier fileCopier) { + this.fileCopier = fileCopier; + reload(); } /** @@ -77,7 +75,7 @@ public class HelpMessagesService implements Reloadable { public String getMessage(HelpMessageKey key) { String message = fileConfiguration.getString(key.getKey()); return message == null - ? key.getFallback() + ? getDefault(key.getKey()) : message; } @@ -89,12 +87,31 @@ public class HelpMessagesService implements Reloadable { if (message != null) { return message; } - return defaultPermission.name(); // FIXME: Default message + return getDefault(path); } @Override public void reload() { - fileConfiguration = YamlConfiguration.loadConfiguration(new File(dataFolder, "messages/help_en.yml")); + MessageFileData fileData = fileCopier.initializeData(lang -> "messages/help_" + lang + ".yml"); + this.fileConfiguration = YamlConfiguration.loadConfiguration(fileData.getFile()); + this.defaultFile = fileData.getDefaultFile(); + } + + private String getDefault(String code) { + if (defaultFile == null) { + return getDefaultErrorMessage(code); + } + + if (defaultConfiguration == null) { + InputStream stream = Messages.class.getResourceAsStream(defaultFile); + defaultConfiguration = YamlConfiguration.loadConfiguration(new InputStreamReader(stream)); + } + String message = defaultConfiguration.getString(code); + return message == null ? getDefaultErrorMessage(code) : message; + } + + private static String getDefaultErrorMessage(String code) { + return "Error retrieving message '" + code + "'"; } private String getText(String path, Supplier defaultTextGetter) { diff --git a/src/main/java/fr/xephi/authme/message/MessageFileCopier.java b/src/main/java/fr/xephi/authme/message/MessageFileCopier.java new file mode 100644 index 000000000..b8e32b7dd --- /dev/null +++ b/src/main/java/fr/xephi/authme/message/MessageFileCopier.java @@ -0,0 +1,63 @@ +package fr.xephi.authme.message; + +import fr.xephi.authme.initialization.DataFolder; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.PluginSettings; +import fr.xephi.authme.util.FileUtils; + +import javax.inject.Inject; +import java.io.File; +import java.util.function.Function; + +public class MessageFileCopier { + + private static final String DEFAULT_LANGUAGE = "en"; + + private final File dataFolder; + private final Settings settings; + + @Inject + MessageFileCopier(@DataFolder File dataFolder, Settings settings) { + this.dataFolder = dataFolder; + this.settings = settings; + } + + public MessageFileData initializeData(Function pathBuilder) { + String language = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE); + return new MessageFileData( + initializeFile(language, pathBuilder), + pathBuilder.apply(DEFAULT_LANGUAGE)); + } + + private File initializeFile(String language, Function pathBuilder) { + String filePath = pathBuilder.apply(language); + File file = new File(dataFolder, filePath); + if (FileUtils.copyFileFromResource(file, filePath)) { + return file; + } + + String defaultFilePath = pathBuilder.apply(DEFAULT_LANGUAGE); + if (FileUtils.copyFileFromResource(file, defaultFilePath)) { + return file; + } + return null; + } + + public static final class MessageFileData { + private final File file; + private final String defaultFile; + + MessageFileData(File file, String defaultFile) { + this.file = file; + this.defaultFile = defaultFile; + } + + public File getFile() { + return file; + } + + public String getDefaultFile() { + return defaultFile; + } + } +} diff --git a/src/main/java/fr/xephi/authme/message/Messages.java b/src/main/java/fr/xephi/authme/message/Messages.java index e17ee1a1a..ff3ebeee9 100644 --- a/src/main/java/fr/xephi/authme/message/Messages.java +++ b/src/main/java/fr/xephi/authme/message/Messages.java @@ -1,8 +1,8 @@ package fr.xephi.authme.message; import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.initialization.SettingsDependent; -import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.initialization.Reloadable; +import fr.xephi.authme.message.MessageFileCopier.MessageFileData; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; @@ -16,25 +16,24 @@ import java.io.InputStreamReader; /** * Class for retrieving and sending translatable messages to players. */ -public class Messages implements SettingsDependent { +public class Messages implements Reloadable { // Custom Authme tag replaced to new line private static final String NEWLINE_TAG = "%nl%"; + private final MessageFileCopier fileCopier; private FileConfiguration configuration; private String fileName; - private final String defaultFile; + private String defaultFile; private FileConfiguration defaultConfiguration; - /** + /* * Constructor. - * - * @param settings The settings */ @Inject - Messages(Settings settings) { - reload(settings); - this.defaultFile = settings.getDefaultMessagesFile(); + Messages(MessageFileCopier fileCopier) { + this.fileCopier = fileCopier; + reload(); } /** @@ -122,10 +121,12 @@ public class Messages implements SettingsDependent { } @Override - public void reload(Settings settings) { - File messageFile = settings.getMessagesFile(); + public void reload() { + MessageFileData messageFileData = fileCopier.initializeData(lang -> "messages/messages_" + lang + ".yml"); + File messageFile = messageFileData.getFile(); this.configuration = YamlConfiguration.loadConfiguration(messageFile); this.fileName = messageFile.getName(); + this.defaultFile = messageFileData.getDefaultFile(); } private String getDefault(String code) { diff --git a/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java b/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java index 4c2b78a23..e78fc9d61 100644 --- a/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java +++ b/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java @@ -14,7 +14,6 @@ import fr.xephi.authme.settings.properties.PluginSettings; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -74,7 +73,6 @@ public class HelpProviderTest { } @Test - @Ignore // FIXME: Fix test public void shouldShowLongDescription() { // given CommandDescription command = getCommandWithLabel(commands, "authme", "login"); @@ -347,7 +345,7 @@ public class HelpProviderTest { * @return The generated FoundCommandResult object */ private static FoundCommandResult newFoundResult(CommandDescription command, List labels) { - return new FoundCommandResult(command, labels, Collections.emptyList(), 0.0, FoundResultStatus.SUCCESS); + return new FoundCommandResult(command, labels, Collections.emptyList(), 0.0, FoundResultStatus.SUCCESS); } private static String removeColors(String str) { diff --git a/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java b/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java index a7a4af313..271a87a5f 100644 --- a/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java @@ -12,6 +12,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import java.io.File; +import java.util.function.Function; import java.util.logging.Logger; import static org.hamcrest.Matchers.arrayWithSize; @@ -19,8 +20,8 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; -import static org.junit.Assume.assumeThat; import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; @@ -56,7 +57,8 @@ public class MessagesIntegrationTest { Settings settings = mock(Settings.class); given(settings.getMessagesFile()).willReturn(testFile); given(settings.getDefaultMessagesFile()).willReturn(YML_DEFAULT_TEST_FILE); - messages = new Messages(settings); + MessageFileCopier copier = copierReturning(testFile, YML_DEFAULT_TEST_FILE); + messages = new Messages(copier); } @Test @@ -235,9 +237,8 @@ public class MessagesIntegrationTest { @Test public void shouldAllowNullAsDefaultFile() { // given - Settings settings = mock(Settings.class); - given(settings.getMessagesFile()).willReturn(TestHelper.getJarFile(YML_TEST_FILE)); - Messages testMessages = new Messages(settings); + MessageFileCopier fileCopier = copierReturning(TestHelper.getJarFile(YML_TEST_FILE), YML_DEFAULT_TEST_FILE); + Messages testMessages = new Messages(fileCopier); // Key not present in test file MessageKey key = MessageKey.TWO_FACTOR_CREATE; @@ -248,26 +249,6 @@ public class MessagesIntegrationTest { assertThat(message, containsString("Error retrieving message")); } - @Test - public void shouldLoadOtherFile() { - // given - MessageKey key = MessageKey.WRONG_PASSWORD; - // assumption: message comes back as defined in messages_test.yml - assumeThat(messages.retrieveSingle(key), equalTo("§cWrong password!")); - Settings settings = mock(Settings.class); - given(settings.getMessagesFile()).willReturn(TestHelper.getJarFile( - TestHelper.PROJECT_ROOT + "message/messages_test2.yml")); - - // when - messages.reload(settings); - - // then - assertThat(messages.retrieveSingle(key), equalTo("test2 - wrong password")); - // check that default message handling still works - assertThat(messages.retrieveSingle(MessageKey.MUST_REGISTER_MESSAGE), - equalTo("Message from default file")); - } - @Test public void shouldRetrieveMessageWithReplacements() { // given @@ -279,4 +260,12 @@ public class MessagesIntegrationTest { // then assertThat(result, equalTo("Use /captcha 24680 to solve the captcha")); } + + @SuppressWarnings("unchecked") + private static MessageFileCopier copierReturning(File file, String defaultFile) { + MessageFileCopier copier = mock(MessageFileCopier.class); + given(copier.initializeData(any(Function.class))) + .willReturn(new MessageFileCopier.MessageFileData(file, defaultFile)); + return copier; + } }