You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2011/06/09 11:59:24 UTC

svn commit: r1133761 - in /jackrabbit/sandbox/microkernel/src: main/java/org/apache/jackrabbit/mk/ main/java/org/apache/jackrabbit/mk/json/ test/java/org/apache/jackrabbit/mk/json/ test/resources/ test/resources/org/ test/resources/org/apache/ test/res...

Author: mduerig
Date: Thu Jun  9 09:59:23 2011
New Revision: 1133761

URL: http://svn.apache.org/viewvc?rev=1133761&view=rev
Log:
MicroKernel prototype (WIP)
add JsonBuilder (which does correct stting value escaping)

Added:
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/json/JsonBuilder.java
    jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/json/
    jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/json/JsonBuilderTest.java
    jackrabbit/sandbox/microkernel/src/test/resources/
    jackrabbit/sandbox/microkernel/src/test/resources/org/
    jackrabbit/sandbox/microkernel/src/test/resources/org/apache/
    jackrabbit/sandbox/microkernel/src/test/resources/org/apache/jackrabbit/
    jackrabbit/sandbox/microkernel/src/test/resources/org/apache/jackrabbit/mk/
    jackrabbit/sandbox/microkernel/src/test/resources/org/apache/jackrabbit/mk/json/
    jackrabbit/sandbox/microkernel/src/test/resources/org/apache/jackrabbit/mk/json/test.json
Modified:
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java?rev=1133761&r1=1133760&r2=1133761&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java Thu Jun  9 09:59:23 2011
@@ -20,6 +20,8 @@ import org.apache.jackrabbit.mk.api.Micr
 import org.apache.jackrabbit.mk.api.MicroKernelException;
 import org.apache.jackrabbit.mk.json.DiffHandler;
 import org.apache.jackrabbit.mk.json.DiffParser;
+import org.apache.jackrabbit.mk.json.JsonBuilder;
+import org.apache.jackrabbit.mk.json.JsonBuilder.JsonObjectBuilder;
 import org.apache.jackrabbit.mk.mem.JsopBuilder;
 import org.apache.jackrabbit.mk.mem.JsopTokenizer;
 import org.apache.jackrabbit.mk.store.Commit;
@@ -398,45 +400,35 @@ public class MicroKernelImpl implements 
     //-------------------------------------------------------< implementation >
 
     void toJson(Node node, String name, int depth, boolean metaProps, StringBuilder buf) throws Exception {
-        buf.append("{");
+        toJson(node, name, depth, metaProps, JsonBuilder.create(buf));
+    }
+
+    void toJson(Node node, String name, int depth, boolean metaProps, JsonObjectBuilder builder) throws Exception {
         if (metaProps) {
-            buf.append("\":name\":\"" + name + "\",");
+            builder.value(":name", name);
         }
-        for (Map.Entry prop : node.getProperties().entrySet()) {
-            buf.append('"');
-            buf.append(prop.getKey());
-            buf.append("\":");
-            buf.append(prop.getValue());
-            buf.append(",");
+        for (Map.Entry<String, String> prop : node.getProperties().entrySet()) {
+            builder.value(prop.getKey(), prop.getValue());
         }
 
         long childCount = node.getChildNodeCount();
         if (metaProps) {
-            buf.append("\":childNodeCount\":");
-            buf.append(childCount);
-            buf.append(",");
+            builder.value(":childNodeCount", childCount);
         }
         if (childCount > 0 && depth >= 0) {
             for (Map.Entry<String, String> child : node.getChildNodeEntries().entrySet()) {
-                buf.append('"');
                 String childName = child.getKey();
-                buf.append(childName);
-                buf.append("\":");
+                JsonObjectBuilder childBuilder = builder.object(childName);
                 if (depth > 0) {
                     String childId = child.getValue();
-                    toJson(rep.getStore().getNode(childId), childName, depth - 1, metaProps, buf);
+                    toJson(rep.getStore().getNode(childId), childName, depth - 1, metaProps, childBuilder);
                 }
                 else {
-                    buf.append("{}");
+                    childBuilder.build();
                 }
-                buf.append(',');
             }
         }
-        // trim redundant trailing comma
-        if (buf.charAt(buf.length() - 1) == ',') {
-            buf.deleteCharAt(buf.length() - 1);
-        }
-        buf.append("}");
+        builder.build();
     }
 
     static void addNode(CommitBuilder cb, String path, String name, JSONObject jsonNode) throws Exception {

Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/json/JsonBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/json/JsonBuilder.java?rev=1133761&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/json/JsonBuilder.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/json/JsonBuilder.java Thu Jun  9 09:59:23 2011
@@ -0,0 +1,445 @@
+/*
+ * 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.jackrabbit.mk.json;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * Partially based on json-simple
+ * Limitation: arrays can only have primitive members (i.e. no arrays nor objects)
+ */
+public final class JsonBuilder {
+    private final Appendable writer;
+
+    private JsonBuilder(Appendable writer) {
+        this.writer = writer;
+    }
+
+    public static JsonObjectBuilder create(Appendable writer) throws IOException {
+        return new JsonBuilder(writer).new JsonObjectBuilder(null);
+    }
+
+    public final class JsonObjectBuilder {
+        private final JsonObjectBuilder parent;
+
+        private boolean hasKeys;
+
+        public JsonObjectBuilder(JsonObjectBuilder parent) throws IOException {
+            this.parent = parent;
+            writer.append('{');
+        }
+        
+        public JsonObjectBuilder value(String key, String value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder value(String key, int value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder value(String key, long value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder value(String key, float value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder value(String key, double value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder value(String key, Number value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder value(String key, boolean value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder nil(String key) throws IOException {
+            write(key, "null");
+            return this;
+        }
+
+        public JsonObjectBuilder array(String key, String[] value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder array(String key, int[] value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder array(String key, long[] value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder array(String key, float[] value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder array(String key, double[] value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder array(String key, Number[] value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonObjectBuilder array(String key, boolean[] value) throws IOException {
+            write(key, encode(value));
+            return this;
+        }
+
+        public JsonArrayBuilder array(String key) throws IOException {
+            writeKey(key);
+            return new JsonArrayBuilder(this);
+        }
+
+        public JsonObjectBuilder object(String key) throws IOException {
+            writeKey(key);
+            return new JsonObjectBuilder(this);
+        }
+
+        public JsonObjectBuilder build() throws IOException {
+            writer.append('}');
+            return parent;
+        }
+
+        //------------------------------------------< private >---
+
+        private void optionalComma() throws IOException {
+            if (hasKeys) {
+                writer.append(',');
+            }
+            else {
+                hasKeys = true;
+            }
+        }
+
+        private void writeKey(String key) throws IOException {
+            optionalComma();
+            writer.append(quote(escape(key)));
+            writer.append(':');
+        }
+
+        private void write(String key, String value) throws IOException {
+            writeKey(key);
+            writer.append(value);
+        }
+
+    }
+
+    public final class JsonArrayBuilder {
+        private final JsonObjectBuilder parent;
+
+        private boolean hasValues;
+
+        public JsonArrayBuilder(JsonObjectBuilder parent) throws IOException {
+            writer.append('[');
+            this.parent = parent;
+        }
+
+        public JsonArrayBuilder value(String value) throws IOException {
+            optionalComma();
+            writer.append(encode(value));
+            return this;
+        }
+
+        public JsonArrayBuilder value(int value) throws IOException {
+            optionalComma();
+            writer.append(encode(value));
+            return this;
+        }
+
+        public JsonArrayBuilder value(long value) throws IOException {
+            optionalComma();
+            writer.append(encode(value));
+            return this;
+        }
+
+        public JsonArrayBuilder value(float value) throws IOException {
+            optionalComma();
+            writer.append(encode(value));
+            return this;
+        }
+
+        public JsonArrayBuilder value(double value) throws IOException {
+            optionalComma();
+            writer.append(encode(value));
+            return this;
+        }
+
+        public JsonArrayBuilder value(Number value) throws IOException {
+            optionalComma();
+            writer.append(encode(value));
+            return this;
+        }
+
+        public JsonArrayBuilder value(boolean value) throws IOException {
+            optionalComma();
+            writer.append(encode(value));
+            return this;
+        }
+
+        public JsonArrayBuilder nil() throws IOException {
+            optionalComma();
+            writer.append("null");
+            return this;
+        }
+
+        public JsonObjectBuilder build() throws IOException {
+            writer.append(']');
+            return parent;
+        }
+
+        //------------------------------------------< private >---
+
+        private void optionalComma() throws IOException {
+            if (hasValues) {
+                writer.append(',');
+            }
+            else {
+                hasValues = true;
+            }
+        }
+    }
+
+    /**
+     * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
+     */
+    public static String escape(String string) {
+        if(string == null) {
+            return null;
+        }
+
+        StringBuffer sb = new StringBuffer();
+        for(int i = 0; i < string.length(); i++) {
+            char ch = string.charAt(i);
+            switch(ch) {
+                case '"':
+                    sb.append("\\\"");
+                    break;
+                case '\\':
+                    sb.append("\\\\");
+                    break;
+                case '\b':
+                    sb.append("\\b");
+                    break;
+                case '\f':
+                    sb.append("\\f");
+                    break;
+                case '\n':
+                    sb.append("\\n");
+                    break;
+                case '\r':
+                    sb.append("\\r");
+                    break;
+                case '\t':
+                    sb.append("\\t");
+                    break;
+                case '/':
+                    sb.append("\\/");
+                    break;
+                default:
+                    //Reference: http://www.unicode.org/versions/Unicode5.1.0/
+                    if (ch >= '\u0000' && ch <= '\u001F' ||
+                            ch >= '\u007F' && ch <= '\u009F' ||
+                            ch >= '\u2000' && ch <= '\u20FF') {
+
+                        String ss = Integer.toHexString(ch);
+                        sb.append("\\u");
+                        for (int k = 0; k < 4 - ss.length(); k++) {
+                            sb.append('0');
+                        }
+                        sb.append(ss.toUpperCase());
+                    }
+                    else {
+                        sb.append(ch);
+                    }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    public static String quote(String string) {
+        return '"' + string + '"';
+    }
+
+    public static String encode(String value) {
+        return quote(escape(value));
+    }
+
+    public static String encode(int value) {
+        return Integer.toString(value);
+    }
+
+    public static String encode(long value) {
+        return Long.toString(value);
+    }
+
+    public static String encode(float value) {
+        return Float.isInfinite(value) || Float.isNaN(value)
+            ? "null"
+            : Float.toString(value);
+    }
+
+    public static String encode(double value) {
+        return Double.isInfinite(value) || Double.isNaN(value)
+            ? "null"
+            : Double.toString(value);
+    }
+
+    public static String encode(Number value) {
+        return value.toString();
+    }
+
+    public static String encode(boolean value) {
+        return Boolean.toString(value);
+    }
+
+    public static String encode(String[] values) {
+        if (values.length == 0) {
+            return "[]";
+        }
+
+        StringBuffer sb = new StringBuffer();
+        sb.append('[');
+        for (String value : values) {
+            sb.append(encode(value));
+            sb.append(',');
+        }
+        sb.deleteCharAt(sb.length() - 1);
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String encode(int[] values) {
+        if (values.length == 0) {
+            return "[]";
+        }
+
+        StringBuffer sb = new StringBuffer();
+        sb.append('[');
+        for (int value : values) {
+            sb.append(encode(value));
+            sb.append(',');
+        }
+        sb.deleteCharAt(sb.length() - 1);
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String encode(long[] values) {
+        if (values.length == 0) {
+            return "[]";
+        }
+
+        StringBuffer sb = new StringBuffer();
+        sb.append('[');
+        for (long value : values) {
+            sb.append(encode(value));
+            sb.append(',');
+        }
+        sb.deleteCharAt(sb.length() - 1);
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String encode(float[] values) {
+        if (values.length == 0) {
+            return "[]";
+        }
+
+        StringBuffer sb = new StringBuffer();
+        sb.append('[');
+        for (float value : values) {
+            sb.append(encode(value));
+            sb.append(',');
+        }
+        sb.deleteCharAt(sb.length() - 1);
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String encode(double[] values) {
+        if (values.length == 0) {
+            return "[]";
+        }
+
+        StringBuffer sb = new StringBuffer();
+        sb.append('[');
+        for (double value : values) {
+            sb.append(encode(value));
+            sb.append(',');
+        }
+        sb.deleteCharAt(sb.length() - 1);
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String encode(Number[] values) {
+        if (values.length == 0) {
+            return "[]";
+        }
+
+        StringBuffer sb = new StringBuffer();
+        sb.append('[');
+        for (Number value : values) {
+            sb.append(encode(value));
+            sb.append(',');
+        }
+        sb.deleteCharAt(sb.length() - 1);
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static String encode(boolean[] values) {
+        if (values.length == 0) {
+            return "[]";
+        }
+
+        StringBuffer sb = new StringBuffer();
+        sb.append('[');
+        for (boolean value : values) {
+            sb.append(encode(value));
+            sb.append(',');
+        }
+        sb.deleteCharAt(sb.length() - 1);
+        sb.append(']');
+        return sb.toString();
+    }
+
+}

Added: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/json/JsonBuilderTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/json/JsonBuilderTest.java?rev=1133761&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/json/JsonBuilderTest.java (added)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/json/JsonBuilderTest.java Thu Jun  9 09:59:23 2011
@@ -0,0 +1,215 @@
+/*
+ * 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.jackrabbit.mk.json;
+
+import junit.framework.Assert;
+import org.apache.jackrabbit.mk.json.JsonBuilder.JsonArrayBuilder;
+import org.apache.jackrabbit.mk.json.JsonBuilder.JsonObjectBuilder;
+import org.json.simple.parser.ContentHandler;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+public class JsonBuilderTest {
+
+    @Test 
+    public void jsonBuilder() throws IOException {
+
+        StringWriter sw = new StringWriter();
+        JsonBuilder.create(sw)
+                .value("foo", "bar")
+                .value("int", 3)
+                .value("float", 3f)
+                .object("obj")
+                    .value("boolean", true)
+                    .nil("nil")
+                    .array("arr")
+                        .value(1)
+                        .value(2.0f)
+                        .value(2.0d)
+                        .value("42")
+                    .build()
+                .build()
+                .array("string array", new String[]{"","1","foo"})
+                .array("int array", new int[]{1,2,3})
+                .array("long array", new long[]{1,2,3})
+                .array("float array", new float[]{1,2,3})
+                .array("double array", new double[]{1,2,3})
+                .array("boolean array", new boolean[]{true, false})
+                .array("number array", new BigDecimal[]{new BigDecimal(21), new BigDecimal(42)})
+                .value("some", "more")
+            .build();
+
+        String json = sw.toString();
+        assertEquals("{\"foo\":\"bar\",\"int\":3,\"float\":3.0,\"obj\":{\"boolean\":true,\"nil\":null," +
+                "\"arr\":[1,2.0,2.0,\"42\"]},\"string array\":[\"\",\"1\",\"foo\"],\"int array\":[1,2,3]," +
+                "\"long array\":[1,2,3],\"float array\":[1.0,2.0,3.0],\"double array\":[1.0,2.0,3.0]," +
+                "\"boolean array\":[true,false],\"number array\":[21,42],\"some\":\"more\"}", json);
+    }
+
+    @Test
+    public void escape() throws IOException {
+        StringWriter sw = new StringWriter();
+        JsonBuilder.create(sw)
+                .value("back\\slash", "\\")
+                .value("back\\\\slash", "\\\\")
+            .build();
+
+        String json = sw.toString();
+        assertEquals("{\"back\\\\slash\":\"\\\\\",\"back\\\\\\\\slash\":\"\\\\\\\\\"}", json);
+    }
+
+    @Test
+    public void fixedPoint() throws IOException, ParseException {
+        InputStream one = JsonBuilderTest.class.getResourceAsStream("test.json");
+        assertNotNull(one);
+        InputStreamReader isr = new InputStreamReader(one);
+
+        String s1 = fix(isr);
+        String s2 = fix(s1);
+
+        // fix == fix fix
+        assertEquals(s1, s2);
+    }
+
+    //------------------------------------------< private >---
+
+    private static String fix(Reader reader) throws IOException, ParseException {
+        StringWriter sw = new StringWriter();
+        new JSONParser().parse(reader, new JsonHandler(JsonBuilder.create(sw)));
+        return sw.toString();
+    }
+
+    private static String fix(String string) throws IOException, ParseException {
+        return fix(new StringReader(string));
+    }
+
+    private static class JsonHandler implements ContentHandler {
+        private JsonObjectBuilder objectBuilder;
+        private JsonArrayBuilder arrayBuilder;
+        private String currentKey;
+
+        public JsonHandler(JsonObjectBuilder objectBuilder) {
+            this.objectBuilder = objectBuilder;
+        }
+
+        public void startJSON() throws ParseException, IOException {}
+        public void endJSON() throws ParseException, IOException {}
+
+        public boolean startObject() throws ParseException, IOException {
+            if (currentKey != null) {
+                objectBuilder = objectBuilder.object(currentKey);
+            }
+            return true;
+        }
+
+        public boolean endObject() throws ParseException, IOException {
+            objectBuilder = objectBuilder.build();
+            return true;
+        }
+
+        public boolean startObjectEntry(String key) throws ParseException, IOException {
+            currentKey = key;
+            return true;
+        }
+
+        public boolean endObjectEntry() throws ParseException, IOException {
+            return true;
+        }
+
+        public boolean startArray() throws ParseException, IOException {
+            arrayBuilder = objectBuilder.array(currentKey);
+            return true;
+        }
+
+        public boolean endArray() throws ParseException, IOException {
+            objectBuilder = arrayBuilder.build();
+            arrayBuilder = null;
+            return true;
+        }
+
+        public boolean primitive(Object value) throws ParseException, IOException {
+            if (arrayBuilder == null) {
+                if(value == null){
+                    objectBuilder.nil(currentKey);
+                }
+                else if(value instanceof String) {
+                    objectBuilder.value(currentKey, (String)value);
+                }
+                else if(value instanceof Integer) {
+                    objectBuilder.value(currentKey, ((Integer) value).intValue());
+                }
+                else if(value instanceof Long) {
+                    objectBuilder.value(currentKey, ((Long) value).longValue());
+                }
+                else if(value instanceof Double) {
+                    objectBuilder.value(currentKey, ((Double) value).doubleValue());
+                }
+                else if(value instanceof Float) {
+                    objectBuilder.value(currentKey, ((Float) value).floatValue());
+                }
+                else if(value instanceof Boolean) {
+                    objectBuilder.value(currentKey, (Boolean) value);
+                }
+                else {
+                    Assert.fail();
+                }
+            }
+            else {
+                if(value == null){
+                    arrayBuilder.nil();
+                }
+                else if(value instanceof String) {
+                    arrayBuilder.value((String) value);
+                }
+                else if(value instanceof Integer) {
+                    arrayBuilder.value(((Integer) value).intValue());
+                }
+                else if(value instanceof Long) {
+                    arrayBuilder.value(((Long) value).longValue());
+                }
+                else if(value instanceof Double) {
+                    arrayBuilder.value(((Double) value).doubleValue());
+                }
+                else if(value instanceof Float) {
+                    arrayBuilder.value(((Float) value).floatValue());
+                }
+                else if(value instanceof Boolean) {
+                    arrayBuilder.value((Boolean) value);
+                }
+                else {
+                    Assert.fail();
+                }
+            }
+            return true;
+        }
+    }
+}

Added: jackrabbit/sandbox/microkernel/src/test/resources/org/apache/jackrabbit/mk/json/test.json
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/resources/org/apache/jackrabbit/mk/json/test.json?rev=1133761&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/resources/org/apache/jackrabbit/mk/json/test.json (added)
+++ jackrabbit/sandbox/microkernel/src/test/resources/org/apache/jackrabbit/mk/json/test.json Thu Jun  9 09:59:23 2011
@@ -0,0 +1,31 @@
+{
+    "a":"Aqq",
+    "b":"Bqq",
+    "arr":[1,2,3,0.2, true, null, "quc"],
+    "obj":{
+        "q":0.02,
+        "n":null,
+        "bool": {
+            "t":true,
+            "f":false
+        },
+        "":{"":{"":{"":{"":{"":{"":{"":{"":{"":{"":{"":{"":{}}}}}}}}}}}}},
+        "1":{
+	        "test-node" : {
+                "jcr:primaryType" : "sling:propertySetTestNodeType",
+                "string" : "Sling",
+                "strings" : ["Apache", "Sling"],
+                "long" : 42,
+                "longs" : [4, 8, 15, 16, 23, 42],
+                "boolean" : true,
+                "booleans" : [true, false],
+                "uri" : "http://www.google.com/",
+                "uris" : ["http://sling.apache.org/", "http://www.google.com/"],
+                "name" : "sling:test",
+                "names" : ["jcr:base", "sling:test"],
+                "path" : "/sling-test/initial-content-folder/folder-content-test",
+                "paths" : ["/sling-test/initial-content-folder/folder-content-test", "/apps"]
+	       }
+        }
+    }
+}
\ No newline at end of file