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:16 UTC

[1/7] groovy git commit: Binary compatibility improvements

Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_4_X 5e034d314 -> 33319ff6a


Binary compatibility improvements


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

Branch: refs/heads/GROOVY_2_4_X
Commit: 4284a3929bdab9ecf5369f50ebb4ee2662ce36f9
Parents: 6165159
Author: graemerocher <gr...@gmail.com>
Authored: Wed Dec 2 11:49:02 2015 +0100
Committer: John Wagenleitner <jw...@apache.org>
Committed: Fri Dec 11 14:39:57 2015 -0800

----------------------------------------------------------------------
 .../java/groovy/json/StreamingJsonBuilder.java  | 25 ++++++++++++++++++++
 1 file changed, 25 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/4284a392/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
----------------------------------------------------------------------
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 f37789c..b5a0133 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
@@ -210,6 +210,13 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
     }
 
     /**
+     * Delegates to {@link #call(Iterable, Closure)}
+     */
+    public Object call(Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+        return call((Iterable)coll, c);
+    }
+
+    /**
      * A closure passed to a JSON builder will create a root JSON object
      * <p>
      * Example:
@@ -294,6 +301,13 @@ 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);
+    }
+
+    /**
      * If you use named arguments and a closure as last argument,
      * the key/value pairs of the map (as named arguments)
      * and the key/value pairs represented in the closure
@@ -571,6 +585,13 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
         }
 
         /**
+         * Delegates to {@link #call(String, Iterable, Closure)}
+         */
+        public void call(String name, Collection coll, Closure c) throws IOException {
+            call(name, (Iterable)coll, c);
+        }
+
+        /**
          * Writes the name and value of a JSON attribute
          *
          * @param name The attribute name
@@ -667,6 +688,10 @@ 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, Closure closure) throws IOException {
+            return writeCollectionWithClosure(writer, (Iterable)coll, closure);
+        }
+
         public static Object writeCollectionWithClosure(Writer writer, Iterable coll, Closure closure) throws IOException {
             writer.write(JsonOutput.OPEN_BRACKET);
             boolean first = true;


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

Posted by jw...@apache.org.
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")]
 


[3/7] groovy git commit: Fix typo

Posted by jw...@apache.org.
Fix typo


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

Branch: refs/heads/GROOVY_2_4_X
Commit: 6917c57ee664876ff02d743cbb834befddc462f2
Parents: 4284a39
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Dec 6 13:04:23 2015 -0800
Committer: John Wagenleitner <jw...@apache.org>
Committed: Fri Dec 11 14:39:58 2015 -0800

----------------------------------------------------------------------
 .../src/main/java/groovy/json/StreamingJsonBuilder.java            | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/6917c57e/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
----------------------------------------------------------------------
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 b5a0133..5c8e10e 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
@@ -616,7 +616,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             writeObject(writer, value, callable);
         }
         /**
-         * Writes the name and another JSON boject
+         * Writes the name and another JSON object
          *
          * @param name The attribute name
          * @param value The value


[5/7] groovy git commit: GROOVY-7706 - StreamingJsonBuilder should handle nested closures (closes #208)

Posted by jw...@apache.org.
GROOVY-7706 - StreamingJsonBuilder should handle nested closures (closes #208)


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

Branch: refs/heads/GROOVY_2_4_X
Commit: 7bf43908af7f99cfb4e9496b706160ebaee1f34f
Parents: f92af36
Author: graemerocher <gr...@gmail.com>
Authored: Wed Dec 9 14:06:20 2015 +0100
Committer: John Wagenleitner <jw...@apache.org>
Committed: Fri Dec 11 14:41:42 2015 -0800

----------------------------------------------------------------------
 .../main/java/groovy/json/StreamingJsonBuilder.java | 10 +++++++++-
 .../groovy/json/StreamingJsonBuilderTest.groovy     | 16 ++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/7bf43908/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
----------------------------------------------------------------------
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 5c8e10e..7290d52 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
@@ -487,6 +487,9 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             this.first = first;
         }
 
+        /**
+         * @return Obtains the current writer
+         */
         public Writer getWriter() {
             return writer;
         }
@@ -500,7 +503,12 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
                     switch (len) {
                         case 1:
                             final Object value = arr[0];
-                            call(name, value);
+                            if(value instanceof Closure) {
+                                call(name, (Closure)value);
+                            }
+                            else {
+                                call(name, value);
+                            }
                             return null;
                         case 2:
                             if(arr[len -1] instanceof Closure) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/7bf43908/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy b/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
index 9bae655..f37e8ee 100644
--- a/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
+++ b/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
@@ -65,6 +65,22 @@ class StreamingJsonBuilderTest extends GroovyTestCase {
         }
     }
 
+    void testJsonBuilderWithNestedClosures() {
+        new StringWriter().with { w ->
+            def builder = new StreamingJsonBuilder(w)
+
+            builder.response {
+                status "ok"
+                results {
+                    sectionId "world"
+                    assert delegate instanceof StreamingJsonBuilder.StreamingJsonDelegate
+                }
+            }
+
+            assert w.toString() == '{"response":{"status":"ok","results":{"sectionId":"world"}}}'
+        }
+    }
+
     void testJsonBuilderConstructor() {
         new StringWriter().with { w ->
             new StreamingJsonBuilder(w, [a: 1, b: true])


[2/7] groovy git commit: Support for Array and Iterable not just Collection in StreamingJsonBuilder (closes #203)

Posted by jw...@apache.org.
Support for Array and Iterable not just Collection in StreamingJsonBuilder (closes #203)


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

Branch: refs/heads/GROOVY_2_4_X
Commit: 616515909b80c3a01474251af96b8bac5fb44e82
Parents: 5e034d3
Author: graemerocher <gr...@gmail.com>
Authored: Wed Dec 2 11:13:25 2015 +0100
Committer: John Wagenleitner <jw...@apache.org>
Committed: Fri Dec 11 14:39:57 2015 -0800

----------------------------------------------------------------------
 .../src/main/java/groovy/json/JsonOutput.java   |  18 +-
 .../java/groovy/json/StreamingJsonBuilder.java  | 171 +++++++++++++------
 .../groovy/json/StreamingJsonBuilderTest.groovy |  45 +++++
 3 files changed, 175 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/61651590/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java b/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java
index b9a4e4b..8bee49d 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java
@@ -305,10 +305,7 @@ public class JsonOutput {
             } else if (Enum.class.isAssignableFrom(objectClass)) {
                 buffer.addQuoted(((Enum<?>) object).name());
             }else if (File.class.isAssignableFrom(objectClass)){
-                Map<?, ?> properties = DefaultGroovyMethods.getProperties(object);
-                properties.remove("class");
-                properties.remove("declaringClass");
-                properties.remove("metaClass");
+                Map<?, ?> properties = getObjectProperties(object);
                 //Clean up all recursive references to File objects
                 Iterator<? extends Map.Entry<?, ?>> iterator = properties.entrySet().iterator();
                 while(iterator.hasNext()){
@@ -320,15 +317,20 @@ public class JsonOutput {
 
                 writeMap(properties, buffer);
             } else {
-                Map<?, ?> properties = DefaultGroovyMethods.getProperties(object);
-                properties.remove("class");
-                properties.remove("declaringClass");
-                properties.remove("metaClass");
+                Map<?, ?> properties = getObjectProperties(object);
                 writeMap(properties, buffer);
             }
         }
     }
 
+    private static Map<?, ?> getObjectProperties(Object object) {
+        Map<?, ?> properties = DefaultGroovyMethods.getProperties(object);
+        properties.remove("class");
+        properties.remove("declaringClass");
+        properties.remove("metaClass");
+        return properties;
+    }
+
 
     /**
      * Serializes any char sequence and writes it into specified buffer.

http://git-wip-us.apache.org/repos/asf/groovy/blob/61651590/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
----------------------------------------------------------------------
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 f96d8f6..f37789c 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
@@ -205,10 +205,8 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
      * @param coll a collection
      * @param c a closure used to convert the objects of coll
      */
-    public Object call(Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
-        StreamingJsonDelegate.writeCollectionWithClosure(writer, coll, c);
-
-        return null;
+    public Object call(Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+        return StreamingJsonDelegate.writeCollectionWithClosure(writer, coll, c);
     }
 
     /**
@@ -287,7 +285,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, Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+    public void call(String name, Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
         writer.write(JsonOutput.OPEN_BRACE);
         writer.write(JsonOutput.toJson(name));
         writer.write(JsonOutput.COLON);
@@ -405,28 +403,46 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
         if (args != null && Object[].class.isAssignableFrom(args.getClass())) {
             Object[] arr = (Object[]) args;
             try {
-                if (arr.length == 0) {
-                    call(name);
-                } else if (arr.length == 1) {
-                    if (arr[0] instanceof Closure) {
-                        final Closure callable = (Closure) arr[0];
-                        call(name, callable);
-                    } else if (arr[0] instanceof Map) {
-                        final Map<String, Map> map = Collections.singletonMap(name, (Map) arr[0]);
-                        call(map);
-                    } else {
+                switch(arr.length) {
+                    case 0:
+                        call(name);
+                    break;
+                    case 1:
+                        if (arr[0] instanceof Closure) {
+                            final Closure callable = (Closure) arr[0];
+                            call(name, callable);
+                        } else if (arr[0] instanceof Map) {
+                            final Map<String, Map> map = Collections.singletonMap(name, (Map) arr[0]);
+                            call(map);
+                        } else {
+                            notExpectedArgs = true;
+                        }
+                    break;
+                    case 2:
+                        final Object first = arr[0];
+                        final Object second = arr[1];
+                        final boolean isClosure = second instanceof Closure;
+
+                        if(isClosure && first instanceof Map ) {
+                            final Closure callable = (Closure) second;
+                            call(name, (Map)first, callable);
+                        }
+                        else if(isClosure && first instanceof Iterable) {
+                            final Iterable coll = (Iterable) first;
+                            final Closure callable = (Closure) second;
+                            call(name, coll, callable);
+                        }
+                        else if(isClosure && first.getClass().isArray()) {
+                            final Iterable coll = Arrays.asList((Object[])first);
+                            final Closure callable = (Closure) second;
+                            call(name, coll, callable);
+                        }
+                        else {
+                            notExpectedArgs = true;
+                        }
+                    break;
+                    default:
                         notExpectedArgs = true;
-                    }
-                } else if (arr.length == 2 && arr[0] instanceof Map && arr[1] instanceof Closure) {
-                    Map map = (Map) arr[0];
-                    final Closure callable = (Closure) arr[1];
-                    call(name, map, callable);
-                } else if (StreamingJsonDelegate.isCollectionWithClosure(arr)) {
-                    final Collection coll = (Collection) arr[0];
-                    final Closure callable = (Closure) arr[1];
-                    call(name, coll, callable);
-                } else {
-                    notExpectedArgs = true;
                 }
             } catch (IOException ioe) {
                 throw new JsonException(ioe);
@@ -447,9 +463,9 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
      */
     public static class StreamingJsonDelegate extends GroovyObjectSupport {
 
-        private Writer writer;
-        private boolean first;
-        private State state;
+        protected final Writer writer;
+        protected boolean first;
+        protected State state;
 
 
         public StreamingJsonDelegate(Writer w, boolean first) {
@@ -457,21 +473,42 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             this.first = first;
         }
 
+        public Writer getWriter() {
+            return writer;
+        }
+
         public Object invokeMethod(String name, Object args) {
             if (args != null && Object[].class.isAssignableFrom(args.getClass())) {
                 try {
                     Object[] arr = (Object[]) args;
 
-                    if (arr.length == 1) {
-                        final Object value = arr[0];
-                        call(name, value);
-                    } else if (isCollectionWithClosure(arr)) {
-                        final Collection coll = (Collection) arr[0];
-                        final Closure callable = (Closure) arr[1];
-                        call(name, coll, callable);
-                    } else {
-                        final List<Object> list = Arrays.asList(arr);
-                        call(name, list);
+                    final int len = arr.length;
+                    switch (len) {
+                        case 1:
+                            final Object value = arr[0];
+                            call(name, value);
+                            return null;
+                        case 2:
+                            if(arr[len -1] instanceof Closure) {
+                                final Object obj = arr[0];
+                                final Closure callable = (Closure) arr[1];
+                                if(obj instanceof Iterable) {
+                                    call(name, (Iterable)obj, callable);
+                                    return null;
+                                }
+                                else if(obj.getClass().isArray()) {
+                                    call(name, Arrays.asList( (Object[])obj), callable);
+                                    return null;
+                                }
+                                else {
+                                    call(name, obj, callable);
+                                    return null;
+                                }
+                            }
+                        default:
+                            final List<Object> list = Arrays.asList(arr);
+                            call(name, list);
+
                     }
                 } catch (IOException ioe) {
                     throw new JsonException(ioe);
@@ -528,7 +565,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, Collection coll, Closure c) throws IOException {
+        public void call(String name, Iterable coll, Closure c) throws IOException {
             writeName(name);
             writeObjects(coll, c);
         }
@@ -546,6 +583,33 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
         }
 
         /**
+         * Writes the name and value of a JSON attribute
+         *
+         * @param name The attribute name
+         * @param value The value
+         * @throws IOException
+         */
+        public void call(String name, Object value, @DelegatesTo(StreamingJsonDelegate.class) Closure callable) throws IOException {
+            writeName(name);
+            verifyValue();
+            writeObject(writer, value, callable);
+        }
+        /**
+         * Writes the name and another JSON boject
+         *
+         * @param name The attribute name
+         * @param value The value
+         * @throws IOException
+         */
+        public void call(String name,@DelegatesTo(StreamingJsonDelegate.class) Closure value) throws IOException {
+            writeName(name);
+            verifyValue();
+            writer.write(JsonOutput.OPEN_BRACE);
+            StreamingJsonDelegate.cloneDelegateAndGetContent(writer, value);
+            writer.write(JsonOutput.CLOSE_BRACE);
+
+        }
+        /**
          * Writes an unescaped value. Note: can cause invalid JSON if passed JSON is invalid
          *
          * @param name The attribute name
@@ -558,12 +622,12 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
         }
 
 
-        private void writeObjects(Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
+        private void writeObjects(Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
             verifyValue();
             writeCollectionWithClosure(writer, coll, c);
         }
 
-        private void verifyValue() {
+        protected void verifyValue() {
             if(state == State.VALUE) {
                 throw new IllegalStateException("Cannot write value when value has just been written. Write a name first!");
             }
@@ -573,7 +637,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
         }
 
 
-        private void writeName(String name) throws IOException {
+        protected void writeName(String name) throws IOException {
             if(state == State.NAME) {
                 throw new IllegalStateException("Cannot write a name when a name has just been written. Write a value first!");
             }
@@ -589,21 +653,21 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             writer.write(JsonOutput.COLON);
         }
 
-        private void writeValue(Object value) throws IOException {
+        protected void writeValue(Object value) throws IOException {
             verifyValue();
             writer.write(JsonOutput.toJson(value));
         }
 
-        private void writeArray(List<Object> list) throws IOException {
+        protected void writeArray(List<Object> list) throws IOException {
             verifyValue();
             writer.write(JsonOutput.toJson(list));
         }
 
         public static boolean isCollectionWithClosure(Object[] args) {
-            return args.length == 2 && args[0] instanceof Collection && args[1] instanceof Closure;
+            return args.length == 2 && args[0] instanceof Iterable && args[1] instanceof Closure;
         }
 
-        public static Object writeCollectionWithClosure(Writer writer, Collection coll, Closure closure) throws IOException {
+        public static Object writeCollectionWithClosure(Writer writer, Iterable coll, Closure closure) throws IOException {
             writer.write(JsonOutput.OPEN_BRACKET);
             boolean first = true;
             for (Object it : coll) {
@@ -613,16 +677,21 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
                     first = false;
                 }
 
-                writer.write(JsonOutput.OPEN_BRACE);
-                curryDelegateAndGetContent(writer, closure, it);
-                writer.write(JsonOutput.CLOSE_BRACE);
+                writeObject(writer, it, closure);
             }
             writer.write(JsonOutput.CLOSE_BRACKET);
 
             return writer;
         }
 
-        public static void cloneDelegateAndGetContent(Writer w, Closure c) {
+        private static void writeObject(Writer writer, Object object, Closure closure) throws IOException {
+            writer.write(JsonOutput.OPEN_BRACE);
+            curryDelegateAndGetContent(writer, closure, object);
+            writer.write(JsonOutput.CLOSE_BRACE);
+        }
+
+        public static void cloneDelegateAndGetContent(Writer w, Closure c)
+        {
             cloneDelegateAndGetContent(w, c, true);
         }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/61651590/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy b/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
index 19f4477..9bae655 100644
--- a/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
+++ b/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
@@ -231,6 +231,51 @@ class StreamingJsonBuilderTest extends GroovyTestCase {
         }
     }
 
+    void testIterableAndClosure() {
+        def authors = [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")]
+        Iterable it = [iterator:{->
+            authors.iterator()
+        }] as Iterable
+        new StringWriter().with { w ->
+            def json = new StreamingJsonBuilder(w)
+            json it, { Author author ->
+                name author.name
+            }
+
+            assert w.toString() == '[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]'
+        }
+    }
+
+    void testMethodWithIterableAndClosure() {
+        def authors = [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")]
+        Iterable it = [iterator:{->
+            authors.iterator()
+        }] as Iterable
+
+        new StringWriter().with { w ->
+            def json = new StreamingJsonBuilder(w)
+            json.authors it, { Author author ->
+                name author.name
+            }
+
+            assert w.toString() == '{"authors":[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]}'
+        }
+    }
+
+    void testMethodWithArrayAndClosure() {
+        def authors = [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")]
+
+
+        new StringWriter().with { w ->
+            def json = new StreamingJsonBuilder(w)
+            json.authors authors as Author[], { Author author ->
+                name author.name
+            }
+
+            assert w.toString() == '{"authors":[{"name":"Guillaume"},{"name":"Jochen"},{"name":"Paul"}]}'
+        }
+    }
+
     void testMethodWithCollectionAndClosure() {
         def authors = [new Author(name: "Guillaume"), new Author(name: "Jochen"), new Author(name: "Paul")]
 


[6/7] groovy git commit: GROOVY-7708 - StreamingJsonBuilder - improve @CompileStatic support (closes #209)

Posted by jw...@apache.org.
GROOVY-7708 - StreamingJsonBuilder - improve @CompileStatic support (closes #209)


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

Branch: refs/heads/GROOVY_2_4_X
Commit: ae9a433a17df5e0c1336cb5559edb8da33e8f550
Parents: 7bf4390
Author: graemerocher <gr...@gmail.com>
Authored: Wed Dec 9 14:49:15 2015 +0100
Committer: John Wagenleitner <jw...@apache.org>
Committed: Fri Dec 11 14:41:42 2015 -0800

----------------------------------------------------------------------
 .../main/java/groovy/json/StreamingJsonBuilder.java | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/ae9a433a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
----------------------------------------------------------------------
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 7290d52..0f6d41a 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
@@ -587,7 +587,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, Closure c) throws IOException {
+        public void call(String name, Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
             writeName(name);
             writeObjects(coll, c);
         }
@@ -595,7 +595,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
         /**
          * Delegates to {@link #call(String, Iterable, Closure)}
          */
-        public void call(String name, Collection coll, Closure c) throws IOException {
+        public void call(String name, Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure c) throws IOException {
             call(name, (Iterable)coll, c);
         }
 
@@ -696,11 +696,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, Closure closure) throws IOException {
+        public static Object writeCollectionWithClosure(Writer writer, Collection coll, @DelegatesTo(StreamingJsonDelegate.class) Closure closure) throws IOException {
             return writeCollectionWithClosure(writer, (Iterable)coll, closure);
         }
 
-        public static Object writeCollectionWithClosure(Writer writer, Iterable coll, Closure closure) throws IOException {
+        public static Object writeCollectionWithClosure(Writer writer, Iterable coll, @DelegatesTo(StreamingJsonDelegate.class) Closure closure) throws IOException {
             writer.write(JsonOutput.OPEN_BRACKET);
             boolean first = true;
             for (Object it : coll) {
@@ -723,12 +723,12 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             writer.write(JsonOutput.CLOSE_BRACE);
         }
 
-        public static void cloneDelegateAndGetContent(Writer w, Closure c)
+        public static void cloneDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c)
         {
             cloneDelegateAndGetContent(w, c, true);
         }
 
-        public static void cloneDelegateAndGetContent(Writer w, Closure c, boolean first) {
+        public static void cloneDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c, boolean first) {
             StreamingJsonDelegate delegate = new StreamingJsonDelegate(w, first);
             Closure cloned = (Closure) c.clone();
             cloned.setDelegate(delegate);
@@ -736,11 +736,11 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
             cloned.call();
         }
 
-        public static void curryDelegateAndGetContent(Writer w, Closure c, Object o) {
+        public static void curryDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c, Object o) {
             curryDelegateAndGetContent(w, c, o, true);
         }
 
-        public static void curryDelegateAndGetContent(Writer w, Closure c, Object o, boolean first) {
+        public static void curryDelegateAndGetContent(Writer w, @DelegatesTo(StreamingJsonDelegate.class) Closure c, Object o, boolean first) {
             StreamingJsonDelegate delegate = new StreamingJsonDelegate(w, first);
             Closure curried = c.curry(o);
             curried.setDelegate(delegate);


[7/7] groovy git commit: GROOVY-7707 - StreamingJsonBuilder - writing unescaped output doesn't reset state (closes #210)

Posted by jw...@apache.org.
GROOVY-7707 - StreamingJsonBuilder - writing unescaped output doesn't reset state (closes #210)


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

Branch: refs/heads/GROOVY_2_4_X
Commit: 33319ff6a61f248cc9e82ccfa28a847740ce0458
Parents: ae9a433
Author: graemerocher <gr...@gmail.com>
Authored: Thu Dec 10 14:46:12 2015 +0100
Committer: John Wagenleitner <jw...@apache.org>
Committed: Fri Dec 11 14:41:43 2015 -0800

----------------------------------------------------------------------
 .../main/java/groovy/json/StreamingJsonBuilder.java |  1 +
 .../groovy/json/StreamingJsonBuilderTest.groovy     | 16 +++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/33319ff6/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
----------------------------------------------------------------------
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 0f6d41a..193a088 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/StreamingJsonBuilder.java
@@ -647,6 +647,7 @@ public class StreamingJsonBuilder extends GroovyObjectSupport {
          */
         public void call(String name, JsonOutput.JsonUnescaped json) throws IOException {
             writeName(name);
+            verifyValue();
             writer.write(json.toString());
         }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/33319ff6/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy b/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
index f37e8ee..41b8841 100644
--- a/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
+++ b/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
@@ -93,8 +93,22 @@ class StreamingJsonBuilderTest extends GroovyTestCase {
             new StreamingJsonBuilder(w).call {
                 a 1
                 b JsonOutput.unescaped('{"name":"Fred"}')
+                c 3
             }
-            assert w.toString() == '{"a":1,"b":{"name":"Fred"}}'
+            assert w.toString() == '{"a":1,"b":{"name":"Fred"},"c":3}'
+        }
+    }
+
+
+    @CompileStatic
+    void testUnescapedJsonCompileStatic() {
+        new StringWriter().with { w ->
+            new StreamingJsonBuilder(w).call {
+                call 'a', 1
+                call 'b', JsonOutput.unescaped('{"name":"Fred"}')
+                call 'c', 3
+            }
+            assert w.toString() == '{"a":1,"b":{"name":"Fred"},"c":3}'
         }
     }