diff --git a/pom.xml b/pom.xml index f72e0d553..4a836e44e 100644 --- a/pom.xml +++ b/pom.xml @@ -543,7 +543,7 @@ ch.jalu configme - 0.4.1 + 1.0.1 true diff --git a/src/main/java/fr/xephi/authme/message/updater/JarMessageSource.java b/src/main/java/fr/xephi/authme/message/updater/JarMessageSource.java index 34c95a6ce..f1996f236 100644 --- a/src/main/java/fr/xephi/authme/message/updater/JarMessageSource.java +++ b/src/main/java/fr/xephi/authme/message/updater/JarMessageSource.java @@ -39,7 +39,7 @@ public class JarMessageSource { } private static String getString(String path, PropertyReader reader) { - return reader == null ? null : reader.getTypedObject(path, String.class); + return reader == null ? null : reader.getString(path); } private static MessageMigraterPropertyReader loadJarFile(String jarPath) { diff --git a/src/main/java/fr/xephi/authme/message/updater/MessageKeyConfigurationData.java b/src/main/java/fr/xephi/authme/message/updater/MessageKeyConfigurationData.java new file mode 100644 index 000000000..50f948f4b --- /dev/null +++ b/src/main/java/fr/xephi/authme/message/updater/MessageKeyConfigurationData.java @@ -0,0 +1,43 @@ +package fr.xephi.authme.message.updater; + +import ch.jalu.configme.configurationdata.ConfigurationDataImpl; +import ch.jalu.configme.properties.Property; +import ch.jalu.configme.resource.PropertyReader; +import fr.xephi.authme.message.MessageKey; + +import java.util.List; +import java.util.Map; + +public class MessageKeyConfigurationData extends ConfigurationDataImpl { + + /** + * Constructor. + * + * @param propertyListBuilder property list builder for message key properties + * @param allComments registered comments + */ + public MessageKeyConfigurationData(MessageUpdater.MessageKeyPropertyListBuilder propertyListBuilder, + Map> allComments) { + super(propertyListBuilder.getAllProperties(), allComments); + } + + @Override + public void initializeValues(PropertyReader reader) { + getAllMessageProperties().stream() + .filter(prop -> prop.isPresent(reader)) + .forEach(prop -> setValue(prop, prop.determineValue(reader))); + } + + @SuppressWarnings("unchecked") + public List> getAllMessageProperties() { + return (List) getProperties(); + } + + public String getMessage(MessageKey messageKey) { + return getValue(new MessageUpdater.MessageKeyProperty(messageKey)); + } + + public void setMessage(MessageKey messageKey, String message) { + setValue(new MessageUpdater.MessageKeyProperty(messageKey), message); + } +} diff --git a/src/main/java/fr/xephi/authme/message/updater/MessageMigraterPropertyReader.java b/src/main/java/fr/xephi/authme/message/updater/MessageMigraterPropertyReader.java index ab9f8d3b8..a41b53409 100644 --- a/src/main/java/fr/xephi/authme/message/updater/MessageMigraterPropertyReader.java +++ b/src/main/java/fr/xephi/authme/message/updater/MessageMigraterPropertyReader.java @@ -12,20 +12,19 @@ import java.io.InputStreamReader; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Objects; +import java.util.Set; /** * Implementation of {@link PropertyReader} which can read a file or a stream with * a specified charset. */ -public final class MessageMigraterPropertyReader implements PropertyReader { +final class MessageMigraterPropertyReader implements PropertyReader { - public static final Charset CHARSET = StandardCharsets.UTF_8; + private static final Charset CHARSET = StandardCharsets.UTF_8; private Map root; - /** See same field in {@link ch.jalu.configme.resource.YamlFileReader} for details. */ - private boolean hasObjectAsRoot = false; private MessageMigraterPropertyReader(Map valuesMap) { root = valuesMap; @@ -38,14 +37,11 @@ public final class MessageMigraterPropertyReader implements PropertyReader { * @return the created property reader */ public static MessageMigraterPropertyReader loadFromFile(File file) { - Map valuesMap; try (InputStream is = new FileInputStream(file)) { - valuesMap = readStreamToMap(is); + return loadFromStream(is); } catch (IOException e) { throw new IllegalStateException("Error while reading file '" + file + "'", e); } - - return new MessageMigraterPropertyReader(valuesMap); } public static MessageMigraterPropertyReader loadFromStream(InputStream inputStream) { @@ -53,10 +49,20 @@ public final class MessageMigraterPropertyReader implements PropertyReader { return new MessageMigraterPropertyReader(valuesMap); } + @Override + public boolean contains(String path) { + return getObject(path) != null; + } + + @Override + public Set getKeys(boolean b) { + throw new UnsupportedOperationException(); + } + @Override public Object getObject(String path) { if (path.isEmpty()) { - return hasObjectAsRoot ? root.get("") : root; + return root.get(""); } Object node = root; String[] keys = path.split("\\."); @@ -70,66 +76,29 @@ public final class MessageMigraterPropertyReader implements PropertyReader { } @Override - public T getTypedObject(String path, Class clazz) { - Object value = getObject(path); - if (clazz.isInstance(value)) { - return clazz.cast(value); - } - return null; + public String getString(String path) { + Object o = getObject(path); + return o instanceof String ? (String) o : null; } @Override - public void set(String path, Object value) { - Objects.requireNonNull(path); - - if (path.isEmpty()) { - root.clear(); - root.put("", value); - hasObjectAsRoot = true; - } else if (hasObjectAsRoot) { - throw new ConfigMeException("The root path is a bean property; you cannot set values to any subpath. " - + "Modify the bean at the root or set a new one instead."); - } else { - setValueInChildPath(path, value); - } - } - - /** - * Sets the value at the given path. This method is used when the root is a map and not a specific object. - * - * @param path the path to set the value at - * @param value the value to set - */ - @SuppressWarnings("unchecked") - private void setValueInChildPath(String path, Object value) { - Map node = root; - String[] keys = path.split("\\."); - for (int i = 0; i < keys.length - 1; ++i) { - Object child = node.get(keys[i]); - if (child instanceof Map) { - node = (Map) child; - } else { // child is null or some other value - replace with map - Map newEntry = new HashMap<>(); - node.put(keys[i], newEntry); - if (value == null) { - // For consistency, replace whatever value/null here with an empty map, - // but if the value is null our work here is done. - return; - } - node = newEntry; - } - } - // node now contains the parent map (existing or newly created) - if (value == null) { - node.remove(keys[keys.length - 1]); - } else { - node.put(keys[keys.length - 1], value); - } + public Integer getInt(String path) { + throw new UnsupportedOperationException(); } @Override - public void reload() { - throw new UnsupportedOperationException("Reload not supported by this implementation"); + public Double getDouble(String path) { + throw new UnsupportedOperationException(); + } + + @Override + public Boolean getBoolean(String path) { + throw new UnsupportedOperationException(); + } + + @Override + public List getList(String path) { + throw new UnsupportedOperationException(); } private static Map readStreamToMap(InputStream inputStream) { diff --git a/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java b/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java index 433f0b17b..895764f2b 100644 --- a/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java +++ b/src/main/java/fr/xephi/authme/message/updater/MessageUpdater.java @@ -1,10 +1,10 @@ package fr.xephi.authme.message.updater; -import ch.jalu.configme.SettingsManager; import ch.jalu.configme.configurationdata.ConfigurationData; import ch.jalu.configme.configurationdata.PropertyListBuilder; import ch.jalu.configme.properties.Property; import ch.jalu.configme.properties.StringProperty; +import ch.jalu.configme.resource.PropertyReader; import ch.jalu.configme.resource.PropertyResource; import com.google.common.collect.ImmutableMap; import com.google.common.io.Files; @@ -20,21 +20,15 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; + +import static java.util.Collections.singletonList; /** * Migrates the used messages file to a complete, up-to-date version when necessary. */ public class MessageUpdater { - /** - * Configuration data object for all message keys incl. comments associated to sections. - */ - private static final ConfigurationData CONFIGURATION_DATA = buildConfigurationData(); - - public static ConfigurationData getConfigurationData() { - return CONFIGURATION_DATA; - } - /** * Applies any necessary migrations to the user's messages file and saves it if it has been modified. * @@ -57,52 +51,57 @@ public class MessageUpdater { */ private boolean migrateAndSave(File userFile, JarMessageSource jarMessageSource) { // YamlConfiguration escapes all special characters when saving, making the file hard to use, so use ConfigMe + MessageKeyConfigurationData configurationData = createConfigurationData(); PropertyResource userResource = new MigraterYamlFileResource(userFile); + PropertyReader reader = userResource.createReader(); + configurationData.initializeValues(reader); + // Step 1: Migrate any old keys in the file to the new paths - boolean movedOldKeys = migrateOldKeys(userResource); + boolean movedOldKeys = migrateOldKeys(reader, configurationData); // Step 2: Perform newer migrations - boolean movedNewerKeys = migrateKeys(userResource); + boolean movedNewerKeys = migrateKeys(reader, configurationData); // Step 3: Take any missing messages from the message files shipped in the AuthMe JAR - boolean addedMissingKeys = addMissingKeys(jarMessageSource, userResource); + boolean addedMissingKeys = addMissingKeys(jarMessageSource, configurationData); if (movedOldKeys || movedNewerKeys || addedMissingKeys) { backupMessagesFile(userFile); - SettingsManager settingsManager = new SettingsManager(userResource, null, CONFIGURATION_DATA); - settingsManager.save(); + userResource.exportProperties(configurationData); ConsoleLogger.debug("Successfully saved {0}", userFile); return true; } return false; } - private boolean migrateKeys(PropertyResource userResource) { - return moveIfApplicable(userResource, "misc.two_factor_create", MessageKey.TWO_FACTOR_CREATE.getKey()); + private boolean migrateKeys(PropertyReader propertyReader, MessageKeyConfigurationData configurationData) { + return moveIfApplicable(propertyReader, configurationData, + "misc.two_factor_create", MessageKey.TWO_FACTOR_CREATE); } - private static boolean moveIfApplicable(PropertyResource resource, String oldPath, String newPath) { - if (resource.getString(newPath) == null && resource.getString(oldPath) != null) { - resource.setValue(newPath, resource.getString(oldPath)); + private static boolean moveIfApplicable(PropertyReader reader, MessageKeyConfigurationData configurationData, + String oldPath, MessageKey messageKey) { + if (configurationData.getMessage(messageKey) == null && reader.getString(oldPath) != null) { + configurationData.setMessage(messageKey, reader.getString(oldPath)); return true; } return false; } - private boolean migrateOldKeys(PropertyResource userResource) { - boolean hasChange = OldMessageKeysMigrater.migrateOldPaths(userResource); + private boolean migrateOldKeys(PropertyReader propertyReader, MessageKeyConfigurationData configurationData) { + boolean hasChange = OldMessageKeysMigrater.migrateOldPaths(propertyReader, configurationData); if (hasChange) { ConsoleLogger.info("Old keys have been moved to the new ones in your messages_xx.yml file"); } return hasChange; } - private boolean addMissingKeys(JarMessageSource jarMessageSource, PropertyResource userResource) { + private boolean addMissingKeys(JarMessageSource jarMessageSource, MessageKeyConfigurationData configurationData) { List addedKeys = new ArrayList<>(); - for (Property property : CONFIGURATION_DATA.getProperties()) { + for (Property property : configurationData.getAllMessageProperties()) { final String key = property.getPath(); - if (userResource.getString(key) == null) { - userResource.setValue(key, jarMessageSource.getMessageFromJar(property)); + if (configurationData.getValue(property) == null) { + configurationData.setValue(property, jarMessageSource.getMessageFromJar(property)); addedKeys.add(key); } } @@ -129,40 +128,68 @@ public class MessageUpdater { * * @return the configuration data to export with */ - private static ConfigurationData buildConfigurationData() { - Map comments = ImmutableMap.builder() - .put("registration", new String[]{"Registration"}) - .put("password", new String[]{"Password errors on registration"}) - .put("login", new String[]{"Login"}) - .put("error", new String[]{"Errors"}) - .put("antibot", new String[]{"AntiBot"}) - .put("unregister", new String[]{"Unregister"}) - .put("misc", new String[]{"Other messages"}) - .put("session", new String[]{"Session messages"}) - .put("on_join_validation", new String[]{"Error messages when joining"}) - .put("email", new String[]{"Email"}) - .put("recovery", new String[]{"Password recovery by email"}) - .put("captcha", new String[]{"Captcha"}) - .put("verification", new String[]{"Verification code"}) - .put("time", new String[]{"Time units"}) - .put("two_factor", new String[]{"Two-factor authentication"}) + public static MessageKeyConfigurationData createConfigurationData() { + Map comments = ImmutableMap.builder() + .put("registration", "Registration") + .put("password", "Password errors on registration") + .put("login", "Login") + .put("error", "Errors") + .put("antibot", "AntiBot") + .put("unregister", "Unregister") + .put("misc", "Other messages") + .put("session", "Session messages") + .put("on_join_validation", "Error messages when joining") + .put("email", "Email") + .put("recovery", "Password recovery by email") + .put("captcha", "Captcha") + .put("verification", "Verification code") + .put("time", "Time units") + .put("two_factor", "Two-factor authentication") .build(); Set addedKeys = new HashSet<>(); - PropertyListBuilder builder = new PropertyListBuilder(); + MessageKeyPropertyListBuilder builder = new MessageKeyPropertyListBuilder(); // Add one key per section based on the comments map above so that the order is clear for (String path : comments.keySet()) { MessageKey key = Arrays.stream(MessageKey.values()).filter(p -> p.getKey().startsWith(path + ".")) .findFirst().orElseThrow(() -> new IllegalStateException(path)); - builder.add(new StringProperty(key.getKey(), "")); + builder.addMessageKey(key); addedKeys.add(key.getKey()); } // Add all remaining keys to the property list builder Arrays.stream(MessageKey.values()) .filter(key -> !addedKeys.contains(key.getKey())) - .forEach(key -> builder.add(new StringProperty(key.getKey(), ""))); + .forEach(builder::addMessageKey); - return new ConfigurationData(builder.create(), comments); + // Create ConfigurationData instance + Map> commentsMap = comments.entrySet().stream() + .collect(Collectors.toMap(e -> e.getKey(), e -> singletonList(e.getValue()))); + return new MessageKeyConfigurationData(builder, commentsMap); } + static final class MessageKeyProperty extends StringProperty { + + MessageKeyProperty(MessageKey messageKey) { + super(messageKey.getKey(), ""); + } + + @Override + protected String getFromReader(PropertyReader reader) { + return reader.getString(getPath()); + } + } + + static final class MessageKeyPropertyListBuilder { + + private PropertyListBuilder propertyListBuilder = new PropertyListBuilder(); + + void addMessageKey(MessageKey key) { + propertyListBuilder.add(new MessageKeyProperty(key)); + } + + @SuppressWarnings("unchecked") + List getAllProperties() { + return (List) propertyListBuilder.create(); + } + } } diff --git a/src/main/java/fr/xephi/authme/message/updater/MigraterYamlFileResource.java b/src/main/java/fr/xephi/authme/message/updater/MigraterYamlFileResource.java index 69b580ae1..c8b6755bf 100644 --- a/src/main/java/fr/xephi/authme/message/updater/MigraterYamlFileResource.java +++ b/src/main/java/fr/xephi/authme/message/updater/MigraterYamlFileResource.java @@ -1,41 +1,30 @@ package fr.xephi.authme.message.updater; -import ch.jalu.configme.beanmapper.leafproperties.LeafPropertiesGenerator; -import ch.jalu.configme.configurationdata.ConfigurationData; -import ch.jalu.configme.exception.ConfigMeException; -import ch.jalu.configme.properties.Property; -import ch.jalu.configme.resource.PropertyPathTraverser; +import ch.jalu.configme.resource.PropertyReader; import ch.jalu.configme.resource.YamlFileResource; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.List; - -import static fr.xephi.authme.message.updater.MessageMigraterPropertyReader.CHARSET; /** - * Extension of {@link YamlFileResource} to fine-tune the export style - * and to be able to specify the character encoding. + * Extension of {@link YamlFileResource} to fine-tune the export style. */ public class MigraterYamlFileResource extends YamlFileResource { - private static final String INDENTATION = " "; - - private final File file; private Yaml singleQuoteYaml; public MigraterYamlFileResource(File file) { - super(file, MessageMigraterPropertyReader.loadFromFile(file), new LeafPropertiesGenerator()); - this.file = file; + super(file); } @Override - protected Yaml getSingleQuoteYaml() { + public PropertyReader createReader() { + return MessageMigraterPropertyReader.loadFromFile(getFile()); + } + + @Override + protected Yaml createNewYaml() { if (singleQuoteYaml == null) { DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); @@ -47,57 +36,4 @@ public class MigraterYamlFileResource extends YamlFileResource { } return singleQuoteYaml; } - - @Override - public void exportProperties(ConfigurationData configurationData) { - try (FileOutputStream fos = new FileOutputStream(file); - OutputStreamWriter writer = new OutputStreamWriter(fos, CHARSET)) { - PropertyPathTraverser pathTraverser = new PropertyPathTraverser(configurationData); - for (Property property : convertPropertiesToExportableTypes(configurationData.getProperties())) { - - List pathElements = pathTraverser.getPathElements(property); - for (PropertyPathTraverser.PathElement pathElement : pathElements) { - writeComments(writer, pathElement.indentationLevel, pathElement.comments); - writer.append("\n") - .append(indent(pathElement.indentationLevel)) - .append(pathElement.name) - .append(":"); - } - - writer.append(" ") - .append(toYaml(property, pathElements.get(pathElements.size() - 1).indentationLevel)); - } - writer.flush(); - writer.close(); - } catch (IOException e) { - throw new ConfigMeException("Could not save config to '" + file.getPath() + "'", e); - } finally { - singleQuoteYaml = null; - } - } - - private void writeComments(Writer writer, int indentation, String[] comments) throws IOException { - if (comments.length == 0) { - return; - } - String commentStart = "\n" + indent(indentation) + "# "; - for (String comment : comments) { - writer.append(commentStart).append(comment); - } - } - - private String toYaml(Property property, int indent) { - Object value = property.getValue(this); - String representation = transformValue(property, value); - String[] lines = representation.split("\\n"); - return String.join("\n" + indent(indent), lines); - } - - private static String indent(int level) { - String result = ""; - for (int i = 0; i < level; i++) { - result += INDENTATION; - } - return result; - } } diff --git a/src/main/java/fr/xephi/authme/message/updater/OldMessageKeysMigrater.java b/src/main/java/fr/xephi/authme/message/updater/OldMessageKeysMigrater.java index c4e0c3143..739a449d3 100644 --- a/src/main/java/fr/xephi/authme/message/updater/OldMessageKeysMigrater.java +++ b/src/main/java/fr/xephi/authme/message/updater/OldMessageKeysMigrater.java @@ -1,6 +1,6 @@ package fr.xephi.authme.message.updater; -import ch.jalu.configme.resource.PropertyResource; +import ch.jalu.configme.resource.PropertyReader; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; import fr.xephi.authme.message.MessageKey; @@ -16,7 +16,6 @@ import static com.google.common.collect.ImmutableMap.of; */ final class OldMessageKeysMigrater { - @VisibleForTesting static final Map KEYS_TO_OLD_PATH = ImmutableMap.builder() .put(MessageKey.LOGIN_SUCCESS, "login") @@ -130,23 +129,26 @@ final class OldMessageKeysMigrater { /** * Migrates any existing old key paths to their new paths if no text has been defined for the new key. * - * @param resource the resource to modify and read from + * @param reader the property reader to get values from + * @param configurationData the configuration data to write to * @return true if at least one message could be migrated, false otherwise */ - static boolean migrateOldPaths(PropertyResource resource) { + static boolean migrateOldPaths(PropertyReader reader, MessageKeyConfigurationData configurationData) { boolean wasPropertyMoved = false; for (Map.Entry migrationEntry : KEYS_TO_OLD_PATH.entrySet()) { - wasPropertyMoved |= moveIfApplicable(resource, migrationEntry.getKey(), migrationEntry.getValue()); + wasPropertyMoved |= moveIfApplicable(reader, configurationData, + migrationEntry.getKey(), migrationEntry.getValue()); } return wasPropertyMoved; } - private static boolean moveIfApplicable(PropertyResource resource, MessageKey messageKey, String oldPath) { - if (resource.getString(messageKey.getKey()) == null) { - String textAtOldPath = resource.getString(oldPath); + private static boolean moveIfApplicable(PropertyReader reader, MessageKeyConfigurationData configurationData, + MessageKey messageKey, String oldPath) { + if (configurationData.getMessage(messageKey) == null) { + String textAtOldPath = reader.getString(oldPath); if (textAtOldPath != null) { textAtOldPath = replaceOldPlaceholders(messageKey, textAtOldPath); - resource.setValue(messageKey.getKey(), textAtOldPath); + configurationData.setMessage(messageKey, textAtOldPath); return true; } } diff --git a/src/main/java/fr/xephi/authme/service/ValidationService.java b/src/main/java/fr/xephi/authme/service/ValidationService.java index 2e52192fe..2583cdf77 100644 --- a/src/main/java/fr/xephi/authme/service/ValidationService.java +++ b/src/main/java/fr/xephi/authme/service/ValidationService.java @@ -23,7 +23,6 @@ import org.bukkit.entity.Player; import javax.annotation.PostConstruct; import javax.inject.Inject; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; @@ -45,7 +44,6 @@ public class ValidationService implements Reloadable { private GeoIpService geoIpService; private Pattern passwordRegex; - private Set unrestrictedNames; private Multimap restrictedNames; ValidationService() { @@ -55,8 +53,6 @@ public class ValidationService implements Reloadable { @Override public void reload() { passwordRegex = Utils.safePatternCompile(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)); - // Use Set for more efficient contains() lookup - unrestrictedNames = new HashSet<>(settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES)); restrictedNames = settings.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS) ? loadNameRestrictions(settings.getProperty(RestrictionSettings.RESTRICTED_USERS)) : HashMultimap.create(); @@ -140,7 +136,7 @@ public class ValidationService implements Reloadable { * @return true if unrestricted, false otherwise */ public boolean isUnrestricted(String name) { - return unrestrictedNames.contains(name.toLowerCase()); + return settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES).contains(name.toLowerCase()); } /** @@ -208,7 +204,7 @@ public class ValidationService implements Reloadable { * @param configuredRestrictions the restriction rules to convert to a map * @return map of allowed IPs/domain names by player name */ - private Multimap loadNameRestrictions(List configuredRestrictions) { + private Multimap loadNameRestrictions(Set configuredRestrictions) { Multimap restrictions = HashMultimap.create(); for (String restriction : configuredRestrictions) { if (isInsideString(';', restriction)) { diff --git a/src/main/java/fr/xephi/authme/service/yaml/YamlFileResourceProvider.java b/src/main/java/fr/xephi/authme/service/yaml/YamlFileResourceProvider.java index b13294371..9509d7304 100644 --- a/src/main/java/fr/xephi/authme/service/yaml/YamlFileResourceProvider.java +++ b/src/main/java/fr/xephi/authme/service/yaml/YamlFileResourceProvider.java @@ -1,7 +1,8 @@ package fr.xephi.authme.service.yaml; +import ch.jalu.configme.exception.ConfigMeException; +import ch.jalu.configme.resource.PropertyReader; import ch.jalu.configme.resource.YamlFileResource; -import org.yaml.snakeyaml.parser.ParserException; import java.io.File; @@ -15,16 +16,32 @@ public final class YamlFileResourceProvider { /** * Creates a {@link YamlFileResource} instance for the given file. Wraps SnakeYAML's parse exception - * into an AuthMe exception. + * thrown when a reader is created into an AuthMe exception. * * @param file the file to load * @return the generated resource */ public static YamlFileResource loadFromFile(File file) { - try { - return new YamlFileResource(file); - } catch (ParserException e) { - throw new YamlParseException(file.getPath(), e); + return new AuthMeYamlFileResource(file); + } + + /** + * Extension of {@link YamlFileResource} which wraps SnakeYAML's parse exception into a custom + * exception when a reader is created. + */ + private static final class AuthMeYamlFileResource extends YamlFileResource { + + AuthMeYamlFileResource(File file) { + super(file); + } + + @Override + public PropertyReader createReader() { + try { + return super.createReader(); + } catch (ConfigMeException e) { + throw new YamlParseException(getFile().getPath(), e); + } } } } diff --git a/src/main/java/fr/xephi/authme/service/yaml/YamlParseException.java b/src/main/java/fr/xephi/authme/service/yaml/YamlParseException.java index b070bcf35..5cc3283ec 100644 --- a/src/main/java/fr/xephi/authme/service/yaml/YamlParseException.java +++ b/src/main/java/fr/xephi/authme/service/yaml/YamlParseException.java @@ -1,6 +1,8 @@ package fr.xephi.authme.service.yaml; -import org.yaml.snakeyaml.parser.ParserException; +import ch.jalu.configme.exception.ConfigMeException; + +import static com.google.common.base.MoreObjects.firstNonNull; /** * Exception when a YAML file could not be parsed. @@ -13,10 +15,10 @@ public class YamlParseException extends RuntimeException { * Constructor. * * @param file the file a parsing exception occurred with - * @param snakeYamlException the caught exception from SnakeYAML + * @param configMeException the caught exception from ConfigMe */ - public YamlParseException(String file, ParserException snakeYamlException) { - super(snakeYamlException); + public YamlParseException(String file, ConfigMeException configMeException) { + super(firstNonNull(configMeException.getCause(), configMeException)); this.file = file; } diff --git a/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java b/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java index b18944aac..ca611315f 100644 --- a/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java +++ b/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java @@ -1,7 +1,7 @@ package fr.xephi.authme.settings; -import ch.jalu.configme.properties.Property; -import ch.jalu.configme.resource.PropertyResource; +import ch.jalu.configme.properties.BaseProperty; +import ch.jalu.configme.resource.PropertyReader; import java.util.Collection; import java.util.LinkedHashSet; @@ -15,7 +15,7 @@ import static com.google.common.collect.Sets.newHashSet; * * @param the enum type */ -public class EnumSetProperty> extends Property> { +public class EnumSetProperty> extends BaseProperty> { private final Class enumClass; @@ -26,8 +26,8 @@ public class EnumSetProperty> extends Property> { } @Override - protected Set getFromResource(PropertyResource resource) { - Object entry = resource.getObject(getPath()); + protected Set getFromReader(PropertyReader reader) { + Object entry = reader.getObject(getPath()); if (entry instanceof Collection) { return ((Collection) entry).stream() .map(val -> toEnum(String.valueOf(val))) @@ -45,4 +45,11 @@ public class EnumSetProperty> extends Property> { } return null; } + + @Override + public Object toExportValue(Set value) { + return value.stream() + .map(Enum::name) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index 01bf25801..5465875dc 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -1,6 +1,6 @@ package fr.xephi.authme.settings; -import ch.jalu.configme.SettingsManager; +import ch.jalu.configme.SettingsManagerImpl; import ch.jalu.configme.configurationdata.ConfigurationData; import ch.jalu.configme.migration.MigrationService; import ch.jalu.configme.resource.PropertyResource; @@ -16,7 +16,7 @@ import static fr.xephi.authme.util.FileUtils.copyFileFromResource; /** * The AuthMe settings manager. */ -public class Settings extends SettingsManager { +public class Settings extends SettingsManagerImpl { private final File pluginFolder; private String passwordEmailMessage; @@ -33,7 +33,7 @@ public class Settings extends SettingsManager { */ public Settings(File pluginFolder, PropertyResource resource, MigrationService migrationService, ConfigurationData configurationData) { - super(resource, migrationService, configurationData); + super(resource, configurationData, migrationService); this.pluginFolder = pluginFolder; loadSettingsFromFiles(); } diff --git a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java index cc671656b..2b9cdd830 100644 --- a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java +++ b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java @@ -1,8 +1,9 @@ package fr.xephi.authme.settings; +import ch.jalu.configme.configurationdata.ConfigurationData; import ch.jalu.configme.migration.PlainMigrationService; import ch.jalu.configme.properties.Property; -import ch.jalu.configme.resource.PropertyResource; +import ch.jalu.configme.resource.PropertyReader; import com.google.common.base.MoreObjects; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.initialization.DataFolder; @@ -25,6 +26,7 @@ import java.util.Set; import static ch.jalu.configme.properties.PropertyInitializer.newListProperty; import static ch.jalu.configme.properties.PropertyInitializer.newProperty; +import static fr.xephi.authme.settings.properties.DatabaseSettings.MYSQL_POOL_SIZE; 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; @@ -53,33 +55,33 @@ public class SettingsMigrationService extends PlainMigrationService { @Override @SuppressWarnings("checkstyle:BooleanExpressionComplexity") - protected boolean performMigrations(PropertyResource resource, List> properties) { + protected boolean performMigrations(PropertyReader reader, ConfigurationData configurationData) { boolean changes = false; - if ("[a-zA-Z0-9_?]*".equals(resource.getString(ALLOWED_NICKNAME_CHARACTERS.getPath()))) { - resource.setValue(ALLOWED_NICKNAME_CHARACTERS.getPath(), "[a-zA-Z0-9_]*"); + if ("[a-zA-Z0-9_?]*".equals(reader.getString(ALLOWED_NICKNAME_CHARACTERS.getPath()))) { + configurationData.setValue(ALLOWED_NICKNAME_CHARACTERS, "[a-zA-Z0-9_]*"); changes = true; } - setOldOtherAccountsCommandFieldsIfSet(resource); + setOldOtherAccountsCommandFieldsIfSet(reader); // Note ljacqu 20160211: Concatenating migration methods with | instead of the usual || // ensures that all migrations will be performed return changes - | performMailTextToFileMigration(resource) - | migrateJoinLeaveMessages(resource) - | migrateForceSpawnSettings(resource) - | migratePoolSizeSetting(resource) - | changeBooleanSettingToLogLevelProperty(resource) - | hasOldHelpHeaderProperty(resource) - | hasSupportOldPasswordProperty(resource) - | convertToRegistrationType(resource) - | mergeAndMovePermissionGroupSettings(resource) - | moveDeprecatedHashAlgorithmIntoLegacySection(resource) - | moveSaltColumnConfigWithOtherColumnConfigs(resource) - || hasDeprecatedProperties(resource); + | performMailTextToFileMigration(reader) + | migrateJoinLeaveMessages(reader, configurationData) + | migrateForceSpawnSettings(reader, configurationData) + | migratePoolSizeSetting(reader, configurationData) + | changeBooleanSettingToLogLevelProperty(reader, configurationData) + | hasOldHelpHeaderProperty(reader) + | hasSupportOldPasswordProperty(reader) + | convertToRegistrationType(reader, configurationData) + | mergeAndMovePermissionGroupSettings(reader, configurationData) + | moveDeprecatedHashAlgorithmIntoLegacySection(reader, configurationData) + | moveSaltColumnConfigWithOtherColumnConfigs(reader, configurationData) + || hasDeprecatedProperties(reader); } - private static boolean hasDeprecatedProperties(PropertyResource resource) { + private static boolean hasDeprecatedProperties(PropertyReader reader) { String[] deprecatedProperties = { "Converter.Rakamak.newPasswordHash", "Hooks.chestshop", "Hooks.legacyChestshop", "Hooks.notifications", "Passpartu", "Performances", "settings.restrictions.enablePasswordVerifier", "Xenoforo.predefinedSalt", @@ -90,7 +92,7 @@ public class SettingsMigrationService extends PlainMigrationService { "settings.sessions.sessionExpireOnIpChange", "settings.restrictions.otherAccountsCmd", "settings.restrictions.otherAccountsCmdThreshold"}; for (String deprecatedPath : deprecatedProperties) { - if (resource.contains(deprecatedPath)) { + if (reader.contains(deprecatedPath)) { return true; } } @@ -119,12 +121,12 @@ public class SettingsMigrationService extends PlainMigrationService { /** * Check if {@code Email.mailText} is present and move it to the Email.html file if it doesn't exist yet. * - * @param resource The property resource + * @param reader The property reader * @return True if a migration has been completed, false otherwise */ - private boolean performMailTextToFileMigration(PropertyResource resource) { + private boolean performMailTextToFileMigration(PropertyReader reader) { final String oldSettingPath = "Email.mailText"; - final String oldMailText = resource.getString(oldSettingPath); + final String oldMailText = reader.getString(oldSettingPath); if (oldMailText == null) { return false; } @@ -149,12 +151,13 @@ public class SettingsMigrationService extends PlainMigrationService { * Detect deprecated {@code settings.delayJoinLeaveMessages} and inform user of new "remove join messages" * and "remove leave messages" settings. * - * @param resource The property resource + * @param reader The property reader + * @param configData Configuration data * @return True if the configuration has changed, false otherwise */ - private static boolean migrateJoinLeaveMessages(PropertyResource resource) { + private static boolean migrateJoinLeaveMessages(PropertyReader reader, ConfigurationData configData) { Property oldDelayJoinProperty = newProperty("settings.delayJoinLeaveMessages", false); - boolean hasMigrated = moveProperty(oldDelayJoinProperty, DELAY_JOIN_MESSAGE, resource); + boolean hasMigrated = moveProperty(oldDelayJoinProperty, DELAY_JOIN_MESSAGE, reader, configData); if (hasMigrated) { ConsoleLogger.info(String.format("Note that we now also have the settings %s and %s", @@ -167,31 +170,33 @@ public class SettingsMigrationService extends PlainMigrationService { * Detects old "force spawn loc on join" and "force spawn on these worlds" settings and moves them * to the new paths. * - * @param resource The property resource + * @param reader The property reader + * @param configData Configuration data * @return True if the configuration has changed, false otherwise */ - private static boolean migrateForceSpawnSettings(PropertyResource resource) { + private static boolean migrateForceSpawnSettings(PropertyReader reader, ConfigurationData configData) { Property oldForceLocEnabled = newProperty( "settings.restrictions.ForceSpawnLocOnJoinEnabled", false); Property> oldForceWorlds = newListProperty( "settings.restrictions.ForceSpawnOnTheseWorlds", "world", "world_nether", "world_the_ed"); - return moveProperty(oldForceLocEnabled, FORCE_SPAWN_LOCATION_AFTER_LOGIN, resource) - | moveProperty(oldForceWorlds, FORCE_SPAWN_ON_WORLDS, resource); + return moveProperty(oldForceLocEnabled, FORCE_SPAWN_LOCATION_AFTER_LOGIN, reader, configData) + | moveProperty(oldForceWorlds, FORCE_SPAWN_ON_WORLDS, reader, configData); } /** * Detects the old auto poolSize value and replaces it with the default value. * - * @param resource The property resource + * @param reader The property reader + * @param configData Configuration data * @return True if the configuration has changed, false otherwise */ - private static boolean migratePoolSizeSetting(PropertyResource resource) { - Integer oldValue = resource.getInt("DataSource.poolSize"); + private static boolean migratePoolSizeSetting(PropertyReader reader, ConfigurationData configData) { + Integer oldValue = reader.getInt(MYSQL_POOL_SIZE.getPath()); if (oldValue == null || oldValue > 0) { return false; } - resource.setValue("DataSource.poolSize", 10); + configData.setValue(MYSQL_POOL_SIZE, 10); return true; } @@ -199,24 +204,26 @@ public class SettingsMigrationService extends PlainMigrationService { * Changes the old boolean property "hide spam from console" to the new property specifying * the log level. * - * @param resource The property resource + * @param reader The property reader + * @param configData Configuration data * @return True if the configuration has changed, false otherwise */ - private static boolean changeBooleanSettingToLogLevelProperty(PropertyResource resource) { + private static boolean changeBooleanSettingToLogLevelProperty(PropertyReader reader, + ConfigurationData configData) { final String oldPath = "Security.console.noConsoleSpam"; final Property newProperty = PluginSettings.LOG_LEVEL; - if (!newProperty.isPresent(resource) && resource.contains(oldPath)) { + if (!newProperty.isPresent(reader) && reader.contains(oldPath)) { ConsoleLogger.info("Moving '" + oldPath + "' to '" + newProperty.getPath() + "'"); - boolean oldValue = MoreObjects.firstNonNull(resource.getBoolean(oldPath), false); + boolean oldValue = MoreObjects.firstNonNull(reader.getBoolean(oldPath), false); LogLevel level = oldValue ? LogLevel.INFO : LogLevel.FINE; - resource.setValue(newProperty.getPath(), level.name()); + configData.setValue(newProperty, level); return true; } return false; } - private static boolean hasOldHelpHeaderProperty(PropertyResource resource) { - if (resource.contains("settings.helpHeader")) { + private static boolean hasOldHelpHeaderProperty(PropertyReader reader) { + if (reader.contains("settings.helpHeader")) { ConsoleLogger.warning("Help header setting is now in messages/help_xx.yml, " + "please check the file to set it again"); return true; @@ -224,9 +231,9 @@ public class SettingsMigrationService extends PlainMigrationService { return false; } - private static boolean hasSupportOldPasswordProperty(PropertyResource resource) { + private static boolean hasSupportOldPasswordProperty(PropertyReader reader) { String path = "settings.security.supportOldPasswordHash"; - if (resource.contains(path)) { + if (reader.contains(path)) { ConsoleLogger.warning("Property '" + path + "' is no longer supported. " + "Use '" + SecuritySettings.LEGACY_HASHES.getPath() + "' instead."); return true; @@ -237,56 +244,58 @@ public class SettingsMigrationService extends PlainMigrationService { /** * Converts old boolean configurations for registration to the new enum properties, if applicable. * - * @param resource The property resource + * @param reader The property reader + * @param configData Configuration data * @return True if the configuration has changed, false otherwise */ - private static boolean convertToRegistrationType(PropertyResource resource) { + private static boolean convertToRegistrationType(PropertyReader reader, ConfigurationData configData) { String oldEmailRegisterPath = "settings.registration.enableEmailRegistrationSystem"; - if (RegistrationSettings.REGISTRATION_TYPE.isPresent(resource) || !resource.contains(oldEmailRegisterPath)) { + if (RegistrationSettings.REGISTRATION_TYPE.isPresent(reader) || !reader.contains(oldEmailRegisterPath)) { return false; } - boolean useEmail = newProperty(oldEmailRegisterPath, false).getValue(resource); + boolean useEmail = newProperty(oldEmailRegisterPath, false).determineValue(reader); RegistrationType registrationType = useEmail ? RegistrationType.EMAIL : RegistrationType.PASSWORD; String useConfirmationPath = useEmail ? "settings.registration.doubleEmailCheck" : "settings.restrictions.enablePasswordConfirmation"; - boolean hasConfirmation = newProperty(useConfirmationPath, false).getValue(resource); + boolean hasConfirmation = newProperty(useConfirmationPath, false).determineValue(reader); RegisterSecondaryArgument secondaryArgument = hasConfirmation ? RegisterSecondaryArgument.CONFIRMATION : RegisterSecondaryArgument.NONE; ConsoleLogger.warning("Merging old registration settings into '" + RegistrationSettings.REGISTRATION_TYPE.getPath() + "'"); - resource.setValue(RegistrationSettings.REGISTRATION_TYPE.getPath(), registrationType); - resource.setValue(RegistrationSettings.REGISTER_SECOND_ARGUMENT.getPath(), secondaryArgument); + configData.setValue(RegistrationSettings.REGISTRATION_TYPE, registrationType); + configData.setValue(RegistrationSettings.REGISTER_SECOND_ARGUMENT, secondaryArgument); return true; } /** * Migrates old permission group settings to the new configurations. * - * @param resource The property resource + * @param reader The property reader + * @param configData Configuration data * @return True if the configuration has changed, false otherwise */ - private static boolean mergeAndMovePermissionGroupSettings(PropertyResource resource) { + private static boolean mergeAndMovePermissionGroupSettings(PropertyReader reader, ConfigurationData configData) { boolean performedChanges; // We have two old settings replaced by only one: move the first non-empty one Property oldUnloggedInGroup = newProperty("settings.security.unLoggedinGroup", ""); Property oldRegisteredGroup = newProperty("GroupOptions.RegisteredPlayerGroup", ""); - if (!oldUnloggedInGroup.getValue(resource).isEmpty()) { - performedChanges = moveProperty(oldUnloggedInGroup, PluginSettings.REGISTERED_GROUP, resource); + if (!oldUnloggedInGroup.determineValue(reader).isEmpty()) { + performedChanges = moveProperty(oldUnloggedInGroup, PluginSettings.REGISTERED_GROUP, reader, configData); } else { - performedChanges = moveProperty(oldRegisteredGroup, PluginSettings.REGISTERED_GROUP, resource); + performedChanges = moveProperty(oldRegisteredGroup, PluginSettings.REGISTERED_GROUP, reader, configData); } // Move paths of other old options performedChanges |= moveProperty(newProperty("GroupOptions.UnregisteredPlayerGroup", ""), - PluginSettings.UNREGISTERED_GROUP, resource); + PluginSettings.UNREGISTERED_GROUP, reader, configData); performedChanges |= moveProperty(newProperty("permission.EnablePermissionCheck", false), - PluginSettings.ENABLE_PERMISSION_CHECK, resource); + PluginSettings.ENABLE_PERMISSION_CHECK, reader, configData); return performedChanges; } @@ -294,19 +303,21 @@ public class SettingsMigrationService extends PlainMigrationService { * If a deprecated hash is used, it is added to the legacy hashes option and the active hash * is changed to SHA256. * - * @param resource The property resource + * @param reader The property reader + * @param configData Configuration data * @return True if the configuration has changed, false otherwise */ - private static boolean moveDeprecatedHashAlgorithmIntoLegacySection(PropertyResource resource) { - HashAlgorithm currentHash = SecuritySettings.PASSWORD_HASH.getValue(resource); + private static boolean moveDeprecatedHashAlgorithmIntoLegacySection(PropertyReader reader, + ConfigurationData configData) { + HashAlgorithm currentHash = SecuritySettings.PASSWORD_HASH.determineValue(reader); // Skip CUSTOM (has no class) and PLAINTEXT (is force-migrated later on in the startup process) if (currentHash != HashAlgorithm.CUSTOM && currentHash != HashAlgorithm.PLAINTEXT) { Class encryptionClass = currentHash.getClazz(); if (encryptionClass.isAnnotationPresent(Deprecated.class)) { - resource.setValue(SecuritySettings.PASSWORD_HASH.getPath(), HashAlgorithm.SHA256); - Set legacyHashes = SecuritySettings.LEGACY_HASHES.getValue(resource); + configData.setValue(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256); + Set legacyHashes = SecuritySettings.LEGACY_HASHES.determineValue(reader); legacyHashes.add(currentHash); - resource.setValue(SecuritySettings.LEGACY_HASHES.getPath(), legacyHashes); + configData.setValue(SecuritySettings.LEGACY_HASHES, legacyHashes); ConsoleLogger.warning("The hash algorithm '" + currentHash + "' is no longer supported for active use. New hashes will be in SHA256."); return true; @@ -318,28 +329,30 @@ public class SettingsMigrationService extends PlainMigrationService { /** * Moves the property for the password salt column name to the same path as all other column name properties. * - * @param resource The property resource + * @param reader The property reader + * @param configData Configuration data * @return True if the configuration has changed, false otherwise */ - private static boolean moveSaltColumnConfigWithOtherColumnConfigs(PropertyResource resource) { + private static boolean moveSaltColumnConfigWithOtherColumnConfigs(PropertyReader reader, + ConfigurationData configData) { Property oldProperty = newProperty("ExternalBoardOptions.mySQLColumnSalt", DatabaseSettings.MYSQL_COL_SALT.getDefaultValue()); - return moveProperty(oldProperty, DatabaseSettings.MYSQL_COL_SALT, resource); + return moveProperty(oldProperty, DatabaseSettings.MYSQL_COL_SALT, reader, configData); } /** * Retrieves the old config to run a command when alt accounts are detected and sets them to this instance * for further processing. * - * @param resource The property resource + * @param reader The property reader */ - private void setOldOtherAccountsCommandFieldsIfSet(PropertyResource resource) { + private void setOldOtherAccountsCommandFieldsIfSet(PropertyReader reader) { Property commandProperty = newProperty("settings.restrictions.otherAccountsCmd", ""); Property commandThresholdProperty = newProperty("settings.restrictions.otherAccountsCmdThreshold", 0); - if (commandProperty.isPresent(resource) && commandThresholdProperty.getValue(resource) >= 2) { - oldOtherAccountsCommand = commandProperty.getValue(resource); - oldOtherAccountsCommandThreshold = commandThresholdProperty.getValue(resource); + if (commandProperty.isPresent(reader) && commandThresholdProperty.determineValue(reader) >= 2) { + oldOtherAccountsCommand = commandProperty.determineValue(reader); + oldOtherAccountsCommandThreshold = commandThresholdProperty.determineValue(reader); } } @@ -348,19 +361,21 @@ public class SettingsMigrationService extends PlainMigrationService { * * @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 resource The property resource + * @param reader The property reader + * @param configData Configuration data * @param The type of the property * @return True if a migration has been done, false otherwise */ - private static boolean moveProperty(Property oldProperty, - Property newProperty, - PropertyResource resource) { - if (resource.contains(oldProperty.getPath())) { - if (resource.contains(newProperty.getPath())) { + protected static boolean moveProperty(Property oldProperty, + Property newProperty, + PropertyReader reader, + ConfigurationData configData) { + if (reader.contains(oldProperty.getPath())) { + if (reader.contains(newProperty.getPath())) { ConsoleLogger.info("Detected deprecated property " + oldProperty.getPath()); } else { ConsoleLogger.info("Renaming " + oldProperty.getPath() + " to " + newProperty.getPath()); - resource.setValue(newProperty.getPath(), oldProperty.getValue(resource)); + configData.setValue(newProperty, oldProperty.determineValue(reader)); } return true; } diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java index 50d73c9a5..b26844e53 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java @@ -1,6 +1,7 @@ package fr.xephi.authme.settings.commandconfig; import ch.jalu.configme.SettingsManager; +import ch.jalu.configme.SettingsManagerBuilder; import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.service.BukkitService; @@ -148,8 +149,11 @@ public class CommandManager implements Reloadable { File file = new File(dataFolder, "commands.yml"); FileUtils.copyFileFromResource(file, "commands.yml"); - SettingsManager settingsManager = new SettingsManager( - YamlFileResourceProvider.loadFromFile(file), commandMigrationService, CommandSettingsHolder.class); + SettingsManager settingsManager = SettingsManagerBuilder + .withResource(YamlFileResourceProvider.loadFromFile(file)) + .configurationData(CommandSettingsHolder.class) + .migrationService(commandMigrationService) + .create(); CommandConfig commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); onJoinCommands = newReplacer(commandConfig.getOnJoin()); onLoginCommands = newOnLoginCmdReplacer(commandConfig.getOnLogin()); diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java index a602e49c3..b88e0c882 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java @@ -1,8 +1,8 @@ package fr.xephi.authme.settings.commandconfig; +import ch.jalu.configme.configurationdata.ConfigurationData; import ch.jalu.configme.migration.MigrationService; -import ch.jalu.configme.properties.Property; -import ch.jalu.configme.resource.PropertyResource; +import ch.jalu.configme.resource.PropertyReader; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import fr.xephi.authme.settings.SettingsMigrationService; @@ -30,10 +30,10 @@ class CommandMigrationService implements MigrationService { } @Override - public boolean checkAndMigrate(PropertyResource resource, List> properties) { - final CommandConfig commandConfig = CommandSettingsHolder.COMMANDS.getValue(resource); - if (moveOtherAccountsConfig(commandConfig) || isFileEmpty(resource)) { - resource.setValue("", commandConfig); + public boolean checkAndMigrate(PropertyReader reader, ConfigurationData configurationData) { + final CommandConfig commandConfig = CommandSettingsHolder.COMMANDS.determineValue(reader); + if (moveOtherAccountsConfig(commandConfig) || isAnyCommandMissing(reader)) { + configurationData.setValue(CommandSettingsHolder.COMMANDS, commandConfig); return true; } return false; @@ -59,7 +59,7 @@ class CommandMigrationService implements MigrationService { .replace("%playerip%", "%ip"); } - private static boolean isFileEmpty(PropertyResource resource) { - return COMMAND_CONFIG_PROPERTIES.stream().anyMatch(property -> resource.getObject(property) == null); + private static boolean isAnyCommandMissing(PropertyReader reader) { + return COMMAND_CONFIG_PROPERTIES.stream().anyMatch(property -> reader.getObject(property) == null); } } diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java index 965813c96..ce502c80f 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java @@ -1,13 +1,10 @@ package fr.xephi.authme.settings.commandconfig; -import ch.jalu.configme.SectionComments; import ch.jalu.configme.SettingsHolder; +import ch.jalu.configme.configurationdata.CommentsConfiguration; import ch.jalu.configme.properties.BeanProperty; import ch.jalu.configme.properties.Property; -import java.util.HashMap; -import java.util.Map; - /** * Settings holder class for the commands.yml settings. */ @@ -16,12 +13,11 @@ public final class CommandSettingsHolder implements SettingsHolder { public static final Property COMMANDS = new BeanProperty<>(CommandConfig.class, "", new CommandConfig()); - private CommandSettingsHolder() { } - @SectionComments - public static Map sectionComments() { + @Override + public void registerComments(CommentsConfiguration conf) { String[] rootComments = { "This configuration file allows you to execute commands on various events.", "Supported placeholders in commands:", @@ -60,21 +56,15 @@ public final class CommandSettingsHolder implements SettingsHolder { " ifNumberOfAccountsAtLeast: 5" }; - Map commentMap = new HashMap<>(); - commentMap.put("", rootComments); - commentMap.put("onFirstLogin", new String[]{ - "Commands to run for players logging in whose 'last login date' was empty" - }); - commentMap.put("onUnregister", new String[]{ - "Commands to run whenever a player is unregistered (by himself, or by an admin)" - }); - commentMap.put("onLogout", new String[]{ + conf.setComment("", rootComments); + conf.setComment("onFirstLogin", + "Commands to run for players logging in whose 'last login date' was empty"); + conf.setComment("onUnregister", + "Commands to run whenever a player is unregistered (by himself, or by an admin)"); + conf.setComment("onLogout", "These commands are called whenever a logged in player uses /logout or quits.", "The commands are not run if a player that was not logged in quits the server.", "Note: if your server crashes, these commands won't be run, so don't rely on them to undo", - "'onLogin' commands that would be dangerous for non-logged in players to have!" - }); - return commentMap; + "'onLogin' commands that would be dangerous for non-logged in players to have!"); } - } diff --git a/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java b/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java index 2fbe7ea24..c3793485c 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java +++ b/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java @@ -19,7 +19,7 @@ public final class AuthMeSettingsRetriever { * @return configuration data */ public static ConfigurationData buildConfigurationData() { - return ConfigurationDataBuilder.collectData( + return ConfigurationDataBuilder.createConfiguration( DatabaseSettings.class, PluginSettings.class, RestrictionSettings.class, EmailSettings.class, HooksSettings.class, ProtectionSettings.class, PurgeSettings.class, SecuritySettings.class, RegistrationSettings.class, diff --git a/src/main/java/fr/xephi/authme/settings/properties/ConverterSettings.java b/src/main/java/fr/xephi/authme/settings/properties/ConverterSettings.java index d1c426d6b..451c9c244 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/ConverterSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/ConverterSettings.java @@ -1,12 +1,9 @@ package fr.xephi.authme.settings.properties; import ch.jalu.configme.Comment; -import ch.jalu.configme.SectionComments; import ch.jalu.configme.SettingsHolder; +import ch.jalu.configme.configurationdata.CommentsConfiguration; import ch.jalu.configme.properties.Property; -import com.google.common.collect.ImmutableMap; - -import java.util.Map; import static ch.jalu.configme.properties.PropertyInitializer.newProperty; @@ -51,9 +48,9 @@ public final class ConverterSettings implements SettingsHolder { private ConverterSettings() { } - @SectionComments - public static Map buildSectionComments() { - return ImmutableMap.of("Converter", - new String[]{"Converter settings: see https://github.com/AuthMe/AuthMeReloaded/wiki/Converters"}); + @Override + public void registerComments(CommentsConfiguration conf) { + conf.setComment("Converter", + "Converter settings: see https://github.com/AuthMe/AuthMeReloaded/wiki/Converters"); } } diff --git a/src/main/java/fr/xephi/authme/settings/properties/LimboSettings.java b/src/main/java/fr/xephi/authme/settings/properties/LimboSettings.java index 68a4b7170..309b69231 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/LimboSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/LimboSettings.java @@ -1,17 +1,14 @@ package fr.xephi.authme.settings.properties; import ch.jalu.configme.Comment; -import ch.jalu.configme.SectionComments; import ch.jalu.configme.SettingsHolder; +import ch.jalu.configme.configurationdata.CommentsConfiguration; import ch.jalu.configme.properties.Property; -import com.google.common.collect.ImmutableMap; import fr.xephi.authme.data.limbo.AllowFlightRestoreType; import fr.xephi.authme.data.limbo.WalkFlySpeedRestoreType; import fr.xephi.authme.data.limbo.persistence.LimboPersistenceType; import fr.xephi.authme.data.limbo.persistence.SegmentSize; -import java.util.Map; - import static ch.jalu.configme.properties.PropertyInitializer.newProperty; /** @@ -72,8 +69,8 @@ public final class LimboSettings implements SettingsHolder { private LimboSettings() { } - @SectionComments - public static Map createSectionComments() { + @Override + public void registerComments(CommentsConfiguration conf) { String[] limboExplanation = { "Before a user logs in, various properties are temporarily removed from the player,", "such as OP status, ability to fly, and walk/fly speed.", @@ -81,6 +78,6 @@ public final class LimboSettings implements SettingsHolder { "In this section, you may define how these properties should be handled.", "Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players" }; - return ImmutableMap.of("limbo", limboExplanation); + conf.setComment("limbo", limboExplanation); } } diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index e769dd9b0..2fa90c317 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -5,9 +5,10 @@ import ch.jalu.configme.SettingsHolder; import ch.jalu.configme.properties.Property; import java.util.List; +import java.util.Set; import static ch.jalu.configme.properties.PropertyInitializer.newListProperty; -import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseListProperty; +import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseStringSetProperty; import static ch.jalu.configme.properties.PropertyInitializer.newProperty; public final class RestrictionSettings implements SettingsHolder { @@ -24,8 +25,8 @@ public final class RestrictionSettings implements SettingsHolder { newProperty("settings.restrictions.hideChat", false); @Comment("Allowed commands for unauthenticated players") - public static final Property> ALLOW_COMMANDS = - newLowercaseListProperty("settings.restrictions.allowCommands", + public static final Property> ALLOW_COMMANDS = + newLowercaseStringSetProperty("settings.restrictions.allowCommands", "/login", "/register", "/l", "/reg", "/email", "/captcha", "/2fa", "/totp"); @Comment({ @@ -83,8 +84,8 @@ public final class RestrictionSettings implements SettingsHolder { " AllowedRestrictedUser:", " - playername;127.0.0.1", " - playername;regex:127\\.0\\.0\\..*"}) - public static final Property> RESTRICTED_USERS = - newLowercaseListProperty("settings.restrictions.AllowedRestrictedUser"); + public static final Property> RESTRICTED_USERS = + newLowercaseStringSetProperty("settings.restrictions.AllowedRestrictedUser"); @Comment("Ban unknown IPs trying to log in with a restricted username?") public static final Property BAN_UNKNOWN_IP = @@ -177,8 +178,8 @@ public final class RestrictionSettings implements SettingsHolder { "- 'npcPlayer'", "- 'npcPlayer2'" }) - public static final Property> UNRESTRICTED_NAMES = - newLowercaseListProperty("settings.unrestrictions.UnrestrictedName"); + public static final Property> UNRESTRICTED_NAMES = + newLowercaseStringSetProperty("settings.unrestrictions.UnrestrictedName"); private RestrictionSettings() { } diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index d4ce71fc5..0cffd2804 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -6,10 +6,9 @@ import ch.jalu.configme.properties.Property; import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.settings.EnumSetProperty; -import java.util.List; import java.util.Set; -import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseListProperty; +import static ch.jalu.configme.properties.PropertyInitializer.newLowercaseStringSetProperty; import static ch.jalu.configme.properties.PropertyInitializer.newProperty; public final class SecuritySettings implements SettingsHolder { @@ -86,8 +85,8 @@ public final class SecuritySettings implements SettingsHolder { "- '123456'", "- 'password'", "- 'help'"}) - public static final Property> UNSAFE_PASSWORDS = - newLowercaseListProperty("settings.security.unsafePasswords", + public static final Property> UNSAFE_PASSWORDS = + newLowercaseStringSetProperty("settings.security.unsafePasswords", "123456", "password", "qwerty", "12345", "54321", "123456789", "help"); @Comment("Tempban a user's IP address if they enter the wrong password too many times") diff --git a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java index 6d1770d4e..887bf6d09 100644 --- a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java +++ b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java @@ -41,6 +41,7 @@ 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.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; /** @@ -91,7 +92,7 @@ public class AuthMeInitializationTest { public void shouldInitializeAllServices() { // given Settings settings = - new Settings(dataFolder, mock(PropertyResource.class), null, buildConfigurationData()); + new Settings(dataFolder, mock(PropertyResource.class, RETURNS_DEEP_STUBS), null, buildConfigurationData()); Injector injector = new InjectorBuilder() .addDefaultHandlers("fr.xephi.authme") diff --git a/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java b/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java index 5e79ef993..1c4f7542f 100644 --- a/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/command/help/HelpMessagesConsistencyTest.java @@ -1,5 +1,7 @@ package fr.xephi.authme.command.help; +import ch.jalu.configme.resource.PropertyReader; +import ch.jalu.configme.resource.YamlFileReader; import fr.xephi.authme.TestHelper; import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandInitializer; @@ -61,16 +63,16 @@ public class HelpMessagesConsistencyTest { @Test public void shouldHaveEntryForEachHelpMessageKey() { // given - FileConfiguration configuration = YamlConfiguration.loadConfiguration(DEFAULT_MESSAGES_FILE); + PropertyReader reader = new YamlFileReader(DEFAULT_MESSAGES_FILE); // when / then for (HelpMessage message : HelpMessage.values()) { - assertThat("Default configuration has entry for message '" + message + "'", - configuration.contains(message.getKey()), equalTo(true)); + assertThat("Default configuration should have entry for message '" + message + "'", + reader.contains(message.getKey()), equalTo(true)); } for (HelpSection section : HelpSection.values()) { - assertThat("Default configuration has entry for section '" + section + "'", - configuration.contains(section.getKey()), equalTo(true)); + assertThat("Default configuration should have entry for section '" + section + "'", + reader.contains(section.getKey()), equalTo(true)); } } diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java index 59d837a9c..59eae81a9 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java @@ -57,6 +57,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import static com.google.common.collect.Sets.newHashSet; import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; import static fr.xephi.authme.service.BukkitServiceTestHelper.setBukkitServiceToScheduleSyncDelayedTaskWithDelay; import static org.hamcrest.Matchers.contains; @@ -206,8 +207,7 @@ public class PlayerListenerTest { public void shouldNotStopAllowedCommand() { // given given(settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)).willReturn(true); - given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)) - .willReturn(Arrays.asList("/plugins", "/mail", "/msg")); + given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(newHashSet("/plugins", "/mail", "/msg")); PlayerCommandPreprocessEvent event = mockCommandEvent("/Mail send test Test"); // when @@ -222,7 +222,7 @@ public class PlayerListenerTest { public void shouldNotCancelEventForAuthenticatedPlayer() { // given given(settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)).willReturn(false); - given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(Collections.emptyList()); + given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(Collections.emptySet()); Player player = playerWithMockedServer(); // PlayerCommandPreprocessEvent#getPlayer is final, so create a spy instead of a mock PlayerCommandPreprocessEvent event = spy(new PlayerCommandPreprocessEvent(player, "/hub")); @@ -243,7 +243,7 @@ public class PlayerListenerTest { public void shouldCancelCommandEvent() { // given given(settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)).willReturn(false); - given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(Arrays.asList("/spawn", "/help")); + given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(newHashSet("/spawn", "/help")); Player player = playerWithMockedServer(); PlayerCommandPreprocessEvent event = spy(new PlayerCommandPreprocessEvent(player, "/hub")); given(listenerService.shouldCancelEvent(player)).willReturn(true); @@ -262,7 +262,7 @@ public class PlayerListenerTest { public void shouldCancelFastCommandEvent() { // given given(settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)).willReturn(false); - given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(Arrays.asList("/spawn", "/help")); + given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(newHashSet("/spawn", "/help")); Player player = playerWithMockedServer(); PlayerCommandPreprocessEvent event = spy(new PlayerCommandPreprocessEvent(player, "/hub")); given(quickCommandsProtectionManager.isAllowed(player.getName())).willReturn(false); diff --git a/src/test/java/fr/xephi/authme/message/HelpMessageConsistencyTest.java b/src/test/java/fr/xephi/authme/message/HelpMessageConsistencyTest.java index 399fd93a7..83db38d2f 100644 --- a/src/test/java/fr/xephi/authme/message/HelpMessageConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/message/HelpMessageConsistencyTest.java @@ -1,11 +1,11 @@ package fr.xephi.authme.message; +import ch.jalu.configme.resource.PropertyReader; +import ch.jalu.configme.resource.YamlFileReader; import fr.xephi.authme.TestHelper; import fr.xephi.authme.command.help.HelpMessage; import fr.xephi.authme.command.help.HelpSection; import fr.xephi.authme.permission.DefaultPermission; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Test; @@ -49,27 +49,27 @@ public class HelpMessageConsistencyTest { public void shouldHaveRequiredEntries() { for (File file : helpFiles) { // given - FileConfiguration configuration = YamlConfiguration.loadConfiguration(file); + PropertyReader reader = new YamlFileReader(file); // when / then - assertHasAllHelpSectionEntries(file.getName(), configuration); + assertHasAllHelpSectionEntries(file.getName(), reader); } } - private void assertHasAllHelpSectionEntries(String filename, FileConfiguration configuration) { + private void assertHasAllHelpSectionEntries(String filename, PropertyReader reader) { for (HelpSection section : HelpSection.values()) { assertThat(filename + " should have entry for HelpSection '" + section + "'", - configuration.getString(section.getKey()), notEmptyString()); + reader.getString(section.getKey()), notEmptyString()); } for (HelpMessage message : HelpMessage.values()) { assertThat(filename + " should have entry for HelpMessage '" + message + "'", - configuration.getString(message.getKey()), notEmptyString()); + reader.getString(message.getKey()), notEmptyString()); } for (DefaultPermission defaultPermission : DefaultPermission.values()) { assertThat(filename + " should have entry for DefaultPermission '" + defaultPermission + "'", - configuration.getString(getPathForDefaultPermission(defaultPermission)), notEmptyString()); + reader.getString(getPathForDefaultPermission(defaultPermission)), notEmptyString()); } } diff --git a/src/test/java/fr/xephi/authme/message/MessageFilePlaceholderTest.java b/src/test/java/fr/xephi/authme/message/MessageFilePlaceholderTest.java index 4e692c18d..f7b8596d0 100644 --- a/src/test/java/fr/xephi/authme/message/MessageFilePlaceholderTest.java +++ b/src/test/java/fr/xephi/authme/message/MessageFilePlaceholderTest.java @@ -1,10 +1,10 @@ package fr.xephi.authme.message; +import ch.jalu.configme.resource.PropertyReader; +import ch.jalu.configme.resource.YamlFileReader; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import fr.xephi.authme.TestHelper; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -51,12 +51,12 @@ public class MessageFilePlaceholderTest { @Test public void shouldHaveAllPlaceholders() { // given - FileConfiguration configuration = YamlConfiguration.loadConfiguration(messagesFile); - List errors = new ArrayList<>(); + PropertyReader reader = new YamlFileReader(messagesFile); + List errors = new ArrayList<>(0); // when for (MessageKey key : MessageKey.values()) { - List missingTags = findMissingTags(key, configuration); + List missingTags = findMissingTags(key, reader); if (!missingTags.isEmpty()) { errors.add("Message key '" + key + "' should have tags: " + String.join(", ", missingTags)); } @@ -68,9 +68,9 @@ public class MessageFilePlaceholderTest { } } - private List findMissingTags(MessageKey key, FileConfiguration configuration) { - if (key.getTags().length > 0 && configuration.contains(key.getKey())) { - String message = configuration.getString(key.getKey()); + private List findMissingTags(MessageKey key, PropertyReader reader) { + if (key.getTags().length > 0 && reader.contains(key.getKey())) { + String message = reader.getString(key.getKey()); return Arrays.stream(key.getTags()) .filter(tag -> !EXCLUSIONS.get(key).contains(tag) && !message.contains(tag)) .collect(Collectors.toList()); diff --git a/src/test/java/fr/xephi/authme/message/MessagesFileConsistencyTest.java b/src/test/java/fr/xephi/authme/message/MessagesFileConsistencyTest.java index 9e16994da..c1362dd61 100644 --- a/src/test/java/fr/xephi/authme/message/MessagesFileConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/message/MessagesFileConsistencyTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.message; +import ch.jalu.configme.resource.PropertyReader; +import ch.jalu.configme.resource.YamlFileReader; import fr.xephi.authme.TestHelper; import fr.xephi.authme.util.StringUtils; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.junit.Test; import java.io.File; @@ -24,10 +24,10 @@ public class MessagesFileConsistencyTest { @Test public void shouldHaveAllMessages() { File file = TestHelper.getJarFile(MESSAGES_FILE); - FileConfiguration configuration = YamlConfiguration.loadConfiguration(file); + PropertyReader reader = new YamlFileReader(file); List errors = new ArrayList<>(); for (MessageKey messageKey : MessageKey.values()) { - validateMessage(messageKey, configuration, errors); + validateMessage(messageKey, reader, errors); } if (!errors.isEmpty()) { @@ -36,9 +36,9 @@ public class MessagesFileConsistencyTest { } } - private static void validateMessage(MessageKey messageKey, FileConfiguration configuration, List errors) { + private static void validateMessage(MessageKey messageKey, PropertyReader reader, List errors) { final String key = messageKey.getKey(); - final String message = configuration.getString(key); + final String message = reader.getString(key); if (StringUtils.isEmpty(message)) { errors.add("Messages file should have message for key '" + key + "'"); diff --git a/src/test/java/fr/xephi/authme/message/YamlTextFileCheckerTest.java b/src/test/java/fr/xephi/authme/message/YamlTextFileCheckerTest.java index b04259b21..2b1820fb6 100644 --- a/src/test/java/fr/xephi/authme/message/YamlTextFileCheckerTest.java +++ b/src/test/java/fr/xephi/authme/message/YamlTextFileCheckerTest.java @@ -1,10 +1,11 @@ package fr.xephi.authme.message; +import ch.jalu.configme.resource.PropertyReader; +import ch.jalu.configme.resource.YamlFileReader; import fr.xephi.authme.TestHelper; import fr.xephi.authme.command.help.HelpSection; import fr.xephi.authme.util.ExceptionUtils; import fr.xephi.authme.util.StringUtils; -import org.bukkit.configuration.file.YamlConfiguration; import org.junit.BeforeClass; import org.junit.Test; @@ -81,8 +82,8 @@ public class YamlTextFileCheckerTest { */ private void checkFile(File file, String mandatoryKey, List errors) { try { - YamlConfiguration configuration = YamlConfiguration.loadConfiguration(file); - if (StringUtils.isEmpty(configuration.getString(mandatoryKey))) { + PropertyReader reader = new YamlFileReader(file); + if (StringUtils.isEmpty(reader.getString(mandatoryKey))) { errors.add("Message for '" + mandatoryKey + "' is empty"); } } catch (Exception e) { diff --git a/src/test/java/fr/xephi/authme/message/updater/MessageUpdaterTest.java b/src/test/java/fr/xephi/authme/message/updater/MessageUpdaterTest.java index 254e0b1a6..cb4d03158 100644 --- a/src/test/java/fr/xephi/authme/message/updater/MessageUpdaterTest.java +++ b/src/test/java/fr/xephi/authme/message/updater/MessageUpdaterTest.java @@ -1,13 +1,11 @@ package fr.xephi.authme.message.updater; -import ch.jalu.configme.configurationdata.ConfigurationData; import ch.jalu.configme.properties.Property; +import ch.jalu.configme.resource.PropertyReader; +import ch.jalu.configme.resource.YamlFileReader; import com.google.common.io.Files; -import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.TestHelper; import fr.xephi.authme.message.MessageKey; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -16,6 +14,7 @@ import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -65,13 +64,13 @@ public class MessageUpdaterTest { // then assertThat(wasChanged, equalTo(true)); - FileConfiguration configuration = YamlConfiguration.loadConfiguration(messagesFile); + PropertyReader reader = new YamlFileReader(messagesFile); // Existing keys should not be overridden - assertThat(configuration.getString(MessageKey.LOGIN_SUCCESS.getKey()), equalTo("&cHere we have&bdefined some colors &dand some other <hings")); - assertThat(configuration.getString(MessageKey.EMAIL_ALREADY_USED_ERROR.getKey()), equalTo("")); + assertThat(reader.getString(MessageKey.LOGIN_SUCCESS.getKey()), equalTo("&cHere we have&bdefined some colors &dand some other <hings")); + assertThat(reader.getString(MessageKey.EMAIL_ALREADY_USED_ERROR.getKey()), equalTo("")); // Check that new keys were added - assertThat(configuration.getString(MessageKey.SECOND.getKey()), equalTo("second")); - assertThat(configuration.getString(MessageKey.ERROR.getKey()), equalTo("&4An unexpected error occurred, please contact an administrator!")); + assertThat(reader.getString(MessageKey.SECOND.getKey()), equalTo("second")); + assertThat(reader.getString(MessageKey.ERROR.getKey()), equalTo("&4An unexpected error occurred, please contact an administrator!")); } @Test @@ -85,18 +84,18 @@ public class MessageUpdaterTest { // then assertThat(wasChanged, equalTo(true)); - FileConfiguration configuration = YamlConfiguration.loadConfiguration(messagesFile); - assertThat(configuration.getString(MessageKey.PASSWORD_MATCH_ERROR.getKey()), + PropertyReader reader = new YamlFileReader(messagesFile); + assertThat(reader.getString(MessageKey.PASSWORD_MATCH_ERROR.getKey()), equalTo("Password error message")); - assertThat(configuration.getString(MessageKey.INVALID_NAME_CHARACTERS.getKey()), + assertThat(reader.getString(MessageKey.INVALID_NAME_CHARACTERS.getKey()), equalTo("not valid username: Allowed chars are %valid_chars")); - assertThat(configuration.getString(MessageKey.INVALID_OLD_EMAIL.getKey()), + assertThat(reader.getString(MessageKey.INVALID_OLD_EMAIL.getKey()), equalTo("Email (old) is not valid!!")); - assertThat(configuration.getString(MessageKey.CAPTCHA_WRONG_ERROR.getKey()), + assertThat(reader.getString(MessageKey.CAPTCHA_WRONG_ERROR.getKey()), equalTo("The captcha code is %captcha_code for you")); - assertThat(configuration.getString(MessageKey.CAPTCHA_FOR_REGISTRATION_REQUIRED.getKey()), + assertThat(reader.getString(MessageKey.CAPTCHA_FOR_REGISTRATION_REQUIRED.getKey()), equalTo("Now type /captcha %captcha_code")); - assertThat(configuration.getString(MessageKey.SECONDS.getKey()), + assertThat(reader.getString(MessageKey.SECONDS.getKey()), equalTo("seconds in plural")); } @@ -111,10 +110,10 @@ public class MessageUpdaterTest { // then assertThat(wasChanged, equalTo(true)); - FileConfiguration configuration = YamlConfiguration.loadConfiguration(messagesFile); - assertThat(configuration.getString(MessageKey.TWO_FACTOR_CREATE.getKey()), equalTo("Old 2fa create text")); - assertThat(configuration.getString(MessageKey.WRONG_PASSWORD.getKey()), equalTo("test2 - wrong password")); // from pre-5.5 key - assertThat(configuration.getString(MessageKey.SECOND.getKey()), equalTo("second")); // from messages_en.yml + PropertyReader reader = new YamlFileReader(messagesFile); + assertThat(reader.getString(MessageKey.TWO_FACTOR_CREATE.getKey()), equalTo("Old 2fa create text")); + assertThat(reader.getString(MessageKey.WRONG_PASSWORD.getKey()), equalTo("test2 - wrong password")); // from pre-5.5 key + assertThat(reader.getString(MessageKey.SECOND.getKey()), equalTo("second")); // from messages_en.yml } @Test @@ -125,7 +124,7 @@ public class MessageUpdaterTest { .collect(Collectors.toSet()); // when - Set messageKeysFromConfigData = MessageUpdater.getConfigurationData().getProperties().stream() + Set messageKeysFromConfigData = MessageUpdater.createConfigurationData().getProperties().stream() .map(Property::getPath) .collect(Collectors.toSet()); @@ -141,8 +140,7 @@ public class MessageUpdaterTest { .collect(Collectors.toSet()); // when - Map comments = ReflectionTestUtils.getFieldValue( - ConfigurationData.class, MessageUpdater.getConfigurationData(), "sectionComments"); + Map> comments = MessageUpdater.createConfigurationData().getAllComments(); // then assertThat(comments.keySet(), equalTo(rootPaths)); diff --git a/src/test/java/fr/xephi/authme/message/updater/MigraterYamlFileResourceTest.java b/src/test/java/fr/xephi/authme/message/updater/MigraterYamlFileResourceTest.java index f6e6dcd2d..03d79e71f 100644 --- a/src/test/java/fr/xephi/authme/message/updater/MigraterYamlFileResourceTest.java +++ b/src/test/java/fr/xephi/authme/message/updater/MigraterYamlFileResourceTest.java @@ -1,8 +1,10 @@ package fr.xephi.authme.message.updater; import ch.jalu.configme.configurationdata.ConfigurationData; +import ch.jalu.configme.configurationdata.ConfigurationDataBuilder; import ch.jalu.configme.properties.Property; import ch.jalu.configme.properties.StringProperty; +import ch.jalu.configme.resource.PropertyReader; import com.google.common.io.Files; import fr.xephi.authme.TestHelper; import org.junit.Rule; @@ -31,14 +33,15 @@ public class MigraterYamlFileResourceTest { public void shouldReadChineseFile() { // given File file = TestHelper.getJarFile(CHINESE_MESSAGES_FILE); - - // when MigraterYamlFileResource resource = new MigraterYamlFileResource(file); + // when + PropertyReader reader = resource.createReader(); + // then - assertThat(resource.getString("first"), equalTo("错误的密码")); - assertThat(resource.getString("second"), equalTo("为了验证您的身份,您需要将一个电子邮件地址与您的帐户绑定!")); - assertThat(resource.getString("third"), equalTo("您已经可以在当前会话中执行任何敏感命令!")); + assertThat(reader.getString("first"), equalTo("错误的密码")); + assertThat(reader.getString("second"), equalTo("为了验证您的身份,您需要将一个电子邮件地址与您的帐户绑定!")); + assertThat(reader.getString("third"), equalTo("您已经可以在当前会话中执行任何敏感命令!")); } @Test @@ -47,24 +50,26 @@ public class MigraterYamlFileResourceTest { File file = temporaryFolder.newFile(); Files.copy(TestHelper.getJarFile(CHINESE_MESSAGES_FILE), file); MigraterYamlFileResource resource = new MigraterYamlFileResource(file); + ConfigurationData configurationData = buildConfigurationData(); + configurationData.initializeValues(resource.createReader()); String newMessage = "您当前并没有任何邮箱与该账号绑定"; - resource.setValue("third", newMessage); + configurationData.setValue(new StringProperty("third", ""), newMessage); // when - resource.exportProperties(buildConfigurationData()); + resource.exportProperties(configurationData); // then - resource = new MigraterYamlFileResource(file); - assertThat(resource.getString("first"), equalTo("错误的密码")); - assertThat(resource.getString("second"), equalTo("为了验证您的身份,您需要将一个电子邮件地址与您的帐户绑定!")); - assertThat(resource.getString("third"), equalTo(newMessage)); + PropertyReader reader = resource.createReader(); + assertThat(reader.getString("first"), equalTo("错误的密码")); + assertThat(reader.getString("second"), equalTo("为了验证您的身份,您需要将一个电子邮件地址与您的帐户绑定!")); + assertThat(reader.getString("third"), equalTo(newMessage)); } private static ConfigurationData buildConfigurationData() { - List> properties = Arrays.asList( + List> properties = Arrays.asList( new StringProperty("first", "first"), new StringProperty("second", "second"), new StringProperty("third", "third")); - return new ConfigurationData(properties); + return ConfigurationDataBuilder.createConfiguration(properties); } } diff --git a/src/test/java/fr/xephi/authme/service/ValidationServiceTest.java b/src/test/java/fr/xephi/authme/service/ValidationServiceTest.java index ad777eab9..003036542 100644 --- a/src/test/java/fr/xephi/authme/service/ValidationServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/ValidationServiceTest.java @@ -22,10 +22,10 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import java.util.Arrays; import java.util.Collections; import java.util.logging.Logger; +import static com.google.common.collect.Sets.newHashSet; import static java.util.Arrays.asList; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -57,10 +57,9 @@ public class ValidationServiceTest { given(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+"); given(settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3); given(settings.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).willReturn(20); - given(settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS)) - .willReturn(asList("unsafe", "other-unsafe")); + given(settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS)).willReturn(newHashSet("unsafe", "other-unsafe")); given(settings.getProperty(EmailSettings.MAX_REG_PER_EMAIL)).willReturn(3); - given(settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES)).willReturn(asList("name01", "npc")); + given(settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES)).willReturn(newHashSet("name01", "npc")); given(settings.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)).willReturn(false); } @@ -261,7 +260,7 @@ public class ValidationServiceTest { assertThat(validationService.isUnrestricted("NAME01"), equalTo(true)); // Check reloading - given(settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES)).willReturn(asList("new", "names")); + given(settings.getProperty(RestrictionSettings.UNRESTRICTED_NAMES)).willReturn(newHashSet("new", "names")); validationService.reload(); assertThat(validationService.isUnrestricted("npc"), equalTo(false)); assertThat(validationService.isUnrestricted("New"), equalTo(true)); @@ -350,7 +349,7 @@ public class ValidationServiceTest { // given given(settings.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)).willReturn(true); given(settings.getProperty(RestrictionSettings.RESTRICTED_USERS)) - .willReturn(Arrays.asList("Bobby;127.0.0.4", "Tamara;32.24.16.8", "Gabriel;regex:93\\.23\\.44\\..*", "emanuel;94.65.24.*", "imyourisp;*.yourisp.net")); + .willReturn(newHashSet("Bobby;127.0.0.4", "Tamara;32.24.16.8", "Gabriel;regex:93\\.23\\.44\\..*", "emanuel;94.65.24.*", "imyourisp;*.yourisp.net")); validationService.reload(); Player bobby = mockPlayer("bobby", "127.0.0.4"); @@ -389,7 +388,7 @@ public class ValidationServiceTest { Logger logger = TestHelper.setupLogger(); given(settings.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)).willReturn(true); given(settings.getProperty(RestrictionSettings.RESTRICTED_USERS)) - .willReturn(Arrays.asList("Bobby;127.0.0.4", "Tamara;")); + .willReturn(newHashSet("Bobby;127.0.0.4", "Tamara;")); // when validationService.reload(); diff --git a/src/test/java/fr/xephi/authme/service/yaml/YamlFileResourceProviderTest.java b/src/test/java/fr/xephi/authme/service/yaml/YamlFileResourceProviderTest.java index f870a6b43..3b6bbddbb 100644 --- a/src/test/java/fr/xephi/authme/service/yaml/YamlFileResourceProviderTest.java +++ b/src/test/java/fr/xephi/authme/service/yaml/YamlFileResourceProviderTest.java @@ -26,7 +26,7 @@ public class YamlFileResourceProviderTest { YamlFileResource resource = YamlFileResourceProvider.loadFromFile(yamlFile); // then - assertThat(resource.getString("test.jkl"), equalTo("Test test")); + assertThat(resource.createReader().getString("test.jkl"), equalTo("Test test")); } @Test @@ -36,7 +36,7 @@ public class YamlFileResourceProviderTest { // when try { - YamlFileResourceProvider.loadFromFile(yamlFile); + YamlFileResourceProvider.loadFromFile(yamlFile).createReader(); // then fail("Expected exception to be thrown"); diff --git a/src/test/java/fr/xephi/authme/settings/SettingsConsistencyTest.java b/src/test/java/fr/xephi/authme/settings/SettingsConsistencyTest.java index 87d9b8aac..5a1de0e6e 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsConsistencyTest.java @@ -1,30 +1,22 @@ package fr.xephi.authme.settings; -import ch.jalu.configme.SectionComments; -import ch.jalu.configme.SettingsHolder; import ch.jalu.configme.configurationdata.ConfigurationData; import ch.jalu.configme.properties.EnumProperty; import ch.jalu.configme.properties.Property; import com.google.common.collect.ImmutableSet; -import fr.xephi.authme.ClassCollector; -import fr.xephi.authme.ReflectionTestUtils; -import fr.xephi.authme.TestHelper; import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever; import fr.xephi.authme.settings.properties.SecuritySettings; import org.junit.BeforeClass; import org.junit.Test; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import static com.google.common.base.Preconditions.checkArgument; import static fr.xephi.authme.ReflectionTestUtils.getFieldValue; import static org.junit.Assert.fail; @@ -58,7 +50,7 @@ public class SettingsConsistencyTest { // when / then for (Property property : properties) { - if (configurationData.getCommentsForSection(property.getPath()).length == 0) { + if (configurationData.getCommentsForSection(property.getPath()).isEmpty()) { fail("No comment defined for " + property); } } @@ -67,83 +59,27 @@ public class SettingsConsistencyTest { @Test public void shouldNotHaveVeryLongCommentLines() { // given - List> properties = configurationData.getProperties(); - List> badProperties = new ArrayList<>(); + Map> commentEntries = configurationData.getAllComments(); + List badPaths = new ArrayList<>(0); // when - for (Property property : properties) { - for (String comment : configurationData.getCommentsForSection(property.getPath())) { + for (Map.Entry> commentEntry : commentEntries.entrySet()) { + for (String comment : commentEntry.getValue()) { if (comment.length() > MAX_COMMENT_LENGTH) { - badProperties.add(property); + badPaths.add(commentEntry.getKey()); break; } } } // then - if (!badProperties.isEmpty()) { + if (!badPaths.isEmpty()) { fail("Comment lines should not be longer than " + MAX_COMMENT_LENGTH + " chars, " - + "but found too long comments for:\n- " - + badProperties.stream().map(Property::getPath).collect(Collectors.joining("\n- "))); + + "but found too long comments for paths:\n- " + + String.join("\n- ", badPaths)); } } - @Test - public void shouldNotHaveVeryLongSectionCommentLines() { - // given - List sectionCommentMethods = getSectionCommentMethods(); - Set badMethods = new HashSet<>(); - - // when - for (Method method : sectionCommentMethods) { - boolean hasTooLongLine = getSectionComments(method).stream() - .anyMatch(line -> line.length() > MAX_COMMENT_LENGTH); - if (hasTooLongLine) { - badMethods.add(method); - } - } - - // then - if (!badMethods.isEmpty()) { - String methodList = badMethods.stream() - .map(m -> m.getName() + " in " + m.getDeclaringClass().getSimpleName()) - .collect(Collectors.joining("\n- ")); - fail("Found SectionComments methods with too long comments:\n- " + methodList); - } - } - - /** - * Gets all {@link SectionComments} methods from {@link SettingsHolder} implementations. - */ - @SuppressWarnings("unchecked") - private List getSectionCommentMethods() { - // Find all SettingsHolder classes - List> settingsClasses = - new ClassCollector(TestHelper.SOURCES_FOLDER, TestHelper.PROJECT_ROOT + "settings/properties/") - .collectClasses(SettingsHolder.class); - checkArgument(!settingsClasses.isEmpty(), "Could not find any SettingsHolder classes"); - - // Find all @SectionComments methods in these classes - return settingsClasses.stream() - .map(Class::getDeclaredMethods) - .flatMap(Arrays::stream) - .filter(method -> method.isAnnotationPresent(SectionComments.class)) - .collect(Collectors.toList()); - } - - /** - * Returns all comments returned from the given SectionComments method, flattened into one list. - * - * @param sectionCommentsMethod the method whose comments should be retrieved - * @return flattened list of all comments provided by the method - */ - private static List getSectionComments(Method sectionCommentsMethod) { - // @SectionComments methods are static - Map comments = ReflectionTestUtils.invokeMethod(sectionCommentsMethod, null); - return comments.values().stream() - .flatMap(Arrays::stream) - .collect(Collectors.toList()); - } /** * Checks that enum properties have all possible enum values listed in their comment diff --git a/src/test/java/fr/xephi/authme/settings/SettingsIntegrationTest.java b/src/test/java/fr/xephi/authme/settings/SettingsIntegrationTest.java index 705b51f06..e9a58c677 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsIntegrationTest.java @@ -38,7 +38,7 @@ public class SettingsIntegrationTest { private static final String INCOMPLETE_FILE = TestHelper.PROJECT_ROOT + "settings/config-incomplete-sample.yml"; private static ConfigurationData CONFIG_DATA = - ConfigurationDataBuilder.collectData(TestConfiguration.class); + ConfigurationDataBuilder.createConfiguration(TestConfiguration.class); @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); diff --git a/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java b/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java index 51cef1936..021bfb93b 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java @@ -1,7 +1,7 @@ package fr.xephi.authme.settings; import ch.jalu.configme.configurationdata.ConfigurationData; -import ch.jalu.configme.properties.Property; +import ch.jalu.configme.resource.PropertyReader; import ch.jalu.configme.resource.PropertyResource; import ch.jalu.configme.resource.YamlFileResource; import com.google.common.io.Files; @@ -108,7 +108,7 @@ public class SettingsMigrationServiceTest { SettingsMigrationService migrationService = new SettingsMigrationService(dataFolder); // when - migrationService.performMigrations(resource, AuthMeSettingsRetriever.buildConfigurationData().getProperties()); + migrationService.performMigrations(resource.createReader(), AuthMeSettingsRetriever.buildConfigurationData()); // then assertThat(migrationService.hasOldOtherAccountsCommand(), equalTo(true)); @@ -146,8 +146,8 @@ public class SettingsMigrationServiceTest { } @Override - protected boolean performMigrations(PropertyResource resource, List> properties) { - boolean result = super.performMigrations(resource, properties); + protected boolean performMigrations(PropertyReader reader, ConfigurationData configurationData) { + boolean result = super.performMigrations(reader, configurationData); returnedValues.add(result); return result; } diff --git a/src/test/java/fr/xephi/authme/settings/SettingsTest.java b/src/test/java/fr/xephi/authme/settings/SettingsTest.java index 9482c09a3..93934b1ab 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsTest.java @@ -17,6 +17,7 @@ import java.nio.file.Files; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; /** @@ -25,7 +26,7 @@ import static org.mockito.Mockito.mock; public class SettingsTest { private static final ConfigurationData CONFIG_DATA = - ConfigurationDataBuilder.collectData(TestConfiguration.class); + ConfigurationDataBuilder.createConfiguration(TestConfiguration.class); @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -49,7 +50,7 @@ public class SettingsTest { createFile(emailFile); Files.write(emailFile.toPath(), emailMessage.getBytes()); - PropertyResource resource = mock(PropertyResource.class); + PropertyResource resource = mock(PropertyResource.class, RETURNS_DEEP_STUBS); Settings settings = new Settings(testPluginFolder, resource, null, CONFIG_DATA); // when @@ -67,7 +68,7 @@ public class SettingsTest { createFile(emailFile); Files.write(emailFile.toPath(), emailMessage.getBytes()); - PropertyResource resource = mock(PropertyResource.class); + PropertyResource resource = mock(PropertyResource.class, RETURNS_DEEP_STUBS); Settings settings = new Settings(testPluginFolder, resource, null, CONFIG_DATA); // when @@ -85,7 +86,7 @@ public class SettingsTest { createFile(emailFile); Files.write(emailFile.toPath(), emailMessage.getBytes()); - PropertyResource resource = mock(PropertyResource.class); + PropertyResource resource = mock(PropertyResource.class, RETURNS_DEEP_STUBS); Settings settings = new Settings(testPluginFolder, resource, null, CONFIG_DATA); // when diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java index 307a48587..800bcc052 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java @@ -1,7 +1,8 @@ package fr.xephi.authme.settings.commandconfig; -import ch.jalu.configme.beanmapper.BeanDescriptionFactory; -import ch.jalu.configme.beanmapper.BeanPropertyDescription; +import ch.jalu.configme.beanmapper.propertydescription.BeanDescriptionFactoryImpl; +import ch.jalu.configme.beanmapper.propertydescription.BeanPropertyDescription; +import ch.jalu.configme.configurationdata.ConfigurationData; import ch.jalu.configme.configurationdata.ConfigurationDataBuilder; import ch.jalu.configme.resource.PropertyResource; import ch.jalu.configme.resource.YamlFileResource; @@ -52,7 +53,7 @@ public class CommandMigrationServiceTest { // when boolean result = commandMigrationService.checkAndMigrate( - resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); + resource.createReader(), ConfigurationDataBuilder.createConfiguration(CommandSettingsHolder.class)); // then assertThat(result, equalTo(true)); @@ -66,7 +67,7 @@ public class CommandMigrationServiceTest { // when boolean result = commandMigrationService.checkAndMigrate( - resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); + resource.createReader(), ConfigurationDataBuilder.createConfiguration(CommandSettingsHolder.class)); // then assertThat(result, equalTo(true)); @@ -80,7 +81,7 @@ public class CommandMigrationServiceTest { // when boolean result = commandMigrationService.checkAndMigrate( - resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); + resource.createReader(), ConfigurationDataBuilder.createConfiguration(CommandSettingsHolder.class)); // then assertThat(result, equalTo(false)); @@ -93,8 +94,8 @@ public class CommandMigrationServiceTest { @Test public void shouldHaveAllPropertiesFromCommandConfig() { // given - String[] properties = new BeanDescriptionFactory() - .collectWritableFields(CommandConfig.class) + String[] properties = new BeanDescriptionFactoryImpl() + .getAllProperties(CommandConfig.class) .stream() .map(BeanPropertyDescription::getName) .toArray(String[]::new); @@ -112,13 +113,14 @@ public class CommandMigrationServiceTest { given(settingsMigrationService.getOldOtherAccountsCommandThreshold()).willReturn(3); File commandFile = TestHelper.getJarFile(TestHelper.PROJECT_ROOT + "settings/commandconfig/commands.complete.yml"); PropertyResource resource = new YamlFileResource(commandFile); + ConfigurationData configurationData = ConfigurationDataBuilder.createConfiguration(CommandSettingsHolder.class); // when commandMigrationService.checkAndMigrate( - resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); + resource.createReader(), configurationData); // then - Map onLoginCommands = CommandSettingsHolder.COMMANDS.getValue(resource).getOnLogin(); + Map onLoginCommands = configurationData.getValue(CommandSettingsHolder.COMMANDS).getOnLogin(); assertThat(onLoginCommands, aMapWithSize(6)); // 5 in the file + the newly migrated on OnLoginCommand newCommand = getUnknownOnLoginCommand(onLoginCommands); assertThat(newCommand.getCommand(), equalTo("helpop %p (%ip) has other accounts!")); diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java index 668fae785..99b4d615b 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java @@ -42,7 +42,7 @@ public class CommandYmlConsistencyTest { // when boolean result = commandMigrationService.checkAndMigrate( - resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); + resource.createReader(), ConfigurationDataBuilder.createConfiguration(CommandSettingsHolder.class)); // then assertThat(result, equalTo(false)); diff --git a/src/test/java/tools/docs/config/UpdateConfigPageTask.java b/src/test/java/tools/docs/config/UpdateConfigPageTask.java index 15cd50e76..d82cda195 100644 --- a/src/test/java/tools/docs/config/UpdateConfigPageTask.java +++ b/src/test/java/tools/docs/config/UpdateConfigPageTask.java @@ -1,7 +1,7 @@ package tools.docs.config; import ch.jalu.configme.SettingsManager; -import ch.jalu.configme.resource.YamlFileResource; +import ch.jalu.configme.SettingsManagerBuilder; import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever; import fr.xephi.authme.util.FileUtils; import tools.utils.AutoToolTask; @@ -31,8 +31,9 @@ public class UpdateConfigPageTask implements AutoToolTask { try { // Create empty temporary .yml file and save the config to it config = File.createTempFile("authme-config-", ".yml"); - SettingsManager settingsManager = new SettingsManager( - new YamlFileResource(config), null, AuthMeSettingsRetriever.buildConfigurationData()); + SettingsManager settingsManager = SettingsManagerBuilder.withYamlFile(config) + .configurationData(AuthMeSettingsRetriever.buildConfigurationData()) + .create(); settingsManager.save(); // Get the contents and generate template file diff --git a/src/test/java/tools/docs/translations/TranslationsGatherer.java b/src/test/java/tools/docs/translations/TranslationsGatherer.java index e42b266d1..3e2119ff2 100644 --- a/src/test/java/tools/docs/translations/TranslationsGatherer.java +++ b/src/test/java/tools/docs/translations/TranslationsGatherer.java @@ -1,8 +1,8 @@ package tools.docs.translations; +import ch.jalu.configme.resource.PropertyReader; +import ch.jalu.configme.resource.YamlFileReader; import fr.xephi.authme.message.MessageKey; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import tools.utils.ToolsConstants; import java.io.File; @@ -43,10 +43,10 @@ public class TranslationsGatherer { } private void processMessagesFile(String code, File file) { - FileConfiguration configuration = YamlConfiguration.loadConfiguration(file); + PropertyReader reader = new YamlFileReader(file); int availableMessages = 0; for (MessageKey key : MessageKey.values()) { - if (configuration.contains(key.getKey())) { + if (reader.contains(key.getKey())) { ++availableMessages; } } diff --git a/src/test/java/tools/filegeneration/GenerateCommandsYml.java b/src/test/java/tools/filegeneration/GenerateCommandsYml.java index 73232d90d..34a1bb1b3 100644 --- a/src/test/java/tools/filegeneration/GenerateCommandsYml.java +++ b/src/test/java/tools/filegeneration/GenerateCommandsYml.java @@ -1,7 +1,7 @@ package tools.filegeneration; import ch.jalu.configme.SettingsManager; -import ch.jalu.configme.resource.YamlFileResource; +import ch.jalu.configme.SettingsManagerBuilder; import fr.xephi.authme.settings.commandconfig.CommandConfig; import fr.xephi.authme.settings.commandconfig.CommandSettingsHolder; import tools.utils.AutoToolTask; @@ -24,8 +24,9 @@ public class GenerateCommandsYml implements AutoToolTask { CommandConfig commandConfig = CommandSettingsHolder.COMMANDS.getDefaultValue(); // Export the value to the file - SettingsManager settingsManager = new SettingsManager( - new YamlFileResource(file), null, CommandSettingsHolder.class); + SettingsManager settingsManager = SettingsManagerBuilder.withYamlFile(file) + .configurationData(CommandSettingsHolder.class) + .create(); settingsManager.setProperty(CommandSettingsHolder.COMMANDS, commandConfig); settingsManager.save(); diff --git a/src/test/java/tools/messages/MessagesFileWriter.java b/src/test/java/tools/messages/MessagesFileWriter.java index 534be000c..8f43247a4 100644 --- a/src/test/java/tools/messages/MessagesFileWriter.java +++ b/src/test/java/tools/messages/MessagesFileWriter.java @@ -1,10 +1,10 @@ package tools.messages; -import ch.jalu.configme.SettingsManager; import ch.jalu.configme.configurationdata.ConfigurationData; import ch.jalu.configme.properties.Property; -import ch.jalu.configme.resource.PropertyResource; +import ch.jalu.configme.resource.PropertyReader; import ch.jalu.configme.resource.YamlFileResource; +import fr.xephi.authme.message.updater.MessageKeyConfigurationData; import fr.xephi.authme.message.updater.MessageUpdater; import fr.xephi.authme.message.updater.MigraterYamlFileResource; import org.bukkit.configuration.file.FileConfiguration; @@ -47,12 +47,18 @@ public final class MessagesFileWriter { } private void performWrite() { + // Initialize ConfigMe classes + MessageKeyConfigurationData configurationData = MessageUpdater.createConfigurationData(); + YamlFileResource resource = new MigraterYamlFileResource(file); + PropertyReader reader = resource.createReader(); + configurationData.initializeValues(reader); + // Store initial comments so we can add them back later - List initialComments = getInitialUserComments(); + List initialComments = getInitialUserComments(configurationData); // Create property resource with new defaults, save with ConfigMe for proper sections & comments - PropertyResource resource = createPropertyResourceWithCommentEntries(); - new SettingsManager(resource, null, MessageUpdater.getConfigurationData()).save(); + addMissingMessagesWithCommentMarker(reader, configurationData); + resource.exportProperties(configurationData); // Go through the newly saved file and replace texts with comment marker to actual YAML comments // and add initial comments back to the file @@ -60,11 +66,14 @@ public final class MessagesFileWriter { } /** + * Returns the comments at the top which are custom to the file. + * + * @param configurationData the configuration data * @return any custom comments at the top of the file, for later usage */ - private List getInitialUserComments() { + private List getInitialUserComments(ConfigurationData configurationData) { final List initialComments = new ArrayList<>(); - final String firstCommentByConfigMe = getFirstCommentByConfigMe(); + final String firstCommentByConfigMe = getFirstCommentByConfigMe(configurationData); for (String line : FileIoUtils.readLinesFromFile(file.toPath())) { if (line.isEmpty() || line.startsWith("#") && !line.equals(firstCommentByConfigMe)) { @@ -86,27 +95,30 @@ public final class MessagesFileWriter { } /** - * @return the first comment generated by ConfigMe (comment of the first root path) + * Returns the first comment generated by ConfigMe (comment of the first root path). + * + * @param configurationData the configuration data + * @return first comment which is generated by ConfigMe */ - private static String getFirstCommentByConfigMe() { - ConfigurationData configurationData = MessageUpdater.getConfigurationData(); + private static String getFirstCommentByConfigMe(ConfigurationData configurationData) { String firstRootPath = configurationData.getProperties().get(0).getPath().split("\\.")[0]; - return "# " + configurationData.getCommentsForSection(firstRootPath)[0]; + return "# " + configurationData.getCommentsForSection(firstRootPath).get(0); } /** - * @return generated {@link PropertyResource} with missing entries taken from the default file and marked - * with the {@link #COMMENT_MARKER} + * Adds a text with a {@link #COMMENT_MARKER} for all properties which are not yet present in the reader. + * + * @param reader the property reader + * @param configurationData the configuration data */ - private PropertyResource createPropertyResourceWithCommentEntries() { - YamlFileResource resource = new MigraterYamlFileResource(file); - for (Property property : MessageUpdater.getConfigurationData().getProperties()) { - String text = resource.getString(property.getPath()); + private void addMissingMessagesWithCommentMarker(PropertyReader reader, + MessageKeyConfigurationData configurationData) { + for (Property property : configurationData.getAllMessageProperties()) { + String text = reader.getString(property.getPath()); if (text == null) { - resource.setValue(property.getPath(), COMMENT_MARKER + defaultFile.getString(property.getPath())); + configurationData.setValue(property, COMMENT_MARKER + defaultFile.getString(property.getPath())); } } - return resource; } /**