use buffered reader, assume always UTF-8, fix toMap() convenience
This commit is contained in:
parent
9759d5c020
commit
9f584c4c7a
9 changed files with 133 additions and 24 deletions
|
@ -7,7 +7,10 @@ import org.xbib.datastructures.api.Generator;
|
||||||
import org.xbib.datastructures.api.Node;
|
import org.xbib.datastructures.api.Node;
|
||||||
import org.xbib.datastructures.api.Parser;
|
import org.xbib.datastructures.api.Parser;
|
||||||
import org.xbib.datastructures.api.TimeValue;
|
import org.xbib.datastructures.api.TimeValue;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -35,9 +38,15 @@ public class Json implements DataStructure {
|
||||||
this.separator = separator;
|
this.separator = separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public static Map<String, Object> toMap(String json) throws IOException {
|
||||||
public static Map<String, Object> toMap(String yaml) throws IOException {
|
return toMap(new StringReader(json));
|
||||||
return (Map<String, Object>) INSTANCE.createParser().parse(new StringReader(yaml)).get();
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> toMap(Reader reader) throws IOException {
|
||||||
|
// buffered reader is required for mark() support
|
||||||
|
try (BufferedReader bufferedReader = new BufferedReader(reader)){
|
||||||
|
return JsonGenerator.toMap(INSTANCE.createParser().parse(bufferedReader));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toString(Map<String, Object> map) throws IOException {
|
public static String toString(Map<String, Object> map) throws IOException {
|
||||||
|
|
|
@ -263,16 +263,16 @@ public class JsonBuilder implements Builder {
|
||||||
int l = string.length();
|
int l = string.length();
|
||||||
for (int i = 0; i < l; i++) {
|
for (int i = 0; i < l; i++) {
|
||||||
char c = string.charAt(i);
|
char c = string.charAt(i);
|
||||||
if (c == '"' || c < 32 || c >= 127 || c == '\\') {
|
if (c == '"' || c == '\\' || c < 32) {
|
||||||
if (start < i) {
|
if (i > start) {
|
||||||
sb.append(string, start, i - start);
|
sb.append(string, start, i);
|
||||||
}
|
}
|
||||||
start = i;
|
start = i + 1;
|
||||||
sb.append(escapeCharacter(c));
|
sb.append(escapeCharacter(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (start < l) {
|
if (l > start) {
|
||||||
sb.append(string, start, l - start);
|
sb.append(string, start, l);
|
||||||
}
|
}
|
||||||
sb.append('"');
|
sb.append('"');
|
||||||
return sb;
|
return sb;
|
||||||
|
|
|
@ -2,6 +2,8 @@ package org.xbib.datastructures.json.tiny;
|
||||||
|
|
||||||
import org.xbib.datastructures.api.Generator;
|
import org.xbib.datastructures.api.Generator;
|
||||||
import org.xbib.datastructures.api.Node;
|
import org.xbib.datastructures.api.Node;
|
||||||
|
import org.xbib.datastructures.tiny.TinyList;
|
||||||
|
import org.xbib.datastructures.tiny.TinyMap;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
@ -27,6 +29,11 @@ public class JsonGenerator implements Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Map<String, Object> toMap(Node<?> root) {
|
||||||
|
return (Map<String, Object>) internalMap(root);
|
||||||
|
}
|
||||||
|
|
||||||
private void internalWrite(Node<?> curnode) throws IOException {
|
private void internalWrite(Node<?> curnode) throws IOException {
|
||||||
if (curnode instanceof ValueNode) {
|
if (curnode instanceof ValueNode) {
|
||||||
ValueNode valueNode = (ValueNode) curnode;
|
ValueNode valueNode = (ValueNode) curnode;
|
||||||
|
@ -49,4 +56,27 @@ public class JsonGenerator implements Generator {
|
||||||
builder.endCollection();
|
builder.endCollection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Object internalMap(Node<?> curnode) {
|
||||||
|
if (curnode instanceof ValueNode) {
|
||||||
|
ValueNode valueNode = (ValueNode) curnode;
|
||||||
|
return valueNode.get();
|
||||||
|
} else if (curnode instanceof MapNode) {
|
||||||
|
MapNode mapNode = (MapNode) curnode;
|
||||||
|
TinyMap.Builder<String, Object> map = TinyMap.builder();
|
||||||
|
for (Map.Entry<CharSequence, Node<?>> e : mapNode.get().entrySet()) {
|
||||||
|
map.put(e.getKey().toString(), internalMap(e.getValue()));
|
||||||
|
}
|
||||||
|
return map.build();
|
||||||
|
} else if (curnode instanceof ListNode) {
|
||||||
|
ListNode listNode = (ListNode) curnode;
|
||||||
|
TinyList.Builder<Object> list = TinyList.builder();
|
||||||
|
for (Node<?> node : listNode.get()) {
|
||||||
|
list.add(internalMap(node));
|
||||||
|
}
|
||||||
|
return list.build();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.xbib.datastructures.json.tiny.test;
|
package org.xbib.datastructures.json.tiny.test;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.xbib.datastructures.json.tiny.Json;
|
||||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||||
import org.xbib.datastructures.json.tiny.StreamParser;
|
import org.xbib.datastructures.json.tiny.StreamParser;
|
||||||
|
|
||||||
|
@ -11,9 +12,17 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class JsonBuilderTest {
|
public class JsonBuilderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUmlautEncoding() throws IOException{
|
||||||
|
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||||
|
jsonBuilder.buildMap(Map.of("Hello", "Jörg"));
|
||||||
|
assertEquals("{\"Hello\":\"Jörg\"}", jsonBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testObjectStrFromMap() throws IOException {
|
public void testObjectStrFromMap() throws IOException {
|
||||||
JsonBuilder jsonBuilder = new JsonBuilder();
|
JsonBuilder jsonBuilder = new JsonBuilder();
|
||||||
|
@ -213,4 +222,11 @@ public class JsonBuilderTest {
|
||||||
assertEquals("[{\"a\":\"b\"},{\"c\":\"d\"}]", jsonBuilder.build());
|
assertEquals("[{\"a\":\"b\"},{\"c\":\"d\"}]", jsonBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void testJsonToMap() throws IOException {
|
||||||
|
Map<String, Object> map = Json.toMap("{\"map\":{\"a\":\"b\"}}");
|
||||||
|
assertTrue(map.get("map") instanceof Map);
|
||||||
|
assertEquals("b", ((Map<String, Object>) map.get("map")).get("a"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,29 +9,33 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
public class ParserTest {
|
public class ParserTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringParser() throws IOException {
|
public void testStringParser() throws IOException {
|
||||||
try (InputStream inputStream = ParserTest.class.getResourceAsStream("/org/xbib/datastructures/json/tiny/test/test.json")) {
|
try (InputStream inputStream = ParserTest.class.getResourceAsStream("/org/xbib/datastructures/json/tiny/test/test.json")) {
|
||||||
|
if (inputStream != null) {
|
||||||
byte[] b = inputStream.readAllBytes();
|
byte[] b = inputStream.readAllBytes();
|
||||||
String string = new String(b, StandardCharsets.UTF_8);
|
String string = new String(b, StandardCharsets.UTF_8);
|
||||||
StringParser stringParser = new StringParser(new TinyJsonListener());
|
StringParser stringParser = new StringParser(new TinyJsonListener());
|
||||||
stringParser.parse(string);
|
stringParser.parse(string);
|
||||||
Logger.getLogger("").log(Level.INFO, stringParser.getNode().get().toString());
|
assertEquals("{a=b, c=d, e=[f, g], h={i={j=k}}, l=null, m=true, n=false, o=0, p=1, q=-1, r=0.0, s=1.0, t=2.1, u=-1.0, v=-2.1, w=, x=₫, y=Jörg}",
|
||||||
stringParser.parse(string);
|
stringParser.getNode().get().toString());
|
||||||
Logger.getLogger("").log(Level.INFO, stringParser.getNode().get().toString());
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStreamParser() throws IOException {
|
public void testStreamParser() throws IOException {
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(ParserTest.class.getResourceAsStream("/org/xbib/datastructures/json/tiny/test/test.json")))) {
|
InputStream inputStream = ParserTest.class.getResourceAsStream("/org/xbib/datastructures/json/tiny/test/test.json");
|
||||||
|
if (inputStream != null) {
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
|
||||||
StreamParser streamParser = new StreamParser(new TinyJsonListener());
|
StreamParser streamParser = new StreamParser(new TinyJsonListener());
|
||||||
Logger.getLogger("").log(Level.INFO, streamParser.parse(reader).get().toString());
|
assertEquals("{a=b, c=d, e=[f, g], h={i={j=k}}, l=null, m=true, n=false, o=0, p=1, q=-1, r=0.0, s=1.0, t=2.1, u=-1.0, v=-2.1, w=, x=₫, y=Jörg}", streamParser.parse(reader).get().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,5 +19,6 @@
|
||||||
"u": -1.0,
|
"u": -1.0,
|
||||||
"v": -2.1,
|
"v": -2.1,
|
||||||
"w": "",
|
"w": "",
|
||||||
"x": "\u20AB"
|
"x": "\u20AB",
|
||||||
|
"y": "Jörg"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@ package org.xbib.datastructures.yaml.tiny;
|
||||||
import org.xbib.datastructures.api.*;
|
import org.xbib.datastructures.api.*;
|
||||||
import org.xbib.datastructures.api.Builder;
|
import org.xbib.datastructures.api.Builder;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -31,9 +33,15 @@ public class Yaml implements DataStructure {
|
||||||
this.separator = separator;
|
this.separator = separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Map<String, Object> toMap(String yaml) throws IOException {
|
public static Map<String, Object> toMap(String yaml) throws IOException {
|
||||||
return (Map<String, Object>) INSTANCE.createParser().parse(new StringReader(yaml)).get();
|
return toMap(new StringReader(yaml));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> toMap(Reader reader) throws IOException {
|
||||||
|
// buffered reader is required for mark() support
|
||||||
|
try (BufferedReader bufferedReader = new BufferedReader(reader)){
|
||||||
|
return YamlGenerator.toMap(INSTANCE.createParser().parse(bufferedReader));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toString(Map<String, Object> map) throws IOException {
|
public static String toString(Map<String, Object> map) throws IOException {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package org.xbib.datastructures.yaml.tiny;
|
||||||
|
|
||||||
import org.xbib.datastructures.api.Generator;
|
import org.xbib.datastructures.api.Generator;
|
||||||
import org.xbib.datastructures.api.Node;
|
import org.xbib.datastructures.api.Node;
|
||||||
|
import org.xbib.datastructures.tiny.TinyList;
|
||||||
|
import org.xbib.datastructures.tiny.TinyMap;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
@ -27,6 +29,11 @@ public class YamlGenerator implements Generator {
|
||||||
this.indent = indent;
|
this.indent = indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Map<String, Object> toMap(Node<?> root) {
|
||||||
|
return (Map<String, Object>) internalMap(root);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Writer writer) throws IOException {
|
public void generate(Writer writer) throws IOException {
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
|
@ -156,4 +163,28 @@ public class YamlGenerator implements Generator {
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Object internalMap(Node<?> curnode) {
|
||||||
|
if (curnode instanceof ValueNode) {
|
||||||
|
ValueNode valueNode = (ValueNode) curnode;
|
||||||
|
return valueNode.get();
|
||||||
|
} else if (curnode instanceof MapNode) {
|
||||||
|
MapNode mapNode = (MapNode) curnode;
|
||||||
|
TinyMap.Builder<String, Object> map = TinyMap.builder();
|
||||||
|
for (Map.Entry<CharSequence, Node<?>> e : mapNode.get().entrySet()) {
|
||||||
|
map.put(e.getKey().toString(), internalMap(e.getValue()));
|
||||||
|
}
|
||||||
|
return map.build();
|
||||||
|
} else if (curnode instanceof ListNode) {
|
||||||
|
ListNode listNode = (ListNode) curnode;
|
||||||
|
TinyList.Builder<Object> list = TinyList.builder();
|
||||||
|
for (Node<?> node : listNode.get()) {
|
||||||
|
list.add(internalMap(node));
|
||||||
|
}
|
||||||
|
return list.build();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,12 @@ import org.xbib.datastructures.api.DataStructure;
|
||||||
import org.xbib.datastructures.tiny.TinyMap;
|
import org.xbib.datastructures.tiny.TinyMap;
|
||||||
import org.xbib.datastructures.yaml.tiny.Yaml;
|
import org.xbib.datastructures.yaml.tiny.Yaml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class YamlBuilderTest {
|
public class YamlBuilderTest {
|
||||||
|
|
||||||
|
@ -104,4 +106,12 @@ public class YamlBuilderTest {
|
||||||
"- e: f\n" +
|
"- e: f\n" +
|
||||||
" g: h\n", builder.build());
|
" g: h\n", builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void testYamlToMap() throws IOException {
|
||||||
|
Map<String, Object> map = Yaml.toMap("map:\n a: b\n");
|
||||||
|
assertTrue(map.get("map") instanceof Map);
|
||||||
|
assertEquals("b", ((Map<String, Object>) map.get("map")).get("a"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue