sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jus...@apache.org
Subject svn commit: r894698 - in /sling/trunk: ./ bundles/commons/json/ bundles/commons/json/src/main/java/org/apache/sling/commons/json/groovy/ bundles/commons/json/src/test/groovy/ bundles/commons/json/src/test/groovy/org/ bundles/commons/json/src/test/groov...
Date Wed, 30 Dec 2009 19:34:32 GMT
Author: justin
Date: Wed Dec 30 19:34:31 2009
New Revision: 894698

URL: http://svn.apache.org/viewvc?rev=894698&view=rev
Log:
SLING-1257 - adding a Groovy Builder for producing JSON documents

Added:
    sling/trunk/bundles/commons/json/src/main/java/org/apache/sling/commons/json/groovy/
    sling/trunk/bundles/commons/json/src/main/java/org/apache/sling/commons/json/groovy/JSONGroovyBuilder.java
    sling/trunk/bundles/commons/json/src/test/groovy/
    sling/trunk/bundles/commons/json/src/test/groovy/org/
    sling/trunk/bundles/commons/json/src/test/groovy/org/apache/
    sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/
    sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/commons/
    sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/commons/json/
    sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/commons/json/groovy/
    sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/commons/json/groovy/JSONGroovyBuilderTest.groovy
    sling/trunk/bundles/commons/json/src/test/java/org/apache/sling/commons/json/test/
    sling/trunk/bundles/commons/json/src/test/java/org/apache/sling/commons/json/test/JSONAssert.java
    sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/JSONGroovyBuilderIntegrationTest.java
    sling/trunk/launchpad/testing/src/test/resources/integration-test/builder.groovy
Modified:
    sling/trunk/bundles/commons/json/pom.xml
    sling/trunk/launchpad/builder/src/main/bundles/list.xml
    sling/trunk/parent/pom.xml
    sling/trunk/pom.xml

Modified: sling/trunk/bundles/commons/json/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/json/pom.xml?rev=894698&r1=894697&r2=894698&view=diff
==============================================================================
--- sling/trunk/bundles/commons/json/pom.xml (original)
+++ sling/trunk/bundles/commons/json/pom.xml Wed Dec 30 19:34:31 2009
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>8</version>
+        <version>9-SNAPSHOT</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 
@@ -48,12 +48,25 @@
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
+                        <Import-Package>groovy.*;resolution:=optional,*</Import-Package>
                         <Export-Package>
                             org.apache.sling.commons.json.*;version=${pom.version}
                         </Export-Package>
                     </instructions>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.codehaus.groovy.maven</groupId>
+                <artifactId>gmaven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>testCompile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
 
@@ -63,6 +76,11 @@
         <artifactId>jcr</artifactId>
       </dependency>
       <dependency>
+      	<groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-all</artifactId>
+        <version>1.6.0</version>
+      </dependency>
+      <dependency>
         <groupId>org.apache.sling</groupId>
         <artifactId>org.apache.sling.commons.testing</artifactId>
         <version>2.0.2-incubator</version>
@@ -72,5 +90,16 @@
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
       </dependency>
+      <dependency>
+      	<groupId>org.slf4j</groupId>
+      	<artifactId>slf4j-api</artifactId>
+      	<version>1.5.2</version>
+      </dependency>
+      <dependency>
+      	<groupId>org.slf4j</groupId>
+      	<artifactId>slf4j-simple</artifactId>
+      	<version>1.5.2</version>
+      	<scope>test</scope>
+      </dependency>
     </dependencies>
 </project>

Added: sling/trunk/bundles/commons/json/src/main/java/org/apache/sling/commons/json/groovy/JSONGroovyBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/json/src/main/java/org/apache/sling/commons/json/groovy/JSONGroovyBuilder.java?rev=894698&view=auto
==============================================================================
--- sling/trunk/bundles/commons/json/src/main/java/org/apache/sling/commons/json/groovy/JSONGroovyBuilder.java
(added)
+++ sling/trunk/bundles/commons/json/src/main/java/org/apache/sling/commons/json/groovy/JSONGroovyBuilder.java
Wed Dec 30 19:34:31 2009
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.json.groovy;
+
+import groovy.lang.Closure;
+import groovy.util.BuilderSupport;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Groovy builder for JSON values.
+ *
+ * Based on code written by Andres Almiray <aalmiray@users.sourceforge.net> as
+ * part of the json-lib project - http://json-lib.sourceforge.net/
+ */
+public class JSONGroovyBuilder extends BuilderSupport {
+
+    /**
+     * The string 'json' which indicates that the root node should be used
+     * as-is. Otherwise, the root node is wrapped in a JSON object.
+     */
+    private static final String JSON = "json";
+
+    /**
+     * A logger instance.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(JSONGroovyBuilder.class);
+
+    /**
+     * A stack containing the names of created nodes.
+     */
+    protected Stack<String> nodeNames = new Stack<String>();
+
+    private void addFromMap(JSONObject obj, Map attributes) {
+        for (Iterator it = attributes.keySet().iterator(); it.hasNext();) {
+            String key = (String) it.next();
+            Object value = resolveValue(attributes.get(key));
+
+            try {
+                obj.put(key, value);
+            } catch (JSONException e) {
+            }
+
+        }
+    }
+
+    private Object resolveValue(Object value) {
+        if (value instanceof Map) {
+            JSONObject sub = new JSONObject();
+            addFromMap(sub, (Map) value);
+            value = sub;
+        } else if (value instanceof Closure) {
+            Object oldCurrent = getCurrent();
+            JSONObject sub = new JSONObject();
+            setCurrent(sub);
+            Closure c = (Closure) value;
+            c.setDelegate(this);
+            c.call();
+            setCurrent(oldCurrent);
+            value = sub;
+        } else if (value instanceof List) {
+            value = new JSONArray((List) value);
+        }
+
+        return value;
+    }
+
+    /**
+     * Create a node with the specified name.
+     */
+    @Override
+    protected Object createNode(Object name) {
+        nodeNames.push((String) name);
+        return new JSONObject();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected Object createNode(Object name, Map attributes) {
+        nodeNames.push((String) name);
+        JSONObject obj = new JSONObject();
+        addFromMap(obj, attributes);
+        return obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected Object createNode(Object name, Map attributes, Object value) {
+        nodeNames.push((String) name);
+        if (value instanceof Map) {
+            JSONArray arr = new JSONArray();
+            arr.put(new JSONObject(attributes));
+            arr.put(new JSONObject((Map) value));
+            return arr;
+        } else {
+            nodeNames.pop();
+            logger.warn("Unhandled createNode(O,M,O). Only able to handle cases where value
Object is a Map. name={}, value={}",
+                    new Object[] { name, value });
+            return null;
+        }
+    }
+
+    @Override
+    protected Object createNode(Object name, Object value) {
+        nodeNames.push((String) name);
+        if (value instanceof List) {
+            JSONArray arr = new JSONArray();
+            for (Object obj : (List) value) {
+                arr.put(resolveValue(obj));
+            }
+            return arr;
+        } else if (value instanceof Closure) {
+            Object oldCurrent = getCurrent();
+            JSONObject obj = new JSONObject();
+            setCurrent(obj);
+            Closure c = (Closure) value;
+            c.setDelegate(this);
+            c.call();
+            setCurrent(oldCurrent);
+            return obj;
+        } else if (value instanceof String) {
+            return value;
+        } else if (value instanceof Number) {
+            return value;
+        } else if (value instanceof Boolean) {
+            return value;
+        } else {
+            System.err.println("Unhandlable class: " + value.getClass());
+            nodeNames.pop();
+            return null;
+        }
+    }
+
+    /**
+     * Add the child node to the parent, using the name at the top of the node
+     * names stack.
+     *
+     * @param parent the parent node
+     * @param child the child node
+     */
+    @Override
+    protected void setParent(Object parent, Object child) {
+        if (!nodeNames.isEmpty()) {
+            try {
+                ((JSONObject) parent).accumulate(nodeNames.pop(), child);
+            } catch (JSONException e) {
+            }
+        }
+    }
+
+    /**
+     * On the completion of the top-level node, if the node name isn't 'json',
+     * create a container object.
+     *
+     * @param parent the parent node
+     * @param child the node which was just created
+     */
+    @Override
+    protected Object postNodeCompletion(Object parent, Object node) {
+        if (parent == null && !nodeNames.empty()) {
+            String rootName = nodeNames.pop();
+            if (!JSON.equals(rootName)) {
+                JSONObject obj = new JSONObject();
+                try {
+                    return obj.put(rootName, node);
+                } catch (JSONException e) {
+                    logger.error("Unable to create container JSON Object", e);
+                    return super.postNodeCompletion(parent, node);
+                }
+            } else {
+                return super.postNodeCompletion(parent, node);
+            }
+        } else {
+            return super.postNodeCompletion(parent, node);
+        }
+    }
+
+    protected boolean log = false;
+
+}

Added: sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/commons/json/groovy/JSONGroovyBuilderTest.groovy
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/commons/json/groovy/JSONGroovyBuilderTest.groovy?rev=894698&view=auto
==============================================================================
--- sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/commons/json/groovy/JSONGroovyBuilderTest.groovy
(added)
+++ sling/trunk/bundles/commons/json/src/test/groovy/org/apache/sling/commons/json/groovy/JSONGroovyBuilderTest.groovy
Wed Dec 30 19:34:31 2009
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.json.groovy;
+
+import org.apache.sling.commons.json.*;
+import org.apache.sling.commons.json.test.*;
+
+/**
+ * Test of JSONGroovyBuilder.
+ *
+ * Based on code written by Andres Almiray <aalmiray@users.sourceforge.net> as
+ * part of the json-lib project - http://json-lib.sourceforge.net/
+ */
+public class JSONGroovyBuilderTest extends GroovyTestCase {
+	JSONGroovyBuilder builder
+
+	void testBuildDefaultRootEmptyObject(){
+		def actual = builder.json {}
+		JSONAssert.assertEquals( new JSONObject(), actual)
+	}
+	void testBuildDefaultRootEmptyArray(){
+		def actual = builder.json ([])
+		JSONAssert.assertEquals( new JSONArray(), actual)
+	}
+	void testBuildDefaultRootObjectWithClosure(){
+		def actual = builder.json {
+			string "json"
+			integer 1
+			bool true
+		}
+		def expected = new JSONObject()
+				.put("string","json")
+				.put("integer",1)
+				.put("bool",true)
+		JSONAssert.assertEquals(expected, actual)
+		assertEquals("json", actual.get("string"))
+	}
+	void testBuildDefaultRootObjectWithMap(){
+		def actual = builder.json([
+		'string': "json",
+		'integer': 1,
+		'bool': true
+		])
+		def expected = new JSONObject()
+				.put("string","json")
+				.put("integer",1)
+				.put("bool",true)
+		JSONAssert.assertEquals(expected, actual)
+	}
+	void testBuildDefaultRootArrayWithList(){
+		def actual = builder.json(["json", 1, true])
+		def expected = new JSONArray()
+				.put("json")
+				.put(1)
+				.put(true)
+		JSONAssert.assertEquals(expected, actual)
+	}
+	void testBuildDefaultRootNestedObjects(){
+		def actual = builder.json {
+			first { integer 42 }
+			second { integer 48 }
+		}
+		def expected = new JSONObject()
+				.put( "first", new JSONObject().put("integer",42) )
+				.put( "second", new JSONObject().put("integer",48) )
+		JSONAssert.assertEquals(expected, actual)
+	}
+	void testBuildObjectWithMaps(){
+		def actual = builder.json {
+			books {
+				book ([title: "The Definitive Guide to Grails", author: "Graeme Rocher"])
+				book ([title: "Groovy in Action", author: "Dierk Konig"])
+			}
+		}
+		def expected = new JSONObject()
+				.put( "books", new JSONObject()
+				.put( "book", new JSONObject()
+				.put("title", "The Definitive Guide to Grails")
+				.put("author", "Graeme Rocher") )
+				.accumulate( "book", new JSONObject()
+				.put("title", "Groovy in Action")
+				.put("author", "Dierk Konig") )
+				)
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testNonDefaultRootName() {
+		def actual = builder.books {
+			book ([title: "The Definitive Guide to Grails", author: "Graeme Rocher"])
+			book ([title: "Groovy in Action", author: "Dierk Konig"])
+		}
+		def expected = new JSONObject()
+				.put("books", new JSONObject()
+				.put("book", new JSONObject()
+				.put("title", "The Definitive Guide to Grails")
+				.put("author", "Graeme Rocher"))
+				.accumulate( "book", new JSONObject()
+				.put("title", "Groovy in Action")
+				.put("author", "Dierk Konig"))
+				)
+		JSONAssert.assertEquals(expected, actual)
+
+	}
+
+
+	void testBuildObjectWithList(){
+		def actual = builder.json {
+			list(
+			[title: "The Definitive Guide to Grails", author: "Graeme Rocher"],
+			[title: "Groovy in Action", author: "Dierk Konig"]
+			)
+		}
+		def expected = new JSONObject().put("list", new JSONArray().
+				put(new JSONObject().put("title", "The Definitive Guide to Grails").put("author", "Graeme
Rocher")).
+				put(new JSONObject().put("title", "Groovy in Action").put("author", "Dierk Konig"))
+
+				)
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObjectWithClosures(){
+		def actual = builder.json {
+			books {
+				book  {
+					title  "The Definitive Guide to Grails"
+					author "Graeme Rocher"
+				}
+				book  {
+					title  "Groovy in Action"
+					author  "Dierk Konig"
+				}
+			}
+		}
+		def expected = new JSONObject()
+				.put( "books", new JSONObject()
+				.put( "book", new JSONObject()
+				.put("title", "The Definitive Guide to Grails")
+				.put("author", "Graeme Rocher") )
+				.accumulate( "book", new JSONObject()
+				.put("title", "Groovy in Action")
+				.put("author", "Dierk Konig") )
+				)
+
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObjectWithClosures2(){
+		def actual = builder.json {
+			books {
+				2.times {
+					book {
+						title "The Definitive Guide to Grails"
+						author "Graeme Rocher"
+					}
+				}
+			}
+		}
+		def expected = new JSONObject()
+				.put( "books", new JSONObject()
+				.put( "book", new JSONObject()
+				.put("title", "The Definitive Guide to Grails")
+				.put("author", "Graeme Rocher") )
+				.accumulate( "book", new JSONObject()
+				.put("title", "The Definitive Guide to Grails")
+				.put("author", "Graeme Rocher") )
+				)
+
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObjectWithClosures3(){
+		def actual = builder.json{
+			books {
+				book {
+					title "The Definitive Guide to Grails"
+					author "Graeme Rocher"
+				}
+				book {
+					title "Groovy in Action"
+					author "Dierk Konig"
+				}
+			}
+		}
+		def expected = new JSONObject()
+				.put( "books", new JSONObject()
+				.put( "book", new JSONObject()
+				.put("title", "The Definitive Guide to Grails")
+				.put("author", "Graeme Rocher") )
+				.accumulate( "book", new JSONObject()
+				.put("title", "Groovy in Action")
+				.put("author", "Dierk Konig") )
+				)
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObjectWithMultipleClosures(){
+		def actual = builder.json {
+			books ([{
+				title "The Definitive Guide to Grails"
+				author "Graeme Rocher"
+			}, {
+				title "Groovy in Action"
+				author "Dierk Konig"
+			}])
+		}
+		def expected = new JSONObject()
+				.put( "books", new JSONArray()
+				.put( new JSONObject()
+				.put("title", "The Definitive Guide to Grails")
+				.put("author", "Graeme Rocher") )
+				.put( new JSONObject()
+				.put("title", "Groovy in Action")
+				.put("author", "Dierk Konig") )
+				)
+
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObject_Map_with_Closure(){
+		def actual = builder.json([object:{key "value"}])
+		def expected = new JSONObject()
+				.put( "object", new JSONObject()
+				.put( "key", "value" )
+				)
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObject_Map_with_Map(){
+		def actual = builder.json([object:[key:"value"]])
+		def expected = new JSONObject()
+				.put( "object", new JSONObject()
+				.put( "key", "value" )
+				)
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObject_Map_with_List(){
+		def actual = builder.json([object: [1,2,3]])
+		def expected = new JSONObject()
+				.put( "object", [1,2,3] )
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObject_List_with_Closure(){
+		def actual = builder.json([{key "value"}])
+		def expected = new JSONArray()
+				.put( new JSONObject()
+				.put( "key", "value" )
+				)
+		JSONAssert.assertEquals(expected, actual)
+	}
+	void testBuildObject_List_with_Map(){
+		def actual = builder.json([[key:"value"]])
+		def expected = new JSONArray()
+				.put( new JSONObject()
+				.put( "key", "value" )
+				)
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObject_List_with_List(){
+		def actual = builder.json([[1,2,3]])
+		def expected = new JSONArray()
+				.put( [1,2,3] )
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObject_Method_with_Map(){
+		def actual = builder.json {
+			node( ['key':"value"] )
+		}
+		def expected = new JSONObject()
+				.put( "node", new JSONObject().put("key","value") )
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObject_Method_with_List(){
+		def actual = builder.json {
+			node( [1,2,3] )
+		}
+		def expected = new JSONObject()
+				.put( "node", new JSONArray([1,2,3]) )
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	void testBuildObject_Method_with_Map_multipleArgs(){
+		def actual = builder.json {
+			node( ['key':"value"], ['key':"value"] )
+		}
+		def expected = new JSONObject()
+				.put( "node", new JSONArray()
+				.put( new JSONObject().put("key","value") )
+				.put( new JSONObject().put("key","value") )
+				)
+		JSONAssert.assertEquals(expected, actual)
+	}
+
+	protected void setUp(){
+		builder = new JSONGroovyBuilder()
+	}
+}
\ No newline at end of file

Added: sling/trunk/bundles/commons/json/src/test/java/org/apache/sling/commons/json/test/JSONAssert.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/json/src/test/java/org/apache/sling/commons/json/test/JSONAssert.java?rev=894698&view=auto
==============================================================================
--- sling/trunk/bundles/commons/json/src/test/java/org/apache/sling/commons/json/test/JSONAssert.java
(added)
+++ sling/trunk/bundles/commons/json/src/test/java/org/apache/sling/commons/json/test/JSONAssert.java
Wed Dec 30 19:34:31 2009
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.json.test;
+
+import java.util.Iterator;
+
+import junit.framework.Assert;
+
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+
+/**
+ * Provides assertions on equality for JSON Arrays and Objects.
+ * 
+ * Based on code written by Andres Almiray <aalmiray@users.sourceforge.net> as
+ * part of the json-lib project - http://json-lib.sourceforge.net/
+ */
+public class JSONAssert extends Assert {
+	/**
+	 * Asserts that two JSONArrays are equal.
+	 */
+	public static void assertEquals(JSONArray expected, JSONArray actual)
+			throws JSONException {
+		assertEquals(null, expected, actual);
+	}
+
+	/**
+	 * Asserts that two JSONObjects are equal.
+	 */
+	public static void assertEquals(JSONObject expected, JSONObject actual)
+			throws JSONException {
+		assertEquals(null, expected, actual);
+	}
+
+	/**
+	 * Asserts that two JSONArrays are equal.
+	 */
+	public static void assertEquals(String message, JSONArray expected,
+			JSONArray actual) throws JSONException {
+		String header = message == null ? "" : message + ": ";
+		if (expected == null) {
+			fail(header + "expected array was null");
+		}
+		if (actual == null) {
+			fail(header + "actual array was null");
+		}
+		if (expected == actual || expected.equals(actual)) {
+			return;
+		}
+		if (actual.length() != expected.length()) {
+			fail(header + "arrays sizes differed, expected.length()="
+					+ expected.length() + " actual.length()=" + actual.length());
+		}
+
+		int max = expected.length();
+		for (int i = 0; i < max; i++) {
+			Object o1 = expected.get(i);
+			Object o2 = actual.get(i);
+
+			// handle nulls
+			if (JSONObject.NULL.equals(o1)) {
+				if (JSONObject.NULL.equals(o2)) {
+					continue;
+				} else {
+					fail(header + "arrays first differed at element [" + i
+							+ "];");
+				}
+			} else {
+				if (JSONObject.NULL.equals(o2)) {
+					fail(header + "arrays first differed at element [" + i
+							+ "];");
+				}
+			}
+
+			if (o1 instanceof JSONArray && o2 instanceof JSONArray) {
+				JSONArray e = (JSONArray) o1;
+				JSONArray a = (JSONArray) o2;
+				assertEquals(header + "arrays first differed at element " + i
+						+ ";", e, a);
+			} else if (o1 instanceof JSONObject && o2 instanceof JSONObject) {
+				assertEquals(header + "arrays first differed at element [" + i
+						+ "];", (JSONObject) o1, (JSONObject) o2);
+			} else if (o1 instanceof String) {
+				assertEquals(header + "arrays first differed at element [" + i
+						+ "];", (String) o1, String.valueOf(o2));
+			} else if (o2 instanceof String) {
+				assertEquals(header + "arrays first differed at element [" + i
+						+ "];", String.valueOf(o1), (String) o2);
+			} else {
+				assertEquals(header + "arrays first differed at element [" + i
+						+ "];", o1, o2);
+			}
+		}
+	}
+
+	/**
+	 * Asserts that two JSONObjects are equal.
+	 */
+	public static void assertEquals(String message, JSONObject expected,
+			JSONObject actual) throws JSONException {
+		String header = message == null ? "" : message + ": ";
+		if (expected == null) {
+			fail(header + "expected object was null");
+		}
+		if (actual == null) {
+			fail(header + "actual object was null");
+		}
+		if (expected == actual /* || expected.equals( actual ) */) {
+			return;
+		}
+
+		JSONArray expectedNames = expected.names();
+		JSONArray actualNames = actual.names();
+
+		if (expectedNames == null && actualNames == null) {
+			return;
+		}
+
+		if (expectedNames == null) {
+		    expectedNames = new JSONArray();
+		}
+		
+		if (actualNames == null) {
+		    actualNames = new JSONArray();
+		}
+
+		assertEquals(header
+				+ "names sizes differed, expected.names().length()="
+				+ expectedNames.length() + " actual.names().length()="
+				+ actualNames.length(), expectedNames.length(), actualNames
+				.length());
+		for (Iterator<String> keys = expected.keys(); keys.hasNext();) {
+			String key = (String) keys.next();
+			Object o1 = expected.opt(key);
+			Object o2 = actual.opt(key);
+
+			if (JSONObject.NULL.equals(o1)) {
+				if (JSONObject.NULL.equals(o2)) {
+					continue;
+				} else {
+					fail(header + "objects differed at key [" + key + "];");
+				}
+			} else {
+				if (JSONObject.NULL.equals(o2)) {
+					fail(header + "objects differed at key [" + key + "];");
+				}
+			}
+
+			if (o1 instanceof JSONObject && o2 instanceof JSONObject) {
+				assertEquals(header + "objects differed at key [" + key + "];",
+						(JSONObject) o1, (JSONObject) o2);
+			} else if (o1 instanceof JSONArray && o2 instanceof JSONArray) {
+				assertEquals(header + "objects differed at key [" + key + "];",
+						(JSONArray) o1, (JSONArray) o2);
+			} else if (o1 instanceof String) {
+				assertEquals(header + "objects differed at key [" + key + "];",
+						(String) o1, String.valueOf(o2));
+			} else if (o2 instanceof String) {
+				assertEquals(header + "objects differed at key [" + key + "];",
+						String.valueOf(o1), (String) o2);
+			} else {
+				assertEquals(header + "objects differed at key [" + key + "];",
+						o1, o2);
+			}
+		}
+	}
+
+}

Modified: sling/trunk/launchpad/builder/src/main/bundles/list.xml
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/builder/src/main/bundles/list.xml?rev=894698&r1=894697&r2=894698&view=diff
==============================================================================
--- sling/trunk/launchpad/builder/src/main/bundles/list.xml (original)
+++ sling/trunk/launchpad/builder/src/main/bundles/list.xml Wed Dec 30 19:34:31 2009
@@ -164,7 +164,7 @@
 		<bundle>
 			<groupId>org.apache.sling</groupId>
 			<artifactId>org.apache.sling.commons.json</artifactId>
-			<version>2.0.4-incubator</version>
+			<version>2.0.5-SNAPSHOT</version>
 		</bundle>
 		<bundle>
 			<groupId>org.apache.felix</groupId>

Added: sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/JSONGroovyBuilderIntegrationTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/JSONGroovyBuilderIntegrationTest.java?rev=894698&view=auto
==============================================================================
--- sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/JSONGroovyBuilderIntegrationTest.java
(added)
+++ sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/JSONGroovyBuilderIntegrationTest.java
Wed Dec 30 19:34:31 2009
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.launchpad.webapp.integrationtest;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+import org.apache.sling.servlets.post.SlingPostConstants;
+
+public class JSONGroovyBuilderIntegrationTest extends RenderingTestBase {
+
+    private String slingResourceType;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // set test values
+        slingResourceType = "integration-test/srt." + System.currentTimeMillis();
+        testText = "This is a test " + System.currentTimeMillis();
+
+        // create the test node, under a path that's specific to this class to allow collisions
+        final String url = HTTP_BASE_URL + "/" + getClass().getSimpleName() + "/" + System.currentTimeMillis()
+ SlingPostConstants.DEFAULT_CREATE_SUFFIX;
+        final Map<String,String> props = new HashMap<String,String>();
+        props.put("sling:resourceType", slingResourceType);
+        props.put("text", testText);
+        displayUrl = testClient.createNode(url, props);
+
+        // the rendering script goes under /apps in the repository
+        scriptPath = "/apps/" + slingResourceType;
+        testClient.mkdirs(WEBDAV_BASE_URL, scriptPath);
+    }
+
+    public void testJSONGroovyBuilder() throws IOException, JSONException {
+        final String toDelete = uploadTestScript("builder.groovy","json.groovy");
+        try {
+            final String content = getContent(displayUrl + ".json", CONTENT_TYPE_JSON);
+            JSONObject jo = new JSONObject(content);
+            assertEquals("Content contained wrong number of items", 1, jo.length());
+            assertEquals("Content contained wrong key", "text", jo.keys().next());
+            assertEquals("Content contained wrong data", testText, jo.get("text"));
+        } finally {
+            testClient.delete(toDelete);
+        }
+    }
+}

Added: sling/trunk/launchpad/testing/src/test/resources/integration-test/builder.groovy
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/testing/src/test/resources/integration-test/builder.groovy?rev=894698&view=auto
==============================================================================
--- sling/trunk/launchpad/testing/src/test/resources/integration-test/builder.groovy (added)
+++ sling/trunk/launchpad/testing/src/test/resources/integration-test/builder.groovy Wed Dec
30 19:34:31 2009
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+builder = new org.apache.sling.commons.json.groovy.JSONGroovyBuilder()
+
+out.write builder.json {
+    text currentNode.getProperty("text").string
+} as String

Modified: sling/trunk/parent/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/parent/pom.xml?rev=894698&r1=894697&r2=894698&view=diff
==============================================================================
--- sling/trunk/parent/pom.xml (original)
+++ sling/trunk/parent/pom.xml Wed Dec 30 19:34:31 2009
@@ -51,7 +51,7 @@
         <site.javadoc.exclude />
         <organization.logo>http://sling.apache.org/site/media.data/logo.png</organization.logo>
     </properties>
-    
+
 
     <scm>
         <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/parent</connection>
@@ -157,7 +157,7 @@
                             <tasks>
                                 <echo>
 ********************** WARNING (SLING-443) **********************************
-On most platforms, building Apache Sling currently requires setting 
+On most platforms, building Apache Sling currently requires setting
 MAVEN_OPTS="-Xmx256M", see https://issues.apache.org/jira/browse/SLING-443
 You might get a "java.lang.OutOfMemoryError: Java heap space" if that
 setting is not correct.
@@ -297,6 +297,11 @@
                     <artifactId>apache-rat-plugin</artifactId>
                     <version>0.6</version>
                 </plugin>
+                <plugin>
+                    <groupId>org.codehaus.groovy.maven</groupId>
+                    <artifactId>gmaven-plugin</artifactId>
+                    <version>1.0</version>
+                </plugin>
             </plugins>
         </pluginManagement>
     </build>
@@ -371,7 +376,7 @@
 	    We should execute this profile manually to make sure that all files in our source code
contain proper licenses.
 	    This is very important and should not be skipped in any scenario.  It is very importnt
for us to follow ASF policy.
 	    Example:  mvn -P prepare-release install
-	    -->    
+	    -->
         <profile>
             <id>rat</id>
             <build>
@@ -447,7 +452,7 @@
         </mailingList>
     </mailingLists>
 
-    <!-- Please visit our website for the current information about the 
+    <!-- Please visit our website for the current information about the
          Apache Sling project team. (see #SLING-1120 why we don't include
          the list here) -->
     <developers>

Modified: sling/trunk/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/pom.xml?rev=894698&r1=894697&r2=894698&view=diff
==============================================================================
--- sling/trunk/pom.xml (original)
+++ sling/trunk/pom.xml Wed Dec 30 19:34:31 2009
@@ -124,9 +124,9 @@
 
         <!-- Launchpad -->
         <module>launchpad/base</module>
+        <module>launchpad/content</module>
         <module>launchpad/builder</module>
         <module>launchpad/bundles</module>
-        <module>launchpad/content</module>
         <module>launchpad/app</module>
         <module>launchpad/webapp</module>
 



Mime
View raw message