jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r1466373 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: core/RootImpl.java spi/state/AbstractRebaseDiff.java spi/state/RebaseDiff.java
Date Wed, 10 Apr 2013 08:14:23 GMT
Author: mduerig
Date: Wed Apr 10 08:14:23 2013
New Revision: 1466373

URL: http://svn.apache.org/r1466373
Log:
OAK-709: Consider moving permission evaluation to the node state level
Failing RebaseDiff

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java
  (with props)
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/spi/state/RebaseDiff.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=1466373&r1=1466372&r2=1466373&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
Wed Apr 10 08:14:23 2013
@@ -32,12 +32,14 @@ import java.util.Collections;
 import java.util.List;
 
 import javax.annotation.Nonnull;
+import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.security.auth.Subject;
 
 import org.apache.jackrabbit.oak.Oak;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.BlobFactory;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.QueryEngine;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
@@ -60,12 +62,13 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+import org.apache.jackrabbit.oak.spi.state.AbstractRebaseDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
-import org.apache.jackrabbit.oak.spi.state.RebaseDiff;
+import org.apache.jackrabbit.oak.util.TODO;
 
 public class RootImpl implements Root {
 
@@ -429,8 +432,7 @@ public class RootImpl implements Root {
         NodeState before = secureHead;
         NodeState after = getRootState();
         NodeBuilder builder = branch.getHead().builder();
-        // FIXME: This rebase should fail on conflicts
-        after.compareAgainstBaseState(before, new RebaseDiff(builder));
+        after.compareAgainstBaseState(before, new PurgeRebaseDiff(builder));
         branch.setRoot(builder.getNodeState());
         reset();
     }
@@ -459,6 +461,74 @@ public class RootImpl implements Root {
         return rootTree.getNodeState();
     }
 
+    //------------------------------------------------------------< PurgeRebaseDiff >---
+
+    private static class PurgeRebaseDiff extends AbstractRebaseDiff {
+        public PurgeRebaseDiff(NodeBuilder builder) {
+            super(builder);
+        }
+
+        @Override
+        protected PurgeRebaseDiff createDiff(NodeBuilder builder, String name) {
+            return new PurgeRebaseDiff(builder.child(name));
+        }
+
+        @Override
+        protected void addExistingProperty(NodeBuilder builder, PropertyState after) {
+            conflict();
+        }
+
+        @Override
+        protected void changeDeletedProperty(NodeBuilder builder, PropertyState after) {
+            conflict();
+        }
+
+        @Override
+        protected void changeChangedProperty(NodeBuilder builder, PropertyState before, PropertyState
after) {
+            conflict();
+        }
+
+        @Override
+        protected void deleteDeletedProperty(NodeBuilder builder, PropertyState before) {
+            conflict();
+        }
+
+        @Override
+        protected void deleteChangedProperty(NodeBuilder builder, PropertyState before) {
+            conflict();
+        }
+
+        @Override
+        protected void addExistingNode(NodeBuilder builder, String name, NodeState after)
{
+            conflict();
+        }
+
+        @Override
+        protected void changeDeletedNode(NodeBuilder builder, String name, NodeState after)
{
+            conflict();
+        }
+
+        @Override
+        protected void deleteDeletedNode(NodeBuilder builder, String name, NodeState before)
{
+            conflict();
+        }
+
+        @Override
+        protected void deleteChangedNode(NodeBuilder builder, String name, NodeState before)
{
+            conflict();
+        }
+
+        private static void conflict() {
+            // FIXME correctly handle conflict cases
+            try {
+                TODO.unimplemented().doNothing();
+            }
+            catch (UnsupportedRepositoryOperationException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+    }
+
     //---------------------------------------------------------< MoveRecord >---
 
     /**

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java?rev=1466373&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java
(added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java
Wed Apr 10 08:14:23 2013
@@ -0,0 +1,228 @@
+/*
+ * 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.oak.spi.state;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+
+/**
+ * {@code AbstractRebaseDiff} serves as base for rebase implementations.
+ * It implements a {@link NodeStateDiff}, which performs the conflict
+ * handling as defined in {@link org.apache.jackrabbit.mk.api.MicroKernel#rebase(String,
String)}
+ * on the Oak SPI state level.
+ * <p>
+ * Intended use of this class is to re-base a branched version of the node state
+ * tree. Given below situation:
+ * <pre>
+ *     + head (master)
+ *     |
+ *     | + branch
+ *     |/
+ *     + base
+ *     |
+ * </pre>
+ * The current state on the master branch is {@code head} and a branch
+ * was created at {@code base}. The current state on the branch is
+ * {@code branch}. Re-basing {@code branch} to the current
+ * {@code head} works as follows:
+ * <pre>
+ *     NodeState head = ...
+ *     NodeState branch = ...
+ *     NodeState base = ...
+ *     NodeBuilder builder = new MemoryNodeBuilder(head);
+ *     branch.compareAgainstBaseState(base, new MyRebaseDiff(builder));
+ *     branch = builder.getNodeState();
+ * </pre>
+ * The result is:
+ * <pre>
+ *       + branch
+ *      /
+ *     + head (master)
+ *     |
+ * </pre>
+ * <p>
+ * Conflicts during rebase cause calls to the various abstracts conflict resolution
+ * methods of this class. Concrete subclasses of this class need to implement these
+ * methods for handling such conflicts.
+ */
+public abstract class AbstractRebaseDiff implements NodeStateDiff {
+    private final NodeBuilder builder;
+
+    protected AbstractRebaseDiff(NodeBuilder builder) {
+        this.builder = builder;
+    }
+
+    /**
+     * Factory method for creating a rebase handler for the named child of the passed
+     * parent builder.
+     *
+     * @param builder  parent builder
+     * @param name  name of the child for which to return a rebase handler
+     * @return  rebase handler for child {@code name} in {@code builder}
+     */
+    protected abstract AbstractRebaseDiff createDiff(NodeBuilder builder, String name);
+
+    /**
+     * Called when the property {@code after} was added on the branch but the property
+     * exists already in the trunk.
+     *
+     * @param builder  parent builder
+     * @param after  added property
+     */
+    protected abstract void addExistingProperty(NodeBuilder builder, PropertyState after);
+
+    /**
+     * Called when the property {@code after} was changed on the branch but was
+     * deleted already in the trunk.
+     *
+     * @param builder  parent builder
+     * @param after  changed property
+     */
+    protected abstract void changeDeletedProperty(NodeBuilder builder, PropertyState after);
+
+    /**
+     * Called when the property {@code after} was changed on the branch but was
+     * already changed to {@code before} in the trunk.
+     *
+     * @param builder  parent property
+     * @param before  changed property in branch
+     * @param after  changed property in trunk
+     */
+    protected abstract void changeChangedProperty(NodeBuilder builder, PropertyState before,
PropertyState after);
+
+    /**
+     * Called when the property {@code before} was deleted in the branch but was
+     * already deleted in the trunk.
+     *
+     * @param builder  parent builder
+     * @param before  deleted property
+     */
+    protected abstract void deleteDeletedProperty(NodeBuilder builder, PropertyState before);
+
+    /**
+     * Called when the property {@code before} was deleted in the branch but was
+     * already changed in the trunk.
+     *
+     * @param builder  parent builder
+     * @param before  deleted property
+     */
+    protected abstract void deleteChangedProperty(NodeBuilder builder, PropertyState before);
+
+    /**
+     * Called when the node {@code after} was added on the branch but the node
+     * exists already in the trunk.
+     *
+     * @param builder  parent builder
+     * @param name  name of the added node
+     * @param after  added added
+     */
+    protected abstract void addExistingNode(NodeBuilder builder, String name, NodeState after);
+
+    /**
+     * Called when the node {@code after} was changed on the branch but was
+     * deleted already in the trunk.
+     *
+     * @param builder  parent builder
+     * @param name  name of the changed node
+     * @param after  changed node
+     */
+    protected abstract void changeDeletedNode(NodeBuilder builder, String name, NodeState
after);
+
+    /**
+     * Called when the node {@code before} was deleted in the branch but was
+     * already deleted in the trunk.
+     *
+     * @param builder  parent builder
+     * @param before  deleted node
+     */
+    protected abstract void deleteDeletedNode(NodeBuilder builder, String name, NodeState
before);
+
+    /**
+     * Called when the node {@code before} was deleted in the branch but was
+     * already changed in the trunk.
+     *
+     * @param builder  parent builder
+     * @param before  deleted node
+     */
+    protected abstract void deleteChangedNode(NodeBuilder builder, String name, NodeState
before);
+
+    @Override
+    public void propertyAdded(PropertyState after) {
+        PropertyState other = builder.getProperty(after.getName());
+        if (other == null) {
+            builder.setProperty(after);
+        } else if (!other.equals(after)) {
+            addExistingProperty(builder, after);
+        }
+    }
+
+    @Override
+    public void propertyChanged(PropertyState before, PropertyState after) {
+        PropertyState other = builder.getProperty(before.getName());
+        if (other == null) {
+            changeDeletedProperty(builder, after);
+        } else if (other.equals(before)) {
+            builder.setProperty(after);
+        } else if (!other.equals(after)) {
+            changeChangedProperty(builder, before, after);
+        }
+    }
+
+    @Override
+    public void propertyDeleted(PropertyState before) {
+        PropertyState other = builder.getProperty(before.getName());
+        if (other == null) {
+            deleteDeletedProperty(builder, before);
+        } else if (other.equals(before)) {
+            builder.removeProperty(before.getName());
+        } else {
+            deleteChangedProperty(builder, before);
+        }
+    }
+
+    @Override
+    public void childNodeAdded(String name, NodeState after) {
+        if (builder.hasChildNode(name)) {
+            addExistingNode(builder, name, after);
+        } else {
+            builder.setNode(name, after);
+        }
+    }
+
+    @Override
+    public void childNodeChanged(
+            String name, NodeState before, NodeState after) {
+        if (builder.hasChildNode(name)) {
+            after.compareAgainstBaseState(before, createDiff(builder, name));
+        } else {
+            changeDeletedNode(builder, name, after);
+        }
+    }
+
+    @Override
+    public void childNodeDeleted(String name, NodeState before) {
+        if (!builder.hasChildNode(name)) {
+            deleteDeletedNode(builder, name, before);
+        } else if (before.equals(builder.child(name).getNodeState())) {
+            builder.removeNode(name);
+        } else {
+            deleteChangedNode(builder, name, before);
+        }
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RebaseDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RebaseDiff.java?rev=1466373&r1=1466372&r2=1466373&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RebaseDiff.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RebaseDiff.java
Wed Apr 10 08:14:23 2013
@@ -22,41 +22,10 @@ import org.apache.jackrabbit.oak.api.Pro
 /**
  * {@code RebaseDiff} implements a {@link NodeStateDiff}, which performs
  * the conflict handling as defined in {@link MicroKernel#rebase(String, String)}
- * on the Oak SPI state level.
- * <p/>
- * Intended use of this class is to re-base a branched version of the node state
- * tree. Given below situation:
- * <pre>
- *     + head (master)
- *     |
- *     | + branch
- *     |/
- *     + base
- *     |
- * </pre>
- * The current state on the master branch is {@code head} and a branch
- * was created at {@code base}. The current state on the branch is
- * {@code branch}. Re-basing {@code branch} to the current
- * {@code head} works as follows:
- * <pre>
- *     NodeState head = ...
- *     NodeState branch = ...
- *     NodeState base = ...
- *     NodeBuilder builder = new MemoryNodeBuilder(head);
- *     branch.compareAgainstBaseState(base, new RebaseDiff(builder));
- *     branch = builder.getNodeState();
- * </pre>
- * The result is:
- * <pre>
- *       + branch
- *      /
- *     + head (master)
- *     |
- * </pre>
- * <p/>
+ * on the Oak SPI state level by annotating conflicting items with conflict
+ * markers.
  */
-public class RebaseDiff implements NodeStateDiff {
-
+public class RebaseDiff extends AbstractRebaseDiff {
     public static final String CONFLICT = ":conflict";
     public static final String DELETE_CHANGED_PROPERTY = "deleteChangedProperty";
     public static final String DELETE_CHANGED_NODE = "deleteChangedNode";
@@ -68,78 +37,61 @@ public class RebaseDiff implements NodeS
     public static final String CHANGE_DELETED_NODE = "changeDeletedNode";
     public static final String DELETE_DELETED_NODE = "deleteDeletedNode";
 
-    private final NodeBuilder builder;
-
     public RebaseDiff(NodeBuilder builder) {
-        this.builder = builder;
+        super(builder);
+    }
+
+    @Override
+    protected RebaseDiff createDiff(NodeBuilder builder, String name) {
+        return new RebaseDiff(builder.child(name));
+    }
+
+    @Override
+    protected void addExistingProperty(NodeBuilder builder, PropertyState after) {
+        conflictMarker(builder, ADD_EXISTING_PROPERTY).setProperty(after);
+    }
+
+    @Override
+    protected void changeDeletedProperty(NodeBuilder builder, PropertyState after) {
+        conflictMarker(builder, CHANGE_DELETED_PROPERTY).setProperty(after);
+    }
+
+    @Override
+    protected void changeChangedProperty(NodeBuilder builder, PropertyState before, PropertyState
after) {
+        conflictMarker(builder, CHANGE_CHANGED_PROPERTY).setProperty(after);
     }
 
     @Override
-    public void propertyAdded(PropertyState after) {
-        PropertyState other = builder.getProperty(after.getName());
-        if (other == null) {
-            builder.setProperty(after);
-        } else if (!other.equals(after)) {
-            conflictMarker(ADD_EXISTING_PROPERTY).setProperty(after);
-        }
+    protected void deleteDeletedProperty(NodeBuilder builder, PropertyState before) {
+        conflictMarker(builder, DELETE_DELETED_PROPERTY).setProperty(before);
     }
 
     @Override
-    public void propertyChanged(PropertyState before, PropertyState after) {
-        PropertyState other = builder.getProperty(before.getName());
-        if (other == null) {
-            conflictMarker(CHANGE_DELETED_PROPERTY).setProperty(after);
-        } else if (other.equals(before)) {
-            builder.setProperty(after);
-        } else if (!other.equals(after)) {
-            conflictMarker(CHANGE_CHANGED_PROPERTY).setProperty(after);
-        }
+    protected void deleteChangedProperty(NodeBuilder builder, PropertyState before) {
+        conflictMarker(builder, DELETE_CHANGED_PROPERTY).setProperty(before);
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) {
-        PropertyState other = builder.getProperty(before.getName());
-        if (other == null) {
-            conflictMarker(DELETE_DELETED_PROPERTY).setProperty(before);
-        } else if (other.equals(before)) {
-            builder.removeProperty(before.getName());
-        } else {
-            conflictMarker(DELETE_CHANGED_PROPERTY).setProperty(before);
-        }
+    protected void addExistingNode(NodeBuilder builder, String name, NodeState after) {
+        conflictMarker(builder, ADD_EXISTING_NODE).setNode(name, after);
     }
 
     @Override
-    public void childNodeAdded(String name, NodeState after) {
-        if (builder.hasChildNode(name)) {
-            conflictMarker(ADD_EXISTING_NODE).setNode(name, after);
-        } else {
-            builder.setNode(name, after);
-        }
+    protected void changeDeletedNode(NodeBuilder builder, String name, NodeState after) {
+        conflictMarker(builder, CHANGE_DELETED_NODE).setNode(name, after);
     }
 
     @Override
-    public void childNodeChanged(
-            String name, NodeState before, NodeState after) {
-        if (builder.hasChildNode(name)) {
-            after.compareAgainstBaseState(
-                    before, new RebaseDiff(builder.child(name)));
-        } else {
-            conflictMarker(CHANGE_DELETED_NODE).setNode(name, after);
-        }
+    protected void deleteDeletedNode(NodeBuilder builder, String name, NodeState before)
{
+        conflictMarker(builder, DELETE_DELETED_NODE).setNode(name, before);
     }
 
     @Override
-    public void childNodeDeleted(String name, NodeState before) {
-        if (!builder.hasChildNode(name)) {
-            conflictMarker(DELETE_DELETED_NODE).setNode(name, before);
-        } else if (before.equals(builder.child(name).getNodeState())) {
-            builder.removeNode(name);
-        } else {
-            conflictMarker(DELETE_CHANGED_NODE).setNode(name, before);
-        }
+    protected void deleteChangedNode(NodeBuilder builder, String name, NodeState before)
{
+        conflictMarker(builder, DELETE_CHANGED_NODE).setNode(name, before);
     }
 
-    private NodeBuilder conflictMarker(String name) {
+    private static NodeBuilder conflictMarker(NodeBuilder builder, String name) {
         return builder.child(CONFLICT).child(name);
     }
 



Mime
View raw message