From 7b140b5664f278a832408c3ef86f612bb7ce0f8c Mon Sep 17 00:00:00 2001 From: CarmJos Date: Fri, 22 Apr 2022 13:45:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=9F=BA=E7=A1=80=E9=83=A8?= =?UTF-8?q?=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/common/pom.xml | 58 + .../bukkit/BukkitConfigValue.java | 34 + .../bukkit/builder/AbstractBukkitBuilder.java | 13 + .../bukkit/builder/BukkitConfigBuilder.java | 19 + .../serializable/SerializableBuilder.java | 28 + .../builder/sound/SoundConfigBuilder.java | 34 + .../bukkit/commented/CommentedEmitter.java | 1513 +++++++++++++++++ .../bukkit/commented/CommentedYaml.java | 73 + .../commented/CommentedYamlConfiguration.java | 69 + .../bukkit/commented/CommentsProvider.java | 7 + .../bukkit/commented/ConfigComments.java | 34 + .../configuration/bukkit/data/ItemConfig.java | 44 + .../bukkit/data/MessageConfig.java | 8 + .../bukkit/data/SoundConfig.java | 67 + .../bukkit/source/BukkitConfigProvider.java | 40 + .../bukkit/source/BukkitSectionWrapper.java | 18 + .../bukkit/value/ConfiguredItem.java | 24 + .../bukkit/value/ConfiguredMessage.java | 27 + .../bukkit/value/ConfiguredSerializable.java | 52 + .../bukkit/value/ConfiguredSound.java | 48 + bungee/pom.xml | 66 + .../lib/configuration/MineConfiguration.java | 74 + .../bungee/BungeeConfigProvider.java | 63 + .../bungee/BungeeSectionWrapper.java | 70 + pom.xml | 6 + 25 files changed, 2489 insertions(+) create mode 100644 bukkit/common/pom.xml create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/BukkitConfigValue.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/AbstractBukkitBuilder.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/BukkitConfigBuilder.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/serializable/SerializableBuilder.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/sound/SoundConfigBuilder.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedEmitter.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedYaml.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedYamlConfiguration.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentsProvider.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/ConfigComments.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/ItemConfig.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/MessageConfig.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/SoundConfig.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/source/BukkitConfigProvider.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/source/BukkitSectionWrapper.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredItem.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredMessage.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredSerializable.java create mode 100644 bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredSound.java create mode 100644 bungee/pom.xml create mode 100644 bungee/src/main/java/cc/carm/lib/configuration/MineConfiguration.java create mode 100644 bungee/src/main/java/cc/carm/lib/configuration/bungee/BungeeConfigProvider.java create mode 100644 bungee/src/main/java/cc/carm/lib/configuration/bungee/BungeeSectionWrapper.java diff --git a/bukkit/common/pom.xml b/bukkit/common/pom.xml new file mode 100644 index 0000000..680c790 --- /dev/null +++ b/bukkit/common/pom.xml @@ -0,0 +1,58 @@ + + + + MineConfiguration + cc.carm.lib + 1.0.0 + ../../pom.xml + + 4.0.0 + + ${java.version} + ${java.version} + + mineconfiguration-bukkit-common + jar + + + + + ${project.parent.groupId} + easyconfiguration-core + ${easyconfiguration.version} + compile + + + + org.spigotmc + spigot-api + 1.8.8-R0.1-SNAPSHOT + provided + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + \ No newline at end of file diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/BukkitConfigValue.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/BukkitConfigValue.java new file mode 100644 index 0000000..9e0cc14 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/BukkitConfigValue.java @@ -0,0 +1,34 @@ +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 extends CachedConfigValue { + + 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(); + } + + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/AbstractBukkitBuilder.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/AbstractBukkitBuilder.java new file mode 100644 index 0000000..4f299a3 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/AbstractBukkitBuilder.java @@ -0,0 +1,13 @@ +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> + extends AbstractConfigBuilder> { + + public AbstractBukkitBuilder() { + super(BukkitConfigProvider.class); + } + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/BukkitConfigBuilder.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/BukkitConfigBuilder.java new file mode 100644 index 0000000..555e6e1 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/BukkitConfigBuilder.java @@ -0,0 +1,19 @@ +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 @NotNull SerializableBuilder ofSerializable(@NotNull Class valueClass) { + return new SerializableBuilder<>(valueClass); + } + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/serializable/SerializableBuilder.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/serializable/SerializableBuilder.java new file mode 100644 index 0000000..8ec3f5a --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/serializable/SerializableBuilder.java @@ -0,0 +1,28 @@ +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 + extends AbstractBukkitBuilder> { + + protected final @NotNull Class valueClass; + + public SerializableBuilder(@NotNull Class valueClass) { + this.valueClass = valueClass; + } + + @Override + protected @NotNull SerializableBuilder getThis() { + return this; + } + + @Override + public @NotNull ConfiguredSerializable build() { + return new ConfiguredSerializable<>(this.provider, this.path, this.comments, this.valueClass, this.defaultValue); + } + +} + diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/sound/SoundConfigBuilder.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/sound/SoundConfigBuilder.java new file mode 100644 index 0000000..b14023d --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/builder/sound/SoundConfigBuilder.java @@ -0,0 +1,34 @@ +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 { + + + 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); + } + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedEmitter.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedEmitter.java new file mode 100644 index 0000000..1dd8847 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedEmitter.java @@ -0,0 +1,1513 @@ +///* +// * Copyright (c) 2008, http://www.snakeyaml.org +// *

+// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// *

+// * http://www.apache.org/licenses/LICENSE-2.0 +// *

+// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +//package cc.carm.lib.configuration.bukkit.commented; +// +//import org.yaml.snakeyaml.DumperOptions; +//import org.yaml.snakeyaml.DumperOptions.Version; +//import org.yaml.snakeyaml.emitter.Emitable; +//import org.yaml.snakeyaml.emitter.EmitterException; +//import org.yaml.snakeyaml.emitter.ScalarAnalysis; +//import org.yaml.snakeyaml.error.YAMLException; +//import org.yaml.snakeyaml.events.*; +//import org.yaml.snakeyaml.nodes.Tag; +//import org.yaml.snakeyaml.reader.StreamReader; +//import org.yaml.snakeyaml.scanner.Constant; +//import org.yaml.snakeyaml.util.ArrayStack; +// +//import java.io.IOException; +//import java.io.Writer; +//import java.util.*; +//import java.util.concurrent.ArrayBlockingQueue; +//import java.util.regex.Pattern; +// +///** +// * Copy of {@link org.yaml.snakeyaml.emitter.Emitter} with some ugly hooks. +// */ +//public final class CommentedEmitter implements Emitable { +// public static final int MIN_INDENT = 1; +// public static final int MAX_INDENT = 10; +// private static final Map ESCAPE_REPLACEMENTS = new HashMap<>(); +// private static final char[] SPACE = {' '}; +// private final static Map DEFAULT_TAG_PREFIXES = new LinkedHashMap<>(); +// private final static Pattern HANDLE_FORMAT = Pattern.compile("^![-_\\w]*!$"); +// private final static Pattern ANCHOR_FORMAT = Pattern.compile("^[-_\\w]*$"); +// +// static { +// ESCAPE_REPLACEMENTS.put('\0', "0"); +// ESCAPE_REPLACEMENTS.put('\u0007', "a"); +// ESCAPE_REPLACEMENTS.put('\u0008', "b"); +// ESCAPE_REPLACEMENTS.put('\u0009', "t"); +// ESCAPE_REPLACEMENTS.put('\n', "n"); +// ESCAPE_REPLACEMENTS.put('\u000B', "v"); +// ESCAPE_REPLACEMENTS.put('\u000C', "f"); +// ESCAPE_REPLACEMENTS.put('\r', "r"); +// ESCAPE_REPLACEMENTS.put('\u001B', "e"); +// ESCAPE_REPLACEMENTS.put('"', "\""); +// ESCAPE_REPLACEMENTS.put('\\', "\\"); +// ESCAPE_REPLACEMENTS.put('\u0085', "N"); +// ESCAPE_REPLACEMENTS.put('\u00A0', "_"); +// ESCAPE_REPLACEMENTS.put('\u2028', "L"); +// ESCAPE_REPLACEMENTS.put('\u2029', "P"); +// } +// +// // Encoding is defined by Writer (cannot be overriden by STREAM-START.) +// // private Charset encoding; +// +// static { +// DEFAULT_TAG_PREFIXES.put("!", "!"); +// DEFAULT_TAG_PREFIXES.put(Tag.PREFIX, "!!"); +// } +// +// // The stream should have the methods `write` and possibly `flush`. +// private final Writer stream; +// // Emitter is a state machine with a stack of states to handle nested +// // structures. +// private final ArrayStack states; +// // Current event and the event queue. +// private final Queue events; +// // The current indentation level and the stack of previous indents. +// private final ArrayStack indents; +// // wytrem start +// CommentsProvider commentsProvider; +// // wytrem start +// boolean isInSequence = false; +// Stack paths = new Stack<>(); +// String lastSimpleKey; +// private EmitterState state; +// private Event event; +// private Integer indent; +// // Flow level. +// private int flowLevel; +// // Contexts. +// private boolean rootContext; +// private boolean mappingContext; +// private boolean simpleKeyContext; +// // +// // Characteristics of the last emitted character: +// // - current position. +// // - is it a whitespace? +// // - is it an indention character +// // (indentation space, '-', '?', or ':')? +// // private int line; this variable is not used +// private int column; +// private boolean whitespace; +// private boolean indention; +// private boolean openEnded; +// // Formatting details. +// private final Boolean canonical; +// // pretty print flow by adding extra line breaks +// private final Boolean prettyFlow; +// private final boolean allowUnicode; +// private int bestIndent; +// private final int indicatorIndent; +// private int bestWidth; +// private final char[] bestLineBreak; +// private final boolean splitLines; +// // wytrem end +// // Tag prefixes. +// private Map tagPrefixes; +// // Prepared anchor and tag. +// private String preparedAnchor; +// private String preparedTag; +// // Scalar analysis and style. +// private ScalarAnalysis analysis; +// // wytrem end +// private DumperOptions.ScalarStyle style; +// +// // In some cases, we wait for a few next events before emitting. +// +// public CommentedEmitter(Writer stream, DumperOptions opts, CommentsProvider commentsProvider) { // wytrem +// // wytrem start +// this.commentsProvider = commentsProvider; +// // wytrem end +// +// // The stream should have the methods `write` and possibly `flush`. +// this.stream = stream; +// // Emitter is a state machine with a stack of states to handle nested +// // structures. +// this.states = new ArrayStack<>(100); +// this.state = new ExpectStreamStart(); +// // Current event and the event queue. +// this.events = new ArrayBlockingQueue<>(100); +// this.event = null; +// // The current indentation level and the stack of previous indents. +// this.indents = new ArrayStack<>(10); +// this.indent = null; +// // Flow level. +// this.flowLevel = 0; +// // Contexts. +// mappingContext = false; +// simpleKeyContext = false; +// +// // +// // Characteristics of the last emitted character: +// // - current position. +// // - is it a whitespace? +// // - is it an indention character +// // (indentation space, '-', '?', or ':')? +// column = 0; +// whitespace = true; +// indention = true; +// +// // Whether the document requires an explicit document indicator +// openEnded = false; +// +// // Formatting details. +// this.canonical = opts.isCanonical(); +// this.prettyFlow = opts.isPrettyFlow(); +// this.allowUnicode = opts.isAllowUnicode(); +// this.bestIndent = 2; +// if ((opts.getIndent() > MIN_INDENT) && (opts.getIndent() < MAX_INDENT)) { +// this.bestIndent = opts.getIndent(); +// } +// this.indicatorIndent = opts.getIndicatorIndent(); +// this.bestWidth = 80; +// if (opts.getWidth() > this.bestIndent * 2) { +// this.bestWidth = opts.getWidth(); +// } +// this.bestLineBreak = opts.getLineBreak().getString().toCharArray(); +// this.splitLines = opts.getSplitLines(); +// +// // Tag prefixes. +// this.tagPrefixes = new LinkedHashMap<>(); +// +// // Prepared anchor and tag. +// this.preparedAnchor = null; +// this.preparedTag = null; +// +// // Scalar analysis and style. +// this.analysis = null; +// this.style = null; +// } +// +// static String prepareAnchor(String anchor) { +// if (anchor.length() == 0) { +// throw new EmitterException("anchor must not be empty"); +// } +// if (!ANCHOR_FORMAT.matcher(anchor).matches()) { +// throw new EmitterException("invalid character in the anchor: " + anchor); +// } +// return anchor; +// } +// +// public void emit(Event event) throws IOException { +// this.events.add(event); +// +// while (!needMoreEvents()) { +// this.event = this.events.poll(); +// // wytrem start +// if (this.event instanceof SequenceStartEvent) { +// this.isInSequence = true; +// } +// +// if (this.event instanceof SequenceEndEvent) { +// this.isInSequence = false; +// } +// +// if (this.event instanceof MappingStartEvent) { +// if (!this.isInSequence) { +// if (lastSimpleKey != null) { +// this.paths.push(lastSimpleKey); +// } +// } +// } +// +// if (this.event instanceof MappingEndEvent) { +// if (!this.isInSequence) { +// if (!this.paths.isEmpty()) { +// this.paths.pop(); +// } +// } +// } +// // wytrem end +// this.state.expect(); +// this.event = null; +// } +// } +// +// // States +// +// // Stream handlers. +// +// private boolean needMoreEvents() { +// if (events.isEmpty()) { +// return true; +// } +// Event event = events.peek(); +// if (event instanceof DocumentStartEvent) { +// return needEvents(1); +// } else if (event instanceof SequenceStartEvent) { +// return needEvents(2); +// } else if (event instanceof MappingStartEvent) { +// return needEvents(3); +// } else { +// return false; +// } +// } +// +// private boolean needEvents(int count) { +// int level = 0; +// Iterator iter = events.iterator(); +// iter.next(); +// while (iter.hasNext()) { +// Event event = iter.next(); +// if (event instanceof DocumentStartEvent || event instanceof CollectionStartEvent) { +// level++; +// } else if (event instanceof DocumentEndEvent || event instanceof CollectionEndEvent) { +// level--; +// } else if (event instanceof StreamEndEvent) { +// level = -1; +// } +// if (level < 0) { +// return false; +// } +// } +// return events.size() < count + 1; +// } +// +// // Document handlers. +// +// private void increaseIndent(boolean flow, boolean indentless) { +// indents.push(indent); +// if (indent == null) { +// if (flow) { +// indent = bestIndent; +// } else { +// indent = 0; +// } +// } else if (!indentless) { +// this.indent += bestIndent; +// } +// } +// +// private void expectNode(boolean root, boolean mapping, boolean simpleKey) throws IOException { +// rootContext = root; +// mappingContext = mapping; +// simpleKeyContext = simpleKey; +// if (event instanceof AliasEvent) { +// expectAlias(); +// } else if (event instanceof ScalarEvent || event instanceof CollectionStartEvent) { +// processAnchor("&"); +// processTag(); +// if (event instanceof ScalarEvent) { +// expectScalar(); +// } else if (event instanceof SequenceStartEvent) { +// if (flowLevel != 0 || canonical || ((SequenceStartEvent) event).isFlow() +// || checkEmptySequence()) { +// expectFlowSequence(); +// } else { +// expectBlockSequence(); +// } +// } else {// MappingStartEvent +// if (flowLevel != 0 || canonical || ((MappingStartEvent) event).isFlow() +// || checkEmptyMapping()) { +// expectFlowMapping(); +// } else { +// expectBlockMapping(); +// } +// } +// } else { +// throw new EmitterException("expected NodeEvent, but got " + event); +// } +// } +// +// private void expectAlias() throws IOException { +// if (((NodeEvent) event).getAnchor() == null) { +// throw new EmitterException("anchor is not specified for alias"); +// } +// processAnchor("*"); +// state = states.pop(); +// } +// +// private void expectScalar() throws IOException { +// // wytrem start +// if (simpleKeyContext) { +// String scalar = analyzeScalar(((ScalarEvent) event).getValue()).getScalar(); +// String path = scalar; +// +// if (!this.paths.isEmpty()) { +// path = String.join(".", this.paths) + "." + path; +// } +// +// String[] comments = this.commentsProvider.apply(path); +// if (comments != null && comments.length > 0) { +// writeLineBreak(null); +// for (String line : comments) { +// if (line.contains("\n")) { +// throw new IllegalArgumentException("Unexpected \\n in comment line."); +// } +// writeIndent(); +// stream.write("# " + line); +// writeLineBreak(null); +// } +// writeIndent(); +// } +// +// lastSimpleKey = scalar; +// } +// // wytrem end +// +// increaseIndent(true, false); +// processScalar(); +// indent = indents.pop(); +// state = states.pop(); +// } +// +// // Node handlers. +// +// private void expectFlowSequence() throws IOException { +// writeIndicator("[", true, true, false); +// flowLevel++; +// increaseIndent(true, false); +// if (prettyFlow) { +// writeIndent(); +// } +// state = new ExpectFirstFlowSequenceItem(); +// } +// +// private void expectFlowMapping() throws IOException { +// writeIndicator("{", true, true, false); +// flowLevel++; +// increaseIndent(true, false); +// if (prettyFlow) { +// writeIndent(); +// } +// state = new ExpectFirstFlowMappingKey(); +// } +// +// private void expectBlockSequence() { +// boolean indentless = mappingContext && !indention; +// increaseIndent(false, indentless); +// state = new ExpectFirstBlockSequenceItem(); +// } +// +// // Flow sequence handlers. +// +// // Block mapping handlers. +// private void expectBlockMapping() { +// increaseIndent(false, false); +// state = new ExpectFirstBlockMappingKey(); +// } +// +// private boolean checkEmptySequence() { +// return event instanceof SequenceStartEvent && !events.isEmpty() && events.peek() instanceof SequenceEndEvent; +// } +// +// private boolean checkEmptyMapping() { +// return event instanceof MappingStartEvent && !events.isEmpty() && events.peek() instanceof MappingEndEvent; +// } +// +// // Flow mapping handlers. +// +// private boolean checkEmptyDocument() { +// if (!(event instanceof DocumentStartEvent) || events.isEmpty()) { +// return false; +// } +// Event event = events.peek(); +// if (event instanceof ScalarEvent) { +// ScalarEvent e = (ScalarEvent) event; +// return e.getAnchor() == null && e.getTag() == null && e.getImplicit() != null && e +// .getValue().length() == 0; +// } +// return false; +// } +// +// private boolean checkSimpleKey() { +// int length = 0; +// if (event instanceof NodeEvent && ((NodeEvent) event).getAnchor() != null) { +// if (preparedAnchor == null) { +// preparedAnchor = prepareAnchor(((NodeEvent) event).getAnchor()); +// } +// length += preparedAnchor.length(); +// } +// String tag = null; +// if (event instanceof ScalarEvent) { +// tag = ((ScalarEvent) event).getTag(); +// } else if (event instanceof CollectionStartEvent) { +// tag = ((CollectionStartEvent) event).getTag(); +// } +// if (tag != null) { +// if (preparedTag == null) { +// preparedTag = prepareTag(tag); +// } +// length += preparedTag.length(); +// } +// if (event instanceof ScalarEvent) { +// if (analysis == null) { +// analysis = analyzeScalar(((ScalarEvent) event).getValue()); +// } +// length += analysis.getScalar().length(); +// } +// return length < 128 && (event instanceof AliasEvent +// || (event instanceof ScalarEvent && !analysis.isEmpty() && !analysis.isMultiline()) +// || checkEmptySequence() || checkEmptyMapping()); +// } +// +// private void processAnchor(String indicator) throws IOException { +// NodeEvent ev = (NodeEvent) event; +// if (ev.getAnchor() == null) { +// preparedAnchor = null; +// return; +// } +// if (preparedAnchor == null) { +// preparedAnchor = prepareAnchor(ev.getAnchor()); +// } +// writeIndicator(indicator + preparedAnchor, true, false, false); +// preparedAnchor = null; +// } +// +// private void processTag() throws IOException { +// String tag; +// if (event instanceof ScalarEvent) { +// ScalarEvent ev = (ScalarEvent) event; +// tag = ev.getTag(); +// if (style == null) { +// style = chooseScalarStyle(); +// } +// if ((!canonical || tag == null) && ((style == null && ev.getImplicit() +// .canOmitTagInPlainScalar()) || (style != null && ev.getImplicit() +// .canOmitTagInNonPlainScalar()))) { +// preparedTag = null; +// return; +// } +// if (ev.getImplicit().canOmitTagInPlainScalar() && tag == null) { +// tag = "!"; +// preparedTag = null; +// } +// } else { +// CollectionStartEvent ev = (CollectionStartEvent) event; +// tag = ev.getTag(); +// if ((!canonical || tag == null) && ev.getImplicit()) { +// preparedTag = null; +// return; +// } +// } +// if (tag == null) { +// throw new EmitterException("tag is not specified"); +// } +// if (preparedTag == null) { +// preparedTag = prepareTag(tag); +// } +// writeIndicator(preparedTag, true, false, false); +// preparedTag = null; +// } +// +// private DumperOptions.ScalarStyle chooseScalarStyle() { +// ScalarEvent ev = (ScalarEvent) event; +// if (analysis == null) { +// analysis = analyzeScalar(ev.getValue()); +// } +// +// if (!ev.isPlain() && ev.getScalarStyle() == DumperOptions.ScalarStyle.DOUBLE_QUOTED || this.canonical) { +// return DumperOptions.ScalarStyle.DOUBLE_QUOTED; +// } +// if (ev.isPlain() && ev.getImplicit().canOmitTagInPlainScalar()) { +// if (!(simpleKeyContext && (analysis.isEmpty() || analysis.isMultiline())) +// && ((flowLevel != 0 && analysis.isAllowFlowPlain()) || (flowLevel == 0 && analysis.isAllowBlockPlain()))) { +// return null; +// } +// } +// if (!ev.isPlain() && (ev.getScalarStyle() == DumperOptions.ScalarStyle.LITERAL || ev.getScalarStyle() == DumperOptions.ScalarStyle.FOLDED)) { +// if (flowLevel == 0 && !simpleKeyContext && analysis.isAllowBlock()) { +// return ev.getScalarStyle(); +// } +// } +// if (ev.isPlain() || ev.getScalarStyle() == DumperOptions.ScalarStyle.SINGLE_QUOTED) { +// if (analysis.isAllowSingleQuoted() && !(simpleKeyContext && analysis.isMultiline())) { +// return DumperOptions.ScalarStyle.SINGLE_QUOTED; +// } +// } +// return DumperOptions.ScalarStyle.DOUBLE_QUOTED; +// } +// +// // Block sequence handlers. +// +// private void processScalar() throws IOException { +// ScalarEvent ev = (ScalarEvent) event; +// +// if (analysis == null) { +// analysis = analyzeScalar(ev.getValue()); +// } +// if (style == null) { +// style = chooseScalarStyle(); +// } +// boolean split = !simpleKeyContext && splitLines; +// if (style == null) { +// +// writePlain(analysis.getScalar(), split); +// } else { +// switch (style) { +// case DOUBLE_QUOTED: +// writeDoubleQuoted(analysis.getScalar(), split); +// break; +// case SINGLE_QUOTED: +// writeSingleQuoted(analysis.getScalar(), split); +// break; +// case FOLDED: +// writeFolded(analysis.getScalar(), split); +// break; +// case LITERAL: +// writeLiteral(analysis.getScalar()); +// break; +// default: +// throw new YAMLException("Unexpected style: " + style); +// } +// } +// analysis = null; +// style = null; +// } +// +// private String prepareVersion(Version version) { +// if (version.major() != 1) { +// throw new EmitterException("unsupported YAML version: " + version); +// } +// return version.getRepresentation(); +// } +// +// private String prepareTagHandle(String handle) { +// if (handle.length() == 0) { +// throw new EmitterException("tag handle must not be empty"); +// } else if (handle.charAt(0) != '!' || handle.charAt(handle.length() - 1) != '!') { +// throw new EmitterException("tag handle must start and end with '!': " + handle); +// } else if (!"!".equals(handle) && !HANDLE_FORMAT.matcher(handle).matches()) { +// throw new EmitterException("invalid character in the tag handle: " + handle); +// } +// return handle; +// } +// +// private String prepareTagPrefix(String prefix) { +// if (prefix.length() == 0) { +// throw new EmitterException("tag prefix must not be empty"); +// } +// StringBuilder chunks = new StringBuilder(); +// int start = 0; +// int end = 0; +// if (prefix.charAt(0) == '!') { +// end = 1; +// } +// while (end < prefix.length()) { +// end++; +// } +// chunks.append(prefix, start, end); +// return chunks.toString(); +// } +// +// private String prepareTag(String tag) { +// if (tag.length() == 0) { +// throw new EmitterException("tag must not be empty"); +// } +// if ("!".equals(tag)) { +// return tag; +// } +// String handle = null; +// String suffix = tag; +// // shall the tag prefixes be sorted as in PyYAML? +// for (String prefix : tagPrefixes.keySet()) { +// if (tag.startsWith(prefix) && ("!".equals(prefix) || prefix.length() < tag.length())) { +// handle = prefix; +// } +// } +// if (handle != null) { +// suffix = tag.substring(handle.length()); +// handle = tagPrefixes.get(handle); +// } +// +// int end = suffix.length(); +// String suffixText = end > 0 ? suffix.substring(0, end) : ""; +// +// if (handle != null) { +// return handle + suffixText; +// } +// return "!<" + suffixText + ">"; +// } +// +// private ScalarAnalysis analyzeScalar(String scalar) { +// // Empty scalar is a special case. +// if (scalar.length() == 0) { +// return new ScalarAnalysis(scalar, true, false, false, true, true, false); +// } +// // Indicators and special characters. +// boolean blockIndicators = false; +// boolean flowIndicators = false; +// boolean lineBreaks = false; +// boolean specialCharacters = false; +// +// // Important whitespace combinations. +// boolean leadingSpace = false; +// boolean leadingBreak = false; +// boolean trailingSpace = false; +// boolean trailingBreak = false; +// boolean breakSpace = false; +// boolean spaceBreak = false; +// +// // Check document indicators. +// if (scalar.startsWith("---") || scalar.startsWith("...")) { +// blockIndicators = true; +// flowIndicators = true; +// } +// // First character or preceded by a whitespace. +// boolean preceededByWhitespace = true; +// boolean followedByWhitespace = scalar.length() == 1 || Constant.NULL_BL_T_LINEBR.has(scalar.codePointAt(1)); +// // The previous character is a space. +// boolean previousSpace = false; +// +// // The previous character is a break. +// boolean previousBreak = false; +// +// int index = 0; +// +// while (index < scalar.length()) { +// int c = scalar.codePointAt(index); +// // Check for indicators. +// if (index == 0) { +// // Leading indicators are special characters. +// if ("#,[]{}&*!|>'\"%@`".indexOf(c) != -1) { +// flowIndicators = true; +// blockIndicators = true; +// } +// if (c == '?' || c == ':') { +// flowIndicators = true; +// if (followedByWhitespace) { +// blockIndicators = true; +// } +// } +// if (c == '-' && followedByWhitespace) { +// flowIndicators = true; +// blockIndicators = true; +// } +// } else { +// // Some indicators cannot appear within a scalar as well. +// if (",?[]{}".indexOf(c) != -1) { +// flowIndicators = true; +// } +// if (c == ':') { +// flowIndicators = true; +// if (followedByWhitespace) { +// blockIndicators = true; +// } +// } +// if (c == '#' && preceededByWhitespace) { +// flowIndicators = true; +// blockIndicators = true; +// } +// } +// // Check for line breaks, special, and unicode characters. +// boolean isLineBreak = Constant.LINEBR.has(c); +// if (isLineBreak) { +// lineBreaks = true; +// } +// if (!(c == '\n' || (0x20 <= c && c <= 0x7E))) { +// if (c == 0x85 || (c >= 0xA0 && c <= 0xD7FF) +// || (c >= 0xE000 && c <= 0xFFFD) +// || (c >= 0x10000 && c <= 0x10FFFF)) { +// // unicode is used +// if (!this.allowUnicode) { +// specialCharacters = true; +// } +// } else { +// specialCharacters = true; +// } +// } +// // Detect important whitespace combinations. +// if (c == ' ') { +// if (index == 0) { +// leadingSpace = true; +// } +// if (index == scalar.length() - 1) { +// trailingSpace = true; +// } +// if (previousBreak) { +// breakSpace = true; +// } +// previousSpace = true; +// previousBreak = false; +// } else if (isLineBreak) { +// if (index == 0) { +// leadingBreak = true; +// } +// if (index == scalar.length() - 1) { +// trailingBreak = true; +// } +// if (previousSpace) { +// spaceBreak = true; +// } +// previousSpace = false; +// previousBreak = true; +// } else { +// previousSpace = false; +// previousBreak = false; +// } +// +// // Prepare for the next character. +// index += Character.charCount(c); +// preceededByWhitespace = Constant.NULL_BL_T.has(c) || isLineBreak; +// followedByWhitespace = true; +// if (index + 1 < scalar.length()) { +// int nextIndex = index + Character.charCount(scalar.codePointAt(index)); +// if (nextIndex < scalar.length()) { +// followedByWhitespace = (Constant.NULL_BL_T.has(scalar.codePointAt(nextIndex))) || isLineBreak; +// } +// } +// } +// // Let's decide what styles are allowed. +// boolean allowFlowPlain = true; +// boolean allowBlockPlain = true; +// boolean allowSingleQuoted = true; +// boolean allowBlock = true; +// // Leading and trailing whitespaces are bad for plain scalars. +// if (leadingSpace || leadingBreak || trailingSpace || trailingBreak) { +// allowFlowPlain = allowBlockPlain = false; +// } +// // We do not permit trailing spaces for block scalars. +// if (trailingSpace) { +// allowBlock = false; +// } +// // Spaces at the beginning of a new line are only acceptable for block +// // scalars. +// if (breakSpace) { +// allowFlowPlain = allowBlockPlain = allowSingleQuoted = false; +// } +// // Spaces followed by breaks, as well as special character are only +// // allowed for double quoted scalars. +// if (spaceBreak || specialCharacters) { +// allowFlowPlain = allowBlockPlain = allowSingleQuoted = allowBlock = false; +// } +// // Although the plain scalar writer supports breaks, we never emit +// // multiline plain scalars in the flow context. +// if (lineBreaks) { +// allowFlowPlain = false; +// } +// // Flow indicators are forbidden for flow plain scalars. +// if (flowIndicators) { +// allowFlowPlain = false; +// } +// // Block indicators are forbidden for block plain scalars. +// if (blockIndicators) { +// allowBlockPlain = false; +// } +// +// return new ScalarAnalysis(scalar, false, lineBreaks, allowFlowPlain, allowBlockPlain, +// allowSingleQuoted, allowBlock); +// } +// +// void flushStream() throws IOException { +// stream.flush(); +// } +// +// void writeStreamStart() { +// // BOM is written by Writer. +// } +// +// // Checkers. +// +// void writeStreamEnd() throws IOException { +// flushStream(); +// } +// +// void writeIndicator(String indicator, boolean needWhitespace, boolean whitespace, +// boolean indentation) throws IOException { +// if (!this.whitespace && needWhitespace) { +// this.column++; +// stream.write(SPACE); +// } +// this.whitespace = whitespace; +// this.indention = this.indention && indentation; +// this.column += indicator.length(); +// openEnded = false; +// stream.write(indicator); +// } +// +// void writeIndent() throws IOException { +// int indent; +// if (this.indent != null) { +// indent = this.indent; +// } else { +// indent = 0; +// } +// +// if (!this.indention || this.column > indent || (this.column == indent && !this.whitespace)) { +// writeLineBreak(null); +// } +// +// writeWhitespace(indent - this.column); +// } +// +// private void writeWhitespace(int length) throws IOException { +// if (length <= 0) { +// return; +// } +// this.whitespace = true; +// char[] data = new char[length]; +// Arrays.fill(data, ' '); +// this.column += length; +// stream.write(data); +// } +// +// // Anchor, Tag, and Scalar processors. +// +// private void writeLineBreak(String data) throws IOException { +// this.whitespace = true; +// this.indention = true; +// this.column = 0; +// if (data == null) { +// stream.write(this.bestLineBreak); +// } else { +// stream.write(data); +// } +// } +// +// void writeVersionDirective(String versionText) throws IOException { +// stream.write("%YAML "); +// stream.write(versionText); +// writeLineBreak(null); +// } +// +// void writeTagDirective(String handleText, String prefixText) throws IOException { +// // XXX: not sure 4 invocations better than StringBuilders created by str +// // + str +// stream.write("%TAG "); +// stream.write(handleText); +// stream.write(SPACE); +// stream.write(prefixText); +// writeLineBreak(null); +// } +// +// // Scalar streams. +// private void writeSingleQuoted(String text, boolean split) throws IOException { +// writeIndicator("'", true, false, false); +// boolean spaces = false; +// boolean breaks = false; +// int start = 0, end = 0; +// char ch; +// while (end <= text.length()) { +// ch = 0; +// if (end < text.length()) { +// ch = text.charAt(end); +// } +// if (spaces) { +// if (ch != ' ') { +// if (start + 1 == end && this.column > this.bestWidth && split && start != 0 +// && end != text.length()) { +// writeIndent(); +// } else { +// int len = end - start; +// this.column += len; +// stream.write(text, start, len); +// } +// start = end; +// } +// } else if (breaks) { +// if (ch == 0 || Constant.LINEBR.hasNo(ch)) { +// nextLine(text, start, end); +// start = end; +// } +// } else { +// if (Constant.LINEBR.has(ch, "\0 '")) { +// if (start < end) { +// int len = end - start; +// this.column += len; +// stream.write(text, start, len); +// start = end; +// } +// } +// } +// if (ch == '\'') { +// this.column += 2; +// stream.write("''"); +// start = end + 1; +// } +// if (ch != 0) { +// spaces = ch == ' '; +// breaks = Constant.LINEBR.has(ch); +// } +// end++; +// } +// writeIndicator("'", false, false, false); +// } +// +// private void nextLine(String text, int start, int end) throws IOException { +// if (text.charAt(start) == '\n') { +// writeLineBreak(null); +// } +// String data = text.substring(start, end); +// for (char br : data.toCharArray()) { +// if (br == '\n') { +// writeLineBreak(null); +// } else { +// writeLineBreak(String.valueOf(br)); +// } +// } +// writeIndent(); +// } +// +// // Analyzers. +// +// private void writeDoubleQuoted(String text, boolean split) throws IOException { +// writeIndicator("\"", true, false, false); +// int start = 0; +// int end = 0; +// while (end <= text.length()) { +// Character ch = null; +// if (end < text.length()) { +// ch = text.charAt(end); +// } +// if (ch == null || "\"\\\u0085\u2028\u2029\uFEFF".indexOf(ch) != -1 +// || !('\u0020' <= ch && ch <= '\u007E')) { +// if (start < end) { +// int len = end - start; +// this.column += len; +// stream.write(text, start, len); +// start = end; +// } +// if (ch != null) { +// String data; +// if (ESCAPE_REPLACEMENTS.containsKey(ch)) { +// data = "\\" + ESCAPE_REPLACEMENTS.get(ch); +// } else if (!this.allowUnicode || !StreamReader.isPrintable(ch)) { +// // if !allowUnicode or the character is not printable, +// // we must encode it +// if (ch <= '\u00FF') { +// String s = "0" + Integer.toString(ch, 16); +// data = "\\x" + s.substring(s.length() - 2); +// } else if (ch >= '\uD800' && ch <= '\uDBFF') { +// if (end + 1 < text.length()) { +// char ch2 = text.charAt(++end); +// String s = "000" + Long.toHexString(Character.toCodePoint(ch, ch2)); +// data = "\\U" + s.substring(s.length() - 8); +// } else { +// String s = "000" + Integer.toString(ch, 16); +// data = "\\u" + s.substring(s.length() - 4); +// } +// } else { +// String s = "000" + Integer.toString(ch, 16); +// data = "\\u" + s.substring(s.length() - 4); +// } +// } else { +// data = String.valueOf(ch); +// } +// this.column += data.length(); +// stream.write(data); +// start = end + 1; +// } +// } +// if ((0 < end && end < (text.length() - 1)) && (ch == ' ' || start >= end) +// && (this.column + (end - start)) > this.bestWidth && split) { +// String data; +// if (start >= end) { +// data = "\\"; +// } else { +// data = text.substring(start, end) + "\\"; +// } +// if (start < end) { +// start = end; +// } +// this.column += data.length(); +// stream.write(data); +// writeIndent(); +// this.whitespace = false; +// this.indention = false; +// if (text.charAt(start) == ' ') { +// data = "\\"; +// this.column += data.length(); +// stream.write(data); +// } +// } +// end += 1; +// } +// writeIndicator("\"", false, false, false); +// } +// +// private String determineBlockHints(String text) { +// StringBuilder hints = new StringBuilder(); +// if (Constant.LINEBR.has(text.charAt(0), " ")) { +// hints.append(bestIndent); +// } +// char ch1 = text.charAt(text.length() - 1); +// if (Constant.LINEBR.hasNo(ch1)) { +// hints.append("-"); +// } else if (text.length() == 1 || Constant.LINEBR.has(text.charAt(text.length() - 2))) { +// hints.append("+"); +// } +// return hints.toString(); +// } +// +// void writeFolded(String text, boolean split) throws IOException { +// String hints = determineBlockHints(text); +// writeIndicator(">" + hints, true, false, false); +// if (hints.length() > 0 && (hints.charAt(hints.length() - 1) == '+')) { +// openEnded = true; +// } +// writeLineBreak(null); +// boolean leadingSpace = true; +// boolean spaces = false; +// boolean breaks = true; +// int start = 0, end = 0; +// while (end <= text.length()) { +// char ch = 0; +// if (end < text.length()) { +// ch = text.charAt(end); +// } +// if (breaks) { +// if (ch == 0 || Constant.LINEBR.hasNo(ch)) { +// if (!leadingSpace && ch != 0 && ch != ' ' && text.charAt(start) == '\n') { +// writeLineBreak(null); +// } +// leadingSpace = ch == ' '; +// String data = text.substring(start, end); +// for (char br : data.toCharArray()) { +// if (br == '\n') { +// writeLineBreak(null); +// } else { +// writeLineBreak(String.valueOf(br)); +// } +// } +// if (ch != 0) { +// writeIndent(); +// } +// start = end; +// } +// } else if (spaces) { +// if (ch != ' ') { +// if (start + 1 == end && this.column > this.bestWidth && split) { +// writeIndent(); +// } else { +// int len = end - start; +// this.column += len; +// stream.write(text, start, len); +// } +// start = end; +// } +// } else { +// if (Constant.LINEBR.has(ch, "\0 ")) { +// int len = end - start; +// this.column += len; +// stream.write(text, start, len); +// if (ch == 0) { +// writeLineBreak(null); +// } +// start = end; +// } +// } +// if (ch != 0) { +// breaks = Constant.LINEBR.has(ch); +// spaces = ch == ' '; +// } +// end++; +// } +// } +// +// void writeLiteral(String text) throws IOException { +// String hints = determineBlockHints(text); +// writeIndicator("|" + hints, true, false, false); +// if (hints.length() > 0 && (hints.charAt(hints.length() - 1)) == '+') { +// openEnded = true; +// } +// writeLineBreak(null); +// boolean breaks = true; +// int start = 0, end = 0; +// while (end <= text.length()) { +// char ch = 0; +// if (end < text.length()) { +// ch = text.charAt(end); +// } +// if (breaks) { +// if (ch == 0 || Constant.LINEBR.hasNo(ch)) { +// String data = text.substring(start, end); +// for (char br : data.toCharArray()) { +// if (br == '\n') { +// writeLineBreak(null); +// } else { +// writeLineBreak(String.valueOf(br)); +// } +// } +// if (ch != 0) { +// writeIndent(); +// } +// start = end; +// } +// } else { +// if (ch == 0 || Constant.LINEBR.has(ch)) { +// stream.write(text, start, end - start); +// if (ch == 0) { +// writeLineBreak(null); +// } +// start = end; +// } +// } +// if (ch != 0) { +// breaks = Constant.LINEBR.has(ch); +// } +// end++; +// } +// } +// +// void writePlain(String text, boolean split) throws IOException { +// if (rootContext) { +// openEnded = true; +// } +// if (text.length() == 0) { +// return; +// } +// if (!this.whitespace) { +// this.column++; +// stream.write(SPACE); +// } +// this.whitespace = false; +// this.indention = false; +// boolean spaces = false; +// boolean breaks = false; +// int start = 0, end = 0; +// while (end <= text.length()) { +// char ch = 0; +// if (end < text.length()) { +// ch = text.charAt(end); +// } +// if (spaces) { +// if (ch != ' ') { +// if (start + 1 == end && this.column > this.bestWidth && split) { +// writeIndent(); +// this.whitespace = false; +// this.indention = false; +// } else { +// int len = end - start; +// this.column += len; +// stream.write(text, start, len); +// } +// start = end; +// } +// } else if (breaks) { +// if (Constant.LINEBR.hasNo(ch)) { +// nextLine(text, start, end); +// this.whitespace = false; +// this.indention = false; +// start = end; +// } +// } else { +// if (Constant.LINEBR.has(ch, "\0 ")) { +// int len = end - start; +// this.column += len; +// stream.write(text, start, len); +// start = end; +// } +// } +// if (ch != 0) { +// spaces = ch == ' '; +// breaks = Constant.LINEBR.has(ch); +// } +// end++; +// } +// } +// +// /** +// * +// */ +// public interface EmitterState { +// void expect() throws IOException; +// } +// +// private class ExpectStreamStart implements EmitterState { +// public void expect() { +// if (event instanceof StreamStartEvent) { +// writeStreamStart(); +// state = new ExpectFirstDocumentStart(); +// } else { +// throw new EmitterException("expected StreamStartEvent, but got " + event); +// } +// } +// } +// +// private class ExpectNothing implements EmitterState { +// public void expect() { +// throw new EmitterException("expecting nothing, but got " + event); +// } +// } +// +// // Writers. +// +// private class ExpectFirstDocumentStart implements EmitterState { +// public void expect() throws IOException { +// new ExpectDocumentStart(true).expect(); +// } +// } +// +// private class ExpectDocumentStart implements EmitterState { +// private final boolean first; +// +// public ExpectDocumentStart(boolean first) { +// this.first = first; +// } +// +// public void expect() throws IOException { +// if (event instanceof DocumentStartEvent) { +// DocumentStartEvent ev = (DocumentStartEvent) event; +// if ((ev.getVersion() != null || ev.getTags() != null) && openEnded) { +// writeIndicator("...", true, false, false); +// writeIndent(); +// } +// if (ev.getVersion() != null) { +// String versionText = prepareVersion(ev.getVersion()); +// writeVersionDirective(versionText); +// } +// tagPrefixes = new LinkedHashMap<>(DEFAULT_TAG_PREFIXES); +// if (ev.getTags() != null) { +// Set handles = new TreeSet<>(ev.getTags().keySet()); +// for (String handle : handles) { +// String prefix = ev.getTags().get(handle); +// tagPrefixes.put(prefix, handle); +// String handleText = prepareTagHandle(handle); +// String prefixText = prepareTagPrefix(prefix); +// writeTagDirective(handleText, prefixText); +// } +// } +// boolean implicit = first && !ev.getExplicit() && !canonical +// && ev.getVersion() == null +// && (ev.getTags() == null || ev.getTags().isEmpty()) +// && !checkEmptyDocument(); +// if (!implicit) { +// writeIndent(); +// writeIndicator("---", true, false, false); +// if (canonical) { +// writeIndent(); +// } +// } +// state = new ExpectDocumentRoot(); +// } else if (event instanceof StreamEndEvent) { +// // fix 313 PyYAML changeset +// // if (openEnded) { +// // writeIndicator("...", true, false, false); +// // writeIndent(); +// // } +// writeStreamEnd(); +// state = new ExpectNothing(); +// } else { +// throw new EmitterException("expected DocumentStartEvent, but got " + event); +// } +// } +// } +// +// private class ExpectDocumentEnd implements EmitterState { +// public void expect() throws IOException { +// if (event instanceof DocumentEndEvent) { +// writeIndent(); +// if (((DocumentEndEvent) event).getExplicit()) { +// writeIndicator("...", true, false, false); +// writeIndent(); +// } +// flushStream(); +// state = new ExpectDocumentStart(false); +// } else { +// throw new EmitterException("expected DocumentEndEvent, but got " + event); +// } +// } +// } +// +// private class ExpectDocumentRoot implements EmitterState { +// public void expect() throws IOException { +// states.push(new ExpectDocumentEnd()); +// expectNode(true, false, false); +// } +// } +// +// private class ExpectFirstFlowSequenceItem implements EmitterState { +// public void expect() throws IOException { +// if (event instanceof SequenceEndEvent) { +// indent = indents.pop(); +// flowLevel--; +// writeIndicator("]", false, false, false); +// state = states.pop(); +// } else { +// if (canonical || (column > bestWidth && splitLines) || prettyFlow) { +// writeIndent(); +// } +// states.push(new ExpectFlowSequenceItem()); +// expectNode(false, false, false); +// } +// } +// } +// +// private class ExpectFlowSequenceItem implements EmitterState { +// public void expect() throws IOException { +// if (event instanceof SequenceEndEvent) { +// indent = indents.pop(); +// flowLevel--; +// if (canonical) { +// writeIndicator(",", false, false, false); +// writeIndent(); +// } +// writeIndicator("]", false, false, false); +// if (prettyFlow) { +// writeIndent(); +// } +// state = states.pop(); +// } else { +// writeIndicator(",", false, false, false); +// if (canonical || (column > bestWidth && splitLines) || prettyFlow) { +// writeIndent(); +// } +// states.push(new ExpectFlowSequenceItem()); +// expectNode(false, false, false); +// } +// } +// } +// +// private class ExpectFirstFlowMappingKey implements EmitterState { +// public void expect() throws IOException { +// if (event instanceof MappingEndEvent) { +// indent = indents.pop(); +// flowLevel--; +// writeIndicator("}", false, false, false); +// state = states.pop(); +// } else { +// if (canonical || (column > bestWidth && splitLines) || prettyFlow) { +// writeIndent(); +// } +// if (!canonical && checkSimpleKey()) { +// states.push(new ExpectFlowMappingSimpleValue()); +// expectNode(false, true, true); +// } else { +// writeIndicator("?", true, false, false); +// states.push(new ExpectFlowMappingValue()); +// expectNode(false, true, false); +// } +// } +// } +// } +// +// private class ExpectFlowMappingKey implements EmitterState { +// public void expect() throws IOException { +// if (event instanceof MappingEndEvent) { +// indent = indents.pop(); +// flowLevel--; +// if (canonical) { +// writeIndicator(",", false, false, false); +// writeIndent(); +// } +// if (prettyFlow) { +// writeIndent(); +// } +// writeIndicator("}", false, false, false); +// state = states.pop(); +// } else { +// writeIndicator(",", false, false, false); +// if (canonical || (column > bestWidth && splitLines) || prettyFlow) { +// writeIndent(); +// } +// if (!canonical && checkSimpleKey()) { +// states.push(new ExpectFlowMappingSimpleValue()); +// expectNode(false, true, true); +// } else { +// writeIndicator("?", true, false, false); +// states.push(new ExpectFlowMappingValue()); +// expectNode(false, true, false); +// } +// } +// } +// } +// +// private class ExpectFlowMappingSimpleValue implements EmitterState { +// public void expect() throws IOException { +// writeIndicator(":", false, false, false); +// states.push(new ExpectFlowMappingKey()); +// expectNode(false, true, false); +// } +// } +// +// private class ExpectFlowMappingValue implements EmitterState { +// public void expect() throws IOException { +// if (canonical || (column > bestWidth) || prettyFlow) { +// writeIndent(); +// } +// writeIndicator(":", true, false, false); +// states.push(new ExpectFlowMappingKey()); +// expectNode(false, true, false); +// } +// } +// +// private class ExpectFirstBlockSequenceItem implements EmitterState { +// public void expect() throws IOException { +// new ExpectBlockSequenceItem(true).expect(); +// } +// } +// +// private class ExpectBlockSequenceItem implements EmitterState { +// private final boolean first; +// +// public ExpectBlockSequenceItem(boolean first) { +// this.first = first; +// } +// +// public void expect() throws IOException { +// if (!this.first && event instanceof SequenceEndEvent) { +// indent = indents.pop(); +// state = states.pop(); +// } else { +// writeIndent(); +// writeWhitespace(indicatorIndent); +// writeIndicator("-", true, false, true); +// states.push(new ExpectBlockSequenceItem(false)); +// expectNode(false, false, false); +// } +// } +// } +// +// private class ExpectFirstBlockMappingKey implements EmitterState { +// public void expect() throws IOException { +// new ExpectBlockMappingKey(true).expect(); +// } +// } +// +// private class ExpectBlockMappingKey implements EmitterState { +// private final boolean first; +// +// public ExpectBlockMappingKey(boolean first) { +// this.first = first; +// } +// +// public void expect() throws IOException { +// if (!this.first && event instanceof MappingEndEvent) { +// indent = indents.pop(); +// state = states.pop(); +// } else { +// writeIndent(); +// if (checkSimpleKey()) { +// states.push(new ExpectBlockMappingSimpleValue()); +// expectNode(false, true, true); +// } else { +// writeIndicator("?", true, false, true); +// states.push(new ExpectBlockMappingValue()); +// expectNode(false, true, false); +// } +// } +// } +// } +// +// private class ExpectBlockMappingSimpleValue implements EmitterState { +// public void expect() throws IOException { +// writeIndicator(":", false, false, false); +// states.push(new ExpectBlockMappingKey(false)); +// expectNode(false, true, false); +// } +// } +// +// private class ExpectBlockMappingValue implements EmitterState { +// public void expect() throws IOException { +// writeIndent(); +// writeIndicator(":", true, false, true); +// states.push(new ExpectBlockMappingKey(false)); +// expectNode(false, true, false); +// } +// } +//} \ No newline at end of file diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedYaml.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedYaml.java new file mode 100644 index 0000000..7b6e599 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedYaml.java @@ -0,0 +1,73 @@ +//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 list = new ArrayList<>(1); +// list.add(data); +// return this.dumpAll(list.iterator()); +// } +// +// @Override +// public void dump(Object data, Writer output) { +// List 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); +// } +// } +//} \ No newline at end of file diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedYamlConfiguration.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedYamlConfiguration.java new file mode 100644 index 0000000..f430803 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentedYamlConfiguration.java @@ -0,0 +1,69 @@ +//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; +// } +//} \ No newline at end of file diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentsProvider.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentsProvider.java new file mode 100644 index 0000000..ddc1d8f --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/CommentsProvider.java @@ -0,0 +1,7 @@ +package cc.carm.lib.configuration.bukkit.commented; + +import java.util.function.Function; + + +public interface CommentsProvider extends Function { +} \ No newline at end of file diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/ConfigComments.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/ConfigComments.java new file mode 100644 index 0000000..d1700ef --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/commented/ConfigComments.java @@ -0,0 +1,34 @@ +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 comments = new HashMap<>(); + + protected Map 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); + } + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/ItemConfig.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/ItemConfig.java new file mode 100644 index 0000000..e70a8d4 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/ItemConfig.java @@ -0,0 +1,44 @@ +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 lore; + @NotNull Map> additional; + + public ItemConfig(@NotNull Material type, @Nullable String name, + @Nullable List lore, @NotNull Map> 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 getLore() { + return lore; + } + + public @NotNull Map> getAdditionalLore() { + return additional; + } + + + + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/MessageConfig.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/MessageConfig.java new file mode 100644 index 0000000..03165bf --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/MessageConfig.java @@ -0,0 +1,8 @@ +package cc.carm.lib.configuration.bukkit.data; + +public class MessageConfig { + + + + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/SoundConfig.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/SoundConfig.java new file mode 100644 index 0000000..f5f9e28 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/data/SoundConfig.java @@ -0,0 +1,67 @@ +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); + } + } + + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/source/BukkitConfigProvider.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/source/BukkitConfigProvider.java new file mode 100644 index 0000000..d7d196b --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/source/BukkitConfigProvider.java @@ -0,0 +1,40 @@ +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 + extends FileConfigProvider { + + protected ConfigInitializer> 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> getInitializer() { + return this.initializer; + } + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/source/BukkitSectionWrapper.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/source/BukkitSectionWrapper.java new file mode 100644 index 0000000..cf95545 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/source/BukkitSectionWrapper.java @@ -0,0 +1,18 @@ +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; + } + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredItem.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredItem.java new file mode 100644 index 0000000..42cb203 --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredItem.java @@ -0,0 +1,24 @@ +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 { + + public ConfiguredItem(@Nullable ConfigurationProvider provider, + @Nullable String sectionPath, @NotNull String[] comments, + @NotNull Class valueClass, @Nullable ItemConfig defaultValue, + @NotNull ConfigValueParser parser, + @NotNull ConfigDataFunction> serializer) { + super(provider, sectionPath, comments, valueClass, defaultValue, parser, serializer); + } + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredMessage.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredMessage.java new file mode 100644 index 0000000..f86fdae --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredMessage.java @@ -0,0 +1,27 @@ +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 { + + + 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) { + + } +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredSerializable.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredSerializable.java new file mode 100644 index 0000000..ff8a7ee --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredSerializable.java @@ -0,0 +1,52 @@ +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 extends BukkitConfigValue { + + public static ConfiguredSerializable of(@NotNull Class valueClass) { + return of(valueClass, null); + } + + public static ConfiguredSerializable of(@NotNull Class valueClass, + @Nullable V defaultValue) { + return builder().ofSerializable(valueClass).defaults(defaultValue).build(); + } + + protected final @NotNull Class valueClass; + + public ConfiguredSerializable(@Nullable BukkitConfigProvider provider, + @Nullable String configPath, @NotNull String[] comments, + @NotNull Class 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); + } + + +} diff --git a/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredSound.java b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredSound.java new file mode 100644 index 0000000..c51836a --- /dev/null +++ b/bukkit/common/src/main/java/cc/carm/lib/configuration/bukkit/value/ConfiguredSound.java @@ -0,0 +1,48 @@ +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 { + + 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 getSoundParser() { + return ConfigValueParser.castToString().andThen((s, d) -> SoundConfig.deserialize(s)); + } + +} diff --git a/bungee/pom.xml b/bungee/pom.xml new file mode 100644 index 0000000..1b6fe78 --- /dev/null +++ b/bungee/pom.xml @@ -0,0 +1,66 @@ + + + + MineConfiguration + cc.carm.lib + 1.0.0 + + 4.0.0 + + ${java.version} + ${java.version} + + mineconfiguration-bungee + jar + + + + + ${project.parent.groupId} + easyconfiguration-core + ${easyconfiguration.version} + compile + + + + net.md-5 + bungeecord-api + 1.18-R0.1-SNAPSHOT + jar + provided + + + + net.md-5 + bungeecord-api + 1.18-R0.1-SNAPSHOT + javadoc + provided + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + \ No newline at end of file diff --git a/bungee/src/main/java/cc/carm/lib/configuration/MineConfiguration.java b/bungee/src/main/java/cc/carm/lib/configuration/MineConfiguration.java new file mode 100644 index 0000000..5ddb443 --- /dev/null +++ b/bungee/src/main/java/cc/carm/lib/configuration/MineConfiguration.java @@ -0,0 +1,74 @@ +package cc.carm.lib.configuration; + +import cc.carm.lib.configuration.bungee.BungeeConfigProvider; +import net.md_5.bungee.config.ConfigurationProvider; +import net.md_5.bungee.config.JsonConfiguration; +import net.md_5.bungee.config.YamlConfiguration; + +import java.io.File; +import java.io.IOException; + +public class MineConfiguration { + + protected static BungeeConfigProvider create(File file, String source, ConfigurationProvider loader) { + BungeeConfigProvider provider = new BungeeConfigProvider(file, loader); + try { + provider.initializeFile(source); + provider.initializeConfig(); + } catch (IOException e) { + e.printStackTrace(); + } + return provider; + } + + public static BungeeConfigProvider from(File file, String source) { + return fromYAML(file, source); + } + + public static BungeeConfigProvider from(File file) { + return from(file, file.getName()); + } + + public static BungeeConfigProvider from(String fileName) { + return from(fileName, fileName); + } + + public static BungeeConfigProvider from(String fileName, String source) { + return from(new File(fileName), source); + } + + public static BungeeConfigProvider fromYAML(File file, String source) { + return create(file, source, ConfigurationProvider.getProvider(YamlConfiguration.class)); + } + + public static BungeeConfigProvider fromYAML(String fileName, String source) { + return fromYAML(new File(fileName), source); + } + + public static BungeeConfigProvider fromYAML(File file) { + return fromYAML(file, file.getName()); + } + + public static BungeeConfigProvider fromYAML(String fileName) { + return fromYAML(fileName, fileName); + } + + + public static BungeeConfigProvider fromJSON(File file, String source) { + return create(file, source, ConfigurationProvider.getProvider(JsonConfiguration.class)); + } + + public static BungeeConfigProvider fromJSON(String fileName, String source) { + return fromJSON(new File(fileName), source); + } + + public static BungeeConfigProvider fromJSON(File file) { + return fromJSON(file, file.getName()); + } + + public static BungeeConfigProvider fromJSON(String fileName) { + return fromJSON(fileName, fileName); + } + + +} diff --git a/bungee/src/main/java/cc/carm/lib/configuration/bungee/BungeeConfigProvider.java b/bungee/src/main/java/cc/carm/lib/configuration/bungee/BungeeConfigProvider.java new file mode 100644 index 0000000..e353081 --- /dev/null +++ b/bungee/src/main/java/cc/carm/lib/configuration/bungee/BungeeConfigProvider.java @@ -0,0 +1,63 @@ +package cc.carm.lib.configuration.bungee; + +import cc.carm.lib.configuration.core.ConfigInitializer; +import cc.carm.lib.configuration.core.source.impl.FileConfigProvider; +import net.md_5.bungee.config.Configuration; +import net.md_5.bungee.config.ConfigurationProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; + +public class BungeeConfigProvider extends FileConfigProvider { + + protected ConfigurationProvider loader; + protected Configuration configuration; + protected ConfigInitializer initializer; + + public BungeeConfigProvider(@NotNull File file, ConfigurationProvider loader) { + super(file); + this.loader = loader; + } + + public void initializeConfig() throws IOException { + this.configuration = getLoader().load(file); + this.initializer = new ConfigInitializer<>(this); + } + + @Override + public @NotNull BungeeSectionWrapper getConfiguration() { + return BungeeSectionWrapper.of(configuration); + } + + @Override + public void reload() throws Exception { + this.configuration = getLoader().load(file); + } + + @Override + public void save() throws Exception { + getLoader().save(configuration, file); + } + + @Override + public void setComments(@NotNull String path, @NotNull String... comments) { + // BungeeCord version doesn't support comments + } + + @Override + public @Nullable String[] getComments(@NotNull String path) { + // BungeeCord version doesn't support comments + return null; + } + + @Override + public @NotNull ConfigInitializer getInitializer() { + return this.initializer; + } + + public ConfigurationProvider getLoader() { + return loader; + } +} diff --git a/bungee/src/main/java/cc/carm/lib/configuration/bungee/BungeeSectionWrapper.java b/bungee/src/main/java/cc/carm/lib/configuration/bungee/BungeeSectionWrapper.java new file mode 100644 index 0000000..238523e --- /dev/null +++ b/bungee/src/main/java/cc/carm/lib/configuration/bungee/BungeeSectionWrapper.java @@ -0,0 +1,70 @@ +package cc.carm.lib.configuration.bungee; + +import cc.carm.lib.configuration.core.source.ConfigurationWrapper; +import net.md_5.bungee.config.Configuration; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.stream.Collectors; + +public class BungeeSectionWrapper implements ConfigurationWrapper { + + private final Configuration section; + + private BungeeSectionWrapper(@NotNull Configuration section) { + this.section = section; + } + + @Contract("!null->!null") + public static @Nullable BungeeSectionWrapper of(@Nullable Configuration section) { + return section == null ? null : new BungeeSectionWrapper(section); + } + + @Override + public @NotNull Set getKeys(boolean deep) { + return new LinkedHashSet<>(section.getKeys()); + } + + @Override + public @NotNull Map getValues(boolean deep) { + return section.getKeys().stream() + .collect(Collectors.toMap(key -> key, section::get, (a, b) -> b, LinkedHashMap::new)); + } + + @Override + public void set(@NotNull String path, @Nullable Object value) { + this.section.set(path, value); + } + + @Override + public boolean contains(@NotNull String path) { + return this.section.contains(path); + } + + @Override + public @Nullable Object get(@NotNull String path) { + return this.section.get(path); + } + + @Override + public boolean isList(@NotNull String path) { + return get(path) instanceof List; + } + + @Override + public @Nullable List getList(@NotNull String path) { + return this.section.getList(path); + } + + @Override + public boolean isConfigurationSection(@NotNull String path) { + return get(path) instanceof Configuration; + } + + @Override + public @Nullable ConfigurationWrapper getConfigurationSection(@NotNull String path) { + return of(this.section.getSection(path)); + } +} diff --git a/pom.xml b/pom.xml index 5fdcc03..d9b3db7 100644 --- a/pom.xml +++ b/pom.xml @@ -3,12 +3,18 @@ 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"> 4.0.0 + + bungee + bukkit/common + 1.8 ${java.version} ${java.version} UTF-8 UTF-8 + + 1.1.0 cc.carm.lib MineConfiguration