Modified: jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/PartialConflictHandler.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/PartialConflictHandler.java?rev=1798662&r1=1798661&r2=1798662&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/PartialConflictHandler.java (original) +++ jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/PartialConflictHandler.java Wed Jun 14 11:03:54 2017 @@ -40,7 +40,9 @@ import org.apache.jackrabbit.oak.spi.sta * instance ({@link Resolution#MERGED}). * * @see ConflictHandler + * @deprecated Use {@link org.apache.jackrabbit.oak.spi.commit.ThreeWayConflictHandler} instead. */ +@Deprecated public interface PartialConflictHandler { /**
Added: jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/ThreeWayConflictHandler.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/ThreeWayConflictHandler.java?rev=1798662&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/ThreeWayConflictHandler.java (added) +++ jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/ThreeWayConflictHandler.java Wed Jun 14 11:03:54 2017 @@ -0,0 +1,184 @@ +/* + * 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.commit; + +import javax.annotation.Nonnull; + +import org.apache.jackrabbit.oak.api.PropertyState; +import org.apache.jackrabbit.oak.spi.state.NodeBuilder; +import org.apache.jackrabbit.oak.spi.state.NodeState; + +/** + * A {@code ThreeWayConflictHandler} is responsible for handling conflicts which happen + * on {@link org.apache.jackrabbit.oak.api.Root#rebase()} and on the implicit rebase operation which + * takes part on {@link org.apache.jackrabbit.oak.api.Root#commit()}. + * + * This interface contains one method per type of conflict which might occur. + * Each of these methods must return a {@link Resolution} for the current conflict. + * The resolution indicates to use the changes in the current {@code Root} instance + * ({@link Resolution#OURS}) or to use the changes from the underlying persistence + * store ({@link Resolution#THEIRS}). Alternatively the resolution can also indicate + * that the changes have been successfully merged by this {@code ThreeWayConflictHandler} + * instance ({@link Resolution#MERGED}). + * + */ +public interface ThreeWayConflictHandler { + /** + * Resolutions for conflicts + */ + enum Resolution { + /** + * Use the changes from the current {@link org.apache.jackrabbit.oak.api.Root} instance + */ + OURS, + + /** + * Use the changes from the underlying persistence store + */ + THEIRS, + + /** + * Indicated changes have been merged by this {@code ConflictHandler} instance. + */ + MERGED, + + /** + * Changes are ignored by this handler. + */ + IGNORED + } + + /** + * The property {@code ours} has been added to {@code parent} which conflicts + * with property {@code theirs} which has been added in the persistence store. + * + * @param parent root of the conflict + * @param ours our version of the property + * @param theirs their version of the property + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution addExistingProperty(@Nonnull NodeBuilder parent, @Nonnull PropertyState ours, + @Nonnull PropertyState theirs); + + /** + * The property {@code ours} has been changed in {@code parent} while it was + * removed in the persistence store. + * + * @param parent root of the conflict + * @param ours our version of the property + * @param base the base version of the property + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution changeDeletedProperty(@Nonnull NodeBuilder parent, @Nonnull PropertyState ours, + @Nonnull PropertyState base); + + /** + * The property {@code ours} has been changed in {@code parent} while it was + * also changed to a different value ({@code theirs}) in the persistence store. + * + * @param parent root of the conflict + * @param ours our version of the property + * @param theirs their version of the property + * @param base the base version of the property + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution changeChangedProperty(@Nonnull NodeBuilder parent, @Nonnull PropertyState ours, + @Nonnull PropertyState theirs, @Nonnull PropertyState base); + + /** + * The property {@code ours} has been removed in {@code parent} while it was + * also removed in the persistence store. + * + * @param parent root of the conflict + * @param base the base version of the property + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution deleteDeletedProperty(@Nonnull NodeBuilder parent, @Nonnull PropertyState base); + + /** + * The property {@code theirs} changed in the persistence store while it has been + * deleted locally. + * + * @param parent root of the conflict + * @param theirs their version of the property + * @param base the base version of the property + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution deleteChangedProperty(@Nonnull NodeBuilder parent, @Nonnull PropertyState theirs, + @Nonnull PropertyState base); + + /** + * The node {@code ours} has been added to {@code parent} which conflicts + * with node {@code theirs} which has been added in the persistence store. + * + * @param parent root of the conflict + * @param name name of the node + * @param ours our version of the node + * @param theirs their version of the node + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution addExistingNode(@Nonnull NodeBuilder parent, @Nonnull String name, @Nonnull NodeState ours, + @Nonnull NodeState theirs); + + /** + * The node {@code ours} has been changed in {@code parent} while it was + * removed in the persistence store. + * + * @param parent root of the conflict + * @param name name of the node + * @param ours our version of the node + * @param base the base version of the node + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution changeDeletedNode(@Nonnull NodeBuilder parent, @Nonnull String name, @Nonnull NodeState ours, + @Nonnull NodeState base); + + /** + * The node {@code theirs} changed in the persistence store while it has been + * deleted locally. + * + * @param parent root of the conflict + * @param name name of the node + * @param theirs their version of the node + * @param base the base version of the node + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution deleteChangedNode(@Nonnull NodeBuilder parent, @Nonnull String name, @Nonnull NodeState theirs, + @Nonnull NodeState base); + + /** + * The node {@code name} has been removed in {@code parent} while it was + * also removed in the persistence store. + * + * @param parent root of the conflict + * @param name name of the node + * @param base the base version of the node + * @return {@link Resolution} of the conflict + */ + @Nonnull + Resolution deleteDeletedNode(@Nonnull NodeBuilder parent, @Nonnull String name, @Nonnull NodeState base); +} Propchange: jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/commit/ThreeWayConflictHandler.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java?rev=1798662&r1=1798661&r2=1798662&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java (original) +++ jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiff.java Wed Jun 14 11:03:54 2017 @@ -96,8 +96,9 @@ public abstract class AbstractRebaseDiff * * @param builder parent builder * @param after changed property + * @param base base property */ - protected abstract void changeDeletedProperty(NodeBuilder builder, PropertyState after); + protected abstract void changeDeletedProperty(NodeBuilder builder, PropertyState after, PropertyState base); /** * Called when the property {@code after} was changed on the branch but was @@ -145,8 +146,9 @@ public abstract class AbstractRebaseDiff * @param builder parent builder * @param name name of the changed node * @param after changed node + * @param base base node */ - protected abstract void changeDeletedNode(NodeBuilder builder, String name, NodeState after); + protected abstract void changeDeletedNode(NodeBuilder builder, String name, NodeState after, NodeState base); /** * Called when the node {@code before} was deleted in the branch but was @@ -181,7 +183,7 @@ public abstract class AbstractRebaseDiff public boolean propertyChanged(PropertyState before, PropertyState after) { PropertyState other = builder.getProperty(before.getName()); if (other == null) { - changeDeletedProperty(builder, after); + changeDeletedProperty(builder, after, before); } else if (other.equals(before)) { builder.setProperty(after); } else if (!other.equals(after)) { @@ -220,7 +222,7 @@ public abstract class AbstractRebaseDiff } else if (after.equals(before)) { return false; } else { - changeDeletedNode(builder, name, after); + changeDeletedNode(builder, name, after, before); } return true; } Modified: jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/state/ConflictAnnotatingRebaseDiff.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/state/ConflictAnnotatingRebaseDiff.java?rev=1798662&r1=1798661&r2=1798662&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/state/ConflictAnnotatingRebaseDiff.java (original) +++ jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/spi/state/ConflictAnnotatingRebaseDiff.java Wed Jun 14 11:03:54 2017 @@ -36,6 +36,8 @@ import static org.apache.jackrabbit.oak. */ public class ConflictAnnotatingRebaseDiff extends AbstractRebaseDiff { public static final String CONFLICT = ":conflict"; + public static final String BASE = ":base"; + public static final String OURS = ":ours"; public ConflictAnnotatingRebaseDiff(NodeBuilder builder) { super(builder); @@ -48,47 +50,61 @@ public class ConflictAnnotatingRebaseDif @Override protected void addExistingProperty(NodeBuilder builder, PropertyState before, PropertyState after) { - conflictMarker(builder, ADD_EXISTING_PROPERTY).setProperty(after); + NodeBuilder cb = conflictMarker(builder, ADD_EXISTING_PROPERTY); + cb.child(BASE).setProperty(before); + cb.child(OURS).setProperty(after); } @Override - protected void changeDeletedProperty(NodeBuilder builder, PropertyState after) { - conflictMarker(builder, CHANGE_DELETED_PROPERTY).setProperty(after); + protected void changeDeletedProperty(NodeBuilder builder, PropertyState after, PropertyState base) { + NodeBuilder cb = conflictMarker(builder, CHANGE_DELETED_PROPERTY); + cb.child(BASE).setProperty(base); + cb.child(OURS).setProperty(after); } @Override protected void changeChangedProperty(NodeBuilder builder, PropertyState before, PropertyState after) { - conflictMarker(builder, CHANGE_CHANGED_PROPERTY).setProperty(after); + NodeBuilder cb = conflictMarker(builder, CHANGE_CHANGED_PROPERTY); + cb.child(BASE).setProperty(before); + cb.child(OURS).setProperty(after); } @Override protected void deleteDeletedProperty(NodeBuilder builder, PropertyState before) { - conflictMarker(builder, DELETE_DELETED_PROPERTY).setProperty(before); + NodeBuilder cb = conflictMarker(builder, DELETE_DELETED_PROPERTY); + cb.child(BASE).setProperty(before); } @Override protected void deleteChangedProperty(NodeBuilder builder, PropertyState before) { - conflictMarker(builder, DELETE_CHANGED_PROPERTY).setProperty(before); + NodeBuilder cb = conflictMarker(builder, DELETE_CHANGED_PROPERTY); + cb.child(BASE).setProperty(before); } @Override protected void addExistingNode(NodeBuilder builder, String name, NodeState before, NodeState after) { - conflictMarker(builder, ADD_EXISTING_NODE).setChildNode(name, after); + NodeBuilder cb = conflictMarker(builder, ADD_EXISTING_NODE); + cb.child(BASE).setChildNode(name, before); + cb.child(OURS).setChildNode(name, after); } @Override - protected void changeDeletedNode(NodeBuilder builder, String name, NodeState after) { - conflictMarker(builder, CHANGE_DELETED_NODE).setChildNode(name, after); + protected void changeDeletedNode(NodeBuilder builder, String name, NodeState after, NodeState base) { + NodeBuilder cb = conflictMarker(builder, CHANGE_DELETED_NODE); + cb.child(BASE).setChildNode(name, base); + cb.child(OURS).setChildNode(name, after); } @Override protected void deleteDeletedNode(NodeBuilder builder, String name, NodeState before) { - conflictMarker(builder, DELETE_DELETED_NODE).setChildNode(name, before); + NodeBuilder cb = conflictMarker(builder, DELETE_DELETED_NODE); + cb.child(BASE).setChildNode(name, before); } @Override protected void deleteChangedNode(NodeBuilder builder, String name, NodeState before) { - conflictMarker(builder, DELETE_CHANGED_NODE).setChildNode(name, before); + NodeBuilder cb = conflictMarker(builder, DELETE_CHANGED_NODE); + cb.child(BASE).setChildNode(name, before); } private static NodeBuilder conflictMarker(NodeBuilder builder, ConflictType ct) { Modified: jackrabbit/oak/trunk/oak-store-spi/src/test/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiffTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/test/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiffTest.java?rev=1798662&r1=1798661&r2=1798662&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-spi/src/test/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiffTest.java (original) +++ jackrabbit/oak/trunk/oak-store-spi/src/test/java/org/apache/jackrabbit/oak/spi/state/AbstractRebaseDiffTest.java Wed Jun 14 11:03:54 2017 @@ -77,7 +77,7 @@ public class AbstractRebaseDiffTest { RebaseDiff rebaseDiff = new RebaseDiff(head.builder()) { @Override - protected void changeDeletedProperty(NodeBuilder builder, PropertyState after) { + protected void changeDeletedProperty(NodeBuilder builder, PropertyState after, PropertyState base) { assertEquals(createProperty("y", 0), after); resolve(); } @@ -258,7 +258,7 @@ public class AbstractRebaseDiffTest { RebaseDiff rebaseDiff = new RebaseDiff(head.builder()) { @Override - protected void changeDeletedNode(NodeBuilder builder, String name, NodeState after) { + protected void changeDeletedNode(NodeBuilder builder, String name, NodeState after, NodeState base) { assertEquals("a", name); resolve(); } @@ -337,7 +337,7 @@ public class AbstractRebaseDiffTest { } @Override - protected void changeDeletedProperty(NodeBuilder builder, PropertyState after) { + protected void changeDeletedProperty(NodeBuilder builder, PropertyState after, PropertyState base) { Assert.fail("changeDeletedProperty " + after); } @@ -362,7 +362,7 @@ public class AbstractRebaseDiffTest { } @Override - protected void changeDeletedNode(NodeBuilder builder, String name, NodeState after) { + protected void changeDeletedNode(NodeBuilder builder, String name, NodeState after, NodeState base) { Assert.fail("changeDeletedNode " + name + '=' + after); }
