From 7452b6d8d2977e0c61414020180041ed93bae73a Mon Sep 17 00:00:00 2001 From: Martin Polden Date: Thu, 6 Feb 2020 09:05:14 +0100 Subject: Move SlimeUtils to vespajlib --- .../src/main/java/com/yahoo/slime/SlimeUtils.java | 110 +++++++++++++++++++++ .../test/java/com/yahoo/slime/SlimeUtilsTest.java | 81 +++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 vespajlib/src/main/java/com/yahoo/slime/SlimeUtils.java create mode 100644 vespajlib/src/test/java/com/yahoo/slime/SlimeUtilsTest.java (limited to 'vespajlib') diff --git a/vespajlib/src/main/java/com/yahoo/slime/SlimeUtils.java b/vespajlib/src/main/java/com/yahoo/slime/SlimeUtils.java new file mode 100644 index 00000000000..4d0b3a8ff2e --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/slime/SlimeUtils.java @@ -0,0 +1,110 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.slime; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Optional; + +/** + * Extra utilities/operations on slime trees. + * + * @author Ulf Lilleengen + */ +public class SlimeUtils { + + public static void copyObject(Inspector from, Cursor to) { + if (from.type() != Type.OBJECT) { + throw new IllegalArgumentException("Cannot copy object: " + from); + } + from.traverse((ObjectTraverser) (name, inspector) -> setObjectEntry(inspector, name, to)); + + } + + private static void setObjectEntry(Inspector from, String name, Cursor to) { + switch (from.type()) { + case NIX: + to.setNix(name); + break; + case BOOL: + to.setBool(name, from.asBool()); + break; + case LONG: + to.setLong(name, from.asLong()); + break; + case DOUBLE: + to.setDouble(name, from.asDouble()); + break; + case STRING: + to.setString(name, from.asString()); + break; + case DATA: + to.setData(name, from.asData()); + break; + case ARRAY: + Cursor array = to.setArray(name); + copyArray(from, array); + break; + case OBJECT: + Cursor object = to.setObject(name); + copyObject(from, object); + break; + } + } + + private static void copyArray(Inspector from, final Cursor to) { + from.traverse((ArrayTraverser) (i, inspector) -> addValue(inspector, to)); + } + + private static void addValue(Inspector from, Cursor to) { + switch (from.type()) { + case NIX: + to.addNix(); + break; + case BOOL: + to.addBool(from.asBool()); + break; + case LONG: + to.addLong(from.asLong()); + break; + case DOUBLE: + to.addDouble(from.asDouble()); + break; + case STRING: + to.addString(from.asString()); + break; + case DATA: + to.addData(from.asData()); + break; + case ARRAY: + Cursor array = to.addArray(); + copyArray(from, array); + break; + case OBJECT: + Cursor object = to.addObject(); + copyObject(from, object); + break; + } + + } + + public static byte[] toJsonBytes(Slime slime) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + new JsonFormat(true).encode(baos, slime); + return baos.toByteArray(); + } + + public static Slime jsonToSlime(byte[] json) { + Slime slime = new Slime(); + new JsonDecoder().decode(slime, json); + return slime; + } + + public static Slime jsonToSlime(String json) { + return jsonToSlime(json.getBytes(StandardCharsets.UTF_8)); + } + + public static Optional optionalString(Inspector inspector) { + return Optional.of(inspector.asString()).filter(s -> !s.isEmpty()); + } +} diff --git a/vespajlib/src/test/java/com/yahoo/slime/SlimeUtilsTest.java b/vespajlib/src/test/java/com/yahoo/slime/SlimeUtilsTest.java new file mode 100644 index 00000000000..8b13ee74aed --- /dev/null +++ b/vespajlib/src/test/java/com/yahoo/slime/SlimeUtilsTest.java @@ -0,0 +1,81 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.slime; + +import com.yahoo.text.Utf8; +import org.junit.Test; + +import java.io.IOException; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +/** + * @author Ulf Lilleengen + */ +public class SlimeUtilsTest { + + @Test + public void test_copying_slime_types_into_cursor() { + Slime slime = new Slime(); + Cursor root = slime.setObject(); + root.setString("foo", "foobie"); + Cursor subobj = root.setObject("bar"); + + Slime slime2 = new Slime(); + Cursor root2 = slime2.setObject(); + root2.setString("a", "a"); + root2.setLong("b", 2); + root2.setBool("c", true); + root2.setDouble("d", 3.14); + root2.setData("e", new byte[]{0x64}); + root2.setNix("f"); + + SlimeUtils.copyObject(slime2.get(), subobj); + + assertThat(root.toString(), is("{\"foo\":\"foobie\",\"bar\":{\"a\":\"a\",\"b\":2,\"c\":true,\"d\":3.14,\"e\":\"0x64\",\"f\":null}}")); + } + + @Test + public void test_copying_slime_arrays_into_cursor() { + Slime slime = new Slime(); + Cursor root = slime.setObject(); + root.setString("foo", "foobie"); + Cursor subobj = root.setObject("bar"); + + Slime slime2 = new Slime(); + Cursor root2 = slime2.setObject(); + Cursor array = root2.setArray("a"); + array.addString("foo"); + array.addLong(4); + array.addBool(true); + array.addDouble(3.14); + array.addNix(); + array.addData(new byte[]{0x64}); + Cursor objinner = array.addObject(); + objinner.setString("inner", "binner"); + + SlimeUtils.copyObject(slime2.get(), subobj); + + assertThat(root.toString(), is("{\"foo\":\"foobie\",\"bar\":{\"a\":[\"foo\",4,true,3.14,null,\"0x64\",{\"inner\":\"binner\"}]}}")); + } + + @Test + public void test_slime_to_json() throws IOException { + Slime slime = new Slime(); + Cursor root = slime.setObject(); + root.setString("foo", "foobie"); + root.setObject("bar"); + String json = Utf8.toString(SlimeUtils.toJsonBytes(slime)); + assertThat(json, is("{\"foo\":\"foobie\",\"bar\":{}}")); + } + + @Test + public void test_json_to_slime() { + byte[] json = Utf8.toBytes("{\"foo\":\"foobie\",\"bar\":{}}"); + Slime slime = SlimeUtils.jsonToSlime(json); + assertThat(slime.get().field("foo").asString(), is("foobie")); + assertTrue(slime.get().field("bar").valid()); + } + +} -- cgit v1.2.3