mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2025-02-22 23:01:28 +01:00
#927 Integrate ConfigMe into AuthMe (work in progress)
- Replace own code with ConfigMe
This commit is contained in:
parent
33eab1df21
commit
c7bb7b460e
7
pom.xml
7
pom.xml
@ -852,6 +852,13 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- ConfigMe -->
|
||||
<dependency>
|
||||
<groupId>com.github.authme</groupId>
|
||||
<artifactId>configme</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Unit Testing Libraries -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
@ -1,9 +1,9 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
import com.github.authme.configme.resource.YamlFileResource;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
@ -15,11 +18,10 @@ import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.SettingsMigrationService;
|
||||
import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.settings.properties.SettingsFieldRetriever;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
import fr.xephi.authme.util.MigrationService;
|
||||
@ -31,6 +33,7 @@ import org.bukkit.entity.Player;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
|
||||
@ -59,10 +62,12 @@ public class Initializer {
|
||||
*/
|
||||
public Settings createSettings() throws Exception {
|
||||
File configFile = new File(authMe.getDataFolder(), "config.yml");
|
||||
PropertyMap properties = SettingsFieldRetriever.getAllPropertyFields();
|
||||
SettingsMigrationService migrationService = new SettingsMigrationService();
|
||||
PropertyResource resource = new YamlFileResource(configFile);
|
||||
SettingsMigrationService migrationService = new SettingsMigrationService(authMe.getDataFolder());
|
||||
List<PropertyEntry> knownProperties = AuthMeSettingsRetriever.getAllPropertyFields();
|
||||
|
||||
if (FileUtils.copyFileFromResource(configFile, "config.yml")) {
|
||||
return new Settings(configFile, authMe.getDataFolder(), properties, migrationService);
|
||||
return new Settings(authMe.getDataFolder(), knownProperties, resource, migrationService);
|
||||
}
|
||||
throw new Exception("Could not copy config.yml from JAR to plugin folder");
|
||||
}
|
||||
@ -71,6 +76,7 @@ public class Initializer {
|
||||
* Sets up the data source.
|
||||
*
|
||||
* @param settings the settings
|
||||
* @return the constructed datasource
|
||||
* @throws ClassNotFoundException if no driver could be found for the datasource
|
||||
* @throws SQLException when initialization of a SQL datasource failed
|
||||
* @throws IOException if flat file cannot be read
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.process;
|
||||
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.AuthGroupHandler;
|
||||
@ -7,7 +8,6 @@ import fr.xephi.authme.permission.AuthGroupType;
|
||||
import fr.xephi.authme.permission.PermissionNode;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -1,108 +1,46 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Strings;
|
||||
import com.github.authme.configme.SettingsManager;
|
||||
import com.github.authme.configme.migration.MigrationService;
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static fr.xephi.authme.util.FileUtils.copyFileFromResource;
|
||||
|
||||
/**
|
||||
* The AuthMe settings manager.
|
||||
*/
|
||||
public class Settings {
|
||||
public class Settings extends SettingsManager {
|
||||
|
||||
private final File pluginFolder;
|
||||
private final File configFile;
|
||||
private final PropertyMap propertyMap;
|
||||
private final SettingsMigrationService migrationService;
|
||||
private FileConfiguration configuration;
|
||||
/** The file with the localized messages based on {@link PluginSettings#MESSAGES_LANGUAGE}. */
|
||||
private File messagesFile;
|
||||
private List<String> welcomeMessage;
|
||||
private String emailMessage;
|
||||
|
||||
/**
|
||||
* Constructor. Checks the given {@link FileConfiguration} object for completeness.
|
||||
* Constructor.
|
||||
*
|
||||
* @param configFile The configuration file
|
||||
* @param pluginFolder The AuthMe plugin folder
|
||||
* @param propertyMap Collection of all available settings
|
||||
* @param migrationService Migration service to check the settings file with
|
||||
* @param pluginFolder the AuthMe plugin folder
|
||||
* @param knownProperties collection of all available settings
|
||||
* @param resource the property resource to read and write properties to
|
||||
* @param migrationService migration service to check the settings file with
|
||||
*/
|
||||
public Settings(File configFile, File pluginFolder, PropertyMap propertyMap,
|
||||
SettingsMigrationService migrationService) {
|
||||
this.configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
this.configFile = configFile;
|
||||
public Settings(File pluginFolder, List<PropertyEntry> knownProperties, PropertyResource resource,
|
||||
MigrationService migrationService) {
|
||||
super(knownProperties, resource, migrationService);
|
||||
this.pluginFolder = pluginFolder;
|
||||
this.propertyMap = propertyMap;
|
||||
this.migrationService = migrationService;
|
||||
validateAndLoadOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for testing purposes, allowing more options.
|
||||
*
|
||||
* @param configuration The FileConfiguration object to use
|
||||
* @param configFile The file to write to
|
||||
* @param pluginFolder The plugin folder
|
||||
* @param propertyMap The property map whose properties should be verified for presence, or null to skip this
|
||||
* @param migrationService Migration service, or null to skip migration checks
|
||||
*/
|
||||
@VisibleForTesting
|
||||
Settings(FileConfiguration configuration, File configFile, File pluginFolder, PropertyMap propertyMap,
|
||||
SettingsMigrationService migrationService) {
|
||||
this.configuration = configuration;
|
||||
this.configFile = configFile;
|
||||
this.pluginFolder = pluginFolder;
|
||||
this.propertyMap = propertyMap;
|
||||
this.migrationService = migrationService;
|
||||
|
||||
if (propertyMap != null && migrationService != null) {
|
||||
validateAndLoadOptions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given property from the configuration.
|
||||
*
|
||||
* @param property The property to retrieve
|
||||
* @param <T> The property's type
|
||||
* @return The property's value
|
||||
*/
|
||||
public <T> T getProperty(Property<T> property) {
|
||||
return property.getFromFile(configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new value for the given property.
|
||||
*
|
||||
* @param property The property to modify
|
||||
* @param value The new value to assign to the property
|
||||
* @param <T> The property's type
|
||||
*/
|
||||
public <T> void setProperty(Property<T> property, T value) {
|
||||
configuration.set(property.getPath(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,71 +79,9 @@ public class Settings {
|
||||
return welcomeMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the configuration.
|
||||
*/
|
||||
public void reload() {
|
||||
configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
validateAndLoadOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the config file. Use after migrating one or more settings.
|
||||
*/
|
||||
public void save() {
|
||||
try (FileWriter writer = new FileWriter(configFile)) {
|
||||
Yaml simpleYaml = newYaml(false);
|
||||
Yaml singleQuoteYaml = newYaml(true);
|
||||
|
||||
writer.write("");
|
||||
// Contains all but the last node of the setting, e.g. [DataSource, mysql] for "DataSource.mysql.username"
|
||||
List<String> currentPath = new ArrayList<>();
|
||||
for (Map.Entry<Property<?>, String[]> entry : propertyMap.entrySet()) {
|
||||
Property<?> property = entry.getKey();
|
||||
|
||||
// Handle properties
|
||||
List<String> propertyPath = Arrays.asList(property.getPath().split("\\."));
|
||||
List<String> commonPathParts = CollectionUtils.filterCommonStart(
|
||||
currentPath, propertyPath.subList(0, propertyPath.size() - 1));
|
||||
List<String> newPathParts = CollectionUtils.getRange(propertyPath, commonPathParts.size());
|
||||
|
||||
if (commonPathParts.isEmpty()) {
|
||||
writer.append("\n");
|
||||
}
|
||||
|
||||
int indentationLevel = commonPathParts.size();
|
||||
if (newPathParts.size() > 1) {
|
||||
for (String path : newPathParts.subList(0, newPathParts.size() - 1)) {
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append(path)
|
||||
.append(": ");
|
||||
++indentationLevel;
|
||||
}
|
||||
}
|
||||
for (String comment : entry.getValue()) {
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append("# ")
|
||||
.append(comment);
|
||||
}
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append(CollectionUtils.getRange(newPathParts, newPathParts.size() - 1).get(0))
|
||||
.append(": ")
|
||||
.append(toYaml(property, indentationLevel, simpleYaml, singleQuoteYaml));
|
||||
|
||||
currentPath = propertyPath.subList(0, propertyPath.size() - 1);
|
||||
}
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Could not save config file:", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateAndLoadOptions() {
|
||||
if (migrationService.checkAndMigrate(configuration, propertyMap, pluginFolder)) {
|
||||
@Override
|
||||
protected void validateAndLoadOptions() {
|
||||
if (migrationService.checkAndMigrate(resource, knownProperties)) {
|
||||
ConsoleLogger.info("Merged new config options");
|
||||
ConsoleLogger.info("Please check your config.yml file for new settings!");
|
||||
save();
|
||||
@ -216,11 +92,6 @@ public class Settings {
|
||||
emailMessage = readEmailMessage();
|
||||
}
|
||||
|
||||
private <T> String toYaml(Property<T> property, int indent, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
String representation = property.toYaml(configuration, simpleYaml, singleQuoteYaml);
|
||||
return Joiner.on("\n" + indent(indent)).join(representation.split("\\n"));
|
||||
}
|
||||
|
||||
private File buildMessagesFile() {
|
||||
String languageCode = getProperty(PluginSettings.MESSAGES_LANGUAGE);
|
||||
|
||||
@ -270,20 +141,4 @@ public class Settings {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static Yaml newYaml(boolean useSingleQuotes) {
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
options.setAllowUnicode(true);
|
||||
if (useSingleQuotes) {
|
||||
options.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);
|
||||
}
|
||||
return new Yaml(options);
|
||||
}
|
||||
|
||||
private static String indent(int level) {
|
||||
// We use an indentation of 4 spaces
|
||||
return Strings.repeat(" ", level * 4);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,17 +1,20 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.github.authme.configme.migration.PlainMigrationService;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.output.LogLevel;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.DELAY_JOIN_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_JOIN_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_LEAVE_MESSAGE;
|
||||
@ -22,55 +25,40 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAW
|
||||
/**
|
||||
* Service for verifying that the configuration is up-to-date.
|
||||
*/
|
||||
public class SettingsMigrationService {
|
||||
public class SettingsMigrationService extends PlainMigrationService {
|
||||
|
||||
/**
|
||||
* Checks the config file and performs any necessary migrations.
|
||||
*
|
||||
* @param configuration The file configuration to check and migrate
|
||||
* @param propertyMap The property map of all existing properties
|
||||
* @param pluginFolder The plugin folder
|
||||
* @return True if there is a change and the config must be saved, false if the config is up-to-date
|
||||
*/
|
||||
public boolean checkAndMigrate(FileConfiguration configuration, PropertyMap propertyMap, File pluginFolder) {
|
||||
return performMigrations(configuration, pluginFolder)
|
||||
|| hasDeprecatedProperties(configuration)
|
||||
|| !containsAllSettings(configuration, propertyMap);
|
||||
private final File pluginFolder;
|
||||
|
||||
public SettingsMigrationService(File pluginFolder) {
|
||||
this.pluginFolder = pluginFolder;
|
||||
}
|
||||
|
||||
private boolean performMigrations(FileConfiguration configuration, File pluginFolder) {
|
||||
@Override
|
||||
protected boolean performMigrations(PropertyResource resource, List<PropertyEntry> knownProperties) {
|
||||
boolean changes = false;
|
||||
if ("[a-zA-Z0-9_?]*".equals(configuration.getString(ALLOWED_NICKNAME_CHARACTERS.getPath()))) {
|
||||
configuration.set(ALLOWED_NICKNAME_CHARACTERS.getPath(), "[a-zA-Z0-9_]*");
|
||||
if ("[a-zA-Z0-9_?]*".equals(resource.getString(ALLOWED_NICKNAME_CHARACTERS.getPath()))) {
|
||||
resource.setValue(ALLOWED_NICKNAME_CHARACTERS.getPath(), "[a-zA-Z0-9_]*");
|
||||
changes = true;
|
||||
}
|
||||
|
||||
// Note ljacqu 20160211: Concatenating migration methods with | instead of the usual ||
|
||||
// ensures that all migrations will be performed
|
||||
return changes
|
||||
| performMailTextToFileMigration(configuration, pluginFolder)
|
||||
| migrateJoinLeaveMessages(configuration)
|
||||
| migrateForceSpawnSettings(configuration)
|
||||
| changeBooleanSettingToLogLevelProperty(configuration);
|
||||
| performMailTextToFileMigration(resource)
|
||||
| migrateJoinLeaveMessages(resource)
|
||||
| migrateForceSpawnSettings(resource)
|
||||
| changeBooleanSettingToLogLevelProperty(resource)
|
||||
|| hasDeprecatedProperties(resource);
|
||||
}
|
||||
|
||||
public boolean containsAllSettings(FileConfiguration configuration, PropertyMap propertyMap) {
|
||||
for (Property<?> property : propertyMap.keySet()) {
|
||||
if (!property.isPresent(configuration)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean hasDeprecatedProperties(FileConfiguration configuration) {
|
||||
private static boolean hasDeprecatedProperties(PropertyResource resource) {
|
||||
String[] deprecatedProperties = {
|
||||
"Converter.Rakamak.newPasswordHash", "Hooks.chestshop", "Hooks.legacyChestshop", "Hooks.notifications",
|
||||
"Passpartu", "Performances", "settings.restrictions.enablePasswordVerifier", "Xenoforo.predefinedSalt",
|
||||
"VeryGames", "settings.restrictions.allowAllCommandsIfRegistrationIsOptional", "DataSource.mySQLWebsite",
|
||||
"Hooks.customAttributes", "Security.stop.kickPlayersBeforeStopping"};
|
||||
for (String deprecatedPath : deprecatedProperties) {
|
||||
if (configuration.contains(deprecatedPath)) {
|
||||
if (resource.contains(deprecatedPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -84,18 +72,18 @@ public class SettingsMigrationService {
|
||||
/**
|
||||
* Check if {@code Email.mailText} is present and move it to the Email.html file if it doesn't exist yet.
|
||||
*
|
||||
* @param configuration The file configuration to verify
|
||||
* @param pluginFolder The plugin data folder
|
||||
* @param resource The property resource
|
||||
* @return True if a migration has been completed, false otherwise
|
||||
*/
|
||||
private static boolean performMailTextToFileMigration(FileConfiguration configuration, File pluginFolder) {
|
||||
private boolean performMailTextToFileMigration(PropertyResource resource) {
|
||||
final String oldSettingPath = "Email.mailText";
|
||||
if (!configuration.contains(oldSettingPath)) {
|
||||
final String oldMailText = resource.getString(oldSettingPath);
|
||||
if (oldMailText == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File emailFile = new File(pluginFolder, "email.html");
|
||||
final String mailText = configuration.getString(oldSettingPath)
|
||||
final String mailText = oldMailText
|
||||
.replace("<playername>", "<playername />").replace("%playername%", "<playername />")
|
||||
.replace("<servername>", "<servername />").replace("%servername%", "<servername />")
|
||||
.replace("<generatedpass>", "<generatedpass />").replace("%generatedpass%", "<generatedpass />")
|
||||
@ -114,12 +102,12 @@ public class SettingsMigrationService {
|
||||
* Detect deprecated {@code settings.delayJoinLeaveMessages} and inform user of new "remove join messages"
|
||||
* and "remove leave messages" settings.
|
||||
*
|
||||
* @param configuration The file configuration
|
||||
* @param resource The property resource
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean migrateJoinLeaveMessages(FileConfiguration configuration) {
|
||||
Property<Boolean> oldDelayJoinProperty = Property.newProperty("settings.delayJoinLeaveMessages", false);
|
||||
boolean hasMigrated = moveProperty(oldDelayJoinProperty, DELAY_JOIN_MESSAGE, configuration);
|
||||
private static boolean migrateJoinLeaveMessages(PropertyResource resource) {
|
||||
Property<Boolean> oldDelayJoinProperty = newProperty("settings.delayJoinLeaveMessages", false);
|
||||
boolean hasMigrated = moveProperty(oldDelayJoinProperty, DELAY_JOIN_MESSAGE, resource);
|
||||
|
||||
if (hasMigrated) {
|
||||
ConsoleLogger.info(String.format("Note that we now also have the settings %s and %s",
|
||||
@ -132,33 +120,33 @@ public class SettingsMigrationService {
|
||||
* Detect old "force spawn loc on join" and "force spawn on these worlds" settings and moves them
|
||||
* to the new paths.
|
||||
*
|
||||
* @param configuration The file configuration
|
||||
* @param resource The property resource
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean migrateForceSpawnSettings(FileConfiguration configuration) {
|
||||
Property<Boolean> oldForceLocEnabled = Property.newProperty(
|
||||
private static boolean migrateForceSpawnSettings(PropertyResource resource) {
|
||||
Property<Boolean> oldForceLocEnabled = newProperty(
|
||||
"settings.restrictions.ForceSpawnLocOnJoinEnabled", false);
|
||||
Property<List<String>> oldForceWorlds = Property.newListProperty(
|
||||
Property<List<String>> oldForceWorlds = newListProperty(
|
||||
"settings.restrictions.ForceSpawnOnTheseWorlds", "world", "world_nether", "world_the_ed");
|
||||
|
||||
return moveProperty(oldForceLocEnabled, FORCE_SPAWN_LOCATION_AFTER_LOGIN, configuration)
|
||||
| moveProperty(oldForceWorlds, FORCE_SPAWN_ON_WORLDS, configuration);
|
||||
return moveProperty(oldForceLocEnabled, FORCE_SPAWN_LOCATION_AFTER_LOGIN, resource)
|
||||
| moveProperty(oldForceWorlds, FORCE_SPAWN_ON_WORLDS, resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the old boolean property "hide spam from console" to the new property specifying
|
||||
* the log level.
|
||||
*
|
||||
* @param configuration The file configuration
|
||||
* @param resource The property resource
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean changeBooleanSettingToLogLevelProperty(FileConfiguration configuration) {
|
||||
private static boolean changeBooleanSettingToLogLevelProperty(PropertyResource resource) {
|
||||
final String oldPath = "Security.console.noConsoleSpam";
|
||||
final Property<LogLevel> newProperty = PluginSettings.LOG_LEVEL;
|
||||
if (!newProperty.isPresent(configuration) && configuration.contains(oldPath)) {
|
||||
if (!newProperty.isPresent(resource) && resource.contains(oldPath)) {
|
||||
ConsoleLogger.info("Moving '" + oldPath + "' to '" + newProperty.getPath() + "'");
|
||||
LogLevel level = configuration.getBoolean(oldPath) ? LogLevel.INFO : LogLevel.FINE;
|
||||
configuration.set(newProperty.getPath(), level.name());
|
||||
LogLevel level = Boolean.valueOf(resource.getString(oldPath)) ? LogLevel.INFO : LogLevel.FINE;
|
||||
resource.setValue(newProperty.getPath(), level.name());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -169,18 +157,18 @@ public class SettingsMigrationService {
|
||||
*
|
||||
* @param oldProperty The old property (create a temporary {@link Property} object with the path)
|
||||
* @param newProperty The new property to move the value to
|
||||
* @param configuration The file configuration
|
||||
* @param resource The property resource
|
||||
* @param <T> The type of the property
|
||||
* @return True if a migration has been done, false otherwise
|
||||
*/
|
||||
private static <T> boolean moveProperty(Property<T> oldProperty,
|
||||
Property<T> newProperty,
|
||||
FileConfiguration configuration) {
|
||||
if (configuration.contains(oldProperty.getPath())) {
|
||||
PropertyResource resource) {
|
||||
if (resource.contains(oldProperty.getPath())) {
|
||||
ConsoleLogger.info("Detected deprecated property " + oldProperty.getPath());
|
||||
if (!configuration.contains(newProperty.getPath())) {
|
||||
if (!resource.contains(newProperty.getPath())) {
|
||||
ConsoleLogger.info("Renamed " + oldProperty.getPath() + " to " + newProperty.getPath());
|
||||
configuration.set(newProperty.getPath(), oldProperty.getFromFile(configuration));
|
||||
resource.setValue(newProperty.getPath(), oldProperty.getValue(resource));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Comment for properties which are also included in the YAML file upon saving.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Comment {
|
||||
|
||||
String[] value();
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Enum property.
|
||||
*
|
||||
* @param <E> The enum class
|
||||
*/
|
||||
class EnumProperty<E extends Enum<E>> extends Property<E> {
|
||||
|
||||
private Class<E> clazz;
|
||||
|
||||
public EnumProperty(Class<E> clazz, String path, E defaultValue) {
|
||||
super(path, defaultValue);
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFromFile(FileConfiguration configuration) {
|
||||
String textValue = configuration.getString(getPath());
|
||||
if (textValue == null) {
|
||||
return getDefaultValue();
|
||||
}
|
||||
E mappedValue = mapToEnum(textValue);
|
||||
return mappedValue == null ? getDefaultValue() : mappedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent(FileConfiguration configuration) {
|
||||
return super.isPresent(configuration) && mapToEnum(configuration.getString(getPath())) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
E value = getFromFile(configuration);
|
||||
return singleQuoteYaml.dump(value.name());
|
||||
}
|
||||
|
||||
private E mapToEnum(String value) {
|
||||
for (E entry : clazz.getEnumConstants()) {
|
||||
if (entry.name().equalsIgnoreCase(value)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,235 +0,0 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Property class, representing a <i>setting</i> that is read from the config.yml file.
|
||||
*/
|
||||
public abstract class Property<T> {
|
||||
|
||||
private final String path;
|
||||
private final T defaultValue;
|
||||
|
||||
protected Property(String path, T defaultValue) {
|
||||
Objects.requireNonNull(defaultValue);
|
||||
this.path = path;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new string list property.
|
||||
*
|
||||
* @param path The property's path
|
||||
* @param defaultValues The items in the default list
|
||||
* @return The created list property
|
||||
*/
|
||||
public static Property<List<String>> newListProperty(String path, String... defaultValues) {
|
||||
// does not have the same name as not to clash with #newProperty(String, String)
|
||||
return new StringListProperty(path, defaultValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new String list property where all values are lowercase.
|
||||
*
|
||||
* @param path The property's path
|
||||
* @param defaultValues The items in the default list
|
||||
* @return The created list property
|
||||
*/
|
||||
public static Property<List<String>> newLowercaseListProperty(String path, String... defaultValues) {
|
||||
return new LowercaseStringListProperty(path, defaultValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new enum property.
|
||||
*
|
||||
* @param clazz The enum class
|
||||
* @param path The property's path
|
||||
* @param defaultValue The default value
|
||||
* @param <E> The enum type
|
||||
* @return The created enum property
|
||||
*/
|
||||
public static <E extends Enum<E>> Property<E> newProperty(Class<E> clazz, String path, E defaultValue) {
|
||||
return new EnumProperty<>(clazz, path, defaultValue);
|
||||
}
|
||||
|
||||
public static Property<Boolean> newProperty(String path, boolean defaultValue) {
|
||||
return new BooleanProperty(path, defaultValue);
|
||||
}
|
||||
|
||||
public static Property<Integer> newProperty(String path, int defaultValue) {
|
||||
return new IntegerProperty(path, defaultValue);
|
||||
}
|
||||
|
||||
public static Property<String> newProperty(String path, String defaultValue) {
|
||||
return new StringProperty(path, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property value from the given configuration – guaranteed to never return null.
|
||||
*
|
||||
* @param configuration The configuration to read the value from
|
||||
* @return The value, or default if not present
|
||||
*/
|
||||
public abstract T getFromFile(FileConfiguration configuration);
|
||||
|
||||
/**
|
||||
* Return whether or not the given configuration file contains the property.
|
||||
*
|
||||
* @param configuration The configuration file to verify
|
||||
* @return True if the property is present, false otherwise
|
||||
*/
|
||||
public boolean isPresent(FileConfiguration configuration) {
|
||||
return configuration.contains(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the property's value as YAML.
|
||||
*
|
||||
* @param configuration The file configuration
|
||||
* @param simpleYaml YAML object (default)
|
||||
* @param singleQuoteYaml YAML object using single quotes
|
||||
* @return The generated YAML
|
||||
*/
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return simpleYaml.dump(getFromFile(configuration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default value of the property.
|
||||
*
|
||||
* @return The default value
|
||||
*/
|
||||
public T getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property path (i.e. the node at which this property is located in the YAML file).
|
||||
*
|
||||
* @return The path
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Property '" + path + "'";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Boolean property.
|
||||
*/
|
||||
private static final class BooleanProperty extends Property<Boolean> {
|
||||
|
||||
public BooleanProperty(String path, Boolean defaultValue) {
|
||||
super(path, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getFromFile(FileConfiguration configuration) {
|
||||
return configuration.getBoolean(getPath(), getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer property.
|
||||
*/
|
||||
private static final class IntegerProperty extends Property<Integer> {
|
||||
|
||||
public IntegerProperty(String path, Integer defaultValue) {
|
||||
super(path, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getFromFile(FileConfiguration configuration) {
|
||||
return configuration.getInt(getPath(), getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String property.
|
||||
*/
|
||||
private static final class StringProperty extends Property<String> {
|
||||
|
||||
public StringProperty(String path, String defaultValue) {
|
||||
super(path, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFromFile(FileConfiguration configuration) {
|
||||
return configuration.getString(getPath(), getDefaultValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return singleQuoteYaml.dump(getFromFile(configuration));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String list property.
|
||||
*/
|
||||
private static class StringListProperty extends Property<List<String>> {
|
||||
|
||||
public StringListProperty(String path, String[] defaultValues) {
|
||||
super(path, Arrays.asList(defaultValues));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getFromFile(FileConfiguration configuration) {
|
||||
if (!configuration.isList(getPath())) {
|
||||
return getDefaultValue();
|
||||
}
|
||||
return configuration.getStringList(getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent(FileConfiguration configuration) {
|
||||
return configuration.isList(getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
List<String> value = getFromFile(configuration);
|
||||
String yaml = singleQuoteYaml.dump(value);
|
||||
// If the property is a non-empty list we need to append a new line because it will be
|
||||
// something like the following, which requires a new line:
|
||||
// - 'item 1'
|
||||
// - 'second item in list'
|
||||
return value.isEmpty() ? yaml : "\n" + yaml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowercase String list property.
|
||||
*/
|
||||
private static final class LowercaseStringListProperty extends StringListProperty {
|
||||
|
||||
public LowercaseStringListProperty(String path, String[] defaultValues) {
|
||||
super(path, defaultValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getFromFile(FileConfiguration configuration) {
|
||||
if (!configuration.isList(getPath())) {
|
||||
return getDefaultValue();
|
||||
}
|
||||
|
||||
// make sure all elements are lowercase
|
||||
List<String> lowercaseList = new ArrayList<>();
|
||||
for (String element : configuration.getStringList(getPath())) {
|
||||
lowercaseList.add(element.toLowerCase());
|
||||
}
|
||||
|
||||
return lowercaseList;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
/**
|
||||
* Marker for classes that define {@link Property} fields.
|
||||
*/
|
||||
public interface SettingsClass {
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.propertymap.SettingsFieldRetriever;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class responsible for retrieving all {@link Property} fields
|
||||
* from {@link SettingsHolder} implementations via reflection.
|
||||
*/
|
||||
public final class AuthMeSettingsRetriever {
|
||||
|
||||
private AuthMeSettingsRetriever() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a list with all property fields in AuthMe {@link SettingsHolder} classes.
|
||||
*
|
||||
* @return list of all known properties
|
||||
*/
|
||||
public static List<PropertyEntry> getAllPropertyFields() {
|
||||
SettingsFieldRetriever retriever = new SettingsFieldRetriever(
|
||||
DatabaseSettings.class, ConverterSettings.class, PluginSettings.class,
|
||||
RestrictionSettings.class, EmailSettings.class, HooksSettings.class,
|
||||
ProtectionSettings.class, PurgeSettings.class, SecuritySettings.class,
|
||||
RegistrationSettings.class, BackupSettings.class);
|
||||
|
||||
return retriever.getAllPropertyFields();
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class BackupSettings implements SettingsClass {
|
||||
public class BackupSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Enable or disable automatic backup")
|
||||
public static final Property<Boolean> ENABLED =
|
||||
|
@ -1,12 +1,12 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class ConverterSettings implements SettingsClass {
|
||||
public class ConverterSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Rakamak file name")
|
||||
public static final Property<String> RAKAMAK_FILE_NAME =
|
||||
|
@ -1,13 +1,13 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class DatabaseSettings implements SettingsClass {
|
||||
public class DatabaseSettings implements SettingsHolder {
|
||||
|
||||
@Comment({"What type of database do you want to use?",
|
||||
"Valid values: sqlite, mysql"})
|
||||
|
@ -1,15 +1,15 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class EmailSettings implements SettingsClass {
|
||||
public class EmailSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Email SMTP server host")
|
||||
public static final Property<String> SMTP_HOST =
|
||||
|
@ -1,15 +1,15 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class HooksSettings implements SettingsClass {
|
||||
public class HooksSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Do we need to hook with multiverse for spawn checking?")
|
||||
public static final Property<Boolean> MULTIVERSE =
|
||||
|
@ -1,13 +1,13 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.output.LogLevel;
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class PluginSettings implements SettingsClass {
|
||||
public class PluginSettings implements SettingsHolder {
|
||||
|
||||
@Comment("The name shown in the help messages")
|
||||
public static final Property<String> HELP_HEADER =
|
||||
|
@ -1,16 +1,16 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
|
||||
public class ProtectionSettings implements SettingsClass {
|
||||
public class ProtectionSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Enable some servers protection (country based login, antibot)")
|
||||
public static final Property<Boolean> ENABLE_PROTECTION =
|
||||
|
@ -1,12 +1,12 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class PurgeSettings implements SettingsClass {
|
||||
public class PurgeSettings implements SettingsHolder {
|
||||
|
||||
@Comment("If enabled, AuthMe automatically purges old, unused accounts")
|
||||
public static final Property<Boolean> USE_AUTO_PURGE =
|
||||
|
@ -1,15 +1,15 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class RegistrationSettings implements SettingsClass {
|
||||
public class RegistrationSettings implements SettingsHolder {
|
||||
|
||||
@Comment("Enable registration on the server?")
|
||||
public static final Property<Boolean> IS_ENABLED =
|
||||
|
@ -1,16 +1,16 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newLowercaseListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newLowercaseListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class RestrictionSettings implements SettingsClass {
|
||||
public class RestrictionSettings implements SettingsHolder {
|
||||
|
||||
@Comment({
|
||||
"Can not authenticated players chat?",
|
||||
|
@ -1,16 +1,16 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import com.github.authme.configme.Comment;
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newLowercaseListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newLowercaseListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
public class SecuritySettings implements SettingsClass {
|
||||
public class SecuritySettings implements SettingsHolder {
|
||||
|
||||
@Comment({"Stop the server if we can't contact the sql database",
|
||||
"Take care with this, if you set this to false,",
|
||||
|
@ -1,75 +0,0 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class responsible for retrieving all {@link Property} fields
|
||||
* from {@link SettingsClass} implementations via reflection.
|
||||
*/
|
||||
public final class SettingsFieldRetriever {
|
||||
|
||||
/** The classes to scan for properties. */
|
||||
private static final List<Class<? extends SettingsClass>> CONFIGURATION_CLASSES = Arrays.asList(
|
||||
DatabaseSettings.class, ConverterSettings.class, PluginSettings.class,
|
||||
RestrictionSettings.class, EmailSettings.class, HooksSettings.class,
|
||||
ProtectionSettings.class, PurgeSettings.class, SecuritySettings.class,
|
||||
RegistrationSettings.class, BackupSettings.class);
|
||||
|
||||
private SettingsFieldRetriever() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan all given classes for their properties and return the generated {@link PropertyMap}.
|
||||
*
|
||||
* @return PropertyMap containing all found properties and their associated comments
|
||||
* @see #CONFIGURATION_CLASSES
|
||||
*/
|
||||
public static PropertyMap getAllPropertyFields() {
|
||||
PropertyMap properties = new PropertyMap();
|
||||
for (Class<?> clazz : CONFIGURATION_CLASSES) {
|
||||
Field[] declaredFields = clazz.getDeclaredFields();
|
||||
for (Field field : declaredFields) {
|
||||
Property<?> property = getPropertyField(field);
|
||||
if (property != null) {
|
||||
properties.put(property, getCommentsForField(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static String[] getCommentsForField(Field field) {
|
||||
if (field.isAnnotationPresent(Comment.class)) {
|
||||
return field.getAnnotation(Comment.class).value();
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the given field's value if it is a static {@link Property}.
|
||||
*
|
||||
* @param field The field's value to return
|
||||
* @return The property the field defines, or null if not applicable
|
||||
*/
|
||||
private static Property<?> getPropertyField(Field field) {
|
||||
field.setAccessible(true);
|
||||
if (field.isAccessible() && Property.class.equals(field.getType()) && Modifier.isStatic(field.getModifiers())) {
|
||||
try {
|
||||
return (Property<?>) field.get(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Could not fetch field '" + field.getName() + "' from class '"
|
||||
+ field.getDeclaringClass().getSimpleName() + "'", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
package fr.xephi.authme.settings.propertymap;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Node class for building a tree from supplied String paths, ordered by insertion.
|
||||
* <p>
|
||||
* For instance, consider a tree to which the following paths are inserted (in the given order):
|
||||
* "animal.bird.duck", "color.yellow", "animal.rodent.rat", "animal.rodent.rabbit", "color.red".
|
||||
* For such a tree:<ul>
|
||||
* <li>"animal" (or any of its children) is sorted before "color" (or any of its children)</li>
|
||||
* <li>"animal.bird" or any child thereof is sorted before "animal.rodent"</li>
|
||||
* <li>"animal.rodent.rat" comes before "animal.rodent.rabbit"</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see PropertyMapComparator
|
||||
*/
|
||||
final class Node {
|
||||
|
||||
private final String name;
|
||||
private final List<Node> children;
|
||||
|
||||
private Node(String name) {
|
||||
this.name = name;
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a root node, i.e. the starting node for a new tree. Call this method to create
|
||||
* a new tree and always pass this root to other methods.
|
||||
*
|
||||
* @return The generated root node.
|
||||
*/
|
||||
public static Node createRoot() {
|
||||
return new Node(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child node, creating any intermediary children that don't exist.
|
||||
*
|
||||
* @param fullPath The entire path of the node to add, separate by periods
|
||||
*/
|
||||
public void addNode(String fullPath) {
|
||||
String[] pathParts = fullPath.split("\\.");
|
||||
Node parent = this;
|
||||
for (String part : pathParts) {
|
||||
Node child = parent.getChild(part);
|
||||
if (child == null) {
|
||||
child = new Node(part);
|
||||
parent.children.add(child);
|
||||
}
|
||||
parent = child;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two nodes by this class' sorting behavior (insertion order).
|
||||
* Note that this method assumes that both supplied paths exist in the tree.
|
||||
*
|
||||
* @param fullPath1 The full path to the first node
|
||||
* @param fullPath2 The full path to the second node
|
||||
* @return The comparison result, in the same format as {@link Comparable#compareTo}
|
||||
*/
|
||||
public int compare(String fullPath1, String fullPath2) {
|
||||
String[] path1 = fullPath1.split("\\.");
|
||||
String[] path2 = fullPath2.split("\\.");
|
||||
|
||||
int commonCount = 0;
|
||||
Node commonNode = this;
|
||||
while (commonCount < path1.length && commonCount < path2.length
|
||||
&& path1[commonCount].equals(path2[commonCount]) && commonNode != null) {
|
||||
commonNode = commonNode.getChild(path1[commonCount]);
|
||||
++commonCount;
|
||||
}
|
||||
|
||||
if (commonNode == null) {
|
||||
ConsoleLogger.warning("Could not find common node for '" + fullPath1 + "' at index " + commonCount);
|
||||
return fullPath1.compareTo(fullPath2); // fallback
|
||||
} else if (commonCount >= path1.length || commonCount >= path2.length) {
|
||||
return Integer.compare(path1.length, path2.length);
|
||||
}
|
||||
int child1Index = commonNode.getChildIndex(path1[commonCount]);
|
||||
int child2Index = commonNode.getChildIndex(path2[commonCount]);
|
||||
return Integer.compare(child1Index, child2Index);
|
||||
}
|
||||
|
||||
private Node getChild(String name) {
|
||||
for (Node child : children) {
|
||||
if (child.name.equals(name)) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the child's index, i.e. the position at which it was inserted to its parent.
|
||||
*
|
||||
* @param name The name of the node
|
||||
* @return The insertion index
|
||||
*/
|
||||
private int getChildIndex(String name) {
|
||||
int i = 0;
|
||||
for (Node child : children) {
|
||||
if (child.name.equals(name)) {
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Node '" + name + "'";
|
||||
}
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package fr.xephi.authme.settings.propertymap;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Class wrapping a {@code Map<Property, String[]>} for storing properties and their associated
|
||||
* comments with custom ordering.
|
||||
*
|
||||
* @see PropertyMapComparator for details about the map's order
|
||||
*/
|
||||
public class PropertyMap {
|
||||
|
||||
private Map<Property<?>, String[]> map;
|
||||
private PropertyMapComparator comparator;
|
||||
|
||||
/**
|
||||
* Create a new property map.
|
||||
*/
|
||||
public PropertyMap() {
|
||||
comparator = new PropertyMapComparator();
|
||||
map = new TreeMap<>(comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new property to the map.
|
||||
*
|
||||
* @param property The property to add
|
||||
* @param comments The comments associated to the property
|
||||
*/
|
||||
public void put(Property<?> property, String[] comments) {
|
||||
comparator.add(property);
|
||||
map.put(property, comments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entry set of the map.
|
||||
*
|
||||
* @return The entry set
|
||||
*/
|
||||
public Set<Map.Entry<Property<?>, String[]>> entrySet() {
|
||||
return map.entrySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key set of the map, i.e. all property objects it holds.
|
||||
*
|
||||
* @return The key set
|
||||
*/
|
||||
public Set<Property<?>> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the map.
|
||||
*
|
||||
* @return The size
|
||||
*/
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package fr.xephi.authme.settings.propertymap;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Custom comparator for {@link PropertyMap}. It guarantees that the map's entries:
|
||||
* <ul>
|
||||
* <li>are grouped by path, e.g. all "DataSource.mysql" properties are together, and "DataSource.mysql" properties
|
||||
* are within the broader "DataSource" group.</li>
|
||||
* <li>are ordered by insertion, e.g. if the first "DataSource" property is inserted before the first "security"
|
||||
* property, then "DataSource" properties will come before the "security" ones.</li>
|
||||
* </ul>
|
||||
*/
|
||||
final class PropertyMapComparator implements Comparator<Property<?>> {
|
||||
|
||||
private Node parent = Node.createRoot();
|
||||
|
||||
/**
|
||||
* Method to call when adding a new property to the map (as to retain its insertion time).
|
||||
*
|
||||
* @param property The property that is being added
|
||||
*/
|
||||
public void add(Property<?> property) {
|
||||
parent.addNode(property.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Property<?> p1, Property<?> p2) {
|
||||
return parent.compare(p1.getPath(), p2.getPath());
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.initialization.Reloadable;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.ProtectionSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
|
@ -2,6 +2,7 @@ package fr.xephi.authme;
|
||||
|
||||
import ch.jalu.injector.Injector;
|
||||
import ch.jalu.injector.InjectorBuilder;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.api.NewAPI;
|
||||
import fr.xephi.authme.command.CommandHandler;
|
||||
@ -35,7 +36,7 @@ import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static fr.xephi.authme.settings.TestSettingsMigrationServices.alwaysFulfilled;
|
||||
import static fr.xephi.authme.settings.properties.SettingsFieldRetriever.getAllPropertyFields;
|
||||
import static fr.xephi.authme.settings.properties.AuthMeSettingsRetriever.getAllPropertyFields;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@ -93,7 +94,7 @@ public class AuthMeInitializationTest {
|
||||
@Test
|
||||
public void shouldInitializeAllServices() {
|
||||
// given
|
||||
Settings settings = new Settings(settingsFile, dataFolder, getAllPropertyFields(), alwaysFulfilled());
|
||||
Settings settings = new Settings(dataFolder, getAllPropertyFields(), mock(PropertyResource.class), alwaysFulfilled());
|
||||
|
||||
Injector injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create();
|
||||
injector.provide(DataFolder.class, dataFolder);
|
||||
|
@ -1,9 +1,9 @@
|
||||
package fr.xephi.authme.command;
|
||||
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@ -9,7 +10,6 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -1,10 +1,10 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -1,9 +1,9 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -1,9 +1,13 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.github.authme.configme.migration.MigrationService;
|
||||
import com.github.authme.configme.migration.PlainMigrationService;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
import com.github.authme.configme.resource.YamlFileResource;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.SettingsFieldRetriever;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.configuration.MemorySection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
@ -35,18 +39,18 @@ public class ConfigFileConsistencyTest {
|
||||
public void shouldHaveAllConfigs() throws IOException {
|
||||
// given
|
||||
File configFile = TestHelper.getJarFile(CONFIG_FILE);
|
||||
FileConfiguration configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
SettingsMigrationService migration = new SettingsMigrationService();
|
||||
PropertyResource resource = new YamlFileResource(configFile);
|
||||
MigrationService migration = new PlainMigrationService();
|
||||
|
||||
// when
|
||||
boolean result = migration.containsAllSettings(configuration, SettingsFieldRetriever.getAllPropertyFields());
|
||||
boolean result = migration.checkAndMigrate(resource, AuthMeSettingsRetriever.getAllPropertyFields());
|
||||
|
||||
// then
|
||||
if (!result) {
|
||||
if (result) {
|
||||
Set<String> knownProperties = getAllKnownPropertyPaths();
|
||||
List<String> missingProperties = new ArrayList<>();
|
||||
for (String path : knownProperties) {
|
||||
if (!configuration.contains(path)) {
|
||||
if (!resource.contains(path)) {
|
||||
missingProperties.add(path);
|
||||
}
|
||||
}
|
||||
@ -82,21 +86,22 @@ public class ConfigFileConsistencyTest {
|
||||
public void shouldHaveValueCorrespondingToPropertyDefault() {
|
||||
// given
|
||||
File configFile = TestHelper.getJarFile(CONFIG_FILE);
|
||||
FileConfiguration configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
PropertyMap propertyMap = SettingsFieldRetriever.getAllPropertyFields();
|
||||
PropertyResource resource = new YamlFileResource(configFile);
|
||||
List<PropertyEntry> knownProperties = AuthMeSettingsRetriever.getAllPropertyFields();
|
||||
|
||||
// when / then
|
||||
for (Property<?> property : propertyMap.keySet()) {
|
||||
for (PropertyEntry propertyEntry : knownProperties) {
|
||||
Property<?> property = propertyEntry.getProperty();
|
||||
assertThat("Default value of '" + property.getPath() + "' in config.yml should be the same as in Property",
|
||||
property.getFromFile(configuration).equals(property.getDefaultValue()), equalTo(true));
|
||||
property.getValue(resource).equals(property.getDefaultValue()), equalTo(true));
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<String> getAllKnownPropertyPaths() {
|
||||
PropertyMap propertyMap = SettingsFieldRetriever.getAllPropertyFields();
|
||||
Set<String> paths = new HashSet<>(propertyMap.size());
|
||||
for (Property<?> property : propertyMap.keySet()) {
|
||||
paths.add(property.getPath());
|
||||
List<PropertyEntry> knownProperties = AuthMeSettingsRetriever.getAllPropertyFields();
|
||||
Set<String> paths = new HashSet<>(knownProperties.size());
|
||||
for (PropertyEntry propertyEntry : knownProperties) {
|
||||
paths.add(propertyEntry.getProperty().getPath());
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.github.authme.configme.migration.PlainMigrationService;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
import com.github.authme.configme.resource.YamlFileResource;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.TestConfiguration;
|
||||
import fr.xephi.authme.settings.properties.TestEnum;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
@ -21,8 +23,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static fr.xephi.authme.settings.TestSettingsMigrationServices.checkAllPropertiesPresent;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@ -35,10 +35,8 @@ public class SettingsIntegrationTest {
|
||||
private static final String COMPLETE_FILE = TestHelper.PROJECT_ROOT + "settings/config-sample-values.yml";
|
||||
/** File name of the sample config missing certain {@link TestConfiguration} values. */
|
||||
private static final String INCOMPLETE_FILE = TestHelper.PROJECT_ROOT + "settings/config-incomplete-sample.yml";
|
||||
/** File name for testing difficult values. */
|
||||
private static final String DIFFICULT_FILE = TestHelper.PROJECT_ROOT + "settings/config-difficult-values.yml";
|
||||
|
||||
private static PropertyMap propertyMap = TestConfiguration.generatePropertyMap();
|
||||
private static List<PropertyEntry> propertyMap = TestConfiguration.generatePropertyMap();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
@ -58,13 +56,13 @@ public class SettingsIntegrationTest {
|
||||
@Test
|
||||
public void shouldLoadAndReadAllProperties() throws IOException {
|
||||
// given
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(copyFileFromResources(COMPLETE_FILE));
|
||||
PropertyResource resource = new YamlFileResource(copyFileFromResources(COMPLETE_FILE));
|
||||
// Pass another, non-existent file to check if the settings had to be rewritten
|
||||
File newFile = temporaryFolder.newFile();
|
||||
|
||||
// when / then
|
||||
Settings settings = new Settings(configuration, newFile, testPluginFolder, propertyMap,
|
||||
checkAllPropertiesPresent());
|
||||
Settings settings = new Settings(testPluginFolder, propertyMap, resource,
|
||||
new PlainMigrationService());
|
||||
Map<Property<?>, Object> expectedValues = ImmutableMap.<Property<?>, Object>builder()
|
||||
.put(TestConfiguration.DURATION_IN_SECONDS, 22)
|
||||
.put(TestConfiguration.SYSTEM_NAME, "Custom sys name")
|
||||
@ -88,16 +86,16 @@ public class SettingsIntegrationTest {
|
||||
public void shouldWriteMissingProperties() {
|
||||
// given/when
|
||||
File file = copyFileFromResources(INCOMPLETE_FILE);
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(file);
|
||||
PropertyResource resource = new YamlFileResource(file);
|
||||
// Expectation: File is rewritten to since it does not have all configurations
|
||||
new Settings(configuration, file, testPluginFolder, propertyMap, checkAllPropertiesPresent());
|
||||
new Settings(testPluginFolder, propertyMap, resource, new PlainMigrationService());
|
||||
|
||||
// Load the settings again -> checks that what we wrote can be loaded again
|
||||
configuration = YamlConfiguration.loadConfiguration(file);
|
||||
resource = new YamlFileResource(file);
|
||||
|
||||
// then
|
||||
Settings settings = new Settings(configuration, file, testPluginFolder, propertyMap,
|
||||
checkAllPropertiesPresent());
|
||||
Settings settings = new Settings(testPluginFolder, propertyMap, resource,
|
||||
new PlainMigrationService());
|
||||
Map<Property<?>, Object> expectedValues = ImmutableMap.<Property<?>, Object>builder()
|
||||
.put(TestConfiguration.DURATION_IN_SECONDS, 22)
|
||||
.put(TestConfiguration.SYSTEM_NAME, "[TestDefaultValue]")
|
||||
@ -116,62 +114,11 @@ public class SettingsIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
/** Verify that "difficult cases" such as apostrophes in strings etc. are handled properly. */
|
||||
@Test
|
||||
public void shouldProperlyExportAnyValues() {
|
||||
// given
|
||||
File file = copyFileFromResources(DIFFICULT_FILE);
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(file);
|
||||
|
||||
// Additional string properties
|
||||
List<Property<String>> additionalProperties = Arrays.asList(
|
||||
newProperty("more.string1", "it's a text with some \\'apostrophes'"),
|
||||
newProperty("more.string2", "\tthis one\nhas some\nnew '' lines-test")
|
||||
);
|
||||
for (Property<?> property : additionalProperties) {
|
||||
propertyMap.put(property, new String[0]);
|
||||
}
|
||||
|
||||
// when
|
||||
new Settings(configuration, file, testPluginFolder, propertyMap, checkAllPropertiesPresent());
|
||||
// reload the file as settings should have been rewritten
|
||||
configuration = YamlConfiguration.loadConfiguration(file);
|
||||
|
||||
// then
|
||||
// assert that we won't rewrite the settings again! One rewrite should produce a valid, complete configuration
|
||||
File unusedFile = new File("config-difficult-values.unused.yml");
|
||||
Settings settings = new Settings(configuration, unusedFile, testPluginFolder, propertyMap,
|
||||
checkAllPropertiesPresent());
|
||||
assertThat(unusedFile.exists(), equalTo(false));
|
||||
assertThat(configuration.contains(TestConfiguration.DUST_LEVEL.getPath()), equalTo(true));
|
||||
|
||||
Map<Property<?>, Object> expectedValues = ImmutableMap.<Property<?>, Object>builder()
|
||||
.put(TestConfiguration.DURATION_IN_SECONDS, 20)
|
||||
.put(TestConfiguration.SYSTEM_NAME, "A 'test' name")
|
||||
.put(TestConfiguration.RATIO_ORDER, TestEnum.FOURTH)
|
||||
.put(TestConfiguration.RATIO_FIELDS, Arrays.asList("Australia\\", "\tBurundi'", "Colombia?\n''"))
|
||||
.put(TestConfiguration.VERSION_NUMBER, -1337)
|
||||
.put(TestConfiguration.SKIP_BORING_FEATURES, false)
|
||||
.put(TestConfiguration.BORING_COLORS, Arrays.asList("it's a difficult string!", "gray\nwith new lines\n"))
|
||||
.put(TestConfiguration.DUST_LEVEL, -1)
|
||||
.put(TestConfiguration.USE_COOL_FEATURES, true)
|
||||
.put(TestConfiguration.COOL_OPTIONS, Collections.EMPTY_LIST)
|
||||
.put(additionalProperties.get(0), additionalProperties.get(0).getDefaultValue())
|
||||
.put(additionalProperties.get(1), additionalProperties.get(1).getDefaultValue())
|
||||
.build();
|
||||
for (Map.Entry<Property<?>, Object> entry : expectedValues.entrySet()) {
|
||||
assertThat("Property '" + entry.getKey().getPath() + "' has expected value"
|
||||
+ entry.getValue() + " but found " + settings.getProperty(entry.getKey()),
|
||||
settings.getProperty(entry.getKey()), equalTo(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReloadSettings() throws IOException {
|
||||
// given
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(temporaryFolder.newFile());
|
||||
File fullConfigFile = copyFileFromResources(COMPLETE_FILE);
|
||||
Settings settings = new Settings(configuration, fullConfigFile, testPluginFolder, propertyMap,
|
||||
PropertyResource resource = new YamlFileResource(temporaryFolder.newFile());
|
||||
Settings settings = new Settings(testPluginFolder, propertyMap, resource,
|
||||
TestSettingsMigrationServices.alwaysFulfilled());
|
||||
|
||||
// when
|
||||
|
@ -1,17 +1,18 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
import com.github.authme.configme.resource.YamlFileResource;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.properties.SettingsFieldRetriever;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.arrayWithSize;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
@ -39,13 +40,13 @@ public class SettingsMigrationServiceTest {
|
||||
public void shouldNotRewriteJarConfig() throws IOException {
|
||||
// given
|
||||
copyConfigToTestFolder();
|
||||
FileConfiguration configuration = YamlConfiguration.loadConfiguration(configTestFile);
|
||||
PropertyMap propertyMap = SettingsFieldRetriever.getAllPropertyFields();
|
||||
PropertyResource resource = new YamlFileResource(configTestFile);
|
||||
List<PropertyEntry> propertyMap = AuthMeSettingsRetriever.getAllPropertyFields();
|
||||
assumeThat(testFolder.listFiles(), arrayWithSize(1));
|
||||
SettingsMigrationService migrationService = new SettingsMigrationService();
|
||||
SettingsMigrationService migrationService = new SettingsMigrationService(testFolder);
|
||||
|
||||
// when
|
||||
boolean result = migrationService.checkAndMigrate(configuration, propertyMap, testFolder);
|
||||
boolean result = migrationService.checkAndMigrate(resource, propertyMap);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(false));
|
||||
|
@ -1,22 +1,23 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.github.authme.configme.migration.PlainMigrationService;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.TestConfiguration;
|
||||
import fr.xephi.authme.settings.properties.TestEnum;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.mockito.internal.stubbing.answers.ReturnsArgumentAt;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.MESSAGES_LANGUAGE;
|
||||
@ -28,13 +29,9 @@ import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyDouble;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
@ -56,38 +53,12 @@ public class SettingsTest {
|
||||
testPluginFolder = temporaryFolder.newFolder();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLoadAllConfigs() {
|
||||
// given
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.getString(anyString(), anyString())).willAnswer(new ReturnsArgumentAt(1));
|
||||
given(configuration.getBoolean(anyString(), anyBoolean())).willAnswer(new ReturnsArgumentAt(1));
|
||||
given(configuration.getDouble(anyString(), anyDouble())).willAnswer(new ReturnsArgumentAt(1));
|
||||
given(configuration.getInt(anyString(), anyInt())).willAnswer(new ReturnsArgumentAt(1));
|
||||
|
||||
setReturnValue(configuration, TestConfiguration.VERSION_NUMBER, 20);
|
||||
setReturnValue(configuration, TestConfiguration.SKIP_BORING_FEATURES, true);
|
||||
setReturnValue(configuration, TestConfiguration.RATIO_ORDER, TestEnum.THIRD);
|
||||
setReturnValue(configuration, TestConfiguration.SYSTEM_NAME, "myTestSys");
|
||||
|
||||
// when / then
|
||||
Settings settings = new Settings(configuration, null, null, null, null);
|
||||
|
||||
assertThat(settings.getProperty(TestConfiguration.VERSION_NUMBER), equalTo(20));
|
||||
assertThat(settings.getProperty(TestConfiguration.SKIP_BORING_FEATURES), equalTo(true));
|
||||
assertThat(settings.getProperty(TestConfiguration.RATIO_ORDER), equalTo(TestEnum.THIRD));
|
||||
assertThat(settings.getProperty(TestConfiguration.SYSTEM_NAME), equalTo("myTestSys"));
|
||||
|
||||
assertDefaultValue(TestConfiguration.DURATION_IN_SECONDS, settings);
|
||||
assertDefaultValue(TestConfiguration.DUST_LEVEL, settings);
|
||||
assertDefaultValue(TestConfiguration.COOL_OPTIONS, settings);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnDefaultFile() throws IOException {
|
||||
// given
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
Settings settings = new Settings(configuration, null, null, null, null);
|
||||
PropertyResource resource = mock(PropertyResource.class);
|
||||
List<PropertyEntry> knownProperties = Collections.emptyList();
|
||||
Settings settings = new Settings(testPluginFolder, knownProperties, resource, new PlainMigrationService());
|
||||
|
||||
// when
|
||||
String defaultFile = settings.getDefaultMessagesFile();
|
||||
@ -99,19 +70,6 @@ public class SettingsTest {
|
||||
assertThat(stream.read(), not(equalTo(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSetProperty() {
|
||||
// given
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
Settings settings = new Settings(configuration, null, null, null, null);
|
||||
|
||||
// when
|
||||
settings.setProperty(TestConfiguration.DUST_LEVEL, -4);
|
||||
|
||||
// then
|
||||
verify(configuration).set(TestConfiguration.DUST_LEVEL.getPath(), -4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnMessagesFile() {
|
||||
// given
|
||||
@ -120,11 +78,11 @@ public class SettingsTest {
|
||||
File file = new File(testPluginFolder, makePath("messages", "messages_" + languageCode + ".yml"));
|
||||
createFile(file);
|
||||
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.contains(anyString())).willReturn(true);
|
||||
setReturnValue(configuration, MESSAGES_LANGUAGE, languageCode);
|
||||
Settings settings = new Settings(configuration, null, testPluginFolder,
|
||||
TestConfiguration.generatePropertyMap(), TestSettingsMigrationServices.alwaysFulfilled());
|
||||
PropertyResource resource = mock(PropertyResource.class);
|
||||
given(resource.contains(anyString())).willReturn(true);
|
||||
setReturnValue(resource, MESSAGES_LANGUAGE, languageCode);
|
||||
Settings settings = new Settings(testPluginFolder, TestConfiguration.generatePropertyMap(),
|
||||
resource, TestSettingsMigrationServices.alwaysFulfilled());
|
||||
|
||||
// when
|
||||
File messagesFile = settings.getMessagesFile();
|
||||
@ -137,11 +95,11 @@ public class SettingsTest {
|
||||
@Test
|
||||
public void shouldCopyDefaultForUnknownLanguageCode() {
|
||||
// given
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.contains(anyString())).willReturn(true);
|
||||
setReturnValue(configuration, MESSAGES_LANGUAGE, "doesntexist");
|
||||
Settings settings = new Settings(configuration, null, testPluginFolder,
|
||||
TestConfiguration.generatePropertyMap(), TestSettingsMigrationServices.alwaysFulfilled());
|
||||
PropertyResource resource = mock(PropertyResource.class);
|
||||
given(resource.contains(anyString())).willReturn(true);
|
||||
setReturnValue(resource, MESSAGES_LANGUAGE, "doesntexist");
|
||||
Settings settings = new Settings(testPluginFolder, TestConfiguration.generatePropertyMap(),
|
||||
resource, TestSettingsMigrationServices.alwaysFulfilled());
|
||||
|
||||
// when
|
||||
File messagesFile = settings.getMessagesFile();
|
||||
@ -159,10 +117,10 @@ public class SettingsTest {
|
||||
createFile(welcomeFile);
|
||||
Files.write(welcomeFile.toPath(), welcomeMessage.getBytes());
|
||||
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
setReturnValue(configuration, RegistrationSettings.USE_WELCOME_MESSAGE, true);
|
||||
Settings settings = new Settings(configuration, null, testPluginFolder,
|
||||
TestConfiguration.generatePropertyMap(), TestSettingsMigrationServices.alwaysFulfilled());
|
||||
PropertyResource resource = mock(PropertyResource.class);
|
||||
setReturnValue(resource, RegistrationSettings.USE_WELCOME_MESSAGE, true);
|
||||
Settings settings = new Settings(testPluginFolder, TestConfiguration.generatePropertyMap(),
|
||||
resource, TestSettingsMigrationServices.alwaysFulfilled());
|
||||
|
||||
// when
|
||||
List<String> result = settings.getWelcomeMessage();
|
||||
@ -181,9 +139,9 @@ public class SettingsTest {
|
||||
createFile(emailFile);
|
||||
Files.write(emailFile.toPath(), emailMessage.getBytes());
|
||||
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
Settings settings = new Settings(configuration, null, testPluginFolder,
|
||||
TestConfiguration.generatePropertyMap(), TestSettingsMigrationServices.alwaysFulfilled());
|
||||
PropertyResource resource = mock(PropertyResource.class);
|
||||
Settings settings = new Settings(testPluginFolder, TestConfiguration.generatePropertyMap(),
|
||||
resource, TestSettingsMigrationServices.alwaysFulfilled());
|
||||
|
||||
// when
|
||||
String result = settings.getEmailMessage();
|
||||
@ -192,26 +150,21 @@ public class SettingsTest {
|
||||
assertThat(result, equalTo(emailMessage));
|
||||
}
|
||||
|
||||
private static <T> void setReturnValue(YamlConfiguration config, Property<T> property, T value) {
|
||||
private static <T> void setReturnValue(PropertyResource resource, Property<T> property, T value) {
|
||||
if (value instanceof String) {
|
||||
when(config.getString(eq(property.getPath()), anyString())).thenReturn((String) value);
|
||||
when(resource.getString(eq(property.getPath()))).thenReturn((String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
when(config.getInt(eq(property.getPath()), anyInt())).thenReturn((Integer) value);
|
||||
when(resource.getInt(eq(property.getPath()))).thenReturn((Integer) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
when(config.getBoolean(eq(property.getPath()), anyBoolean())).thenReturn((Boolean) value);
|
||||
when(resource.getBoolean(eq(property.getPath()))).thenReturn((Boolean) value);
|
||||
} else if (value instanceof Enum<?>) {
|
||||
when(config.getString(property.getPath())).thenReturn(((Enum<?>) value).name());
|
||||
when(resource.getString(property.getPath())).thenReturn(((Enum<?>) value).name());
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Value has unsupported type '"
|
||||
+ (value == null ? "null" : value.getClass().getSimpleName()) + "'");
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertDefaultValue(Property<?> property, Settings setting) {
|
||||
assertThat(property.getPath() + " has default value",
|
||||
setting.getProperty(property).equals(property.getDefaultValue()), equalTo(true));
|
||||
}
|
||||
|
||||
private static void createFile(File file) {
|
||||
try {
|
||||
file.getParentFile().mkdirs();
|
||||
|
@ -1,12 +1,13 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import com.github.authme.configme.migration.MigrationService;
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import com.github.authme.configme.resource.PropertyResource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides {@link SettingsMigrationService} implementations for testing.
|
||||
* Provides {@link MigrationService} implementations for testing.
|
||||
*/
|
||||
public final class TestSettingsMigrationServices {
|
||||
|
||||
@ -18,32 +19,12 @@ public final class TestSettingsMigrationServices {
|
||||
*
|
||||
* @return test settings migration service
|
||||
*/
|
||||
public static SettingsMigrationService alwaysFulfilled() {
|
||||
return new SettingsMigrationService() {
|
||||
public static MigrationService alwaysFulfilled() {
|
||||
return new MigrationService() {
|
||||
@Override
|
||||
public boolean checkAndMigrate(FileConfiguration configuration, PropertyMap propertyMap, File pluginFolder) {
|
||||
public boolean checkAndMigrate(PropertyResource propertyResource, List<PropertyEntry> list) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean containsAllSettings(FileConfiguration configuration, PropertyMap propertyMap) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple settings migration service which is fulfilled if all properties are present.
|
||||
*
|
||||
* @return test settings migration service
|
||||
*/
|
||||
public static SettingsMigrationService checkAllPropertiesPresent() {
|
||||
return new SettingsMigrationService() {
|
||||
// See parent javadoc: true = some migration had to be done, false = config file is up-to-date
|
||||
@Override
|
||||
public boolean checkAndMigrate(FileConfiguration configuration, PropertyMap propertyMap, File pluginFolder) {
|
||||
return !super.containsAllSettings(configuration, propertyMap);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,112 +0,0 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Test for {@link EnumProperty}.
|
||||
*/
|
||||
public class EnumPropertyTest {
|
||||
|
||||
@Test
|
||||
public void shouldReturnCorrectEnumValue() {
|
||||
// given
|
||||
Property<TestEnum> property = Property.newProperty(TestEnum.class, "enum.path", TestEnum.ENTRY_C);
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.getString(property.getPath())).willReturn("Entry_B");
|
||||
|
||||
// when
|
||||
TestEnum result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(TestEnum.ENTRY_B));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFallBackToDefaultForInvalidValue() {
|
||||
// given
|
||||
Property<TestEnum> property = Property.newProperty(TestEnum.class, "enum.path", TestEnum.ENTRY_C);
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.getString(property.getPath())).willReturn("Bogus");
|
||||
|
||||
// when
|
||||
TestEnum result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(TestEnum.ENTRY_C));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFallBackToDefaultForNonExistentValue() {
|
||||
// given
|
||||
Property<TestEnum> property = Property.newProperty(TestEnum.class, "enum.path", TestEnum.ENTRY_C);
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.getString(property.getPath())).willReturn(null);
|
||||
|
||||
// when
|
||||
TestEnum result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(TestEnum.ENTRY_C));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnTrueForContainsCheck() {
|
||||
// given
|
||||
Property<TestEnum> property = Property.newProperty(TestEnum.class, "my.test.path", TestEnum.ENTRY_C);
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.contains(property.getPath())).willReturn(true);
|
||||
given(configuration.getString(property.getPath())).willReturn("ENTRY_B");
|
||||
|
||||
// when
|
||||
boolean result = property.isPresent(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnFalseForFileWithoutConfig() {
|
||||
// given
|
||||
Property<TestEnum> property = Property.newProperty(TestEnum.class, "my.test.path", TestEnum.ENTRY_C);
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.contains(property.getPath())).willReturn(false);
|
||||
|
||||
// when
|
||||
boolean result = property.isPresent(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnFalseForUnknownValue() {
|
||||
// given
|
||||
Property<TestEnum> property = Property.newProperty(TestEnum.class, "my.test.path", TestEnum.ENTRY_C);
|
||||
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||
given(configuration.contains(property.getPath())).willReturn(true);
|
||||
given(configuration.getString(property.getPath())).willReturn("wrong value");
|
||||
|
||||
// when
|
||||
boolean result = property.isPresent(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(false));
|
||||
}
|
||||
|
||||
|
||||
private enum TestEnum {
|
||||
|
||||
ENTRY_A,
|
||||
|
||||
ENTRY_B,
|
||||
|
||||
ENTRY_C
|
||||
|
||||
}
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.internal.stubbing.answers.ReturnsArgumentAt;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Test for {@link Property} and the contained subtypes.
|
||||
*/
|
||||
public class PropertyTest {
|
||||
|
||||
private static YamlConfiguration configuration;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpYamlConfigurationMock() {
|
||||
configuration = mock(YamlConfiguration.class);
|
||||
|
||||
when(configuration.getBoolean(eq("bool.path.test"), anyBoolean())).thenReturn(true);
|
||||
when(configuration.getBoolean(eq("bool.path.wrong"), anyBoolean())).thenAnswer(new ReturnsArgumentAt(1));
|
||||
when(configuration.getInt(eq("int.path.test"), anyInt())).thenReturn(27);
|
||||
when(configuration.getInt(eq("int.path.wrong"), anyInt())).thenAnswer(new ReturnsArgumentAt(1));
|
||||
when(configuration.getString(eq("str.path.test"), anyString())).thenReturn("Test value");
|
||||
when(configuration.getString(eq("str.path.wrong"), anyString())).thenAnswer(new ReturnsArgumentAt(1));
|
||||
when(configuration.isList("list.path.test")).thenReturn(true);
|
||||
when(configuration.getStringList("list.path.test")).thenReturn(Arrays.asList("test1", "Test2", "3rd test"));
|
||||
when(configuration.isList("list.path.wrong")).thenReturn(false);
|
||||
when(configuration.isList("lowercaselist.path.test")).thenReturn(true);
|
||||
when(configuration.getStringList("lowercaselist.path.test")).thenReturn(Arrays.asList("test1", "Test2", "3rd test"));
|
||||
when(configuration.isList("lowercaselist.path.wrong")).thenReturn(false);
|
||||
}
|
||||
|
||||
/* Boolean */
|
||||
@Test
|
||||
public void shouldGetBoolValue() {
|
||||
// given
|
||||
Property<Boolean> property = Property.newProperty("bool.path.test", false);
|
||||
|
||||
// when
|
||||
boolean result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetBoolDefault() {
|
||||
// given
|
||||
Property<Boolean> property = Property.newProperty("bool.path.wrong", true);
|
||||
|
||||
// when
|
||||
boolean result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
/* Integer */
|
||||
@Test
|
||||
public void shouldGetIntValue() {
|
||||
// given
|
||||
Property<Integer> property = Property.newProperty("int.path.test", 3);
|
||||
|
||||
// when
|
||||
int result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(27));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetIntDefault() {
|
||||
// given
|
||||
Property<Integer> property = Property.newProperty("int.path.wrong", -10);
|
||||
|
||||
// when
|
||||
int result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(-10));
|
||||
}
|
||||
|
||||
/* String */
|
||||
@Test
|
||||
public void shouldGetStringValue() {
|
||||
// given
|
||||
Property<String> property = Property.newProperty("str.path.test", "unused default");
|
||||
|
||||
// when
|
||||
String result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo("Test value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetStringDefault() {
|
||||
// given
|
||||
Property<String> property = Property.newProperty("str.path.wrong", "given default value");
|
||||
|
||||
// when
|
||||
String result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo("given default value"));
|
||||
}
|
||||
|
||||
/* String list */
|
||||
@Test
|
||||
public void shouldGetStringListValue() {
|
||||
// given
|
||||
Property<List<String>> property = Property.newListProperty("list.path.test", "1", "b");
|
||||
|
||||
// when
|
||||
List<String> result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, contains("test1", "Test2", "3rd test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetStringListDefault() {
|
||||
// given
|
||||
Property<List<String>> property =
|
||||
Property.newListProperty("list.path.wrong", "default", "list", "elements");
|
||||
|
||||
// when
|
||||
List<String> result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, contains("default", "list", "elements"));
|
||||
}
|
||||
|
||||
/* Lowercase String list */
|
||||
@Test
|
||||
public void shouldGetLowercaseStringListValue() {
|
||||
// given
|
||||
Property<List<String>> property = Property.newLowercaseListProperty("lowercaselist.path.test", "1", "b");
|
||||
|
||||
// when
|
||||
List<String> result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, contains("test1", "test2", "3rd test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetLowercaseStringListDefault() {
|
||||
// given
|
||||
Property<List<String>> property =
|
||||
Property.newLowercaseListProperty("lowercaselist.path.wrong", "default", "list", "elements");
|
||||
|
||||
// when
|
||||
List<String> result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, contains("default", "list", "elements"));
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -20,12 +20,12 @@ import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Test for {@link SettingsClass} implementations.
|
||||
* Test for {@link SettingsHolder} implementations.
|
||||
*/
|
||||
public class SettingsClassConsistencyTest {
|
||||
|
||||
private static final String SETTINGS_FOLDER = "src/main/java/fr/xephi/authme/settings/properties";
|
||||
private static List<Class<? extends SettingsClass>> classes;
|
||||
private static List<Class<? extends SettingsHolder>> classes;
|
||||
|
||||
@BeforeClass
|
||||
public static void scanForSettingsClasses() {
|
||||
@ -37,7 +37,7 @@ public class SettingsClassConsistencyTest {
|
||||
|
||||
classes = new ArrayList<>();
|
||||
for (File file : filesInFolder) {
|
||||
Class<? extends SettingsClass> clazz = getSettingsClassFromFile(file);
|
||||
Class<? extends SettingsHolder> clazz = getSettingsClassFromFile(file);
|
||||
if (clazz != null) {
|
||||
classes.add(clazz);
|
||||
}
|
||||
@ -95,15 +95,15 @@ public class SettingsClassConsistencyTest {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Class<? extends SettingsClass> getSettingsClassFromFile(File file) {
|
||||
private static Class<? extends SettingsHolder> getSettingsClassFromFile(File file) {
|
||||
String fileName = file.getPath();
|
||||
String className = fileName
|
||||
.substring("src/main/java/".length(), fileName.length() - ".java".length())
|
||||
.replace(File.separator, ".");
|
||||
try {
|
||||
Class<?> clazz = SettingsClassConsistencyTest.class.getClassLoader().loadClass(className);
|
||||
if (SettingsClass.class.isAssignableFrom(clazz)) {
|
||||
return (Class<? extends SettingsClass>) clazz;
|
||||
if (SettingsHolder.class.isAssignableFrom(clazz)) {
|
||||
return (Class<? extends SettingsHolder>) clazz;
|
||||
}
|
||||
return null;
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
@ -1,20 +1,21 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import com.github.authme.configme.SettingsHolder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import com.github.authme.configme.propertymap.PropertyEntry;
|
||||
import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newListProperty;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newListProperty;
|
||||
import static com.github.authme.configme.properties.PropertyInitializer.newProperty;
|
||||
|
||||
/**
|
||||
* Sample properties for testing purposes.
|
||||
*/
|
||||
public final class TestConfiguration implements SettingsClass {
|
||||
public final class TestConfiguration implements SettingsHolder {
|
||||
|
||||
public static final Property<Integer> DURATION_IN_SECONDS =
|
||||
newProperty("test.duration", 4);
|
||||
@ -55,17 +56,17 @@ public final class TestConfiguration implements SettingsClass {
|
||||
*
|
||||
* @return The generated property map
|
||||
*/
|
||||
public static PropertyMap generatePropertyMap() {
|
||||
PropertyMap propertyMap = new PropertyMap();
|
||||
public static List<PropertyEntry> generatePropertyMap() {
|
||||
List<PropertyEntry> properties = new ArrayList<>();
|
||||
for (Field field : TestConfiguration.class.getDeclaredFields()) {
|
||||
Object fieldValue = ReflectionTestUtils.getFieldValue(TestConfiguration.class, null, field.getName());
|
||||
if (fieldValue instanceof Property<?>) {
|
||||
Property<?> property = (Property<?>) fieldValue;
|
||||
String[] comments = new String[]{"Comment for '" + property.getPath() + "'"};
|
||||
propertyMap.put(property, comments);
|
||||
properties.add(new PropertyEntry(property, comments));
|
||||
}
|
||||
}
|
||||
return propertyMap;
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
package fr.xephi.authme.settings.propertymap;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Test for {@link PropertyMap}.
|
||||
*/
|
||||
public class PropertyMapTest {
|
||||
|
||||
@Test
|
||||
public void shouldKeepEntriesByInsertionAndGroup() {
|
||||
// given
|
||||
List<String> paths = Arrays.asList("japan", "indonesia.jakarta", "japan.tokyo", "china.shanghai", "egypt.cairo",
|
||||
"china.shenzhen", "china", "indonesia.jakarta.tugu", "egypt", "japan.nagoya", "japan.tokyo.taito");
|
||||
PropertyMap map = new PropertyMap();
|
||||
|
||||
// when
|
||||
for (String path : paths) {
|
||||
Property<?> property = createPropertyWithPath(path);
|
||||
map.put(property, new String[0]);
|
||||
}
|
||||
|
||||
// then
|
||||
Set<Map.Entry<Property<?>, String[]>> entrySet = map.entrySet();
|
||||
List<String> resultPaths = new ArrayList<>(entrySet.size());
|
||||
for (Map.Entry<Property<?>, String[]> entry : entrySet) {
|
||||
resultPaths.add(entry.getKey().getPath());
|
||||
}
|
||||
|
||||
Assert.assertThat(resultPaths, contains("japan", "japan.tokyo", "japan.tokyo.taito", "japan.nagoya",
|
||||
"indonesia.jakarta", "indonesia.jakarta.tugu", "china", "china.shanghai", "china.shenzhen",
|
||||
"egypt", "egypt.cairo"));
|
||||
}
|
||||
|
||||
private static Property<?> createPropertyWithPath(String path) {
|
||||
Property<?> property = mock(Property.class);
|
||||
when(property.getPath()).thenReturn(path);
|
||||
return property;
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package tools.hashmethods;
|
||||
|
||||
import ch.jalu.injector.Injector;
|
||||
import ch.jalu.injector.InjectorBuilder;
|
||||
import com.github.authme.configme.properties.Property;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
import fr.xephi.authme.security.crypts.HexSaltedMethod;
|
||||
@ -9,7 +10,6 @@ import fr.xephi.authme.security.crypts.description.AsciiRestricted;
|
||||
import fr.xephi.authme.security.crypts.description.HasSalt;
|
||||
import fr.xephi.authme.security.crypts.description.Recommendation;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
# Test config file with some "difficult" values
|
||||
|
||||
test:
|
||||
duration: 20.102
|
||||
systemName: 'A ''test'' name'
|
||||
sample:
|
||||
ratio:
|
||||
order: Fourth
|
||||
fields:
|
||||
- Australia\
|
||||
- ' Burundi'''
|
||||
- 'Colombia?
|
||||
|
||||
'''''
|
||||
# The last element above represents "Colombia?\n''"
|
||||
version: -1337
|
||||
features:
|
||||
boring:
|
||||
# YAML allows both "yes"/"no" and "true"/"false" for expressing booleans
|
||||
skip: no
|
||||
colors:
|
||||
- 'it''s a difficult string!'
|
||||
- |
|
||||
gray
|
||||
with new lines
|
||||
# dustLevel: 8 <-- missing property triggering rewrite
|
||||
cool:
|
||||
enabled: yes
|
||||
options: []
|
Loading…
Reference in New Issue
Block a user