package fr.xephi.authme.settings.domain;
import org.bukkit.configuration.file.FileConfiguration;
import org.yaml.snakeyaml.Yaml;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* Property class, representing a setting that is read from the config.yml file.
*/
public abstract class Property {
private final String path;
private final T defaultValue;
protected Property(String path, T defaultValue) {
Objects.requireNonNull(defaultValue);
this.path = path;
this.defaultValue = defaultValue;
}
/**
* Create a new string list property.
*
* @param path The property's path
* @param defaultValues The items in the default list
* @return The created list property
*/
public static Property> newListProperty(String path, String... defaultValues) {
// does not have the same name as not to clash with #newProperty(String, String)
return new StringListProperty(path, defaultValues);
}
/**
* Create a new String list property where all values are lowercase.
*
* @param path The property's path
* @param defaultValues The items in the default list
* @return The created list property
*/
public static Property> newLowercaseListProperty(String path, String... defaultValues) {
return new LowercaseStringListProperty(path, defaultValues);
}
/**
* Create a new enum property.
*
* @param clazz The enum class
* @param path The property's path
* @param defaultValue The default value
* @param The enum type
* @return The created enum property
*/
public static > Property newProperty(Class clazz, String path, E defaultValue) {
return new EnumProperty<>(clazz, path, defaultValue);
}
public static Property newProperty(String path, boolean defaultValue) {
return new BooleanProperty(path, defaultValue);
}
public static Property newProperty(String path, int defaultValue) {
return new IntegerProperty(path, defaultValue);
}
public static Property newProperty(String path, String defaultValue) {
return new StringProperty(path, defaultValue);
}
/**
* Get the property value from the given configuration – guaranteed to never return null.
*
* @param configuration The configuration to read the value from
* @return The value, or default if not present
*/
public abstract T getFromFile(FileConfiguration configuration);
/**
* Return whether or not the given configuration file contains the property.
*
* @param configuration The configuration file to verify
* @return True if the property is present, false otherwise
*/
public boolean isPresent(FileConfiguration configuration) {
return configuration.contains(path);
}
/**
* Format the property's value as YAML.
*
* @param configuration The file configuration
* @param simpleYaml YAML object (default)
* @param singleQuoteYaml YAML object using single quotes
* @return The generated YAML
*/
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
return simpleYaml.dump(getFromFile(configuration));
}
/**
* Return the default value of the property.
*
* @return The default value
*/
public T getDefaultValue() {
return defaultValue;
}
/**
* Return the property path (i.e. the node at which this property is located in the YAML file).
*
* @return The path
*/
public String getPath() {
return path;
}
@Override
public String toString() {
return "Property '" + path + "'";
}
/**
* Boolean property.
*/
private static final class BooleanProperty extends Property {
public BooleanProperty(String path, Boolean defaultValue) {
super(path, defaultValue);
}
@Override
public Boolean getFromFile(FileConfiguration configuration) {
return configuration.getBoolean(getPath(), getDefaultValue());
}
}
/**
* Integer property.
*/
private static final class IntegerProperty extends Property {
public IntegerProperty(String path, Integer defaultValue) {
super(path, defaultValue);
}
@Override
public Integer getFromFile(FileConfiguration configuration) {
return configuration.getInt(getPath(), getDefaultValue());
}
}
/**
* String property.
*/
private static final class StringProperty extends Property {
public StringProperty(String path, String defaultValue) {
super(path, defaultValue);
}
@Override
public String getFromFile(FileConfiguration configuration) {
return configuration.getString(getPath(), getDefaultValue());
}
@Override
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
return singleQuoteYaml.dump(getFromFile(configuration));
}
}
/**
* String list property.
*/
private static class StringListProperty extends Property> {
public StringListProperty(String path, String[] defaultValues) {
super(path, Arrays.asList(defaultValues));
}
@Override
public List getFromFile(FileConfiguration configuration) {
if (!configuration.isList(getPath())) {
return getDefaultValue();
}
return configuration.getStringList(getPath());
}
@Override
public boolean isPresent(FileConfiguration configuration) {
return configuration.isList(getPath());
}
@Override
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
List value = getFromFile(configuration);
String yaml = singleQuoteYaml.dump(value);
// If the property is a non-empty list we need to append a new line because it will be
// something like the following, which requires a new line:
// - 'item 1'
// - 'second item in list'
return value.isEmpty() ? yaml : "\n" + yaml;
}
}
/**
* Lowercase String list property.
*/
private static final class LowercaseStringListProperty extends StringListProperty {
public LowercaseStringListProperty(String path, String[] defaultValues) {
super(path, defaultValues);
}
@Override
public List getFromFile(FileConfiguration configuration) {
if (!configuration.isList(getPath())) {
return getDefaultValue();
}
// make sure all elements are lowercase
List lowercaseList = new ArrayList<>();
for (String element : configuration.getStringList(getPath())) {
lowercaseList.add(element.toLowerCase());
}
return lowercaseList;
}
}
}