mirror of
https://github.com/songoda/SongodaCore.git
synced 2024-11-23 18:45:34 +01:00
config work
This commit is contained in:
parent
379a92a554
commit
7c3936cdf8
@ -1,13 +1,28 @@
|
||||
package com.songoda.core.settingsv2;
|
||||
|
||||
import com.songoda.core.settingsv2.adapters.ConfigOptionsAdapter;
|
||||
import com.google.common.base.Charsets;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConstructor;
|
||||
import org.bukkit.configuration.file.YamlRepresenter;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@ -15,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
/**
|
||||
@ -35,32 +51,101 @@ public class Config extends SongodaConfigurationSection {
|
||||
// public static valueOf(Map<String, ?> args);
|
||||
// public new (Map<String, ?> args)
|
||||
*/
|
||||
|
||||
protected static final String COMMENT_PREFIX = "# ";
|
||||
protected static final String BLANK_CONFIG = "{}\n";
|
||||
|
||||
final File file;
|
||||
final Plugin plugin;
|
||||
final DumperOptions yamlOptions = new DumperOptions();
|
||||
final Representer yamlRepresenter = new YamlRepresenter();
|
||||
final Yaml yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions);
|
||||
protected int indentation = 2; // between 2 and 9 (inclusive)
|
||||
protected char pathChar = '.';
|
||||
SaveTask saveTask;
|
||||
Timer autosaveTimer;
|
||||
/**
|
||||
* save file whenever a change is made
|
||||
*/
|
||||
boolean autosave = false;
|
||||
/**
|
||||
* time in seconds to start a save after a change is made
|
||||
*/
|
||||
int autosaveInterval = 60;
|
||||
/**
|
||||
* remove nodes not defined in defaults
|
||||
*/
|
||||
boolean autoremove = false;
|
||||
|
||||
public Config(@NotNull File file) {
|
||||
super(null, null);
|
||||
this.file = file;
|
||||
this.plugin = null;
|
||||
this.file = file.getAbsoluteFile();
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.file = new File(plugin.getDataFolder(), "config.yml");
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin, @NotNull String file) {
|
||||
super(null, null);
|
||||
this.plugin = plugin;
|
||||
this.file = new File(plugin.getDataFolder(), file);
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin, @NotNull String directory, @NotNull String file) {
|
||||
super(null, null);
|
||||
this.plugin = plugin;
|
||||
this.file = new File(plugin.getDataFolder() + directory, file);
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public boolean getAutosave() {
|
||||
return autosave;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the configuration automatically save whenever it's been changed? <br>
|
||||
* All saves are done asynchronously, so this should not impact server performance.
|
||||
*
|
||||
* @param autosave set to true if autosaving is enabled.
|
||||
* @return this class
|
||||
*/
|
||||
public Config setAutosave(boolean autosave) {
|
||||
this.autosave = autosave;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getAutosaveInterval() {
|
||||
return autosaveInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* If autosave is enabled, this is the delay between a change and when the save is started. <br>
|
||||
* If the configuration is changed within this period, the timer is not reset.
|
||||
*
|
||||
* @param autosaveInterval time in seconds
|
||||
*/
|
||||
public void setAutosaveInterval(int autosaveInterval) {
|
||||
this.autosaveInterval = autosaveInterval;
|
||||
}
|
||||
|
||||
public boolean getAutoremove() {
|
||||
return autoremove;
|
||||
}
|
||||
|
||||
/**
|
||||
* This setting is used to prevent users to from adding extraneous settings
|
||||
* to the config and to remove deprecated settings. <br>
|
||||
* If this is enabled, the config will delete any nodes that are not
|
||||
* defined as a default setting.
|
||||
*
|
||||
* @param autoremove Remove settings that don't exist as defaults
|
||||
* @return this class
|
||||
*/
|
||||
public Config setAutoremove(boolean autoremove) {
|
||||
this.autoremove = autoremove;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Config setHeader(@NotNull String... description) {
|
||||
if (description.length == 0) {
|
||||
@ -90,9 +175,131 @@ public class Config extends SongodaConfigurationSection {
|
||||
}
|
||||
}
|
||||
|
||||
public void load() throws FileNotFoundException, IOException, InvalidConfigurationException {
|
||||
Validate.notNull(file, "File cannot be null");
|
||||
FileInputStream stream = new FileInputStream(file);
|
||||
this.load(new InputStreamReader((InputStream) stream, Charsets.UTF_16));
|
||||
}
|
||||
|
||||
public void load(@NotNull File file) throws FileNotFoundException, IOException, InvalidConfigurationException {
|
||||
Validate.notNull(file, "File cannot be null");
|
||||
FileInputStream stream = new FileInputStream(file);
|
||||
this.load(new InputStreamReader((InputStream) stream, Charsets.UTF_8));
|
||||
}
|
||||
|
||||
public void load(@NotNull Reader reader) throws IOException, InvalidConfigurationException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
try (BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader)) {
|
||||
String line;
|
||||
while ((line = input.readLine()) != null) {
|
||||
builder.append(line).append('\n');
|
||||
}
|
||||
}
|
||||
this.loadFromString(builder.toString());
|
||||
}
|
||||
|
||||
public void loadFromString(@NotNull String contents) throws InvalidConfigurationException {
|
||||
Map input;
|
||||
try {
|
||||
input = (Map) this.yaml.load(contents);
|
||||
} catch (YAMLException e2) {
|
||||
throw new InvalidConfigurationException(e2);
|
||||
} catch (ClassCastException e3) {
|
||||
throw new InvalidConfigurationException("Top level is not a Map.");
|
||||
}
|
||||
if (input != null) {
|
||||
this.parseComments(contents, input);
|
||||
this.convertMapsToSections(input, this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void convertMapsToSections(@NotNull Map<?, ?> input, @NotNull SongodaConfigurationSection section) {
|
||||
for (Map.Entry<?, ?> entry : input.entrySet()) {
|
||||
String key = entry.getKey().toString();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Map) {
|
||||
this.convertMapsToSections((Map) value, section.createSection(key));
|
||||
continue;
|
||||
}
|
||||
section.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseComments(@NotNull String contents, @NotNull Map<?, ?> input) {
|
||||
// TODO
|
||||
// if starts with a comment, load all nonbreaking comments as a header
|
||||
// then load all comments and assign to the next valid node loaded
|
||||
}
|
||||
|
||||
public void deleteNonDefaultSettings() {
|
||||
// Delete old config values (thread-safe)
|
||||
List<String> defaultKeys = Arrays.asList((String[]) defaults.keySet().toArray());
|
||||
for(String key : (String[]) values.keySet().toArray()) {
|
||||
if(!defaultKeys.contains(key)) {
|
||||
values.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onChange() {
|
||||
if (autosave) {
|
||||
delaySave();
|
||||
}
|
||||
}
|
||||
|
||||
public void delaySave() {
|
||||
// save async even if no plugin or if plugin disabled
|
||||
if (changed && saveTask == null) {
|
||||
autosaveTimer = new Timer((plugin != null ? plugin.getName() + "-ConfigSave-" : "ConfigSave-") + file.getName());
|
||||
autosaveTimer.schedule(saveTask = new SaveTask(), autosaveInterval * 1000L);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean saveChanges() {
|
||||
boolean saved = true;
|
||||
if (changed) {
|
||||
saved = save();
|
||||
}
|
||||
if(saveTask != null) {
|
||||
//Close Threads
|
||||
saveTask.cancel();
|
||||
autosaveTimer.cancel();
|
||||
saveTask = null;
|
||||
autosaveTimer = null;
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
|
||||
public boolean save() {
|
||||
return save(file);
|
||||
}
|
||||
|
||||
public boolean save(@NotNull String file) {
|
||||
Validate.notNull(file, "File cannot be null");
|
||||
return this.save(new File(file));
|
||||
}
|
||||
|
||||
public boolean save(@NotNull File file) {
|
||||
Validate.notNull(file, "File cannot be null");
|
||||
if (!file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
String data = this.saveToString();
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter((OutputStream) new FileOutputStream(file), Charsets.UTF_16);) {
|
||||
writer.write(data);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String saveToString() {
|
||||
try {
|
||||
if(autoremove) {
|
||||
deleteNonDefaultSettings();
|
||||
}
|
||||
yamlOptions.setIndent(indentation);
|
||||
yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
@ -104,33 +311,22 @@ public class Config extends SongodaConfigurationSection {
|
||||
String dump = yaml.dump(this.getValues(false));
|
||||
if (dump.equals(BLANK_CONFIG)) {
|
||||
dump = "";
|
||||
} else {
|
||||
// line-by-line apply line spacing formatting and comments per-node
|
||||
}
|
||||
return str.toString() + dump;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Config.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(Config.class.getName()).log(Level.SEVERE, "Error saving config", ex);
|
||||
delaySave();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public int getIndent() {
|
||||
return indentation;
|
||||
}
|
||||
class SaveTask extends TimerTask {
|
||||
|
||||
public void setIndent(int indentation) {
|
||||
this.indentation = indentation;
|
||||
@Override
|
||||
public void run() {
|
||||
saveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
public char getPathSeparator() {
|
||||
return pathChar;
|
||||
}
|
||||
|
||||
public void setPathSeparator(char pathChar) {
|
||||
this.pathChar = pathChar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigOptionsAdapter options() {
|
||||
return new ConfigOptionsAdapter(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,19 +1,17 @@
|
||||
package com.songoda.core.settingsv2;
|
||||
|
||||
import com.songoda.core.settingsv2.adapters.ConfigAdapter;
|
||||
import com.songoda.core.settingsv2.adapters.ConfigDefaultsAdapter;
|
||||
import com.songoda.core.settingsv2.adapters.ConfigOptionsAdapter;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.MemoryConfiguration;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -25,46 +23,105 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class SongodaConfigurationSection extends MemoryConfiguration {
|
||||
|
||||
final Config root;
|
||||
final String fullPath;
|
||||
final SongodaConfigurationSection root;
|
||||
final SongodaConfigurationSection parent;
|
||||
final HashMap<String, Comment> configComments = new HashMap();
|
||||
final HashMap<String, Class> strictKeys = new HashMap();
|
||||
final HashMap<String, Object> defaults = new HashMap();
|
||||
final HashMap<String, Object> values = new HashMap();
|
||||
protected int indentation = 2; // between 2 and 9 (inclusive)
|
||||
protected char pathChar = '.';
|
||||
final HashMap<String, Comment> configComments;
|
||||
final HashMap<String, Class> strictKeys;
|
||||
final LinkedHashMap<String, Object> defaults;
|
||||
final LinkedHashMap<String, Object> values;
|
||||
/**
|
||||
* Internal root state: if any configuration value has changed from file state
|
||||
*/
|
||||
boolean changed = false;
|
||||
final Object lock = new Object();
|
||||
|
||||
public SongodaConfigurationSection(Config root, SongodaConfigurationSection parent) {
|
||||
this.root = root;
|
||||
this.parent = parent;
|
||||
SongodaConfigurationSection() {
|
||||
this.root = this;
|
||||
this.parent = null;
|
||||
fullPath = "";
|
||||
configComments = new HashMap();
|
||||
strictKeys = new HashMap();
|
||||
defaults = new LinkedHashMap();
|
||||
values = new LinkedHashMap();
|
||||
}
|
||||
|
||||
SongodaConfigurationSection(SongodaConfigurationSection root, SongodaConfigurationSection parent, String path) {
|
||||
this.root = root;
|
||||
this.parent = parent;
|
||||
fullPath = parent.fullPath + path + root.pathChar;
|
||||
configComments = null;
|
||||
strictKeys = null;
|
||||
defaults = null;
|
||||
values = null;
|
||||
}
|
||||
|
||||
public int getIndent() {
|
||||
return root.indentation;
|
||||
}
|
||||
|
||||
public void setIndent(int indentation) {
|
||||
root.indentation = indentation;
|
||||
}
|
||||
|
||||
public char getPathSeparator() {
|
||||
return root.pathChar;
|
||||
}
|
||||
|
||||
protected void onChange() {
|
||||
if(parent != null) {
|
||||
root.onChange();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the character used to separate configuration nodes. <br>
|
||||
* IMPORTANT: Do not change this after loading or adding ConfigurationSections!
|
||||
*
|
||||
* @param pathChar character to use
|
||||
*/
|
||||
public void setPathSeparator(char pathChar) {
|
||||
if(!root.values.isEmpty() || !root.defaults.isEmpty())
|
||||
throw new RuntimeException("Path change after config initialization");
|
||||
root.pathChar = pathChar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefault(@NotNull String path, @Nullable Object value) {
|
||||
defaults.put(path, value);
|
||||
// TODO path iteration
|
||||
root.defaults.put(fullPath + path, value);
|
||||
if(!root.changed) {
|
||||
root.changed = root.values.get(fullPath + path) == null;
|
||||
}
|
||||
onChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefaults(Map<String, Object> map) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefaults(Configuration c) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public void addDefaults(@NotNull Map<String, Object> defaults) {
|
||||
defaults.entrySet().stream().forEach(m -> root.defaults.put(fullPath + m.getKey(), m.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults(Configuration c) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
if(fullPath.isEmpty()) {
|
||||
root.defaults.clear();
|
||||
} else {
|
||||
root.defaults.keySet().stream()
|
||||
.filter(k -> k.startsWith(fullPath))
|
||||
.forEach(k -> root.defaults.remove(k));
|
||||
}
|
||||
addDefaults(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigAdapter getDefaults() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public ConfigDefaultsAdapter getDefaults() {
|
||||
return new ConfigDefaultsAdapter(root, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigDefaultsAdapter getDefaultSection() {
|
||||
return new ConfigDefaultsAdapter(root, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -72,308 +129,263 @@ public class SongodaConfigurationSection extends MemoryConfiguration {
|
||||
return new ConfigOptionsAdapter(root);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getKeys(boolean bln) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public Set<String> getKeys(boolean deep) {
|
||||
LinkedHashSet<String> result = new LinkedHashSet();
|
||||
int pathIndex = fullPath.lastIndexOf(root.pathChar);
|
||||
if (deep) {
|
||||
result.addAll(root.values.keySet().stream()
|
||||
.filter(k -> k.startsWith(fullPath))
|
||||
.map(k -> !k.endsWith(String.valueOf(root.pathChar)) ? k.substring(pathIndex + 1) : k.substring(pathIndex + 1, k.length() - 1))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new)));
|
||||
result.addAll(root.defaults.keySet().stream()
|
||||
.filter(k -> k.startsWith(fullPath))
|
||||
.map(k -> !k.endsWith(String.valueOf(root.pathChar)) ? k.substring(pathIndex + 1) : k.substring(pathIndex + 1, k.length() - 1))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new)));
|
||||
} else {
|
||||
result.addAll(root.values.keySet().stream()
|
||||
.filter(k -> k.startsWith(fullPath) && k.lastIndexOf(root.pathChar) == pathIndex)
|
||||
.map(k -> !k.endsWith(String.valueOf(root.pathChar)) ? k.substring(pathIndex + 1) : k.substring(pathIndex + 1, k.length() - 1))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new)));
|
||||
result.addAll(root.defaults.keySet().stream()
|
||||
.filter(k -> k.startsWith(fullPath) && k.lastIndexOf(root.pathChar) == pathIndex + 1)
|
||||
.map(k -> !k.endsWith(String.valueOf(root.pathChar)) ? k.substring(pathIndex + 1) : k.substring(pathIndex + 1, k.length() - 1))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Object> getValues(boolean deep) {
|
||||
LinkedHashMap<String, Object> result = new LinkedHashMap();
|
||||
int pathIndex = fullPath.lastIndexOf(root.pathChar);
|
||||
if (deep) {
|
||||
result.putAll((Map<String, Object>) root.defaults.entrySet().stream()
|
||||
.filter(k -> k.getKey().startsWith(fullPath))
|
||||
.collect(Collectors.toMap(
|
||||
e -> !e.getKey().endsWith(String.valueOf(root.pathChar)) ? e.getKey().substring(pathIndex + 1) : e.getKey().substring(pathIndex + 1, e.getKey().length() - 1),
|
||||
e -> e.getValue(),
|
||||
(v1, v2) -> { throw new IllegalStateException(); }, // never going to be merging keys
|
||||
LinkedHashMap::new)));
|
||||
result.putAll((Map<String, Object>) root.values.entrySet().stream()
|
||||
.filter(k -> k.getKey().startsWith(fullPath))
|
||||
.collect(Collectors.toMap(
|
||||
e -> !e.getKey().endsWith(String.valueOf(root.pathChar)) ? e.getKey().substring(pathIndex + 1) : e.getKey().substring(pathIndex + 1, e.getKey().length() - 1),
|
||||
e -> e.getValue(),
|
||||
(v1, v2) -> { throw new IllegalStateException(); }, // never going to be merging keys
|
||||
LinkedHashMap::new)));
|
||||
} else {
|
||||
result.putAll((Map<String, Object>) root.values.entrySet().stream()
|
||||
.filter(k -> k.getKey().startsWith(fullPath) && k.getKey().lastIndexOf(root.pathChar) == pathIndex)
|
||||
.collect(Collectors.toMap(
|
||||
e -> !e.getKey().endsWith(String.valueOf(root.pathChar)) ? e.getKey().substring(pathIndex + 1) : e.getKey().substring(pathIndex + 1, e.getKey().length() - 1),
|
||||
e -> e.getValue(),
|
||||
(v1, v2) -> { throw new IllegalStateException(); }, // never going to be merging keys
|
||||
LinkedHashMap::new)));
|
||||
result.putAll((Map<String, Object>) root.defaults.entrySet().stream()
|
||||
.filter(k -> k.getKey().startsWith(fullPath) && k.getKey().lastIndexOf(root.pathChar) == pathIndex)
|
||||
.collect(Collectors.toMap(
|
||||
e -> !e.getKey().endsWith(String.valueOf(root.pathChar)) ? e.getKey().substring(pathIndex + 1) : e.getKey().substring(pathIndex + 1, e.getKey().length() - 1),
|
||||
e -> e.getValue(),
|
||||
(v1, v2) -> { throw new IllegalStateException(); }, // never going to be merging keys
|
||||
LinkedHashMap::new)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getValues(boolean bln) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public boolean contains(@NotNull String path) {
|
||||
return root.defaults.containsKey(fullPath + path) || root.values.containsKey(fullPath + path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public boolean contains(@NotNull String path, boolean ignoreDefault) {
|
||||
return (!ignoreDefault && root.defaults.containsKey(fullPath + path)) || root.values.containsKey(fullPath + path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(String string, boolean bln) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSet(String path) {
|
||||
return get(path, null) != null;
|
||||
public boolean isSet(@NotNull String path) {
|
||||
return root.defaults.get(fullPath + path) != null || root.values.get(fullPath + path) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentPath() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
return fullPath.isEmpty() ? "" : fullPath.substring(0, fullPath.length() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
if(fullPath.isEmpty())
|
||||
return "";
|
||||
String[] parts = fullPath.split(Pattern.quote(String.valueOf(root.pathChar)));
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration getRoot() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public SongodaConfigurationSection getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getParent() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public SongodaConfigurationSection getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object get(@NotNull String path) {
|
||||
Object result = root.values.get(fullPath + path);
|
||||
if (result == null) {
|
||||
result = root.defaults.get(fullPath + path);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object get(@NotNull String path, @Nullable Object def) {
|
||||
Object result = root.values.get(fullPath + path);
|
||||
return result != null ? result : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
synchronized(root.lock) {
|
||||
if (value != null) {
|
||||
root.changed |= root.values.put(fullPath + path, value) != value;
|
||||
} else {
|
||||
root.changed |= root.values.remove(fullPath + path) != null;
|
||||
}
|
||||
}
|
||||
onChange();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SongodaConfigurationSection createSection(@NotNull String path) {
|
||||
SongodaConfigurationSection section = new SongodaConfigurationSection(root, this, path);
|
||||
synchronized(root.lock) {
|
||||
root.values.put(fullPath + path, section);
|
||||
}
|
||||
root.changed = true;
|
||||
onChange();
|
||||
return section;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SongodaConfigurationSection createSection(@NotNull String path, Map<?, ?> map) {
|
||||
SongodaConfigurationSection section = new SongodaConfigurationSection(root, this, path);
|
||||
synchronized(root.lock) {
|
||||
root.values.put(fullPath + path, section);
|
||||
}
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
if (entry.getValue() instanceof Map) {
|
||||
section.createSection(entry.getKey().toString(), (Map) entry.getValue());
|
||||
continue;
|
||||
}
|
||||
section.set(entry.getKey().toString(), entry.getValue());
|
||||
}
|
||||
root.changed = true;
|
||||
onChange();
|
||||
return section;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getString(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
return result != null ? result.toString() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getString(@NotNull String path, @Nullable String def) {
|
||||
Object result = get(path);
|
||||
return result != null ? result.toString() : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String string, Object o) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public int getInt(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
return result instanceof Number ? ((Number) result).intValue() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String string, Object o) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public int getInt(@NotNull String path, int def) {
|
||||
Object result = get(path);
|
||||
return result instanceof Number ? ((Number) result).intValue() : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection createSection(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public boolean getBoolean(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
return result instanceof Boolean ? (Boolean) result : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection createSection(String string, Map<?, ?> map) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public boolean getBoolean(@NotNull String path, boolean def) {
|
||||
Object result = get(path);
|
||||
return result instanceof Boolean ? (Boolean) result : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public double getDouble(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
return result instanceof Number ? ((Number) result).doubleValue() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String string, String string1) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public double getDouble(@NotNull String path, double def) {
|
||||
Object result = get(path);
|
||||
return result instanceof Number ? ((Number) result).doubleValue() : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isString(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public long getLong(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
return result instanceof Number ? ((Number) result).longValue(): 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public long getLong(@NotNull String path, long def) {
|
||||
Object result = get(path);
|
||||
return result instanceof Number ? ((Number) result).longValue() : def;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<?> getList(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
return result instanceof List ? (List) result : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<?> getList(@NotNull String path, @Nullable List<?> def) {
|
||||
Object result = get(path);
|
||||
return result instanceof List ? (List) result : def;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getObject(@NotNull String path, @NotNull Class<T> clazz) {
|
||||
Object result = get(path);
|
||||
return result != null && clazz.isInstance(result) ? clazz.cast(result) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getObject(@NotNull String path, @NotNull Class<T> clazz, @Nullable T def) {
|
||||
Object result = get(path);
|
||||
return result != null && clazz.isInstance(result) ? clazz.cast(result) : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(String string, int i) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInt(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String string, boolean bln) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoolean(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(String string, double d) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDouble(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(String string, long l) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLong(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<?> getList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<?> getList(String string, List<?> list) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getStringList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getIntegerList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Boolean> getBooleanList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Double> getDoubleList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Float> getFloatList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getLongList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Byte> getByteList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Character> getCharacterList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Short> getShortList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<?, ?>> getMapList(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getObject(String string, Class<T> type) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getObject(String string, Class<T> type, T t) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ConfigurationSerializable> T getSerializable(String string, Class<T> type) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ConfigurationSerializable> T getSerializable(String string, Class<T> type, T t) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getVector(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getVector(String string, Vector vector) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVector(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflinePlayer getOfflinePlayer(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflinePlayer getOfflinePlayer(String string, OfflinePlayer op) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOfflinePlayer(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(String string, ItemStack is) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemStack(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(String string, Color color) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isColor(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getConfigurationSection(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigurationSection(String string) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getDefaultSection() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
public SongodaConfigurationSection getConfigurationSection(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
return result instanceof SongodaConfigurationSection ? (SongodaConfigurationSection) result : null;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.songoda.core.settingsv2.adapters;
|
||||
|
||||
import com.songoda.core.settingsv2.Config;
|
||||
import java.util.HashMap;
|
||||
import com.songoda.core.settingsv2.SongodaConfigurationSection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -14,16 +13,14 @@ import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class ConfigAdapter implements Configuration {
|
||||
public class ConfigDefaultsAdapter implements Configuration {
|
||||
|
||||
final Config root;
|
||||
final HashMap<String, Object> map;
|
||||
final String path;
|
||||
final SongodaConfigurationSection root;
|
||||
final SongodaConfigurationSection current;
|
||||
|
||||
public ConfigAdapter(Config config, HashMap<String, Object> map, String path) {
|
||||
public ConfigDefaultsAdapter(SongodaConfigurationSection config, SongodaConfigurationSection current) {
|
||||
this.root = config;
|
||||
this.map = map;
|
||||
this.path = path;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
@Override
|
@ -1,6 +1,7 @@
|
||||
package com.songoda.core.settingsv2.adapters;
|
||||
|
||||
import com.songoda.core.settingsv2.Config;
|
||||
import com.songoda.core.settingsv2.SongodaConfigurationSection;
|
||||
import java.util.List;
|
||||
import org.bukkit.configuration.MemoryConfigurationOptions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -8,8 +9,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ConfigOptionsAdapter extends MemoryConfigurationOptions {
|
||||
|
||||
public ConfigOptionsAdapter(Config configuration) {
|
||||
super(configuration);
|
||||
public ConfigOptionsAdapter(SongodaConfigurationSection root) {
|
||||
super(root);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
Loading…
Reference in New Issue
Block a user