jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r1330923 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/core/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/
Date Thu, 26 Apr 2012 16:18:40 GMT
Author: mduerig
Date: Thu Apr 26 16:18:40 2012
New Revision: 1330923

URL: http://svn.apache.org/viewvc?rev=1330923&view=rev
Log:
OAK-18: Define Oak API
- implement rebase

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java?rev=1330923&r1=1330922&r2=1330923&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
Thu Apr 26 16:18:40 2012
@@ -18,6 +18,8 @@
  */
 package org.apache.jackrabbit.oak.core;
 
+import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.mk.util.PathUtils;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.Root;
@@ -26,9 +28,13 @@ import org.apache.jackrabbit.oak.core.Tr
 import org.apache.jackrabbit.oak.kernel.NodeState;
 import org.apache.jackrabbit.oak.kernel.NodeStateBuilder;
 import org.apache.jackrabbit.oak.kernel.NodeStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
 import java.util.List;
 
+import static java.util.Collections.singletonList;
 import static org.apache.jackrabbit.mk.util.PathUtils.elements;
 import static org.apache.jackrabbit.mk.util.PathUtils.getName;
 import static org.apache.jackrabbit.mk.util.PathUtils.getParentPath;
@@ -39,6 +45,7 @@ import static org.apache.jackrabbit.mk.u
  * to the {@link NodeStateBuilder} for the relevant sub-tree.
  */
 public class RootImpl implements Root {
+    static final Logger log = LoggerFactory.getLogger(RootImpl.class);
 
     /** The underlying store to which this root belongs */
     private final NodeStore store;
@@ -104,16 +111,13 @@ public class RootImpl implements Root {
 
     @Override
     public void rebase() {
-        // TODO implement rebase base = store.getRoot().getChildNode(workspaceName);
+        rebase(true);
     }
 
     @Override
     public void commit() throws CommitFailedException {
         store.apply(nodeStateBuilder);
-        treeListener = new TreeListener();
-        base = store.getRoot().getChildNode(workspaceName);
-        nodeStateBuilder = store.getBuilder(base);
-        root = new TreeImpl(store, nodeStateBuilder, treeListener);
+        rebase(false);
     }
 
     @Override
@@ -140,47 +144,187 @@ public class RootImpl implements Root {
         return state;
     }
 
-    // TODO accumulate change log for refresh/rebase
-    private class TreeListener implements Listener {
-        private boolean isDirty;
+    private void rebase(boolean applyChanges) {
+        TreeListener changes = treeListener;
+
+        treeListener = new TreeListener();
+        base = store.getRoot().getChildNode(workspaceName);
+        nodeStateBuilder = store.getBuilder(base);
+        root = new TreeImpl(store, nodeStateBuilder, treeListener);
+
+        if (applyChanges) {
+            apply(changes);
+        }
+    }
+
+    private void apply(TreeListener changes) {
+        for (Operation operation : changes.getChanges()) {
+            try {
+                switch (operation.type) {
+                    case ADD_NODE: {
+                        String parentPath = PathUtils.getParentPath(operation.targetPath);
+                        String name = PathUtils.getName(operation.targetPath);
+                        getChild(parentPath).addChild(name);
+                        break;
+                    }
+                    case REMOVE_NODE: {
+                        String parentPath = PathUtils.getParentPath(operation.targetPath);
+                        String name = PathUtils.getName(operation.targetPath);
+                        getChild(parentPath).removeChild(name);
+                        break;
+                    }
+                    case SET_PROPERTY: {
+                        String parentPath = PathUtils.getParentPath(operation.targetPath);
+                        String name = PathUtils.getName(operation.targetPath);
+                        if (operation.isMultiple) {
+                            getChild(parentPath).setProperty(name, operation.values.get(0));
+                        }
+                        else {
+                            getChild(parentPath).setProperty(name, operation.values);
+                        }
+                        break;
+                    }
+                    case REMOVE_PROPERTY: {
+                        String parentPath = PathUtils.getParentPath(operation.targetPath);
+                        String name = PathUtils.getName(operation.targetPath);
+                        getChild(parentPath).removeProperty(name);
+                        break;
+                    }
+                    case MOVE: {
+                        move(operation.sourcePath, operation.targetPath);
+                        break;
+                    }
+                    case COPY: {
+                        copy(operation.sourcePath, operation.targetPath);
+                        break;
+                    }
+                }
+            }
+            catch (MicroKernelException e) {
+                log.warn("Skipping failed operation on refresh:" + operation);
+            }
+        }
+    }
+
+
+    private static class TreeListener implements Listener {
+        private final List<Operation> operations = new ArrayList<Operation>();
 
         @Override
-        public void addChild(TreeImpl tree, String name) {
-            isDirty = true;
+        public void addChild(TreeImpl parent, String name) {
+            String targetPath = PathUtils.concat(parent.getPath(), name);
+            operations.add(Operation.addNode(targetPath));
         }
 
         @Override
-        public void removeChild(TreeImpl tree, String name) {
-            isDirty = true;
+        public void removeChild(TreeImpl parent, String name) {
+            String targetPath = PathUtils.concat(parent.getPath(), name);
+            operations.add(Operation.removeNode(targetPath));
         }
 
         @Override
-        public void setProperty(TreeImpl tree, String name, CoreValue value) {
-            isDirty = true;
+        public void setProperty(TreeImpl parent, String name, CoreValue value) {
+            String targetPath = PathUtils.concat(parent.getPath(), name);
+            operations.add(Operation.setProperty(targetPath, value));
         }
 
         @Override
-        public void setProperty(TreeImpl tree, String name, List<CoreValue> values)
{
-            isDirty = true;
+        public void setProperty(TreeImpl parent, String name, List<CoreValue> values)
{
+            String targetPath = PathUtils.concat(parent.getPath(), name);
+            operations.add(Operation.setProperty(targetPath, values));
         }
 
         @Override
-        public void removeProperty(TreeImpl tree, String name) {
-            isDirty = true;
+        public void removeProperty(TreeImpl parent, String name) {
+            String targetPath = PathUtils.concat(parent.getPath(), name);
+            operations.add(Operation.removeProperty(targetPath));
         }
 
         @Override
-        public void move(TreeImpl tree, String name, TreeImpl moved) {
-            isDirty = true;
+        public void move(TreeImpl sourceParent, String sourceName, TreeImpl moved) {
+            String sourcePath = PathUtils.concat(sourceParent.getPath(), sourceName);
+            operations.add(Operation.move(sourcePath, moved.getPath()));
         }
 
         @Override
-        public void copy(TreeImpl tree, String name, TreeImpl copied) {
-            isDirty = true;
+        public void copy(TreeImpl sourceParent, String sourceName, TreeImpl copied) {
+            String sourcePath = PathUtils.concat(sourceParent.getPath(), sourceName);
+            operations.add(Operation.copy(sourcePath, copied.getPath()));
+        }
+
+        boolean hasChanges() {
+            return !operations.isEmpty();
         }
 
-        public boolean hasChanges() {
-            return isDirty;
+        List<Operation> getChanges() {
+            return operations;
+        }
+    }
+
+    private static class Operation {
+        final Type type;
+        final String targetPath;
+        final String sourcePath;
+        final List<CoreValue> values;
+        final boolean isMultiple;
+
+        enum Type {ADD_NODE, REMOVE_NODE, SET_PROPERTY, REMOVE_PROPERTY, MOVE, COPY}
+
+        private Operation(Type type, String targetPath, String sourcePath,
+                List<CoreValue> values, boolean isMultiple) {
+
+            this.type = type;
+            this.targetPath = targetPath;
+            this.sourcePath = sourcePath;
+            this.values = values;
+            this.isMultiple = isMultiple;
+        }
+
+        static Operation addNode(String targetPath) {
+            return new Operation(Type.ADD_NODE, targetPath, null, null, false);
+        }
+
+        static Operation removeNode(String targetPath) {
+            return new Operation(Type.REMOVE_NODE, targetPath, null, null, false);
+        }
+
+        static Operation setProperty(String targetPath, CoreValue value) {
+            return new Operation(Type.SET_PROPERTY, targetPath, null, singletonList(value),
false);
+        }
+
+        static Operation setProperty(String targetPath, List<CoreValue> values) {
+            return new Operation(Type.SET_PROPERTY, targetPath, null, values, true);
+        }
+
+        static Operation removeProperty(String targetPath) {
+            return new Operation(Type.REMOVE_PROPERTY, targetPath, null, null, false);
+        }
+
+        static Operation move(String sourcePath, String targetPath) {
+            return new Operation(Type.MOVE, targetPath, sourcePath, null, false);
+        }
+
+        static Operation copy(String sourcePath, String targetPath) {
+            return new Operation(Type.COPY, targetPath, sourcePath, null, false);
+        }
+
+        @Override
+        public String toString() {
+            switch (type) {
+                case ADD_NODE:
+                    return '+' + targetPath + ":{}";
+                case REMOVE_NODE:
+                    return '-' + targetPath;
+                case SET_PROPERTY:
+                    return '^' + targetPath + ':' + (isMultiple ? values : values.get(0));
+                case REMOVE_PROPERTY:
+                    return '^' + targetPath + ":null";
+                case MOVE:
+                    return '>' + sourcePath + ':' + targetPath;
+                case COPY:
+                    return '*' + sourcePath + ':' + targetPath;
+            }
+            throw new IllegalStateException("We should never get here");
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java?rev=1330923&r1=1330922&r2=1330923&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java
Thu Apr 26 16:18:40 2012
@@ -91,56 +91,56 @@ public class TreeImpl implements Tree {
 
         /**
          * The child of the given {@code name} has been added to {@code tree}.
-         * @param tree  parent to which a child was added
+         * @param parent  parent to which a child was added
          * @param name  name of the added child
          */
-        void addChild(TreeImpl tree, String name);
+        void addChild(TreeImpl parent, String name);
 
         /**
          * The child of the given {@code name} has been removed from {@code tree}
-         * @param tree  parent from which a child was removed
+         * @param parent  parent from which a child was removed
          * @param name  name of the removed child
          */
-        void removeChild(TreeImpl tree, String name);
+        void removeChild(TreeImpl parent, String name);
 
         /**
          * The property of the given {@code name} and {@code value} has been set.
-         * @param tree  parent on which the property was set.
+         * @param parent  parent on which the property was set.
          * @param name  name of the property
          * @param value  value of the property
          */
-        void setProperty(TreeImpl tree, String name, CoreValue value);
+        void setProperty(TreeImpl parent, String name, CoreValue value);
 
         /**
          * The property of the given {@code name} and {@code values} has been set.
-         * @param tree  parent on which the property was set.
+         * @param parent  parent on which the property was set.
          * @param name  name of the property
          * @param values  values of the property
          */
-        void setProperty(TreeImpl tree, String name, List<CoreValue> values);
+        void setProperty(TreeImpl parent, String name, List<CoreValue> values);
 
         /**
          * The property of the given {@code name} has been removed.
-         * @param tree  parent on which the property was removed.
+         * @param parent  parent on which the property was removed.
          * @param name  name of the property
          */
-        void removeProperty(TreeImpl tree, String name);
+        void removeProperty(TreeImpl parent, String name);
 
         /**
          * The child with the given {@code name} has been moved.
-         * @param tree  parent from which the child was moved
-         * @param name  name of the moved child
+         * @param sourceParent  parent from which the child was moved
+         * @param sourceName  name of the moved child
          * @param moved  moved child
          */
-        void move(TreeImpl tree, String name, TreeImpl moved);
+        void move(TreeImpl sourceParent, String sourceName, TreeImpl moved);
 
         /**
          * The child with the given {@code name} been copied.
-         * @param tree  parent from which the child way copied
-         * @param name  name of the copied child
+         * @param sourceParent  parent from which the child way copied
+         * @param sourceName  name of the copied child
          * @param copied  copied child
          */
-        void copy(TreeImpl tree, String name, TreeImpl copied);
+        void copy(TreeImpl sourceParent, String sourceName, TreeImpl copied);
     }
 
     @Override
@@ -332,7 +332,7 @@ public class TreeImpl implements Tree {
         builder.addNode(name);
         TreeImpl added = getChild(name);
         if (added != null) {
-            listener.addChild(added, name);
+            listener.addChild(this, name);
         }
         return added;
     }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java?rev=1330923&r1=1330922&r2=1330923&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
Thu Apr 26 16:18:40 2012
@@ -181,8 +181,10 @@ public class SessionImpl extends Abstrac
     @Override
     public void refresh(boolean keepChanges) throws RepositoryException {
         ensureIsAlive();
-        root.rebase();
-        if (!keepChanges) {
+        if (keepChanges) {
+            root.rebase();
+        }
+        else {
             root = contentSession.getCurrentRoot();
         }
     }

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java?rev=1330923&r1=1330922&r2=1330923&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java
Thu Apr 26 16:18:40 2012
@@ -1103,25 +1103,49 @@ public class RepositoryTest extends Abst
 
     @Test
     public void sessionRefreshFalse() throws RepositoryException {
-        Session session = getRepository().login();
+        Session session1 = getRepository().login();
+        Session session2 = getRepository().login();
         try {
-            Node foo = session.getNode("/foo");
+            Node foo = session1.getNode("/foo");
             foo.addNode("added");
-            NodeIterator it = foo.getNodes();
-            assertTrue(it.hasNext());
 
-            session.refresh(false);
-            it = foo.getNodes();
-            assertFalse(it.hasNext());
+            session2.getNode("/foo").addNode("bar");
+            session2.save();
+
+            session1.refresh(false);
+            assertFalse(foo.hasNode("added"));
+            assertTrue(foo.hasNode("bar"));
         }
         finally {
-            session.logout();
+            session1.logout();
+            session2.logout();
+        }
+    }
+
+    @Test
+    public void sessionRefreshTrue() throws RepositoryException {
+        Session session1 = getRepository().login();
+        Session session2 = getRepository().login();
+        try {
+            Node foo = session1.getNode("/foo");
+            foo.addNode("added");
+
+            session2.getNode("/foo").addNode("bar");
+            session2.save();
+
+            session1.refresh(true);
+            assertTrue(foo.hasNode("added"));
+            assertTrue(foo.hasNode("bar"));
+        }
+        finally {
+            session1.logout();
+            session2.logout();
         }
     }
 
     @Test(expected = RepositoryException.class)
-    @Ignore("WIP")  // TODO needs implementation of Tree.refresh
-    public void refreshConflict() throws RepositoryException {
+    @Ignore("WIP")  // TODO clarify
+    public void saveRefreshConflict() throws RepositoryException {
         Session session1 = getRepository().login();
         Session session2 = getRepository().login();
         try {
@@ -1139,7 +1163,7 @@ public class RepositoryTest extends Abst
     }
 
     @Test(expected = RepositoryException.class)
-    @Ignore("WIP")  // TODO needs implementation of Tree.refresh
+    @Ignore("WIP")  // TODO clarify
     public void refreshConflict2() throws RepositoryException {
         getSession().getRootNode().addNode("node");
         getSession().save();



Mime
View raw message