1
mirror of https://github.com/CarmJos/MineConfiguration.git synced 2026-06-04 13:55:03 +08:00

[1.0.0] 初始版本完成

This commit is contained in:
2022-04-23 23:20:50 +08:00
parent 1bcc8d832e
commit 589de2606c
37 changed files with 1094 additions and 1956 deletions
@@ -1,34 +0,0 @@
package cc.carm.lib.configuration.bukkit;
import cc.carm.lib.configuration.bukkit.builder.BukkitConfigBuilder;
import cc.carm.lib.configuration.bukkit.source.BukkitConfigProvider;
import cc.carm.lib.configuration.bukkit.source.BukkitSectionWrapper;
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
import cc.carm.lib.configuration.core.value.impl.CachedConfigValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class BukkitConfigValue<T> extends CachedConfigValue<T> {
public static @NotNull BukkitConfigBuilder builder() {
return new BukkitConfigBuilder();
}
public BukkitConfigValue(@Nullable BukkitConfigProvider provider,
@Nullable String configPath, @NotNull String[] comments, @Nullable T defaultValue) {
super(provider, configPath, comments, defaultValue);
}
public BukkitConfigProvider<?, ?> getBukkitProvider() {
ConfigurationProvider<?> provider = getProvider();
if (provider instanceof BukkitConfigProvider) return (BukkitConfigProvider<?, ?>) getProvider();
else throw new IllegalStateException("Provider is not a SpigotConfigProvider");
}
public BukkitSectionWrapper getBukkitConfig() {
return getBukkitProvider().getConfiguration();
}
}
@@ -1,13 +0,0 @@
package cc.carm.lib.configuration.bukkit.builder;
import cc.carm.lib.configuration.bukkit.source.BukkitConfigProvider;
import cc.carm.lib.configuration.core.builder.AbstractConfigBuilder;
public abstract class AbstractBukkitBuilder<T, B extends AbstractBukkitBuilder<T, B>>
extends AbstractConfigBuilder<T, B, BukkitConfigProvider<?, ?>> {
public AbstractBukkitBuilder() {
super(BukkitConfigProvider.class);
}
}
@@ -1,19 +0,0 @@
package cc.carm.lib.configuration.bukkit.builder;
import cc.carm.lib.configuration.bukkit.builder.serializable.SerializableBuilder;
import cc.carm.lib.configuration.bukkit.builder.sound.SoundConfigBuilder;
import cc.carm.lib.configuration.core.builder.ConfigBuilder;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.jetbrains.annotations.NotNull;
public class BukkitConfigBuilder extends ConfigBuilder {
public @NotNull SoundConfigBuilder createSound() {
return new SoundConfigBuilder();
}
public <V extends ConfigurationSerializable> @NotNull SerializableBuilder<V> ofSerializable(@NotNull Class<V> valueClass) {
return new SerializableBuilder<>(valueClass);
}
}
@@ -1,28 +0,0 @@
package cc.carm.lib.configuration.bukkit.builder.serializable;
import cc.carm.lib.configuration.bukkit.builder.AbstractBukkitBuilder;
import cc.carm.lib.configuration.bukkit.value.ConfiguredSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.jetbrains.annotations.NotNull;
public class SerializableBuilder<T extends ConfigurationSerializable>
extends AbstractBukkitBuilder<T, SerializableBuilder<T>> {
protected final @NotNull Class<T> valueClass;
public SerializableBuilder(@NotNull Class<T> valueClass) {
this.valueClass = valueClass;
}
@Override
protected @NotNull SerializableBuilder<T> getThis() {
return this;
}
@Override
public @NotNull ConfiguredSerializable<T> build() {
return new ConfiguredSerializable<>(this.provider, this.path, this.comments, this.valueClass, this.defaultValue);
}
}
@@ -1,34 +0,0 @@
package cc.carm.lib.configuration.bukkit.builder.sound;
import cc.carm.lib.configuration.bukkit.builder.AbstractBukkitBuilder;
import cc.carm.lib.configuration.bukkit.data.SoundConfig;
import cc.carm.lib.configuration.bukkit.value.ConfiguredSound;
import org.bukkit.Sound;
import org.jetbrains.annotations.NotNull;
public class SoundConfigBuilder extends AbstractBukkitBuilder<SoundConfig, SoundConfigBuilder> {
public @NotNull SoundConfigBuilder defaults(@NotNull Sound sound, float volume, float pitch) {
return defaults(new SoundConfig(sound, volume, pitch));
}
public @NotNull SoundConfigBuilder defaults(@NotNull Sound sound, float volume) {
return defaults(sound, volume, 1.0f);
}
public @NotNull SoundConfigBuilder defaults(@NotNull Sound sound) {
return defaults(sound, 1.0f);
}
@Override
protected @NotNull SoundConfigBuilder getThis() {
return this;
}
@Override
public @NotNull ConfiguredSound build() {
return new ConfiguredSound(this.provider, this.path, this.comments, this.defaultValue);
}
}
@@ -1,73 +0,0 @@
//package cc.carm.lib.configuration.bukkit.commented;
//
//import org.yaml.snakeyaml.DumperOptions;
//import org.yaml.snakeyaml.Yaml;
//import org.yaml.snakeyaml.constructor.BaseConstructor;
//import org.yaml.snakeyaml.error.YAMLException;
//import org.yaml.snakeyaml.nodes.Node;
//import org.yaml.snakeyaml.nodes.Tag;
//import org.yaml.snakeyaml.representer.Representer;
//import org.yaml.snakeyaml.serializer.Serializer;
//
//import java.io.IOException;
//import java.io.StringWriter;
//import java.io.Writer;
//import java.util.ArrayList;
//import java.util.Iterator;
//import java.util.List;
//
///**
// * A hacky extension of {@link Yaml} that allows to write comments when dumping.
// */
//public class CommentedYaml extends Yaml {
//
// private final CommentsProvider commentsProvider;
//
// public CommentedYaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions, CommentsProvider commentsProvider) {
// super(constructor, representer, dumperOptions);
// this.commentsProvider = commentsProvider;
// }
//
// @Override
// public String dump(Object data) {
// List<Object> list = new ArrayList<>(1);
// list.add(data);
// return this.dumpAll(list.iterator());
// }
//
// @Override
// public void dump(Object data, Writer output) {
// List<Object> list = new ArrayList<>(1);
// list.add(data);
// this.dumpAll(list.iterator(), output, null);
// }
//
// @Override
// public String dumpAll(Iterator<?> data) {
// StringWriter buffer = new StringWriter();
// this.dumpAll(data, buffer, null);
// return buffer.toString();
// }
//
// @Override
// public void dumpAll(Iterator<?> data, Writer output) {
// this.dumpAll(data, output, null);
// }
//
// private void dumpAll(Iterator<?> data, Writer output, Tag rootTag) {
// Serializer serializer = new Serializer(new CommentedEmitter(output, this.dumperOptions, this.commentsProvider), this.resolver, this.dumperOptions, rootTag);
//
// try {
// serializer.open();
//
// while (data.hasNext()) {
// Node node = this.representer.represent(data.next());
// serializer.serialize(node);
// }
//
// serializer.close();
// } catch (IOException var6) {
// throw new YAMLException(var6);
// }
// }
//}
@@ -1,69 +0,0 @@
//package cc.carm.lib.configuration.bukkit.commented;
//
//import org.bukkit.configuration.InvalidConfigurationException;
//import org.bukkit.configuration.file.YamlConfiguration;
//import org.bukkit.configuration.file.YamlConstructor;
//import org.bukkit.configuration.file.YamlRepresenter;
//import org.jetbrains.annotations.NotNull;
//import org.yaml.snakeyaml.DumperOptions;
//import org.yaml.snakeyaml.representer.Representer;
//
//import java.io.File;
//import java.io.FileNotFoundException;
//import java.io.IOException;
//import java.io.Reader;
//
///**
// * A yaml file with comments on certain properties, as returned by the given {@link CommentsProvider}.
// * Unlike {@link YamlConfiguration}, this class does not provide a header support.
// */
//public class CommentedYamlConfiguration extends YamlConfiguration {
//
// private final DumperOptions yamlOptions = new DumperOptions();
// private final Representer yamlRepresenter = new YamlRepresenter();
// private final CommentedYaml yaml;
//
// public CommentedYamlConfiguration(CommentsProvider commentsProvider) {
// this.yaml = new CommentedYaml(new YamlConstructor(), this.yamlRepresenter, this.yamlOptions, commentsProvider);
// }
//
// public static CommentedYamlConfiguration loadConfiguration(CommentsProvider commentsProvider, File file) {
// CommentedYamlConfiguration config = new CommentedYamlConfiguration(commentsProvider);
//
// try {
// config.load(file);
// } catch (FileNotFoundException ignored) {
// } catch (IOException | InvalidConfigurationException var4) {
// var4.printStackTrace();
// }
//
// return config;
// }
//
// public static CommentedYamlConfiguration loadConfiguration(CommentsProvider commentsProvider, Reader reader) {
// CommentedYamlConfiguration config = new CommentedYamlConfiguration(commentsProvider);
//
// try {
// config.load(reader);
// } catch (IOException | InvalidConfigurationException ex) {
// ex.printStackTrace();
// }
//
// return config;
// }
//
// @Override
// public @NotNull String saveToString() {
// this.yamlOptions.setIndent(this.options().indent());
// this.yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
// this.yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
// String dump = this.yaml.dump(this.getValues(false));
// if (dump.equals("{}\n")) {
// dump = "";
// }
//
// // No header support.
//
// return dump;
// }
//}
@@ -1,7 +0,0 @@
package cc.carm.lib.configuration.bukkit.commented;
import java.util.function.Function;
public interface CommentsProvider extends Function<String, String[]> {
}
@@ -1,34 +0,0 @@
package cc.carm.lib.configuration.bukkit.commented;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class ConfigComments implements CommentsProvider {
Map<String, String[]> comments = new HashMap<>();
protected Map<String, String[]> getComments() {
return comments;
}
public void set(@NotNull String path, @NotNull String... comments) {
if (comments.length == 0) {
getComments().remove(path);
} else {
getComments().put(path, comments);
}
}
public @Nullable String[] get(@NotNull String path) {
return getComments().get(path);
}
@Override
public String[] apply(String s) {
return get(s);
}
}
@@ -1,44 +0,0 @@
package cc.carm.lib.configuration.bukkit.data;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
public class ItemConfig {
@NotNull Material type;
@Nullable String name;
@Nullable List<String> lore;
@NotNull Map<String, List<String>> additional;
public ItemConfig(@NotNull Material type, @Nullable String name,
@Nullable List<String> lore, @NotNull Map<String, List<String>> additional) {
this.type = type;
this.name = name;
this.lore = lore;
this.additional = additional;
}
public @NotNull Material getType() {
return type;
}
public @Nullable String getName() {
return name;
}
public @Nullable List<String> getLore() {
return lore;
}
public @NotNull Map<String, List<String>> getAdditionalLore() {
return additional;
}
}
@@ -1,8 +0,0 @@
package cc.carm.lib.configuration.bukkit.data;
public class MessageConfig {
}
@@ -1,67 +0,0 @@
package cc.carm.lib.configuration.bukkit.data;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SoundConfig {
protected Sound type;
protected float volume;
protected float pitch;
public SoundConfig(Sound type) {
this(type, 1, 1);
}
public SoundConfig(Sound type, float volume) {
this(type, volume, 1);
}
public SoundConfig(Sound type, float volume, float pitch) {
this.type = type;
this.volume = volume;
this.pitch = pitch;
}
public void playTo(Player player) {
player.playSound(player.getLocation(), type, volume, pitch);
}
public void playToAll() {
Bukkit.getOnlinePlayers().forEach(this::playTo);
}
public @NotNull String serialize() {
if (pitch != 1) {
return type.name() + ":" + volume + ":" + pitch;
} else if (volume != 1) {
return type.name() + ":" + volume;
} else {
return type.name();
}
}
@Contract("null -> null")
public static @Nullable SoundConfig deserialize(@Nullable String string) throws Exception {
if (string == null) return null;
String[] args = string.contains(":") ? string.split(":") : new String[]{string};
if (args.length < 1) return null;
try {
return new SoundConfig(
Sound.valueOf(args[0]),
(args.length >= 2) ? Float.parseFloat(args[1]) : 1,
(args.length >= 3) ? Float.parseFloat(args[2]) : 1
);
} catch (Exception exception) {
throw new Exception("Sound " + string + " wasn't configured correctly.", exception);
}
}
}
@@ -1,40 +0,0 @@
package cc.carm.lib.configuration.bukkit.source;
import cc.carm.lib.configuration.core.ConfigInitializer;
import cc.carm.lib.configuration.core.source.impl.FileConfigProvider;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public abstract class BukkitConfigProvider<W extends BukkitSectionWrapper, C extends YamlConfiguration>
extends FileConfigProvider<W> {
protected ConfigInitializer<? extends BukkitConfigProvider<W, C>> initializer;
protected C configuration;
public BukkitConfigProvider(@NotNull File file) {
super(file);
}
public abstract void initializeConfig();
@Override
public abstract @NotNull W getConfiguration();
@Override
public void reload() throws Exception {
configuration.load(getFile());
}
@Override
public void save() throws Exception {
configuration.save(getFile());
}
@Override
public @NotNull ConfigInitializer<? extends BukkitConfigProvider<W, C>> getInitializer() {
return this.initializer;
}
}
@@ -1,18 +0,0 @@
package cc.carm.lib.configuration.bukkit.source;
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
import org.bukkit.configuration.ConfigurationSection;
public abstract class BukkitSectionWrapper implements ConfigurationWrapper {
private final ConfigurationSection section;
private BukkitSectionWrapper(ConfigurationSection section) {
this.section = section;
}
public ConfigurationSection getSourceSection() {
return section;
}
}
@@ -1,24 +0,0 @@
package cc.carm.lib.configuration.bukkit.value;
import cc.carm.lib.configuration.bukkit.data.ItemConfig;
import cc.carm.lib.configuration.core.function.ConfigDataFunction;
import cc.carm.lib.configuration.core.function.ConfigValueParser;
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
import cc.carm.lib.configuration.core.source.ConfigurationWrapper;
import cc.carm.lib.configuration.core.value.type.ConfiguredSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class ConfiguredItem extends ConfiguredSection<ItemConfig> {
public ConfiguredItem(@Nullable ConfigurationProvider<?> provider,
@Nullable String sectionPath, @NotNull String[] comments,
@NotNull Class<ItemConfig> valueClass, @Nullable ItemConfig defaultValue,
@NotNull ConfigValueParser<ConfigurationWrapper, ItemConfig> parser,
@NotNull ConfigDataFunction<ItemConfig, ? extends Map<String, Object>> serializer) {
super(provider, sectionPath, comments, valueClass, defaultValue, parser, serializer);
}
}
@@ -1,27 +0,0 @@
package cc.carm.lib.configuration.bukkit.value;
import cc.carm.lib.configuration.bukkit.data.MessageConfig;
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
import cc.carm.lib.configuration.core.value.impl.CachedConfigValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ConfiguredMessage extends CachedConfigValue<MessageConfig> {
public ConfiguredMessage(@Nullable ConfigurationProvider<?> provider,
@Nullable String sectionPath, @NotNull String[] comments,
@Nullable MessageConfig defaultValue) {
super(provider, sectionPath, comments, defaultValue);
}
@Override
public @Nullable MessageConfig get() {
return null;
}
@Override
public void set(@Nullable MessageConfig value) {
}
}
@@ -1,52 +0,0 @@
package cc.carm.lib.configuration.bukkit.value;
import cc.carm.lib.configuration.bukkit.BukkitConfigValue;
import cc.carm.lib.configuration.bukkit.source.BukkitConfigProvider;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
public class ConfiguredSerializable<T extends ConfigurationSerializable> extends BukkitConfigValue<T> {
public static <V extends ConfigurationSerializable> ConfiguredSerializable<V> of(@NotNull Class<V> valueClass) {
return of(valueClass, null);
}
public static <V extends ConfigurationSerializable> ConfiguredSerializable<V> of(@NotNull Class<V> valueClass,
@Nullable V defaultValue) {
return builder().ofSerializable(valueClass).defaults(defaultValue).build();
}
protected final @NotNull Class<T> valueClass;
public ConfiguredSerializable(@Nullable BukkitConfigProvider provider,
@Nullable String configPath, @NotNull String[] comments,
@NotNull Class<T> valueClass, @Nullable T defaultValue) {
super(provider, configPath, comments, defaultValue);
this.valueClass = valueClass;
}
@Override
public @Nullable T get() {
if (isExpired()) { // 已过时的数据,需要重新解析一次。
try {
// 若未出现错误,则直接更新缓存并返回。
return updateCache(getBukkitConfig().get(getConfigPath(), getDefaultValue(), valueClass));
} catch (Exception e) {
// 出现了解析错误,提示并返回默认值。
e.printStackTrace();
return useDefault();
}
} else return Optional.ofNullable(getCachedValue()).orElse(defaultValue);
}
@Override
public void set(@Nullable T value) {
updateCache(value);
setValue(value);
}
}
@@ -1,48 +0,0 @@
package cc.carm.lib.configuration.bukkit.value;
import cc.carm.lib.configuration.bukkit.BukkitConfigValue;
import cc.carm.lib.configuration.bukkit.data.SoundConfig;
import cc.carm.lib.configuration.core.function.ConfigValueParser;
import cc.carm.lib.configuration.core.source.ConfigurationProvider;
import cc.carm.lib.configuration.core.value.type.ConfiguredValue;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
public class ConfiguredSound extends ConfiguredValue<SoundConfig> {
public static @NotNull ConfiguredSound of(Sound sound) {
return BukkitConfigValue.builder().createSound().defaults(sound).build();
}
public static @NotNull ConfiguredSound of(Sound sound, float volume) {
return BukkitConfigValue.builder().createSound().defaults(sound, volume).build();
}
public static @NotNull ConfiguredSound of(Sound sound, float volume, float pitch) {
return BukkitConfigValue.builder().createSound().defaults(sound, volume, pitch).build();
}
public ConfiguredSound(@Nullable ConfigurationProvider<?> provider,
@Nullable String sectionPath, @NotNull String[] comments,
@Nullable SoundConfig defaultValue) {
super(provider, sectionPath, comments, SoundConfig.class, defaultValue, getSoundParser(), SoundConfig::serialize);
}
public void playTo(@NotNull Player player) {
Optional.ofNullable(get()).ifPresent(c -> c.playTo(player));
}
public void playToAll() {
Optional.ofNullable(get()).ifPresent(SoundConfig::playToAll);
}
public static ConfigValueParser<Object, SoundConfig> getSoundParser() {
return ConfigValueParser.castToString().andThen((s, d) -> SoundConfig.deserialize(s));
}
}
+11 -5
View File
@@ -3,17 +3,16 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>MineConfiguration</artifactId>
<artifactId>mineconfiguration-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>1.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<artifactId>mineconfiguration-bukkit-common</artifactId>
<artifactId>mineconfiguration-bukkit</artifactId>
<packaging>jar</packaging>
<dependencies>
@@ -26,8 +25,15 @@
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<groupId>${project.parent.groupId}</groupId>
<artifactId>mineconfiguration-craftbukkit</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -0,0 +1,33 @@
package cc.carm.lib.configuration;
import cc.carm.lib.configuration.bukkit.source.BukkitConfigProvider;
import java.io.File;
import java.io.IOException;
public class MineConfiguration {
public static BukkitConfigProvider from(File file, String source) {
BukkitConfigProvider provider = new BukkitConfigProvider(file);
try {
provider.initializeFile(source);
provider.initializeConfig();
} catch (IOException e) {
e.printStackTrace();
}
return provider;
}
public static BukkitConfigProvider from(File file) {
return from(file, file.getName());
}
public static BukkitConfigProvider from(String fileName) {
return from(fileName, fileName);
}
public static BukkitConfigProvider from(String fileName, String source) {
return from(new File(fileName), source);
}
}
@@ -0,0 +1,68 @@
package cc.carm.lib.configuration.bukkit.source;
import cc.carm.lib.configuration.core.ConfigInitializer;
import cc.carm.lib.configuration.core.source.ConfigCommentInfo;
import cc.carm.lib.configuration.craft.source.CraftConfigProvider;
import cc.carm.lib.configuration.craft.source.CraftSectionWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedWriter;
import java.io.File;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class BukkitConfigProvider extends CraftConfigProvider {
protected static final char SEPARATOR = '.';
protected BukkitYAMLComments bukkitComments = new BukkitYAMLComments();
public BukkitConfigProvider(@NotNull File file) {
super(file);
}
public void initializeConfig() {
this.configuration = YamlConfiguration.loadConfiguration(file);
this.initializer = new ConfigInitializer<>(this);
}
@Override
public @NotNull CraftSectionWrapper getConfiguration() {
return CraftSectionWrapper.of(this.configuration);
}
@Override
public void reload() throws Exception {
configuration.load(getFile());
}
@Override
public void save() throws Exception {
configuration.save(getFile());
StringWriter writer = new StringWriter();
this.bukkitComments.writeComments(configuration, new BufferedWriter(writer));
String value = writer.toString(); // config contents
Path toUpdatePath = getFile().toPath();
if (!value.equals(new String(Files.readAllBytes(toUpdatePath), StandardCharsets.UTF_8))) {
Files.write(toUpdatePath, value.getBytes(StandardCharsets.UTF_8));
}
}
@Override
public void setComment(@Nullable String path, @Nullable ConfigCommentInfo comment) {
this.bukkitComments.set(path, comment);
}
@Override
public @Nullable ConfigCommentInfo getComment(@Nullable String path) {
return this.bukkitComments.get(path);
}
}
@@ -0,0 +1,115 @@
package cc.carm.lib.configuration.bukkit.source;
import cc.carm.lib.configuration.core.source.ConfigCommentInfo;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static cc.carm.lib.configuration.craft.source.CraftConfigProvider.SEPARATOR;
public class BukkitYAMLComments {
Map<String, ConfigCommentInfo> comments = new HashMap<>();
protected Map<String, ConfigCommentInfo> getComments() {
return comments;
}
public void set(@Nullable String path, @Nullable ConfigCommentInfo comments) {
if (comments == null) {
getComments().remove(path);
} else {
getComments().put(path, comments);
}
}
public @NotNull ConfigCommentInfo get(@Nullable String path) {
return getComments().getOrDefault(path, ConfigCommentInfo.defaults());
}
public @Nullable String buildComments(@NotNull String indents, @Nullable String path) {
ConfigCommentInfo comments = get(path);
if (!String.join("", comments.getComments()).isEmpty()) {
String prefix = comments.startWrap() ? "\n" : "";
String suffix = comments.endWrap() ? "\n" : "";
StringJoiner joiner = new StringJoiner("\n", prefix, suffix);
for (String comment : comments.getComments()) {
if (comment.length() == 0) joiner.add(" ");
else joiner.add(indents + "# " + comment);
}
return joiner + "\n";
} else {
return comments.startWrap() || comments.endWrap() ? "\n" : null;
}
}
/**
* 从一个文件读取配置并写入注释到某个写入器中。
* 该方法的部分源代码借鉴自 tchristofferson/ConfigUpdater 项目。
*
* @param source 源配置文件
* @param writer 配置写入器
* @throws IOException 当写入发生错误时抛出
*/
public void writeComments(@NotNull YamlConfiguration source, @NotNull BufferedWriter writer) throws IOException {
FileConfiguration temp = new YamlConfiguration(); // 该对象用于临时记录配置内容
for (String fullKey : source.getKeys(true)) {
String indents = getIndents(fullKey);
String comment = buildComments(indents, fullKey);
if (comment != null) writer.write(comment);
Object currentValue = source.get(fullKey);
String[] splitFullKey = fullKey.split("[" + SEPARATOR + "]");
String trailingKey = splitFullKey[splitFullKey.length - 1];
if (currentValue instanceof ConfigurationSection) {
writer.write(indents + trailingKey + ":");
if (!((ConfigurationSection) currentValue).getKeys(false).isEmpty()) {
writer.write("\n");
} else {
writer.write(" {}\n");
}
continue;
}
temp.set(trailingKey, currentValue);
String yaml = temp.saveToString();
yaml = yaml.substring(0, yaml.length() - 1).replace("\n", "\n" + indents);
String toWrite = indents + yaml + "\n";
temp.set(trailingKey, null);
writer.write(toWrite);
}
String endComment = buildComments("", null);
if (endComment != null) writer.write(endComment);
writer.close();
}
/**
* 得到一个键的缩进。
* 该方法的源代码来自 tchristofferson/ConfigUpdater 项目。
*
* @param key 键
* @return 该键的缩进文本
*/
protected static String getIndents(String key) {
String[] splitKey = key.split("[" + SEPARATOR + "]");
return IntStream.range(1, splitKey.length).mapToObj(i -> " ").collect(Collectors.joining());
}
}