jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r1196766 - in /jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src: main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java test/java/org/apache/jackrabbit/spi2microkernel/MicrokernelTest.java
Date Wed, 02 Nov 2011 19:08:26 GMT
Author: mduerig
Date: Wed Nov  2 19:08:25 2011
New Revision: 1196766

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

Modified:
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/MicrokernelTest.java

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java?rev=1196766&r1=1196765&r2=1196766&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java
(original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java
Wed Nov  2 19:08:25 2011
@@ -20,7 +20,6 @@
 package org.apache.jackrabbit.spi2microkernel;
 
 import org.apache.jackrabbit.mk.api.MicroKernel;
-import org.apache.jackrabbit.mk.json.JsopTokenizer;
 import org.apache.jackrabbit.mk.util.PathUtils;
 import org.apache.jackrabbit.spi.Event;
 import org.apache.jackrabbit.spi.EventBundle;
@@ -37,11 +36,17 @@ import org.apache.jackrabbit.spi.commons
 import org.apache.jackrabbit.spi.commons.identifier.IdFactoryImpl;
 import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
 import org.apache.jackrabbit.spi2microkernel.json.FullJsonParser;
+import org.apache.jackrabbit.spi2microkernel.json.JsonHandler;
+import org.apache.jackrabbit.spi2microkernel.json.JsonParser;
+import org.apache.jackrabbit.spi2microkernel.json.JsonTokenizer;
 import org.apache.jackrabbit.spi2microkernel.json.JsonValue;
 import org.apache.jackrabbit.spi2microkernel.json.JsonValue.JsonArray;
 import org.apache.jackrabbit.spi2microkernel.json.JsonValue.JsonObject;
-import org.apache.jackrabbit.spi2microkernel.json.JsonValue.Type;
+import org.apache.jackrabbit.spi2microkernel.json.JsopHandler;
+import org.apache.jackrabbit.spi2microkernel.json.JsopParser;
 import org.apache.jackrabbit.spi2microkernel.json.ParseException;
+import org.apache.jackrabbit.spi2microkernel.json.Token;
+import org.apache.jackrabbit.spi2microkernel.json.Token.Type;
 import org.apache.jackrabbit.spi2microkernel.json.UnescapingJsonTokenizer;
 import org.apache.jackrabbit.spi2microkernel.util.WrappedRepositoryException;
 import org.slf4j.Logger;
@@ -125,6 +130,12 @@ public class SubscriptionImpl implements
         return IdFactoryImpl.getInstance().createNodeId((String) null, path);
     }
 
+    private static NodeId createParentId(Path path) {
+        return path.denotesRoot()
+            ? null
+            : createNodeId(getParent(path));
+    }
+
     private static Path getParent(Path path) {
         try {
             return path.getAncestor(1);
@@ -145,8 +156,8 @@ public class SubscriptionImpl implements
         }
     }
 
-    private static Path readPath(JsopTokenizer jsopTokenizer) {
-        String path = jsopTokenizer.readString();
+    private static Path getPath(Token token) {
+        String path = token.text();
         int index = PathUtils.getNextSlash(path, 1); // slash off workspace name
         path = index == -1
             ? "/"
@@ -335,84 +346,121 @@ public class SubscriptionImpl implements
             return new EventBundleImpl(events, isLocal);
         }
 
-        private Collection<Event> getEvents(String changes, EventTemplate eventTemplate)
{
-            Collection<Event> events = new LinkedList<Event>();
-            JsopTokenizer jsopTokenizer = new JsopTokenizer(changes);
-
-            while (jsopTokenizer.read() != JsopTokenizer.END) {
-                int tokenType = jsopTokenizer.getTokenType();
-                switch(tokenType) {
-                    case '+': addItem(jsopTokenizer, eventTemplate, events); break;
-                    case '-': removeNode(jsopTokenizer, eventTemplate, events); break;
-                    case '^': setProperty(jsopTokenizer, eventTemplate, events); break;
-                    case '>': moveNode(jsopTokenizer, eventTemplate, events); break;
-                    default: // skip
+        private Collection<Event> getEvents(String jsop, final EventTemplate eventTemplate)
{
+            final Collection<Event> events = new LinkedList<Event>();
+
+            new JsopParser(new JsopHandler(){
+                @Override
+                public void add(Token path, JsonTokenizer object) {
+                    addNode(getPath(path), object, eventTemplate, events);
+                }
+
+                @Override
+                public void add(Token path, Token value) {
+                    Path qPath = getPath(path);
+                    NodeId parentId = createParentId(qPath);
+                    addProperty(qPath, parentId, eventTemplate, events);
+                }
+
+                @Override
+                public void add(Token path, Token[] values) {
+                    Path qPath = getPath(path);
+                    NodeId parentId = createParentId(qPath);
+                    addProperty(qPath, parentId, eventTemplate, events);
+                }
+
+                @Override
+                public void remove(Token path) {
+                    removeNode(getPath(path), eventTemplate, events);
                 }
-            }
+
+                @Override
+                public void set(Token path, Token value) {
+                    setProperty(getPath(path), eventTemplate, events, value.type() == Type.NULL);
+                }
+
+                @Override
+                public void set(Token path, Token[] values) {
+                    setProperty(getPath(path), eventTemplate, events, false);
+                }
+
+                @Override
+                public void reorder(Token path, Token position, Token target) {
+                    log.error("Not implemented", new UnsupportedOperationException("Not implemented"));
+                }
+
+                @Override
+                public void move(Token path, Token target) {
+                    moveNode(getPath(path), getPath(target), eventTemplate, events);
+                }
+            }).parseJsop(new UnescapingJsonTokenizer(jsop));
 
             return events;
         }
 
-        private void addItem(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate, Collection<Event>
events) {
-            Path path = readPath(jsopTokenizer);
-            NodeId parentId = path.denotesRoot()
-                ? null
-                : createNodeId(getParent(path));
+        private void addNode(final Path path, JsonTokenizer object, final EventTemplate eventTemplate,
+                             final Collection<Event> events) {
 
-            addItem(jsopTokenizer, eventTemplate, events, path, parentId);
-        }
+            NodeId parentId = createParentId(path);
+            addNode(path, parentId, eventTemplate, events);
 
-        private void addItem(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate, Collection<Event>
events,
-                Path path, NodeId parentId) {
+            new JsonParser(new JsonHandler(){
+                private Path parentPath = path;
 
+                @Override
+                public void atom(Token key, Token value) {
+                    Name name = Paths.stringToName(key.text());
+                    Path path = createPath(parentPath, name);
+                    addProperty(path, createNodeId(parentPath), eventTemplate, events);
+                }
+
+                @Override
+                public void object(JsonParser parser, Token key, JsonTokenizer tokenizer)
{
+                    Name name = Paths.stringToName(key.text());
+                    Path path = createPath(parentPath, name);
+                    addNode(path, createNodeId(parentPath), eventTemplate, events);
+                    parentPath = path;
+                    super.object(parser, key, tokenizer);
+                    parentPath = getParent(parentPath);
+                }
+
+                @Override
+                public void array(JsonParser parser, Token key, JsonTokenizer tokenizer)
{
+                    Name name = Paths.stringToName(key.text());
+                    Path path = createPath(parentPath, name);
+                    addProperty(path, createNodeId(parentPath), eventTemplate, events);
+                    new JsonParser(JsonHandler.INSTANCE).parseArray(tokenizer);
+                }
+            }).parseObject(object);
+        }
+
+        private void addNode(Path path, NodeId parentId, EventTemplate eventTemplate, Collection<Event>
events) {
             EventTemplate addItemEvent = eventTemplate.copy();
             addItemEvent.setPath(path);
             addItemEvent.setParentId(parentId);
             // todo set primaryType, mixinTypes this needs context in the journal in the
case of property events
             // fixme it seems type based filtering does not respect the type hierarchy (see
JCR-2542)
 
-            jsopTokenizer.read(':');
-            if (jsopTokenizer.read() == '{') {
-                addItemEvent.setType(Event.NODE_ADDED);
-                NodeId nodeId = createNodeId(path);
-                addItemEvent.setItemId(nodeId);
-                events.add(addItemEvent.buildEvent());
-                addInnerItems(jsopTokenizer, eventTemplate, events, nodeId);
-            }
-            else {
-                if (jsopTokenizer.getTokenType() == '[') {
-                    // skip over array
-                    while(jsopTokenizer.read() != ']') {}
-                }
-
-                addItemEvent.setType(Event.PROPERTY_ADDED);
-                addItemEvent.setItemId(createPropertyId(parentId, path.getName()));
-                events.add(addItemEvent.buildEvent());
-            }
+            addItemEvent.setType(Event.NODE_ADDED);
+            NodeId nodeId = createNodeId(path);
+            addItemEvent.setItemId(nodeId);
+            events.add(addItemEvent.buildEvent());
         }
 
-        private void addInnerItems(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate,
Collection<Event> events,
-                NodeId parentId) {
-
-            int tokenType;
-            while ((tokenType = jsopTokenizer.read()) != '}' && tokenType != JsopTokenizer.END)
{
-                if (tokenType == ',') {
-                    jsopTokenizer.read();
-                }
-
-                Name name = Paths.stringToName(jsopTokenizer.getToken());
-                Path path = createPath(parentId.getPath(), name);
+        private void addProperty(Path path, NodeId parentId, EventTemplate eventTemplate,
Collection<Event> events) {
+            EventTemplate addItemEvent = eventTemplate.copy();
+            addItemEvent.setPath(path);
+            addItemEvent.setParentId(parentId);
+            // todo set primaryType, mixinTypes this needs context in the journal in the
case of property events
+            // fixme it seems type based filtering does not respect the type hierarchy (see
JCR-2542)
 
-                addItem(jsopTokenizer, eventTemplate, events, path, parentId);
-            }
+            addItemEvent.setType(Event.PROPERTY_ADDED);
+            addItemEvent.setItemId(createPropertyId(parentId, path.getName()));
+            events.add(addItemEvent.buildEvent());
         }
 
-        private void removeNode(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate,
Collection<Event> events) {
-            Path path = readPath(jsopTokenizer);
-            NodeId parentId = path.denotesRoot()
-                ? null
-                : createNodeId(getParent(path));
-
+        private void removeNode(Path path, EventTemplate eventTemplate, Collection<Event>
events) {
+            NodeId parentId = createParentId(path);
             EventTemplate removeNodeEvent = eventTemplate.copy();
             removeNodeEvent.setType(Event.NODE_REMOVED);
             removeNodeEvent.setPath(path);
@@ -425,10 +473,8 @@ public class SubscriptionImpl implements
             // todo consider ways to generate events of (large) sub tree
         }
 
-        private void setProperty(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate,
Collection<Event> events) {
-            Path path = readPath(jsopTokenizer);
-            NodeId parentId = createNodeId(getParent(path));
-
+        private void setProperty(Path path, EventTemplate eventTemplate, Collection<Event>
events, boolean nullValue) {
+            NodeId parentId = createParentId(path);
             EventTemplate setPropertyEvent = eventTemplate.copy();
             setPropertyEvent.setPath(path);
             setPropertyEvent.setParentId(parentId);
@@ -436,8 +482,7 @@ public class SubscriptionImpl implements
             // todo set primaryType, mixinTypes this needs context in the journal
             // fixme it seems type based filtering does not respect the type hierarchy (see
JCR-2542)
 
-            jsopTokenizer.read(':');
-            if (jsopTokenizer.read() == JsopTokenizer.NULL) {
+            if (nullValue) {
                 setPropertyEvent.setType(Event.PROPERTY_REMOVED);
             }
             else {
@@ -448,20 +493,16 @@ public class SubscriptionImpl implements
             // todo consider ways to generate events of (large) sub tree
         }
 
-        private void moveNode(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate, Collection<Event>
events) {
+        private void moveNode(Path path, Path target, EventTemplate eventTemplate, Collection<Event>
events) {
             try {
-                Path fromPath = readPath(jsopTokenizer);
-                jsopTokenizer.read(':');
-                Path toPath = readPath(jsopTokenizer);
-
                 EventTemplate moveNodeEvent = eventTemplate.copy();
                 moveNodeEvent.setType(Event.NODE_MOVED);
-                moveNodeEvent.setPath(toPath);
-                moveNodeEvent.setItemId(createNodeId(toPath));
+                moveNodeEvent.setPath(target);
+                moveNodeEvent.setItemId(createNodeId(target));
 
                 Map<Name, QValue> info = new HashMap<Name, QValue>();
-                info.put(Paths.stringToName("srcAbsPath"), Values.pathToValue(fromPath));
-                info.put(Paths.stringToName("destAbsPath"), Values.pathToValue(toPath));
+                info.put(Paths.stringToName("srcAbsPath"), Values.pathToValue(path));
+                info.put(Paths.stringToName("destAbsPath"), Values.pathToValue(target));
                 moveNodeEvent.setInfo(info);
 
                 events.add(moveNodeEvent.buildEvent());
@@ -488,7 +529,7 @@ public class SubscriptionImpl implements
 
         private long getLong(JsonObject jsonObject, String key) {
             JsonValue o = jsonObject.get(key);
-            if (o.type() == Type.NUMBER) {
+            if (o.type() == JsonValue.Type.NUMBER) {
                 return Long.parseLong(o.asAtom().value());
             }
             else {

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/MicrokernelTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/MicrokernelTest.java?rev=1196766&r1=1196765&r2=1196766&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/MicrokernelTest.java
(original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/MicrokernelTest.java
Wed Nov  2 19:08:25 2011
@@ -23,12 +23,15 @@ import junit.framework.Assert;
 import org.apache.jackrabbit.mk.MicroKernelFactory;
 import org.apache.jackrabbit.mk.api.MicroKernel;
 import org.apache.jackrabbit.mk.api.MicroKernelException;
-import org.apache.jackrabbit.mk.json.JsopTokenizer;
 import org.apache.jackrabbit.spi2microkernel.json.FullJsonParser;
+import org.apache.jackrabbit.spi2microkernel.json.JsonTokenizer;
 import org.apache.jackrabbit.spi2microkernel.json.JsonValue;
 import org.apache.jackrabbit.spi2microkernel.json.JsonValue.JsonArray;
 import org.apache.jackrabbit.spi2microkernel.json.JsonValue.JsonObject;
 import org.apache.jackrabbit.spi2microkernel.json.JsonValue.Type;
+import org.apache.jackrabbit.spi2microkernel.json.JsopHandler;
+import org.apache.jackrabbit.spi2microkernel.json.JsopParser;
+import org.apache.jackrabbit.spi2microkernel.json.Token;
 import org.apache.jackrabbit.spi2microkernel.json.UnescapingJsonTokenizer;
 import org.apache.jackrabbit.spi2microkernel.util.NumberStream;
 import org.junit.After;
@@ -41,6 +44,7 @@ import java.io.IOException;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 public class MicrokernelTest {
 
@@ -272,15 +276,16 @@ public class MicrokernelTest {
 
         JsonArray jsonArray = FullJsonParser.parseArray(new UnescapingJsonTokenizer(journal));
         JsonObject jsonObject = jsonArray.get(0).asObject();
-        String changes = jsonObject.get("changes").asAtom().value();
+        String jsop = jsonObject.get("changes").asAtom().value();
 
-        JsopTokenizer tokenizer = new JsopTokenizer(changes);
-        tokenizer.read('+');
-        assertEquals("/node", tokenizer.readString());
-        tokenizer.read(':');
-        tokenizer.read('{');
-        tokenizer.read('}');
-        tokenizer.read(JsopTokenizer.END);
+        new JsopParser(new FailingJsopHandler(){
+            @Override
+            public void add(Token path, JsonTokenizer object) {
+                assertEquals("/node", path.text());
+                assertEquals("{", object.read().text());
+                assertEquals("}", object.read().text());
+            }
+        }).parseJsop(new UnescapingJsonTokenizer(jsop));
     }
 
     @Test
@@ -300,15 +305,15 @@ public class MicrokernelTest {
 
         JsonArray jsonArray = FullJsonParser.parseArray(new UnescapingJsonTokenizer(journal));
         JsonObject jsonObject = jsonArray.get(0).asObject();
-        String changes = jsonObject.get("changes").asAtom().value();
+        String jsop = jsonObject.get("changes").asAtom().value();
 
-        JsopTokenizer tokenizer = new JsopTokenizer(changes);
-        tokenizer.read('^');
-        assertEquals("/node/prop", tokenizer.readString());
-        tokenizer.read(':');
-        tokenizer.read(JsopTokenizer.NUMBER);
-        assertEquals("21", tokenizer.getToken());
-        tokenizer.read(JsopTokenizer.END);
+        new JsopParser(new FailingJsopHandler(){
+            @Override
+            public void set(Token path, Token value) {
+                assertEquals("/node/prop", path.text());
+                assertEquals("21", value.text());
+            }
+        }).parseJsop(new UnescapingJsonTokenizer(jsop));
     }
 
     @Test
@@ -328,14 +333,47 @@ public class MicrokernelTest {
 
         JsonArray jsonArray = FullJsonParser.parseArray(new UnescapingJsonTokenizer(journal));
         JsonObject jsonObject = jsonArray.get(0).asObject();
-        String changes = jsonObject.get("changes").asAtom().value();
+        String jsop = jsonObject.get("changes").asAtom().value();
+
+        new JsopParser(new FailingJsopHandler(){
+            @Override
+            public void set(Token path, Token value) {
+                assertEquals("/node/prop", path.text());
+                assertEquals("bar", value.text());
+            }
+        }).parseJsop(new UnescapingJsonTokenizer(jsop));
+    }
+
+    @Test
+    public void journalSetMultiValuedProperty() {
+        MicroKernel mk = getMicroKernel();
+        String init = mk.getHeadRevision();
+
+        String head = mk.commit("/",
+                "+\"node\" : {\"prop\":\"foo\"}",
+                init, "");
+
+        head = mk.commit("/",
+                "^\"node/prop\":[1,2,3,4]",
+                head, "");
+
+        String journal = mk.getJournal(head, head);
+
+        JsonArray jsonArray = FullJsonParser.parseArray(new UnescapingJsonTokenizer(journal));
+        JsonObject jsonObject = jsonArray.get(0).asObject();
+        String jsop = jsonObject.get("changes").asAtom().value();
 
-        JsopTokenizer tokenizer = new JsopTokenizer(changes);
-        tokenizer.read('^');
-        assertEquals("/node/prop", tokenizer.readString());
-        tokenizer.read(':');
-        assertEquals("bar", tokenizer.readString());
-        tokenizer.read(JsopTokenizer.END);
+        new JsopParser(new FailingJsopHandler(){
+            @Override
+            public void set(Token path, Token[] values) {
+                assertEquals("/node/prop", path.text());
+                assertEquals(4, values.length);
+                assertEquals("1", values[0].text());
+                assertEquals("2", values[1].text());
+                assertEquals("3", values[2].text());
+                assertEquals("4", values[3].text());
+            }
+        }).parseJsop(new UnescapingJsonTokenizer(jsop));
     }
 
     @Test
@@ -366,4 +404,47 @@ public class MicrokernelTest {
         return microkernel;
     }
 
+    private static class FailingJsopHandler extends JsopHandler {
+
+        @Override
+        public void add(Token path, JsonTokenizer object) {
+            fail();
+        }
+
+        @Override
+        public void add(Token path, Token[] values) {
+            fail();
+        }
+
+        @Override
+        public void add(Token path, Token value) {
+            fail();
+        }
+
+        @Override
+        public void remove(Token path) {
+            fail();
+        }
+
+        @Override
+        public void set(Token path, Token value) {
+            fail();
+        }
+
+        @Override
+        public void set(Token path, Token[] values) {
+            fail();
+        }
+
+        @Override
+        public void reorder(Token path, Token position, Token target) {
+            fail();
+        }
+
+        @Override
+        public void move(Token path, Token target) {
+            fail();
+        }
+    }
+
 }



Mime
View raw message