fix JSON construction with maps/collections, more convenience for converting strings
This commit is contained in:
parent
b5491330a5
commit
9759d5c020
6 changed files with 264 additions and 61 deletions
|
@ -16,7 +16,7 @@ public interface Builder {
|
|||
|
||||
Builder buildMap(Map<String, Object> map) throws IOException;
|
||||
|
||||
Builder buildCollection(Collection<Object> collection) throws IOException;
|
||||
Builder buildCollection(Collection<?> collection) throws IOException;
|
||||
|
||||
Builder buildKey(CharSequence key) throws IOException;
|
||||
|
||||
|
@ -24,7 +24,13 @@ public interface Builder {
|
|||
|
||||
Builder buildNull() throws IOException;
|
||||
|
||||
default Builder buildIfNotNull(CharSequence key, Object value) throws IOException {
|
||||
default Builder field(CharSequence key, Object value) throws IOException {
|
||||
buildKey(key);
|
||||
buildValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
default Builder fieldIfNotNull(CharSequence key, Object value) throws IOException {
|
||||
if (value != null){
|
||||
buildKey(key);
|
||||
buildValue(value);
|
||||
|
@ -32,5 +38,25 @@ public interface Builder {
|
|||
return this;
|
||||
}
|
||||
|
||||
default Builder collection(CharSequence key, Collection<?> value) throws IOException {
|
||||
buildKey(key);
|
||||
buildValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
default Builder beginMap(CharSequence key) throws IOException {
|
||||
buildKey(key);
|
||||
beginMap();
|
||||
return this;
|
||||
}
|
||||
|
||||
default Builder beginCollection(CharSequence key) throws IOException {
|
||||
buildKey(key);
|
||||
beginCollection();
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder copy(Builder builder) throws IOException;
|
||||
|
||||
String build();
|
||||
}
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
package org.xbib.datastructures.json.tiny;
|
||||
|
||||
import org.xbib.datastructures.api.*;
|
||||
|
||||
import org.xbib.datastructures.api.Builder;
|
||||
import org.xbib.datastructures.api.ByteSizeValue;
|
||||
import org.xbib.datastructures.api.DataStructure;
|
||||
import org.xbib.datastructures.api.Generator;
|
||||
import org.xbib.datastructures.api.Node;
|
||||
import org.xbib.datastructures.api.Parser;
|
||||
import org.xbib.datastructures.api.TimeValue;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Json implements DataStructure {
|
||||
|
||||
private static final Json INSTANCE = new Json();
|
||||
|
||||
private final char separator;
|
||||
|
||||
private Node<?> root;
|
||||
|
@ -25,6 +35,15 @@ public class Json implements DataStructure {
|
|||
this.separator = separator;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> toMap(String yaml) throws IOException {
|
||||
return (Map<String, Object>) INSTANCE.createParser().parse(new StringReader(yaml)).get();
|
||||
}
|
||||
|
||||
public static String toString(Map<String, Object> map) throws IOException {
|
||||
return INSTANCE.createBuilder().buildMap(map).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parser createParser() {
|
||||
return new StreamParser();
|
||||
|
|
|
@ -3,11 +3,8 @@ package org.xbib.datastructures.json.tiny;
|
|||
import org.xbib.datastructures.api.Builder;
|
||||
import org.xbib.datastructures.api.ByteSizeValue;
|
||||
import org.xbib.datastructures.api.TimeValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.Writer;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
@ -15,31 +12,31 @@ import java.util.Objects;
|
|||
|
||||
public class JsonBuilder implements Builder {
|
||||
|
||||
private final Writer writer;
|
||||
private final Appendable appendable;
|
||||
|
||||
private State state;
|
||||
|
||||
public JsonBuilder() {
|
||||
this(new StringWriter());
|
||||
this(new StringBuilder());
|
||||
}
|
||||
|
||||
public JsonBuilder(Writer writer) {
|
||||
this.writer = writer;
|
||||
this.state = new State(null, 0, Structure.MAP, true);
|
||||
public JsonBuilder(Appendable appendable) {
|
||||
this.appendable = appendable;
|
||||
this.state = new State(null, 0, Structure.DOCSTART, true);
|
||||
}
|
||||
|
||||
public static JsonBuilder builder() {
|
||||
return new JsonBuilder();
|
||||
}
|
||||
|
||||
public static JsonBuilder builder(Writer writer) {
|
||||
return new JsonBuilder(writer);
|
||||
public static JsonBuilder builder(Appendable appendable) {
|
||||
return new JsonBuilder(appendable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder beginCollection() throws IOException {
|
||||
this.state = new State(state, state.level + 1, Structure.COLLECTION, true);
|
||||
writer.write('[');
|
||||
appendable.append('[');
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -48,7 +45,7 @@ public class JsonBuilder implements Builder {
|
|||
if (state.structure != Structure.COLLECTION) {
|
||||
throw new JsonException("no array to close");
|
||||
}
|
||||
writer.write(']');
|
||||
appendable.append(']');
|
||||
this.state = state != null ? state.parent : null;
|
||||
return this;
|
||||
}
|
||||
|
@ -56,25 +53,30 @@ public class JsonBuilder implements Builder {
|
|||
@Override
|
||||
public Builder beginMap() throws IOException {
|
||||
this.state = new State(state, state.level + 1, Structure.MAP, true);
|
||||
writer.write('{');
|
||||
appendable.append('{');
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder endMap() throws IOException {
|
||||
if (state.structure != Structure.MAP) {
|
||||
if (state.structure != Structure.MAP && state.structure != Structure.KEY) {
|
||||
throw new JsonException("no object to close");
|
||||
}
|
||||
writer.write('}');
|
||||
appendable.append('}');
|
||||
this.state = state != null ? state.parent : null;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder buildMap(Map<String, Object> map) throws IOException {
|
||||
Objects.requireNonNull(map);
|
||||
if (state.structure == Structure.COLLECTION) {
|
||||
beginArrayValue(map);
|
||||
}
|
||||
boolean wrap = state.structure != Structure.MAP;
|
||||
if (wrap) {
|
||||
beginMap();
|
||||
}
|
||||
map.forEach((k, v) -> {
|
||||
try {
|
||||
buildKey(k);
|
||||
|
@ -83,12 +85,17 @@ public class JsonBuilder implements Builder {
|
|||
throw new UncheckedIOException(e);
|
||||
}
|
||||
});
|
||||
if (wrap) {
|
||||
endMap();
|
||||
}
|
||||
if (state.structure == Structure.COLLECTION) {
|
||||
endArrayValue(map);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder buildCollection(Collection<Object> collection) throws IOException {
|
||||
public Builder buildCollection(Collection<?> collection) throws IOException {
|
||||
Objects.requireNonNull(collection);
|
||||
beginCollection();
|
||||
collection.forEach(v -> {
|
||||
|
@ -105,7 +112,7 @@ public class JsonBuilder implements Builder {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Builder buildValue(Object object) throws IOException {
|
||||
if (state.structure == Structure.MAP) {
|
||||
if (state.structure == Structure.MAP || state.structure == Structure.KEY) {
|
||||
beginValue(object);
|
||||
} else if (state.structure == Structure.COLLECTION) {
|
||||
beginArrayValue(object);
|
||||
|
@ -142,7 +149,7 @@ public class JsonBuilder implements Builder {
|
|||
} else {
|
||||
throw new IllegalArgumentException("unable to write object class " + object.getClass());
|
||||
}
|
||||
if (state.structure == Structure.MAP) {
|
||||
if (state.structure == Structure.MAP || state.structure == Structure.KEY) {
|
||||
endValue(object);
|
||||
} else if (state.structure == Structure.COLLECTION) {
|
||||
endArrayValue(object);
|
||||
|
@ -152,42 +159,68 @@ public class JsonBuilder implements Builder {
|
|||
|
||||
@Override
|
||||
public Builder buildKey(CharSequence string) throws IOException {
|
||||
if (state.structure == Structure.MAP) {
|
||||
if (state.structure == Structure.COLLECTION) {
|
||||
beginArrayValue(string);
|
||||
}
|
||||
if (state.structure == Structure.MAP || state.structure == Structure.KEY) {
|
||||
beginKey(string != null ? string.toString() : null);
|
||||
}
|
||||
buildString(string, true);
|
||||
if (state.structure == Structure.MAP) {
|
||||
if (state.structure == Structure.MAP || state.structure == Structure.KEY) {
|
||||
endKey(string != null ? string.toString() : null);
|
||||
}
|
||||
state.structure = Structure.KEY;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder buildNull() throws IOException {
|
||||
if (state.structure == Structure.MAP) {
|
||||
if (state.structure == Structure.MAP || state.structure == Structure.KEY) {
|
||||
beginValue(null);
|
||||
} else if (state.structure == Structure.COLLECTION) {
|
||||
beginArrayValue(null);
|
||||
}
|
||||
buildString("null", false);
|
||||
if (state.structure == Structure.MAP || state.structure == Structure.KEY) {
|
||||
endValue(null);
|
||||
} else if (state.structure == Structure.COLLECTION) {
|
||||
endArrayValue(null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder copy(Builder builder) throws IOException {
|
||||
if (state.structure == Structure.MAP || state.structure == Structure.KEY) {
|
||||
beginValue(null);
|
||||
} else if (state.structure == Structure.COLLECTION) {
|
||||
beginArrayValue(null);
|
||||
}
|
||||
appendable.append(builder.build());
|
||||
if (state.structure == Structure.MAP || state.structure == Structure.KEY) {
|
||||
endValue(null);
|
||||
}
|
||||
if (state.structure == Structure.COLLECTION) {
|
||||
endArrayValue(null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String build() {
|
||||
return writer.toString();
|
||||
return appendable.toString();
|
||||
}
|
||||
|
||||
private void beginKey(String k) throws IOException {
|
||||
if (state.first) {
|
||||
state.first = false;
|
||||
} else {
|
||||
writer.write(",");
|
||||
appendable.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
private void endKey(String k) throws IOException {
|
||||
writer.write(":");
|
||||
appendable.append(":");
|
||||
}
|
||||
|
||||
private void beginValue(Object v) {
|
||||
|
@ -200,7 +233,7 @@ public class JsonBuilder implements Builder {
|
|||
if (state.first) {
|
||||
state.first = false;
|
||||
} else {
|
||||
writer.write(",");
|
||||
appendable.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,10 +253,10 @@ public class JsonBuilder implements Builder {
|
|||
}
|
||||
|
||||
private void buildString(CharSequence string, boolean escape) throws IOException {
|
||||
writer.write(escape ? escapeString(string) : string.toString());
|
||||
appendable.append(escape ? escapeString(string) : string);
|
||||
}
|
||||
|
||||
private String escapeString(CharSequence string) {
|
||||
private CharSequence escapeString(CharSequence string) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('"');
|
||||
int start = 0;
|
||||
|
@ -232,17 +265,17 @@ public class JsonBuilder implements Builder {
|
|||
char c = string.charAt(i);
|
||||
if (c == '"' || c < 32 || c >= 127 || c == '\\') {
|
||||
if (start < i) {
|
||||
sb.append(string.toString(), start, i - start);
|
||||
sb.append(string, start, i - start);
|
||||
}
|
||||
start = i;
|
||||
sb.append(escapeCharacter(c));
|
||||
}
|
||||
}
|
||||
if (start < l) {
|
||||
sb.append(string.toString(), start, l - start);
|
||||
sb.append(string, start, l - start);
|
||||
}
|
||||
sb.append('"');
|
||||
return sb.toString();
|
||||
return sb;
|
||||
}
|
||||
|
||||
private static String escapeCharacter(char c) {
|
||||
|
@ -264,7 +297,7 @@ public class JsonBuilder implements Builder {
|
|||
return "\\u0000".substring(0, 6 - hex.length()) + hex;
|
||||
}
|
||||
|
||||
private enum Structure { MAP, COLLECTION };
|
||||
private enum Structure { DOCSTART, MAP, KEY, COLLECTION };
|
||||
|
||||
private static class State {
|
||||
State parent;
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.xbib.datastructures.json.tiny.StreamParser;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -108,4 +109,108 @@ public class JsonBuilderTest {
|
|||
jsonBuilder.buildMap(Map.of("a", "b"));
|
||||
assertEquals("{\"a\":\"b\"}", jsonBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyValue() throws Exception {
|
||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||
jsonBuilder.beginMap();
|
||||
jsonBuilder.buildKey("a");
|
||||
jsonBuilder.buildValue("b");
|
||||
// test comma separation
|
||||
jsonBuilder.buildKey("c");
|
||||
jsonBuilder.buildValue("d");
|
||||
jsonBuilder.endMap();
|
||||
assertEquals("{\"a\":\"b\",\"c\":\"d\"}", jsonBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapBuild() throws Exception {
|
||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||
jsonBuilder.beginMap();
|
||||
jsonBuilder.buildKey("map");
|
||||
// buildMap is wrapped with '{' and '}'
|
||||
jsonBuilder.buildMap(Map.of("a", "b"));
|
||||
jsonBuilder.endMap();
|
||||
assertEquals("{\"map\":{\"a\":\"b\"}}", jsonBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeginMapBuild() throws Exception {
|
||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||
jsonBuilder.beginMap();
|
||||
jsonBuilder.beginMap("map");
|
||||
// buildMap is not wrapped with '{' and '}'
|
||||
jsonBuilder.buildMap(Map.of("a", "b"));
|
||||
jsonBuilder.endMap();
|
||||
jsonBuilder.endMap();
|
||||
assertEquals("{\"map\":{\"a\":\"b\"}}", jsonBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapOfCollections() throws Exception {
|
||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||
jsonBuilder.beginMap();
|
||||
jsonBuilder.beginMap("map");
|
||||
jsonBuilder.collection("a", Arrays.asList("b", "c"));
|
||||
// test comma separation
|
||||
jsonBuilder.collection("d", Arrays.asList("e", "f"));
|
||||
jsonBuilder.endMap();
|
||||
jsonBuilder.endMap();
|
||||
assertEquals("{\"map\":{\"a\":[\"b\",\"c\"],\"d\":[\"e\",\"f\"]}}", jsonBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapOfEmptyCollections() throws Exception {
|
||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||
jsonBuilder.beginMap();
|
||||
jsonBuilder.beginMap("map");
|
||||
jsonBuilder.collection("a", List.of());
|
||||
// test comma separation
|
||||
jsonBuilder.collection("b", List.of());
|
||||
jsonBuilder.endMap();
|
||||
jsonBuilder.endMap();
|
||||
assertEquals("{\"map\":{\"a\":[],\"b\":[]}}", jsonBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionOfMaps() throws Exception {
|
||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||
jsonBuilder.beginMap();
|
||||
jsonBuilder.beginCollection("collection");
|
||||
jsonBuilder.buildMap(Map.of("a", "b"));
|
||||
// test comma separation
|
||||
jsonBuilder.buildMap(Map.of("c", "d"));
|
||||
jsonBuilder.endCollection();
|
||||
jsonBuilder.endMap();
|
||||
assertEquals("{\"collection\":[{\"a\":\"b\"},{\"c\":\"d\"}]}", jsonBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionOfEmptyMaps() throws Exception {
|
||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||
jsonBuilder.beginMap();
|
||||
jsonBuilder.beginCollection("collection");
|
||||
jsonBuilder.buildMap(Map.of());
|
||||
// test comma separation
|
||||
jsonBuilder.buildMap(Map.of());
|
||||
jsonBuilder.endCollection();
|
||||
jsonBuilder.endMap();
|
||||
assertEquals("{\"collection\":[{},{}]}", jsonBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopy() throws Exception {
|
||||
JsonBuilder jsonBuilder1 = new JsonBuilder();
|
||||
jsonBuilder1.buildMap(Map.of("a", "b"));
|
||||
JsonBuilder jsonBuilder2 = new JsonBuilder();
|
||||
jsonBuilder2.buildMap(Map.of("c", "d"));
|
||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||
jsonBuilder.beginCollection();
|
||||
jsonBuilder.copy(jsonBuilder1);
|
||||
// test comma separation
|
||||
jsonBuilder.copy(jsonBuilder2);
|
||||
jsonBuilder.endCollection();
|
||||
assertEquals("[{\"a\":\"b\"},{\"c\":\"d\"}]", jsonBuilder.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,12 +3,17 @@ package org.xbib.datastructures.yaml.tiny;
|
|||
import org.xbib.datastructures.api.*;
|
||||
import org.xbib.datastructures.api.Builder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Yaml implements DataStructure {
|
||||
|
||||
private static final Yaml INSTANCE = new Yaml();
|
||||
;
|
||||
private final char separator;
|
||||
|
||||
private Node<?> root;
|
||||
|
@ -26,6 +31,15 @@ public class Yaml implements DataStructure {
|
|||
this.separator = separator;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> toMap(String yaml) throws IOException {
|
||||
return (Map<String, Object>) INSTANCE.createParser().parse(new StringReader(yaml)).get();
|
||||
}
|
||||
|
||||
public static String toString(Map<String, Object> map) throws IOException {
|
||||
return INSTANCE.createBuilder().buildMap(map).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parser createParser() {
|
||||
return new YamlParser();
|
||||
|
|
|
@ -4,9 +4,7 @@ import org.xbib.datastructures.api.Builder;
|
|||
import org.xbib.datastructures.api.ByteSizeValue;
|
||||
import org.xbib.datastructures.api.TimeValue;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.Writer;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
@ -14,22 +12,22 @@ import java.util.Objects;
|
|||
|
||||
public class YamlBuilder implements Builder {
|
||||
|
||||
public final Writer writer;
|
||||
public final Appendable appendable;
|
||||
|
||||
private final int indent;
|
||||
|
||||
private State state;
|
||||
|
||||
public YamlBuilder() {
|
||||
this(new StringWriter());
|
||||
this(new StringBuilder());
|
||||
}
|
||||
|
||||
public YamlBuilder(Writer writer) {
|
||||
this(writer, 2);
|
||||
public YamlBuilder(Appendable appendable) {
|
||||
this(appendable, 2);
|
||||
}
|
||||
|
||||
public YamlBuilder(Writer writer, int indent) {
|
||||
this.writer = writer;
|
||||
public YamlBuilder(Appendable appendable, int indent) {
|
||||
this.appendable = appendable;
|
||||
this.indent = indent;
|
||||
this.state = new State(null, 0, Structure.MAP, false);
|
||||
}
|
||||
|
@ -38,8 +36,8 @@ public class YamlBuilder implements Builder {
|
|||
return new YamlBuilder();
|
||||
}
|
||||
|
||||
public static YamlBuilder builder(Writer writer) {
|
||||
return new YamlBuilder(writer);
|
||||
public static YamlBuilder builder(Appendable appendable) {
|
||||
return new YamlBuilder(appendable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -89,7 +87,7 @@ public class YamlBuilder implements Builder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Builder buildCollection(Collection<Object> collection) {
|
||||
public Builder buildCollection(Collection<?> collection) {
|
||||
Objects.requireNonNull(collection);
|
||||
beginCollection();
|
||||
collection.forEach(v -> {
|
||||
|
@ -170,9 +168,16 @@ public class YamlBuilder implements Builder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder copy(Builder builder) throws IOException {
|
||||
// TODO: no correct indent yet for copied yaml
|
||||
buildValue(builder.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String build() {
|
||||
return writer.toString();
|
||||
return appendable.toString();
|
||||
}
|
||||
|
||||
private void buildNumber(Number number) throws IOException {
|
||||
|
@ -188,7 +193,8 @@ public class YamlBuilder implements Builder {
|
|||
}
|
||||
|
||||
private void buildString(CharSequence string, boolean escape) throws IOException {
|
||||
String value = escape ? escapeString(string) : string.toString();
|
||||
CharSequence charSequence = escape ? escapeString(string) : string;
|
||||
String value = charSequence.toString();
|
||||
if (!((value.startsWith("'") && value.endsWith("'")) || (value.startsWith("\"") && value.endsWith("\""))) &&
|
||||
value.matches(".*[?\\-#:>|$%&{}\\[\\]]+.*|[ ]+")) {
|
||||
if (value.contains("\"")) {
|
||||
|
@ -197,7 +203,7 @@ public class YamlBuilder implements Builder {
|
|||
value = "\"" + value + "\"";
|
||||
}
|
||||
}
|
||||
writer.write(value);
|
||||
appendable.append(value);
|
||||
}
|
||||
|
||||
private void beginKey(String k) throws IOException {
|
||||
|
@ -205,11 +211,11 @@ public class YamlBuilder implements Builder {
|
|||
state.parent.item = false;
|
||||
return;
|
||||
}
|
||||
writer.write(" ".repeat((state.level - 1) * indent));
|
||||
appendable.append(" ".repeat((state.level - 1) * indent));
|
||||
}
|
||||
|
||||
private void endKey(String k) throws IOException {
|
||||
writer.write(": ");
|
||||
appendable.append(": ");
|
||||
}
|
||||
|
||||
private void beginValue(Object v) throws IOException {
|
||||
|
@ -236,8 +242,8 @@ public class YamlBuilder implements Builder {
|
|||
if (v instanceof Collection) {
|
||||
return;
|
||||
}
|
||||
writer.write(" ".repeat((state.level - 1) * indent));
|
||||
writer.write("- ");
|
||||
appendable.append(" ".repeat((state.level - 1) * indent));
|
||||
appendable.append("- ");
|
||||
state.item = true;
|
||||
}
|
||||
|
||||
|
@ -252,10 +258,10 @@ public class YamlBuilder implements Builder {
|
|||
}
|
||||
|
||||
private void writeLn() throws IOException{
|
||||
writer.write(System.lineSeparator());
|
||||
appendable.append(System.lineSeparator());
|
||||
}
|
||||
|
||||
private String escapeString(CharSequence string) {
|
||||
private CharSequence escapeString(CharSequence string) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int start = 0;
|
||||
int l = string.length();
|
||||
|
@ -263,16 +269,16 @@ public class YamlBuilder implements Builder {
|
|||
char c = string.charAt(i);
|
||||
if (c == '"' || c < 32 || c >= 127 || c == '\\') {
|
||||
if (start < i) {
|
||||
sb.append(string.toString(), start, i - start);
|
||||
sb.append(string, start, i - start);
|
||||
}
|
||||
start = i;
|
||||
sb.append(escapeCharacter(c));
|
||||
}
|
||||
}
|
||||
if (start < l) {
|
||||
sb.append(string.toString(), start, l - start);
|
||||
sb.append(string, start, l - start);
|
||||
}
|
||||
return sb.toString();
|
||||
return sb;
|
||||
}
|
||||
|
||||
private static String escapeCharacter(char c) {
|
||||
|
|
Loading…
Reference in a new issue