incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r591347 - in /incubator/sling/trunk/microsling/microsling-core: ./ src/main/java/org/apache/sling/microsling/helpers/json/ src/main/java/org/apache/sling/microsling/slingservlets/renderers/ src/test/java/org/apache/sling/microsling/integrat...
Date Fri, 02 Nov 2007 14:32:24 GMT
Author: bdelacretaz
Date: Fri Nov  2 07:32:24 2007
New Revision: 591347

URL: http://svn.apache.org/viewvc?rev=591347&view=rev
Log:
SLING-93 - JsonItemWriter implemented using the sling-json JSONWriter. Tests in JsonRenderingTest
need more work

Added:
    incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/JsonRenderingTest.java
  (with props)
Modified:
    incubator/sling/trunk/microsling/microsling-core/README.txt
    incubator/sling/trunk/microsling/microsling-core/pom.xml
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/helpers/json/JsonItemWriter.java
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java

Modified: incubator/sling/trunk/microsling/microsling-core/README.txt
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/README.txt?rev=591347&r1=591346&r2=591347&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/README.txt (original)
+++ incubator/sling/trunk/microsling/microsling-core/README.txt Fri Nov  2 07:32:24 2007
@@ -26,11 +26,14 @@
 
 I'm currently using revision 583722 for my tests.
 
-3) Build the sling-api
+3) Build the sling-api and sling-json modules
 
   cd sling/sling-api
   mvn clean install
 
+  cd sling/json
+  mvn clean install
+  
 4) Run the microsling tests:
 
   cd sling/microsling/microsling-core

Modified: incubator/sling/trunk/microsling/microsling-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/pom.xml?rev=591347&r1=591346&r2=591347&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/pom.xml (original)
+++ incubator/sling/trunk/microsling/microsling-core/pom.xml Fri Nov  2 07:32:24 2007
@@ -61,6 +61,11 @@
       <version>2.0.0-incubator-SNAPSHOT</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>sling-json</artifactId>
+      <version>2.0.0-incubator-SNAPSHOT</version>
+    </dependency>
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>3.8.1</version>

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/helpers/json/JsonItemWriter.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/helpers/json/JsonItemWriter.java?rev=591347&r1=591346&r2=591347&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/helpers/json/JsonItemWriter.java
(original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/helpers/json/JsonItemWriter.java
Fri Nov  2 07:32:24 2007
@@ -16,9 +16,6 @@
  */
 package org.apache.sling.microsling.helpers.json;
 
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.io.Writer;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -32,8 +29,14 @@
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
 
-/** Dumps JCR Items as JSON data */
+import org.apache.sling.json.JSONException;
+import org.apache.sling.json.io.JSONWriter;
+
+/** Dumps JCR Items as JSON data. The dump methods
+ *  are threadsafe.
+ */
 public class JsonItemWriter {
     final Set<String> propertyNamesToIgnore;
 
@@ -45,25 +48,29 @@
         this.propertyNamesToIgnore = propertyNamesToIgnore;
     }
 
-    /** Dump all Nodes of given NodeIterator in JSON */
-    public void dump(NodeIterator it, PrintWriter out)
-            throws RepositoryException {
-        boolean first = true;
-        out.println("[");
+    /** Dump all Nodes of given NodeIterator in JSON 
+     * @throws JSONException */
+    public void dump(NodeIterator it, Writer out) throws RepositoryException, JSONException
{
+        final JSONWriter w = new JSONWriter(out);
+        w.array();
         while (it.hasNext()) {
-            dumpSingleNode(it.nextNode(), out, 1, 0, first);
-            first = false;
+            dumpSingleNode(it.nextNode(), w, 1, 0);
         }
-        out.println("]");
+        w.endArray();
     }
 
-    /** Dump given node in JSON, optionally recursing into its child nodes */
-    public void dump(Node node, PrintWriter out, int currentRecursionLevel,
-            int maxRecursionLevels) throws RepositoryException {
+    /** Dump given node in JSON, optionally recursing into its child nodes */ 
+    public void dump(Node node, Writer w, int maxRecursionLevels) throws RepositoryException,
JSONException {
+        dump(node, new JSONWriter(w), 0, maxRecursionLevels);
+    }
+    
+    /** Dump given node in JSON, optionally recursing into its child nodes */ 
+    protected void dump(Node node, JSONWriter w, int currentRecursionLevel, int maxRecursionLevels)

+    throws RepositoryException, JSONException {
+        
+        w.object();
         PropertyIterator props = node.getProperties();
 
-        boolean first = true;
-
         // the node's actual properties
         while (props.hasNext()) {
             Property prop = props.nextProperty();
@@ -73,233 +80,65 @@
             }
 
             if (!prop.getDefinition().isMultiple()) {
-                if (!(prop.getType() == PropertyType.BINARY)) {
-                    writeProperty(out, currentRecursionLevel, prop.getName(),
-                            stringValue(prop, prop.getValue()), first);
-                    first = false;
-                }
+                writeProperty(w, currentRecursionLevel, prop);
             } else {
-                if (!(prop.getType() == PropertyType.BINARY)) {
-                    out.print(first ? "" : ",\r\n");
-                    first = false;
-                    indent(out, currentRecursionLevel);
-                    Value[] vals = prop.getValues();
-                    int i = 0;
-                    boolean firstval = true;
-                    out.print("\"" + prop.getName() + "\":[");
-                    while (i < vals.length) {
-                        if (!firstval) {
-                            out.print(",");
-                        }
-                        firstval = false;
-                        out.print("\"" + escape(stringValue(prop, vals[i]))
-                                + "\"");
-                        i++;
-                    }
-                    out.print("]");
+                w.array();
+                for(Value v : prop.getValues()) {
+                    w.value(convertValue(v));
                 }
+                w.endArray();
             }
         }
-        NodeIterator nodes = node.getNodes();
-        while (nodes.hasNext()) {
-            Node childnode = nodes.nextNode();
-            out.print(first ? "" : ",\r\n");
-            first = false;
-            dumpSingleNode(childnode, out, currentRecursionLevel, maxRecursionLevels, first);
+        
+        // the child nodes
+        final NodeIterator children = node.getNodes();
+        while(children.hasNext()) {
+            final Node n = children.nextNode();
+            dumpSingleNode(n, w, currentRecursionLevel, maxRecursionLevels);
         }
+        
+        w.endObject();
     }
 
     /** Dump a single node */
-    private void dumpSingleNode(Node n, PrintWriter out,
-            int currentRecursionLevel, int maxRecursionLevels, boolean first)
-            throws RepositoryException {
-        indent(out, currentRecursionLevel);
-        out.print("\"" + n.getName() + "\":");
-        out.println("{");
-        if (maxRecursionLevels == 0
-                || currentRecursionLevel + 1 < maxRecursionLevels) {
-            dump(n, out, currentRecursionLevel + 1, maxRecursionLevels);
-        }
-        out.println("");
-        indent(out, currentRecursionLevel + 1);
-        out.println("}");
-    }
-
-    /**
-     * <p/> escape Java Style.
-     * </p>
-     * 
-     * @param str
-     *            String to escape values in, may be null
-     * @param escapeSingleQuotes
-     *            escapes single quotes if <code>true</code>
-     * @return the escaped string
-     */
-    private String escapeJavaStyleString(String str, boolean escapeSingleQuotes) {
-        if (str == null) {
-            return null;
-        }
-        try {
-            StringWriter writer = new StringWriter(str.length() * 2);
-            escapeJavaStyleString(writer, str, escapeSingleQuotes);
-            return writer.toString();
-        } catch (IOException ioe) {
-            // this should never ever happen while writing to a StringWriter
-            ioe.printStackTrace();
-            return null;
-        }
-    }
-
-    /**
-     * <p/> escape Java Style.
-     * </p>
-     * 
-     * @param out
-     *            write to receieve the escaped string
-     * @param str
-     *            String to escape values in, may be null
-     * @param escapeSingleQuote
-     *            escapes single quotes if <code>true</code>
-     * @throws IOException
-     *             if an IOException occurs
-     */
-    private void escapeJavaStyleString(Writer out, String str,
-            boolean escapeSingleQuote) throws IOException {
-        if (out == null) {
-            throw new IllegalArgumentException("The Writer must not be null");
-        }
-        if (str == null) {
-            return;
-        }
-        int sz;
-        sz = str.length();
-        for (int i = 0; i < sz; i++) {
-            char ch = str.charAt(i);
-
-            // handle unicode
-            if (ch > 0xfff) {
-                out.write("\\u" + hex(ch));
-            } else if (ch > 0xff) {
-                out.write("\\u0" + hex(ch));
-            } else if (ch > 0x7f) {
-                out.write("\\u00" + hex(ch));
-            } else if (ch < 32) {
-                switch (ch) {
-                case '\b':
-                    out.write('\\');
-                    out.write('b');
-                    break;
-                case '\n':
-                    out.write('\\');
-                    out.write('n');
-                    break;
-                case '\t':
-                    out.write('\\');
-                    out.write('t');
-                    break;
-                case '\f':
-                    out.write('\\');
-                    out.write('f');
-                    break;
-                case '\r':
-                    out.write('\\');
-                    out.write('r');
-                    break;
-                default:
-                    if (ch > 0xf) {
-                        out.write("\\u00" + hex(ch));
-                    } else {
-                        out.write("\\u000" + hex(ch));
-                    }
-                    break;
-                }
-            } else {
-                switch (ch) {
-                case '\'':
-                    if (escapeSingleQuote) {
-                        out.write('\\');
-                    }
-                    out.write('\'');
-                    break;
-                case '"':
-                    out.write('\\');
-                    out.write('"');
-                    break;
-                case '\\':
-                    out.write('\\');
-                    out.write('\\');
-                    break;
-                default:
-                    out.write(ch);
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * <p/> Returns an upper case hexadecimal <code>String</code> for the
-     * given character.
-     * </p>
-     * 
-     * @param ch
-     *            The character to convert.
-     * @return An upper case hexadecimal <code>String</code>
-     */
-    private String hex(char ch) {
-        return Integer.toHexString(ch).toUpperCase();
-    }
-
-    /**
-     * outputs spaces per currentRecursionLevel
-     * 
-     * @param out
-     *            printwriter for indentation
-     * @param currentRecursionLevel
-     *            indentation currentRecursionLevel
-     */
-    private void indent(PrintWriter out, int currentRecursionLevel) {
-        int i = 0;
-        while (i++ < currentRecursionLevel) {
-            out.print("  ");
+    protected void dumpSingleNode(Node n, JSONWriter w, int currentRecursionLevel, int maxRecursionLevels)
+    throws RepositoryException, JSONException {
+        w.key(n.getName());
+        if (maxRecursionLevels == 0 || currentRecursionLevel + 1 < maxRecursionLevels)
{
+            dump(n, w, currentRecursionLevel + 1, maxRecursionLevels);
         }
     }
 
     /**
-     * escape String for JSON format
+     * Write a single property
      */
-    private String escape(String orig) {
-        return escapeJavaStyleString(orig, false);
-    }
-
-    /**
-     * write a single property
-     */
-    private void writeProperty(PrintWriter out, int indent, String name,
-            String value, boolean first) {
-        if (!first) {
-            out.println(",");
-        }
-        if (indent > 0) {
-            indent(out, indent);
+    protected void writeProperty(JSONWriter w, int indent, Property p) 
+    throws ValueFormatException, RepositoryException, JSONException {
+        if(p.getType() == PropertyType.BINARY) {
+            // TODO for now we mark binary properties with an initial star in their name
+            // (star is not allowed as a JCR property name)
+            // in the name, and the value should be the size of the binary data
+            w.key("*" + p.getName());
+            
+        } else {
+            w.key(p.getName());
         }
-        out.print("\"" + name + "\":\"" + escape(value) + "\"");
+        
+        w.value(convertValue(p.getValue()));
     }
-
-    /** Convert given Value to a String */
-    private String stringValue(Property prop, Value value)
-            throws RepositoryException {
-        String result = null;
-
-        if (prop.getType() == PropertyType.DATE) {
-            // TODO more flexible format?
+    
+    /** Convert a Value for JSON output */ 
+    protected Object convertValue(Value v) throws ValueFormatException, IllegalStateException,
RepositoryException {
+        if(v.getType() == PropertyType.BINARY) {
+            // TODO return the binary size
+            return new Integer(0);
+            
+        } else if(v.getType() == PropertyType.DATE) {
             final DateFormat fmt = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'Z",
Locale.US);
-            result = fmt.format(value.getDate().getTime());
+            return fmt.format(v.getDate().getTime());
+            
         } else {
-            result = value.getString();
+            return v.getString();
         }
-
-        return result;
     }
-
-}
+}
\ No newline at end of file

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java?rev=591347&r1=591346&r2=591347&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java
(original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java
Fri Nov  2 07:32:24 2007
@@ -17,7 +17,6 @@
 package org.apache.sling.microsling.slingservlets.renderers;
 
 import java.io.IOException;
-import java.io.PrintWriter;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
@@ -29,13 +28,18 @@
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.apache.sling.json.JSONException;
 import org.apache.sling.microsling.helpers.json.JsonItemWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /** A SlingSafeMethodsServlet that renders the current Resource
  *  as simple HTML
  */
 public class JsonRendererServlet extends SlingSafeMethodsServlet {
 
+    private static final Logger log = LoggerFactory.getLogger(JsonRendererServlet.class);
+    
     private static final long serialVersionUID = 5577121546674133317L;
     private final String responseContentType;
     private final JsonItemWriter itemWriter;
@@ -82,18 +86,21 @@
 
         // do the dump
         resp.setContentType(responseContentType);
-        final PrintWriter pw = resp.getWriter();
-        
         try {
-            itemWriter.dump(n,pw,0,maxRecursionLevels);
+            itemWriter.dump(n, resp.getWriter(), maxRecursionLevels);
+        } catch(JSONException je) {
+            reportException(je);
         } catch(RepositoryException re) {
-            throw new HttpStatusCodeException(
-                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-                    re.toString(),
-                    re
-            );
-        } finally {
-            pw.flush();
+            reportException(re);
         }
+    }
+    
+    private void reportException(Exception e) throws HttpStatusCodeException {
+        log.warn("Error in JsonRendererServlet: " + e.toString(),e);
+        throw new HttpStatusCodeException(
+                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                e.toString(),
+                e
+        );
     }
 }

Added: incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/JsonRenderingTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/JsonRenderingTest.java?rev=591347&view=auto
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/JsonRenderingTest.java
(added)
+++ incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/JsonRenderingTest.java
Fri Nov  2 07:32:24 2007
@@ -0,0 +1,88 @@
+/*
+ * 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.microsling.integration;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ScriptableObject;
+
+/** Test creating Nodes and rendering them in JSON */
+public class JsonRenderingTest extends MicroslingHttpTestBase {
+
+    private String testText;
+    private String jsonUrl;
+    
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        // set test values
+        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()
+ ".sling";
+        final Map<String,String> props = new HashMap<String,String>();
+        props.put("text", testText);
+        jsonUrl = testClient.createNode(url, props) + ".json";
+    }
+    
+    /** Evaluate given code using given jsonData as the "data" object */ 
+    protected void assertJavascript(String expectedOutput, String jsonData, String code)
throws IOException {
+        // build the code, something like
+        //  data = <jsonData> ;
+        //  <code>
+        final String jsCode = "data=" + jsonData + ";\n" + code;
+        final Context rhinoContext = Context.enter();
+        final ScriptableObject scope = rhinoContext.initStandardObjects();
+
+        // execute the script, out script variable maps to sw 
+        final StringWriter sw = new StringWriter();
+        final PrintWriter pw = new PrintWriter(sw, true);
+        ScriptableObject.putProperty(scope, "out", Context.javaToJS(pw, scope));
+        final int lineNumber = 1;
+        final Object securityDomain = null;
+        rhinoContext.evaluateString(scope, jsCode, getClass().getSimpleName(), 
+                lineNumber, securityDomain);
+        
+        // check script output
+        pw.flush();
+        final String result = sw.toString().trim();
+        if(!result.equals(expectedOutput)) {
+            fail("Expected '" + expectedOutput + "' but got '" + result + "' for script='"
+ jsCode + "'");
+        }
+    }
+    
+    /** test our assertJavascript method with static json */ 
+    public void testAssertJavascript() throws IOException {
+        final String json = "{ 'a' : '123', 'b' : '456' }";
+        assertJavascript("123456", json ,"out.println(data.a + data.b)");
+    }
+    
+    public void testNonRecursive() throws IOException {
+        final String json = getContent(jsonUrl, CONTENT_TYPE_JSON);
+        assertJavascript(testText, json ,"out.println(data.text)");
+    }
+    
+    public void TODOneedToTestMoreJsonStuff() {
+        // TODO - test recursive JSON retrieval, property filters, etc...
+    }
+ }
\ No newline at end of file

Propchange: incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/JsonRenderingTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/JsonRenderingTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL



Mime
View raw message