You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2020/12/18 22:53:37 UTC

[groovy] branch master updated: GROOVY-9662: StreamingJsonBuilder: set resolve strategy metadata (closes #1445)

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new e3db8d2  GROOVY-9662: StreamingJsonBuilder: set resolve strategy metadata (closes #1445)
e3db8d2 is described below

commit e3db8d289b201bb5eb4f2a665650735bf15ed011
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Dec 18 14:25:54 2020 -0600

    GROOVY-9662: StreamingJsonBuilder: set resolve strategy metadata (closes #1445)
---
 .../java/groovy/json/StreamingJsonBuilder.java     | 58 +++++++-------
 .../spec/test/json/StreamingJsonBuilderTest.groovy | 88 ++++++++++++++++------
 2 files changed, 95 insertions(+), 51 deletions(-)

diff --git a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java b/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
index b3ce2be..525c332 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
@@ -237,15 +237,15 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
      * @param coll a collection
      * @param c a closure used to convert the objects of coll
      */
-    public Object call(Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+    public Object call(Iterable coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
         return StreamingJsonDelegate.writeCollectionWithClosure(writer, coll, c, generator);
     }
 
     /**
      * Delegates to {@link #call(Iterable, Closure)}
      */
-    public Object call(Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
-        return call((Iterable)coll, c);
+    public Object call(Collection coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
+        return call((Iterable) coll, c);
     }
 
     /**
@@ -266,7 +266,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
      *
      * @param c a closure whose method call statements represent key / values of a JSON object
      */
-    public Object call(@DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+    public Object call(@DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
         writer.write(JsonOutput.OPEN_BRACE);
         StreamingJsonDelegate.cloneDelegateAndGetContent(writer, c, true, generator);
         writer.write(JsonOutput.CLOSE_BRACE);
@@ -293,7 +293,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
      * @param name The key for the JSON object
      * @param c a closure whose method call statements represent key / values of a JSON object
      */
-    public void call(String name, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+    public void call(String name, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
         writer.write(JsonOutput.OPEN_BRACE);
         writer.write(generator.toJson(name));
         writer.write(JsonOutput.COLON);
@@ -324,7 +324,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
      * @param coll a collection
      * @param c a closure used to convert the objects of coll
      */
-    public void call(String name, Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+    public void call(String name, Iterable coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
         writer.write(JsonOutput.OPEN_BRACE);
         writer.write(generator.toJson(name));
         writer.write(JsonOutput.COLON);
@@ -335,8 +335,8 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
     /**
      * Delegates to {@link #call(String, Iterable, Closure)}
      */
-    public void call(String name, Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
-        call(name, (Iterable)coll, c);
+    public void call(String name, Collection coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
+        call(name, (Iterable) coll, c);
     }
 
     /**
@@ -361,7 +361,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
      * @param callable Additional attributes of the JSON object represented by the closure
      * @throws IOException
      */
-    public void call(String name, Map map, @DelegatesTo(StreamingJsonDelegate.class) Closure callable) throws IOException {
+    public void call(String name, Map map, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure callable) throws IOException {
         writer.write(JsonOutput.OPEN_BRACE);
         writer.write(generator.toJson(name));
         writer.write(COLON_WITH_OPEN_BRACE);
@@ -612,7 +612,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
          * @param array The list representing the array
          * @throws IOException
          */
-        public void call(String name, Object...array) throws IOException {
+        public void call(String name, Object... array) throws IOException {
             if (generator.isExcludingFieldsNamed(name)) {
                 return;
             }
@@ -645,7 +645,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
          * @param coll a collection
          * @param c a closure used to convert the objects of coll
          */
-        public void call(String name, Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+        public void call(String name, Iterable coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
             if (generator.isExcludingFieldsNamed(name)) {
                 return;
             }
@@ -656,7 +656,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
         /**
          * Delegates to {@link #call(String, Iterable, Closure)}
          */
-        public void call(String name, Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+        public void call(String name, Collection coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
             call(name, (Iterable)coll, c);
         }
 
@@ -682,7 +682,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
          * @param value The value
          * @throws IOException
          */
-        public void call(String name, Object value, @DelegatesTo(StreamingJsonDelegate.class) Closure callable) throws IOException {
+        public void call(String name, Object value, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure callable) throws IOException {
             if (generator.isExcludingFieldsNamed(name)) {
                 return;
             }
@@ -690,6 +690,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             verifyValue();
             writeObject(writer, value, callable, generator);
         }
+
         /**
          * Writes the name and another JSON object
          *
@@ -697,7 +698,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
          * @param value The value
          * @throws IOException
          */
-        public void call(String name,@DelegatesTo(StreamingJsonDelegate.class) Closure value) throws IOException {
+        public void call(String name, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure value) throws IOException {
             if (generator.isExcludingFieldsNamed(name)) {
                 return;
             }
@@ -706,8 +707,8 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             writer.write(JsonOutput.OPEN_BRACE);
             StreamingJsonDelegate.cloneDelegateAndGetContent(writer, value, true, generator);
             writer.write(JsonOutput.CLOSE_BRACE);
-
         }
+
         /**
          * Writes an unescaped value. Note: can cause invalid JSON if passed JSON is invalid
          *
@@ -727,7 +728,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
         /**
          * Writes the given Writable as the value of the given attribute name
          *
-         * @param name The attribute name 
+         * @param name The attribute name
          * @param json The writable value
          * @throws IOException
          */
@@ -742,7 +743,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             }
         }
 
-        private void writeObjects(Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+        private void writeObjects(Iterable coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) throws IOException {
             verifyValue();
             writeCollectionWithClosure(writer, coll, c, generator);
         }
@@ -756,7 +757,6 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             }
         }
 
-
         protected void writeName(String name) throws IOException {
             if (generator.isExcludingFieldsNamed(name)) {
                 return;
@@ -793,12 +793,11 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             return args.length == 2 && args[0] instanceof Iterable && args[1] instanceof Closure;
         }
 
-        public static Object writeCollectionWithClosure(Writer writer, Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure closure) throws IOException {
-            return writeCollectionWithClosure(writer, (Iterable)coll, closure, JsonOutput.DEFAULT_GENERATOR);
+        public static Object writeCollectionWithClosure(Writer writer, Collection coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure closure) throws IOException {
+            return writeCollectionWithClosure(writer, (Iterable) coll, closure, JsonOutput.DEFAULT_GENERATOR);
         }
 
-        private static Object writeCollectionWithClosure(Writer writer, Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure closure, JsonGenerator generator)
-                throws IOException {
+        private static Object writeCollectionWithClosure(Writer writer, Iterable coll, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure closure, JsonGenerator generator) throws IOException {
             writer.write(JsonOutput.OPEN_BRACKET);
             boolean first = true;
             for (Object it : coll) {
@@ -815,22 +814,21 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             return writer;
         }
 
-        private static void writeObject(Writer writer, Object object, Closure closure, JsonGenerator generator) throws IOException {
+        private static void writeObject(Writer writer, Object object, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure closure, JsonGenerator generator) throws IOException {
             writer.write(JsonOutput.OPEN_BRACE);
             curryDelegateAndGetContent(writer, closure, object, true, generator);
             writer.write(JsonOutput.CLOSE_BRACE);
         }
 
-        public static void cloneDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c)
-        {
+        public static void cloneDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c) {
             cloneDelegateAndGetContent(w, c, true);
         }
 
-        public static void cloneDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c, boolean first) {
+        public static void cloneDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, boolean first) {
             cloneDelegateAndGetContent(w, c, first, JsonOutput.DEFAULT_GENERATOR);
         }
 
-        private static void cloneDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c, boolean first, JsonGenerator generator) {
+        private static void cloneDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, boolean first, JsonGenerator generator) {
             StreamingJsonDelegate delegate = new StreamingJsonDelegate(w, first, generator);
             Closure cloned = (Closure) c.clone();
             cloned.setDelegate(delegate);
@@ -838,15 +836,15 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             cloned.call();
         }
 
-        public static void curryDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c, Object o) {
+        public static void curryDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, Object o) {
             curryDelegateAndGetContent(w, c, o, true);
         }
 
-        public static void curryDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c, Object o, boolean first) {
+        public static void curryDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, Object o, boolean first) {
             curryDelegateAndGetContent(w, c, o, first, JsonOutput.DEFAULT_GENERATOR);
         }
 
-        private static void curryDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c, Object o, boolean first, JsonGenerator generator) {
+        private static void curryDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, Object o, boolean first, JsonGenerator generator) {
             StreamingJsonDelegate delegate = new StreamingJsonDelegate(w, first, generator);
             Closure curried = c.curry(o);
             curried.setDelegate(delegate);
diff --git a/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy b/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy
index b34cbdf..dca201e 100644
--- a/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy
+++ b/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy
@@ -18,48 +18,51 @@
  */
 package json
 
-import groovy.test.GroovyTestCase
+import org.junit.Test
 
-class StreamingJsonBuilderTest extends GroovyTestCase {
+import static groovy.test.GroovyAssert.assertScript
 
+final class StreamingJsonBuilderTest {
+
+    @Test
     void testStreamingJsonBuilder() {
-        assertScript """
+        assertScript '''
             import groovy.json.*
             import net.javacrumbs.jsonunit.JsonAssert
 
             // tag::json_string[]
-            String carRecords = '''
+            String carRecords = """
                 {
-                    "records": {
+                  "records": {
                     "car": {
-                        "name": "HSV Maloo",
-                        "make": "Holden",
-                        "year": 2006,
-                        "country": "Australia",
-                        "record": {
-                          "type": "speed",
-                          "description": "production pickup truck with speed of 271kph"
-                        }
+                      "name": "HSV Maloo",
+                      "make": "Holden",
+                      "year": 2006,
+                      "country": "Australia",
+                      "record": {
+                        "type": "speed",
+                        "description": "production pickup truck with speed of 271kph"
                       }
+                    }
                   }
                 }
-            '''
+            """
             // end::json_string[]
 
             // tag::streaming_json_builder[]
             StringWriter writer = new StringWriter()
             StreamingJsonBuilder builder = new StreamingJsonBuilder(writer)
             builder.records {
-              car {
+                car {
                     name 'HSV Maloo'
                     make 'Holden'
-                    year 2006 
+                    year 2006
                     country 'Australia'
                     record {
                         type 'speed'
                         description 'production pickup truck with speed of 271kph'
                     }
-              }
+                }
             }
             String json = JsonOutput.prettyPrint(writer.toString())
             // end::streaming_json_builder[]
@@ -67,9 +70,10 @@ class StreamingJsonBuilderTest extends GroovyTestCase {
             // tag::json_assert[]
             JsonAssert.assertJsonEquals(json, carRecords)
             // end::json_assert[]
-       """
+       '''
     }
 
+    @Test
     void testStreamingJsonBuilderWithGenerator() {
         assertScript '''
             import groovy.json.*
@@ -85,7 +89,7 @@ class StreamingJsonBuilderTest extends GroovyTestCase {
             StreamingJsonBuilder builder = new StreamingJsonBuilder(writer, generator)
 
             builder.records {
-              car {
+                car {
                     name 'HSV Maloo'
                     make 'Holden'
                     year 2006
@@ -95,11 +99,53 @@ class StreamingJsonBuilderTest extends GroovyTestCase {
                         type 'speed'
                         description 'production pickup truck with speed of 271kph'
                     }
-              }
+                }
             }
 
             assert writer.toString() == '{"records":{"car":{"name":"HSV Maloo","homepage":"http://groovy-lang.org"}}}'
             // end::streaming_json_builder_generator[]
         '''
     }
-}
\ No newline at end of file
+
+    @Test // GROOVY-9662
+    void testStreamingJsonBuilderDelegationMetadata() {
+        assertScript '''
+            import groovy.json.*
+            import net.javacrumbs.jsonunit.JsonAssert
+
+            @groovy.transform.CompileStatic
+            class JsonRenderer {
+                final Writer writer = new StringWriter()
+
+                String render() {
+                    new StreamingJsonBuilder(writer).call {
+                        call('logref', 'ref')
+                        call('message', 'msg')
+                        call('path', 'http://localhost:8080')
+                        call('_links') {
+                            // no comma here if delegate used
+                            call('resource') {
+                                // no comma here if delegate used
+                                call('href', 'path')
+                            }
+                        }
+                    }
+                    writer.flush()
+                    writer.toString()
+                }
+            }
+
+            String json = JsonOutput.prettyPrint(new JsonRenderer().render())
+            JsonAssert.assertJsonEquals(json, """{
+                |  "logref": "ref",
+                |  "message": "msg",
+                |  "path": "http://localhost:8080",
+                |  "_links": {
+                |    "resource": {
+                |      "href": "path"
+                |    }
+                |  }
+                |}""".stripMargin())
+        '''
+    }
+}