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/11/02 20:06:43 UTC

svn commit: r1196765 - in /jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src: main/java/org/apache/jackrabbit/spi2microkernel/json/ test/java/org/apache/jackrabbit/spi2microkernel/json/

Author: mduerig
Date: Wed Nov  2 19:06:43 2011
New Revision: 1196765

URL: http://svn.apache.org/viewvc?rev=1196765&view=rev
Log:
Microkernel based Jackrabbit prototype (WIP): JsopParser

Added:
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopHandler.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopParser.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/JsopParserTest.java
Modified:
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizerTest.java

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java?rev=1196765&r1=1196764&r2=1196765&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizer.java Wed Nov  2 19:06:43 2011
@@ -54,7 +54,14 @@ public class DefaultJsonTokenizer extend
                 case 'f': return readLiteral(Type.FALSE, "false");
                 case 'n': return readLiteral(Type.NULL, "null");
                 case '"': return readString();
-                default:  return readNumber();
+                default:
+                    Token token = tryReadNumber();
+                    if (token != null) {
+                        return token;
+                    }
+                    else {
+                        return readUnknown();
+                    }
             }
         }
         else {
@@ -130,7 +137,7 @@ public class DefaultJsonTokenizer extend
     private static final Pattern NUMBER_PATTERN = Pattern.compile(
             "(\\+|-)?(\\d+)((\\.)(\\d+))?(((e|E)(\\+|-)?)(\\d+))?");
 
-    protected Token readNumber() {
+    protected Token tryReadNumber() {
         Matcher matcher = NUMBER_PATTERN.matcher(json.substring(pos));
         if (matcher.lookingAt()) {
             Token token = createToken(Type.NUMBER, matcher.group(), pos);
@@ -138,10 +145,18 @@ public class DefaultJsonTokenizer extend
             return token;
         }
         else {
-            throw new ParseException(pos, "Expected number, found: " + excerpt(json, pos, 40));
+            return null;
         }
     }
 
+    protected Token readUnknown() {
+        int start = pos++;
+        while (pos < json.length() && "{}[]:,tfn+-0123456789\" ".indexOf(json.charAt(pos)) == -1)  {
+            pos++;
+        }
+        return new Token(Type.UNKNOWN, json.substring(start, pos), start);
+    }
+
     //------------------------------------------< private >---
 
     private static String excerpt(String string, int pos, int len) {

Added: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopHandler.java?rev=1196765&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopHandler.java (added)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopHandler.java Wed Nov  2 19:06:43 2011
@@ -0,0 +1,16 @@
+package org.apache.jackrabbit.spi2microkernel.json;
+
+public class JsopHandler {
+
+    public void add(Token path, JsonTokenizer value) {
+        new JsonParser(JsonHandler.INSTANCE).parseObject(value);
+    }
+
+    public void add(Token path, Token value) { }
+    public void add(Token path, Token[] values) { }
+    public void remove(Token path) { }
+    public void set(Token path, Token value) { }
+    public void set(Token path, Token[] values) { }
+    public void reorder(Token path, Token position, Token target) { }
+    public void move(Token path, Token target) { }
+}

Added: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopParser.java?rev=1196765&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopParser.java (added)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/JsopParser.java Wed Nov  2 19:06:43 2011
@@ -0,0 +1,136 @@
+package org.apache.jackrabbit.spi2microkernel.json;
+
+import org.apache.jackrabbit.spi2microkernel.json.Token.Type;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * DIFFS    ::= DIFF*
+ * DIFF     ::= ADD | SET | REMOVE | MOVE
+ * ADD      ::= + STRING : (OBJECT | ATOM | ARRAY)
+ * SET      ::= ^ STRING : ATOM | ARRAY
+ * REMOVE   ::= - STRING
+ * MOVE     ::= > STRING : (STRING | { STRING : STRING })
+ */
+public class JsopParser {
+    private final JsopHandler jsopHandler;
+
+    public JsopParser(JsopHandler jsopHandler) {
+        this.jsopHandler = jsopHandler;
+    }
+
+    /* DIFFS    ::= DIFF* */
+    public void parseJsop(JsonTokenizer tokenizer) {
+        for (Token token = tokenizer.peek(); token.type() != Type.EOF; token = tokenizer.peek()) {
+            parseDiff(tokenizer);
+        }
+    }
+
+    /* DIFF    ::= ADD | SET | REMOVE | MOVE */
+    public void parseDiff(JsonTokenizer tokenizer) {
+        Token token = tokenizer.read(Type.UNKNOWN);
+        String text = token.text();
+        if (text.length() != 1) {
+            throw new ParseException(token.pos(), "Expected one of +, -, ^ or >. Found: " + token);
+        }
+
+        switch (text.charAt(0)) {
+            case '+':
+                parseAdd(tokenizer);
+                break;
+            case '-':
+                parseRemove(tokenizer);
+                break;
+            case '^':
+                parseSet(tokenizer);
+                break;
+            case '>':
+                parseMove(tokenizer);
+                break;
+            default:
+                throw new ParseException(token.pos(), "Expected one of +, -, ^ or >. Found: " + token);
+        }
+    }
+
+    /* ADD      ::= + STRING : (OBJECT | ATOM | ARRAY) */
+    public void parseAdd(JsonTokenizer tokenizer) {
+        Token path = tokenizer.read(Type.STRING);
+        tokenizer.read(Type.COLON);
+        switch (tokenizer.peek().type()) {
+            case BEGIN_OBJECT:
+                jsopHandler.add(path, tokenizer);
+                break;
+            case BEGIN_ARRAY:
+                jsopHandler.add(path, parseArray(tokenizer));
+                break;
+            default:
+                jsopHandler.add(path, parseAtom(tokenizer));
+        }
+    }
+
+    /* REMOVE   ::= - STRING */
+    public void parseRemove(JsonTokenizer tokenizer) {
+        jsopHandler.remove(tokenizer.read(Type.STRING));
+    }
+
+    /* SET      ::= ^ STRING : ATOM | ARRAY*/
+    public void parseSet(JsonTokenizer tokenizer) {
+        Token path = tokenizer.read(Type.STRING);
+        tokenizer.read(Type.COLON);
+        Token token = tokenizer.peek();
+        switch (token.type()) {
+            case BEGIN_OBJECT:
+                throw new ParseException(token.pos(), "Expected one of atom or array. Found: " + token);
+            case BEGIN_ARRAY:
+                jsopHandler.set(path, parseArray(tokenizer));
+                break;
+            default:
+                jsopHandler.set(path, parseAtom(tokenizer));
+        }
+        if (tokenizer.peek(Type.BEGIN_OBJECT)) {
+        }
+    }
+
+    /* MOVE     ::= > STRING : (STRING | { STRING : STRING }) */
+    public void parseMove(JsonTokenizer tokenizer) {
+        Token path = tokenizer.read(Type.STRING);
+        tokenizer.read(Type.COLON);
+        if (tokenizer.peek(Type.BEGIN_OBJECT)) {
+            tokenizer.read(Type.BEGIN_OBJECT);
+            Token position = tokenizer.read(Type.STRING);
+            tokenizer.read(Type.COLON);
+            Token target = tokenizer.read(Type.STRING);
+            tokenizer.read(Type.END_OBJECT);
+            jsopHandler.reorder(path, position, target);
+        }
+        else {
+            jsopHandler.move(path, tokenizer.read(Type.STRING));
+        }
+    }
+
+    //------------------------------------------< private >---
+
+    private static Token parseAtom(JsonTokenizer tokenizer) {
+        Token token = tokenizer.peek();
+        Type type = token.type();
+        if (type != Type.TRUE && type != Type.FALSE && type != Type.NULL && type != Type.STRING && type != Type.NUMBER) {
+            throw new ParseException(token.pos(), "Expected one of atom. Found: " + token);
+        }
+        return tokenizer.read();
+    }
+
+    private static Token[] parseArray(JsonTokenizer tokenizer) {
+        final List<Token> values = new ArrayList<Token>();
+        
+        new JsonParser(new JsonHandler(){
+            @Override
+            public void atom(Token key, Token value) {
+                values.add(value);
+            }
+        }).parseArray(tokenizer);
+        
+        return values.toArray(new Token[values.size()]);
+    }
+
+}

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java?rev=1196765&r1=1196764&r2=1196765&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/json/Token.java Wed Nov  2 19:06:43 2011
@@ -25,7 +25,7 @@ public final class Token {
     private final int pos;
 
     public enum Type {BEGIN_OBJECT, END_OBJECT, BEGIN_ARRAY, END_ARRAY, COLON, COMMA, EOF, TRUE,
-        FALSE, NULL, STRING, NUMBER}
+        FALSE, NULL, STRING, NUMBER, UNKNOWN}
 
     public Token(Type type, String text, int pos) {
         this.type = type;

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizerTest.java?rev=1196765&r1=1196764&r2=1196765&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizerTest.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/DefaultJsonTokenizerTest.java Wed Nov  2 19:06:43 2011
@@ -45,6 +45,7 @@ public class DefaultJsonTokenizerTest {
         new Token(Type.STRING, "", 62),
         new Token(Type.STRING, "\\\"", 65),
         new Token(Type.STRING, "\\\\", 70),
+        new Token(Type.UNKNOWN, "qwe", 75)
 };
 
     private static final String TOKEN_STRING = join(TOKENS);

Added: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/JsopParserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/JsopParserTest.java?rev=1196765&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/JsopParserTest.java (added)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/json/JsopParserTest.java Wed Nov  2 19:06:43 2011
@@ -0,0 +1,83 @@
+package org.apache.jackrabbit.spi2microkernel.json;
+
+import org.apache.jackrabbit.spi2microkernel.json.Token.Type;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+
+public class JsopParserTest {
+
+    @Test
+    public void test() {
+        String jsop =
+            "+\"foo\":\"bar\"" +
+            "+ \"foo\" : \"bar\"" +
+            "+ \"foo\" : {\"key\" : [12, 34]}" +
+            "- \"foo\"" +
+            "^ \"foo\" : \"bar\"" +
+            "> \"foo\" : \"bar\"" +
+            "> \"foo\" : {\"moo\" : \"bar\"}" +
+            "+ \"foo\" : [12, 34]" +
+            "^ \"foo\" : [12, 34]";
+
+        new JsopParser(new JsopHandler(){
+            @Override
+            public void add(Token path, JsonTokenizer value) {
+                assertEquals("foo", path.text());
+                assertEquals(Type.BEGIN_OBJECT, value.read().type());
+                assertEquals("key", value.read().text());
+                assertEquals(Type.COLON, value.read().type());
+                assertEquals(Type.BEGIN_ARRAY, value.read().type());
+                assertEquals("12", value.read().text());
+                assertEquals(Type.COMMA, value.read().type());
+                assertEquals("34", value.read().text());
+                assertEquals(Type.END_ARRAY, value.read().type());
+                assertEquals(Type.END_OBJECT, value.read().type());
+            }
+
+            @Override
+            public void add(Token path, Token value) {
+                assertEquals("foo", path.text());
+                assertEquals("bar", value.text());
+            }
+
+            @Override
+            public void add(Token path, Token[] values) {
+                assertEquals(2, values.length);
+                assertEquals("12", values[0].text());
+                assertEquals("34", values[1].text());
+            }
+
+            @Override
+            public void remove(Token path) {
+                assertEquals("foo", path.text());
+            }
+
+            @Override
+            public void set(Token path, Token value) {
+                assertEquals("foo", path.text());
+                assertEquals("bar", value.text());
+            }
+
+            @Override
+            public void set(Token path, Token[] values) {
+                assertEquals(2, values.length);
+                assertEquals("12", values[0].text());
+                assertEquals("34", values[1].text());
+            }
+
+            @Override
+            public void reorder(Token path, Token position, Token target) {
+                assertEquals("foo", path.text());
+                assertEquals("moo", position.text());
+                assertEquals("bar", target.text());
+            }
+
+            @Override
+            public void move(Token path, Token target) {
+                assertEquals("foo", path.text());
+                assertEquals("bar", target.text());
+            }
+        }).parseJsop(new DefaultJsonTokenizer(jsop));
+    }
+}