You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by jw...@apache.org on 2015/12/12 00:30:19 UTC

[4/7] groovy git commit: GROOVY-7703 - Add support for Iterable with Closure to JsonBuilder/StreamingJsonBuilder (closes #206)

GROOVY-7703 - Add support for Iterable with Closure to JsonBuilder/StreamingJsonBuilder (closes #206)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/f92af36f
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/f92af36f
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/f92af36f

Branch: refs/heads/GROOVY_2_4_X
Commit: f92af36fa775452a3ed8efd825d5b1267d8a033e
Parents: 6917c57
Author: John Wagenleitner <jw...@apache.org>
Authored: Sat Dec 5 13:35:31 2015 -0800
Committer: John Wagenleitner <jw...@apache.org>
Committed: Fri Dec 11 14:40:41 2015 -0800

----------------------------------------------------------------------
 .../src/main/java/groovy/json/JsonBuilder.java  | 46 +++++++++++----
 .../src/main/java/groovy/json/JsonDelegate.java | 12 +++-
 .../groovy/groovy/json/JsonBuilderTest.groovy   | 62 ++++++++++++++++++++
 3 files changed, 106 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/f92af36f/subprojects/groovy-json/src/main/java/groovy/json/JsonBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/JsonBuilder.java b/subprojects/groovy-json/src/main/java/groovy/json/JsonBuilder.java
index dae512b..c4f6bbd 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/JsonBuilder.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/JsonBuilder.java
@@ -174,7 +174,7 @@ public class JsonBuilder extends GroovyObjectSupport implements Writable {
      * @param c a closure used to convert the objects of coll
      * @return a list of values
      */
-    public Object call(Collection coll, Closure c) {
+    public Object call(Iterable coll, Closure c) {
         List<Object> listContent = new ArrayList<Object>();
         if (coll != null) {
             for (Object it : coll) {
@@ -187,6 +187,13 @@ public class JsonBuilder extends GroovyObjectSupport implements Writable {
     }
 
     /**
+     * Delegates to {@link #call(Iterable, Closure)}
+     */
+    public Object call(Collection coll, Closure c) {
+        return call((Iterable)coll, c);
+    }
+
+    /**
      * A closure passed to a JSON builder will create a root JSON object
      * <p>
      * Example:
@@ -278,19 +285,26 @@ public class JsonBuilder extends GroovyObjectSupport implements Writable {
                     return setAndGetContent(name, arr[0]);
                 }
             } else if (arr.length == 2) {
-                if (arr[0] instanceof Map && arr[1] instanceof Closure) {
-                    Map subMap = new LinkedHashMap();
-                    subMap.putAll((Map) arr[0]);
-                    subMap.putAll(JsonDelegate.cloneDelegateAndGetContent((Closure) arr[1]));
+                final Object first = arr[0];
+                final Object second = arr[1];
+                if (second instanceof Closure) {
+                    final Closure closure = (Closure)second;
+                    if (first instanceof Map) {
+                        Map subMap = new LinkedHashMap();
+                        subMap.putAll((Map) first);
+                        subMap.putAll(JsonDelegate.cloneDelegateAndGetContent(closure));
 
-                    return setAndGetContent(name, subMap);
-                } else if (arr[0] instanceof Collection && arr[1] instanceof Closure) {
-                    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
-                    for (Object it : (Collection) arr[0]) {
-                        list.add(JsonDelegate.curryDelegateAndGetContent((Closure) arr[1], it));
-                    }
+                        return setAndGetContent(name, subMap);
+                    } else if (first instanceof Iterable) {
+                        List<Map<String, Object>> list = collectContentForEachEntry((Iterable) first, closure);
+
+                        return setAndGetContent(name, list);
+                    } else if (first != null && first.getClass().isArray()) {
+                        final Iterable coll = Arrays.asList((Object[])first);
+                        List<Map<String, Object>> list = collectContentForEachEntry(coll, closure);
 
-                    return setAndGetContent(name, list);
+                        return setAndGetContent(name, list);
+                    }
                 }
             }
 
@@ -300,6 +314,14 @@ public class JsonBuilder extends GroovyObjectSupport implements Writable {
         }
     }
 
+    private List<Map<String, Object>> collectContentForEachEntry(Iterable coll, Closure closure) {
+        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+        for (Object it : coll) {
+            list.add(JsonDelegate.curryDelegateAndGetContent(closure, it));
+        }
+        return list;
+    }
+
     private Object setAndGetContent(String name, Object value) {
         Map<String, Object> contentMap = new LinkedHashMap<String, Object>();
         contentMap.put(name, value);

http://git-wip-us.apache.org/repos/asf/groovy/blob/f92af36f/subprojects/groovy-json/src/main/java/groovy/json/JsonDelegate.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/JsonDelegate.java b/subprojects/groovy-json/src/main/java/groovy/json/JsonDelegate.java
index 8bec1de..76e297c 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/JsonDelegate.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/JsonDelegate.java
@@ -47,9 +47,10 @@ public class JsonDelegate extends GroovyObjectSupport {
 
             if (arr.length == 1) {
                 val = arr[0];
-            } else if (arr.length == 2 && arr[0] instanceof Collection && arr[1] instanceof Closure) {
+            } else if (isIterableOrArrayAndClosure(arr)) {
                 Closure<?> closure = (Closure<?>) arr[1];
-                Iterator<?> iterator = ((Collection) arr[0]).iterator();
+                Iterator<?> iterator = (arr[0] instanceof Iterable) ?
+                        ((Iterable) arr[0]).iterator() : Arrays.asList((Object[])arr[0]).iterator();
                 List<Object> list = new ArrayList<Object>();
                 while (iterator.hasNext()) {
                     list.add(curryDelegateAndGetContent(closure, iterator.next()));
@@ -64,6 +65,13 @@ public class JsonDelegate extends GroovyObjectSupport {
         return val;
     }
 
+    private boolean isIterableOrArrayAndClosure(Object[] args) {
+        if (args.length != 2 || !(args[1] instanceof Closure)) {
+            return false;
+        }
+        return ((args[0] instanceof Iterable) || (args[0] != null && args[0].getClass().isArray()));
+    }
+
     /**
      * Factory method for creating <code>JsonDelegate</code>s from closures.
      *

http://git-wip-us.apache.org/repos/asf/groovy/blob/f92af36f/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy b/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy
index c3818e3..ec643f0 100644
--- a/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy
+++ b/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy
@@ -151,6 +151,68 @@ class JsonBuilderTest extends GroovyTestCase {
         assert json.toString() == '[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]'
     }
 
+    void testIterableAndClosure() {
+        Iterable authorIterable = [iterator:{->
+            [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")].iterator()
+        }] as Iterable
+        def json = new JsonBuilder()
+        json authorIterable, { Author author ->
+            name author.name
+        }
+
+        assert json.toString() == '[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]'
+    }
+
+    void testMethodWithIterableAndClosure() {
+        Iterable authorIterable = [iterator:{->
+            [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")].iterator()
+        }] as Iterable
+
+        def json = new JsonBuilder()
+        json.authors authorIterable, { Author author ->
+            name author.name
+        }
+
+        assert json.toString() == '{"authors":[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]}'
+    }
+
+    void testNestedMethodWithIterableAndClosure() {
+        Iterable authorIterable = [iterator:{->
+            [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")].iterator()
+        }] as Iterable
+
+        def json = new JsonBuilder()
+        json {
+            authors authorIterable, { Author author ->
+                name author.name
+            }
+        }
+
+        assert json.toString() == '{"authors":[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]}'
+    }
+
+    void testMethodWithArrayAndClosure() {
+        def authorArray = [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")] as Author[]
+        def json = new JsonBuilder()
+        json.authors authorArray, { Author author ->
+            name author.name
+        }
+
+        assert json.toString() == '{"authors":[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]}'
+    }
+
+    void testNestedMethodWithArrayAndClosure() {
+        Author[] authorArray = [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")] as Author[]
+        def json = new JsonBuilder()
+        json {
+            authors authorArray, { Author author ->
+                name author.name
+            }
+        }
+
+        assert json.toString() == '{"authors":[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]}'
+    }
+
     void testMethodWithCollectionAndClosure() {
         def authors = [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")]