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);
}