From 4f0c4e7f556267d7fad50040f5eb4ef01e815f98 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Tue, 30 Jul 2024 23:39:53 +0200 Subject: [PATCH] Slight polish --- .../org/openrewrite/json/AddKeyValue.java | 50 ++-- .../org/openrewrite/json/AddKeyValueTest.java | 239 +++++++++--------- 2 files changed, 143 insertions(+), 146 deletions(-) diff --git a/rewrite-json/src/main/java/org/openrewrite/json/AddKeyValue.java b/rewrite-json/src/main/java/org/openrewrite/json/AddKeyValue.java index f9200791fc0..702cc04869c 100644 --- a/rewrite-json/src/main/java/org/openrewrite/json/AddKeyValue.java +++ b/rewrite-json/src/main/java/org/openrewrite/json/AddKeyValue.java @@ -21,13 +21,14 @@ import org.openrewrite.Option; import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; +import org.openrewrite.internal.ListUtils; import org.openrewrite.json.tree.Json; import org.openrewrite.json.tree.JsonKey; import org.openrewrite.json.tree.JsonRightPadded; import org.openrewrite.json.tree.Space; import org.openrewrite.marker.Markers; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import static java.util.Collections.emptyList; @@ -38,24 +39,24 @@ public class AddKeyValue extends Recipe { @Option(displayName = "Key path", - description = "A JsonPath expression to locate the *parent* JSON entry.", - example = "'$.subjects.*' or '$.' or '$.x[1].y.*' etc.") + description = "A JsonPath expression to locate the *parent* JSON entry.", + example = "'$.subjects.*' or '$.' or '$.x[1].y.*' etc.") String keyPath; @Option(displayName = "Key", - description = "The key to create.", - example = "myKey") + description = "The key to create.", + example = "myKey") String key; @Option(displayName = "Value", - description = "The value to add to the array at the specified key. Can be of any type." + - " String values should be quoted to be inserted as Strings.", - example = "\"myValue\" or '{\"a\": 1}' or '[ 123 ]'") + description = "The value to add to the array at the specified key. Can be of any type." + + " String values should be quoted to be inserted as Strings.", + example = "`\"myValue\"` or `{\"a\": 1}` or `[ 123 ]`") String value; @Option(displayName = "Prepend", - required = false, - description = "If set to `true` the value will be added to the beginning of the object") + required = false, + description = "If set to `true` the value will be added to the beginning of the object") boolean prepend; @Override @@ -71,32 +72,27 @@ public String getDescription() { @Override public TreeVisitor getVisitor() { - JsonPathMatcher pathMatcher = new JsonPathMatcher(keyPath); - return new JsonIsoVisitor() { + private final JsonPathMatcher pathMatcher = new JsonPathMatcher(keyPath); @Override public Json.JsonObject visitObject(Json.JsonObject obj, ExecutionContext ctx) { obj = super.visitObject(obj, ctx); if (pathMatcher.matches(getCursor()) && objectDoesNotContainKey(obj, key)) { - - boolean jsonIsEmpty = obj.getMembers().isEmpty() || obj.getMembers().get(0) instanceof Json.Empty; - Space space = jsonIsEmpty ? Space.EMPTY : obj.getMembers().get(0).getPrefix(); + List originalMembers = obj.getMembers(); + boolean jsonIsEmpty = originalMembers.isEmpty() || originalMembers.get(0) instanceof Json.Empty; + Space space = jsonIsEmpty ? Space.EMPTY : originalMembers.get(0).getPrefix(); JsonRightPadded newKey = rightPaddedKey(); Json.Literal newValue = valueLiteral(); Json newMember = new Json.Member(randomId(), space, Markers.EMPTY, newKey, newValue); - List members = jsonIsEmpty ? new ArrayList<>() : obj.getMembers(); - - if (prepend) { - members.add(0, newMember); - } else { - members.add(newMember); - } + List newMembers = jsonIsEmpty ? Collections.singletonList(newMember) : prepend ? + ListUtils.concat(newMember, originalMembers) : + ListUtils.concat(originalMembers, newMember); - return obj.withMembers(members); + return obj.withMembers(newMembers); } return obj; } @@ -107,14 +103,14 @@ private Json.Literal valueLiteral() { private JsonRightPadded rightPaddedKey() { return new JsonRightPadded<>( - new Json.Literal(randomId(), Space.EMPTY, Markers.EMPTY, "\"" + key + "\"", key), - Space.EMPTY, Markers.EMPTY + new Json.Literal(randomId(), Space.EMPTY, Markers.EMPTY, "\"" + key + "\"", key), + Space.EMPTY, Markers.EMPTY ); } private String unQuote(String value) { if (value.startsWith("'") || value.startsWith("\"")) { - value = value.substring(1, value.length() - 1); + return value.substring(1, value.length() - 1); } return value; } @@ -136,7 +132,7 @@ private boolean keyMatches(JsonKey jsonKey, String key) { } else if (jsonKey instanceof Json.Identifier) { return key.equals(((Json.Identifier) jsonKey).getName()); } - throw new IllegalStateException("Key is not 'Json.Literal' or 'Json.Identifier': " + jsonKey); + return false; } }; diff --git a/rewrite-json/src/test/java/org/openrewrite/json/AddKeyValueTest.java b/rewrite-json/src/test/java/org/openrewrite/json/AddKeyValueTest.java index 9a288ca43c1..e2d8fdb8f72 100644 --- a/rewrite-json/src/test/java/org/openrewrite/json/AddKeyValueTest.java +++ b/rewrite-json/src/test/java/org/openrewrite/json/AddKeyValueTest.java @@ -16,6 +16,7 @@ package org.openrewrite.json; import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; import org.openrewrite.test.RewriteTest; import static org.openrewrite.json.Assertions.json; @@ -23,95 +24,96 @@ class AddKeyValueTest implements RewriteTest { @Test + @DocumentExample void shouldAppendSimpleValue() { rewriteRun( - spec -> spec.recipe(new AddKeyValue("$.", "key", "\"val\"", false)), - //language=json - json( - """ - { - "x": "x", - "l": [ - 1, 2 - ] - } - """, - """ - { - "x": "x", - "l": [ - 1, 2 - ] - , - "key": "val"} - """) - + spec -> spec.recipe(new AddKeyValue("$.", "key", "\"val\"", false)), + //language=json + json( + """ + { + "x": "x", + "l": [ + 1, 2 + ] + } + """, + """ + { + "x": "x", + "l": [ + 1, 2 + ] + , + "key": "val"} + """ + ) ); } @Test void shouldAppendToNestedObject() { rewriteRun( - spec -> spec.recipe(new AddKeyValue("$.x.y.*", "key", "\"val\"", false)), - //language=json - json( - """ - { - "x": { - "y": { } - } - } - """, - """ - { - "x": { - "y": {"key": "val"} - } - } - """) - + spec -> spec.recipe(new AddKeyValue("$.x.y.*", "key", "\"val\"", false)), + //language=json + json( + """ + { + "x": { + "y": { } + } + } + """, + """ + { + "x": { + "y": {"key": "val"} + } + } + """ + ) ); } @Test void shouldAppendToNestedObjectInArray() { rewriteRun( - spec -> spec.recipe(new AddKeyValue("$.x[1].y.*", "key", "\"val\"", false)), - //language=json - json( - """ - { - "x": [ - { }, - { - "y" : { } - } - ] - } - """, - """ - { - "x": [ - { }, - { - "y" : {"key": "val"} - } - ] - } - """) - + spec -> spec.recipe(new AddKeyValue("$.x[1].y.*", "key", "\"val\"", false)), + //language=json + json( + """ + { + "x": [ + { }, + { + "y" : { } + } + ] + } + """, + """ + { + "x": [ + { }, + { + "y" : {"key": "val"} + } + ] + } + """ + ) ); } @Test void shouldNotAppendIfExists() { rewriteRun( - spec -> spec.recipe(new AddKeyValue("$.", "key", "\"val\"", false)), - //language=json - json(""" - { - "key": "x" - }""") + spec -> spec.recipe(new AddKeyValue("$.", "key", "\"val\"", false)), + //language=json + json(""" + { + "key": "x" + }""") ); } @@ -119,61 +121,60 @@ void shouldNotAppendIfExists() { @Test void shouldAppendObject() { rewriteRun( - spec -> spec.recipe(new AddKeyValue( - "$.", "key", """ - { "a": "b" } - """.trim(), false)), - //language=json - json( - """ - { - "x": "x", - "l": [ - 1, 2 - ] - } - """, - """ - { - "x": "x", - "l": [ - 1, 2 - ] - , - "key": { "a": "b" }} - """) - + spec -> spec.recipe(new AddKeyValue( + "$.", "key", """ + { "a": "b" } + """.trim(), false)), + //language=json + json( + """ + { + "x": "x", + "l": [ + 1, 2 + ] + } + """, + """ + { + "x": "x", + "l": [ + 1, 2 + ] + , + "key": { "a": "b" }} + """ + ) ); } @Test void shouldPrependObject() { rewriteRun( - spec -> spec.recipe(new AddKeyValue( - "$.", "key", """ - { "a": "b" } - """.trim(), true)), - //language=json - json( - """ - { - "x": "x", - "l": [ - 1, 2 - ] - } - """, - """ - { - "key": { "a": "b" }, - "x": "x", - "l": [ - 1, 2 - ] - } - """) - + spec -> spec.recipe(new AddKeyValue( + "$.", "key", """ + { "a": "b" } + """.trim(), true)), + //language=json + json( + """ + { + "x": "x", + "l": [ + 1, 2 + ] + } + """, + """ + { + "key": { "a": "b" }, + "x": "x", + "l": [ + 1, 2 + ] + } + """ + ) ); } - -} \ No newline at end of file +}