diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlMapping.java b/src/main/java/com/amihaiemil/eoyaml/YamlMapping.java index eb2ce253..1cd2e28c 100644 --- a/src/main/java/com/amihaiemil/eoyaml/YamlMapping.java +++ b/src/main/java/com/amihaiemil/eoyaml/YamlMapping.java @@ -27,6 +27,7 @@ */ package com.amihaiemil.eoyaml; +import javax.json.JsonObject; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeParseException; @@ -471,4 +472,12 @@ default List children() { } return children; } + + /** + * Turn this YamlMapping to a JsonObject. + * @return JsonObject. + */ + default JsonObject toJsonObject() { + return (JsonObject) this.accept(new YamlToJsonVisitor()); + } } diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlNode.java b/src/main/java/com/amihaiemil/eoyaml/YamlNode.java index e7037dba..fac97e1a 100644 --- a/src/main/java/com/amihaiemil/eoyaml/YamlNode.java +++ b/src/main/java/com/amihaiemil/eoyaml/YamlNode.java @@ -29,6 +29,7 @@ import com.amihaiemil.eoyaml.exceptions.YamlReadingException; +import javax.json.JsonValue; import java.util.List; /** @@ -129,4 +130,11 @@ default T accept(YamlVisitor visitor) { return visitor.visitYamlNode(this); } + /** + * Turn this YamlNode to JsonValue. + * @return JsonValue. + */ + default JsonValue toJsonValue() { + return this.accept(new YamlToJsonVisitor()); + } } diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlSequence.java b/src/main/java/com/amihaiemil/eoyaml/YamlSequence.java index 382d9aef..30c6b4ca 100644 --- a/src/main/java/com/amihaiemil/eoyaml/YamlSequence.java +++ b/src/main/java/com/amihaiemil/eoyaml/YamlSequence.java @@ -27,6 +27,7 @@ */ package com.amihaiemil.eoyaml; +import javax.json.JsonArray; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeParseException; @@ -274,4 +275,12 @@ default LocalDateTime dateTime(final int index) { } return datetime; } + + /** + * Turn this YamlSequence to a JsonArray. + * @return JsonArray. + */ + default JsonArray toJsonArray() { + return (JsonArray) this.accept(new YamlToJsonVisitor()); + } } diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlStream.java b/src/main/java/com/amihaiemil/eoyaml/YamlStream.java index 5d167e20..fe4ea6e9 100644 --- a/src/main/java/com/amihaiemil/eoyaml/YamlStream.java +++ b/src/main/java/com/amihaiemil/eoyaml/YamlStream.java @@ -27,6 +27,7 @@ */ package com.amihaiemil.eoyaml; +import javax.json.JsonArray; import java.util.*; import java.util.function.*; import java.util.stream.*; @@ -223,4 +224,12 @@ default Optional findFirst() { default Optional findAny() { return this.values().stream().findAny(); } + + /** + * Turn this YamlSequence to a JsonArray. + * @return JsonArray. + */ + default JsonArray toJsonArray() { + return (JsonArray) this.accept(new YamlToJsonVisitor()); + } } diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlToJsonVisitor.java b/src/main/java/com/amihaiemil/eoyaml/YamlToJsonVisitor.java new file mode 100644 index 00000000..34bff369 --- /dev/null +++ b/src/main/java/com/amihaiemil/eoyaml/YamlToJsonVisitor.java @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2016-2024, Mihai Emil Andronache + * All rights reserved. + *

+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +package com.amihaiemil.eoyaml; + +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; +import javax.json.JsonValue; + +/** + * Visitor which converts the Yaml to JSON. + * @author Mihai Andronache (amihaiemil@gmail.com) + * @version $Id$ + * @checkstyle ExecutableStatementCount (1000 lines) + * @since 8.0.2 + */ +final class YamlToJsonVisitor implements YamlVisitor { + + @Override + public JsonValue visitYamlMapping(final YamlMapping node) { + final JsonObjectBuilder object = Json.createObjectBuilder(); + node.keys().forEach( + k -> { + if(k instanceof Scalar) { + final String stringKey = ((Scalar) k).value(); + object.add( + stringKey, + this.visitYamlNode(node.value(stringKey)) + ); + } else { + throw new IllegalArgumentException( + "YamlMapping contains key which is not a Scalar. " + + "Cannot convert to JSON!" + ); + } + } + ); + return object.build(); + } + + @Override + public JsonValue visitYamlSequence(final YamlSequence node) { + final JsonArrayBuilder array = Json.createArrayBuilder(); + node.values().forEach( + v -> array.add(this.visitYamlNode(v)) + ); + return array.build(); + } + + @Override + public JsonValue visitYamlStream(final YamlStream node) { + final JsonArrayBuilder array = Json.createArrayBuilder(); + node.values().forEach( + v -> array.add(this.visitYamlNode(v)) + ); + return array.build(); + } + + @Override + public JsonValue visitScalar(final Scalar node) { + return Json.createValue(node.value()); + } + + @Override + public JsonValue defaultResult() { + return JsonValue.EMPTY_JSON_OBJECT; + } + + @Override + public JsonValue aggregateResult( + final JsonValue aggregate, + final JsonValue nextResult + ) { + return null; + } +} diff --git a/src/main/java/com/amihaiemil/eoyaml/YamlVisitor.java b/src/main/java/com/amihaiemil/eoyaml/YamlVisitor.java index 2c963ac0..4b99bbd9 100644 --- a/src/main/java/com/amihaiemil/eoyaml/YamlVisitor.java +++ b/src/main/java/com/amihaiemil/eoyaml/YamlVisitor.java @@ -44,7 +44,19 @@ public interface YamlVisitor { * @return T returned type. */ default T visitYamlNode(final YamlNode node) { - return this.visitChildren(node); + T result; + if (node instanceof Scalar) { + result = this.visitScalar((Scalar) node); + } else if (node instanceof YamlSequence) { + result = this.visitYamlSequence((YamlSequence) node); + } else if (node instanceof YamlMapping) { + result = this.visitYamlMapping((YamlMapping) node); + } else if (node instanceof YamlStream) { + result = this.visitYamlStream((YamlStream) node); + } else { + result = this.visitChildren(node); + } + return result; } /** diff --git a/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingTest.java b/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingTest.java index 7ed636a1..93c728a9 100644 --- a/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingTest.java +++ b/src/test/java/com/amihaiemil/eoyaml/RtYamlMappingTest.java @@ -401,9 +401,16 @@ public void prettyPrintsSimpleYaml() throws Exception { .add("name", "eo-yaml") .add("conditions", "- none") .build(); - System.out.print(yaml.toString()); + System.out.println(yaml.toString()); + System.out.println(yaml.toJsonObject()); String expected = this.readTestResource("simpleMapping.yml"); MatcherAssert.assertThat(yaml.toString(), Matchers.equalTo(expected)); + MatcherAssert.assertThat( + yaml.toJsonObject().toString(), + Matchers.equalTo( + "{\"architect\":\"mihai\",\"developers\":[\"rultor\",\"salikjan\",\"sherif\"],\"name\":\"eo-yaml\",\"conditions\":\"- none\"}" + ) + ); } /**