Return-Path: X-Original-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 22161C04D for ; Wed, 13 Jun 2012 10:45:49 +0000 (UTC) Received: (qmail 72639 invoked by uid 500); 13 Jun 2012 10:45:49 -0000 Delivered-To: apmail-jackrabbit-oak-commits-archive@jackrabbit.apache.org Received: (qmail 72560 invoked by uid 500); 13 Jun 2012 10:45:47 -0000 Mailing-List: contact oak-commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: oak-commits@jackrabbit.apache.org Delivered-To: mailing list oak-commits@jackrabbit.apache.org Received: (qmail 71203 invoked by uid 99); 13 Jun 2012 10:45:43 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Jun 2012 10:45:43 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Jun 2012 10:45:41 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 98F912388AA6; Wed, 13 Jun 2012 10:45:21 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1349742 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/api/ oak-core/src/main/java/org/apache/jackrabbit/oak/core/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ oak-core/src/test/java/org/apac... Date: Wed, 13 Jun 2012 10:45:21 -0000 To: oak-commits@jackrabbit.apache.org From: mduerig@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120613104521.98F912388AA6@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mduerig Date: Wed Jun 13 10:45:20 2012 New Revision: 1349742 URL: http://svn.apache.org/viewvc?rev=1349742&view=rev Log: OAK-133: Session.refresh(true) should allow for manual conflict reconciliation add mechanism for conflict reconciliation to Root.commit() and Root.rebase() Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ConflictHandler.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DefaultConflictHandler.java Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java 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/plugins/name/NamespaceRegistryImpl.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplFuzzIT.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ConflictHandler.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ConflictHandler.java?rev=1349742&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ConflictHandler.java (added) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ConflictHandler.java Wed Jun 13 10:45:20 2012 @@ -0,0 +1,115 @@ +package org.apache.jackrabbit.oak.api; + +import org.apache.jackrabbit.oak.spi.state.NodeState; + +/** + * A {@code ConflictHandler} is responsible for handling conflicts which happen + * on {@link Root#rebase(ConflictHandler)} and on the implicit rebase operation which + * takes part on {@link Root#commit(ConflictHandler)}. + * + * 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 ConflictHandler} + * instance ({@link Resolution#MERGED}). + */ +public interface ConflictHandler { + + /** + * Resolutions for conflicts + */ + enum Resolution { + /** + * Use the changes from the current {@link Root} instance + */ + OURS, + + /** + * Use the changes from the underlying persistence store + */ + THEIRS, + + /** + * Indicated changes have been merged by this {@code ConflictHandler} instance. + */ + MERGED} + + /** + * 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 + */ + Resolution addExistingProperty(Tree parent, PropertyState ours, 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 + * @return {@link Resolution} of the conflict + */ + Resolution changeDeletedProperty(Tree parent, PropertyState ours); + + /** + * 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 + * @return {@link Resolution} of the conflict + */ + Resolution changeChangedProperty(Tree parent, PropertyState ours, PropertyState theirs); + + /** + * 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 + * @return {@link Resolution} of the conflict + */ + Resolution deleteChangedProperty(Tree parent, PropertyState theirs); + + /** + * 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 + */ + Resolution addExistingNode(Tree parent, String name, NodeState ours, 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 + * @return {@link Resolution} of the conflict + */ + Resolution changeDeletedNode(Tree parent, String name, NodeState ours); + + /** + * 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 + * @param theirs their version of the node + * @return {@link Resolution} of the conflict + */ + Resolution deleteChangedNode(Tree parent, String name, NodeState theirs); +} Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java?rev=1349742&r1=1349741&r2=1349742&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Root.java Wed Jun 13 10:45:20 2012 @@ -65,8 +65,10 @@ public interface Root { * Rebase this root to the latest revision. After a call to this method, * all trees obtained through {@link #getTree(String)} become invalid and fresh * instances must be obtained. + * + * @param conflictHandler {@link ConflictHandler} for resolving conflicts. */ - void rebase(); + void rebase(ConflictHandler conflictHandler); /** * Reverts all changes made to this root and refreshed to the latest trunk. @@ -81,9 +83,10 @@ public interface Root { * all trees obtained through {@link #getTree(String)} become invalid and fresh * instances must be obtained. * + * @param conflictHandler {@link ConflictHandler} for resolving conflicts. * @throws CommitFailedException TODO: add description and clarify how JCR exception can be generated from this generic exception */ - void commit() throws CommitFailedException; + void commit(ConflictHandler conflictHandler) throws CommitFailedException; /** * Determine whether there are changes on this tree Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DefaultConflictHandler.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DefaultConflictHandler.java?rev=1349742&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DefaultConflictHandler.java (added) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DefaultConflictHandler.java Wed Jun 13 10:45:20 2012 @@ -0,0 +1,71 @@ +package org.apache.jackrabbit.oak.core; + +import org.apache.jackrabbit.oak.api.ConflictHandler; +import org.apache.jackrabbit.oak.api.PropertyState; +import org.apache.jackrabbit.oak.api.Tree; +import org.apache.jackrabbit.oak.spi.state.NodeState; + +/** + * This implementation of a {@link ConflictHandler} always returns the same resolution. + * It can be used to implement default behaviour or as a base class for more specialised + * implementations. + */ +public class DefaultConflictHandler implements ConflictHandler { + + /** + * A {@code ConflictHandler} which always return {@link Resolution#OURS}. + */ + public static final ConflictHandler OURS = new DefaultConflictHandler(Resolution.OURS); + + /** + * A {@code ConflictHandler} which always return {@link Resolution#THEIRS}. + */ + public static final ConflictHandler THEIRS = new DefaultConflictHandler(Resolution.THEIRS); + + private final Resolution resolution; + + /** + * Create a new {@code ConflictHandler} which always returns {@code resolution}. + * + * @param resolution the resolution to return from all methods of this + * {@code ConflictHandler} instance. + */ + public DefaultConflictHandler(Resolution resolution) { + this.resolution = resolution; + } + + @Override + public Resolution addExistingProperty(Tree parent, PropertyState ours, PropertyState theirs) { + return resolution; + } + + @Override + public Resolution changeDeletedProperty(Tree parent, PropertyState ours) { + return resolution; + } + + @Override + public Resolution changeChangedProperty(Tree parent, PropertyState ours, PropertyState theirs) { + return resolution; + } + + @Override + public Resolution deleteChangedProperty(Tree parent, PropertyState theirs) { + return resolution; + } + + @Override + public Resolution addExistingNode(Tree parent, String name, NodeState ours, NodeState theirs) { + return resolution; + } + + @Override + public Resolution changeDeletedNode(Tree parent, String name, NodeState ours) { + return resolution; + } + + @Override + public Resolution deleteChangedNode(Tree parent, String name, NodeState theirs) { + return resolution; + } +} 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=1349742&r1=1349741&r2=1349742&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 Jun 13 10:45:20 2012 @@ -24,6 +24,8 @@ import java.util.List; import javax.annotation.Nonnull; import org.apache.jackrabbit.oak.api.CommitFailedException; +import org.apache.jackrabbit.oak.api.ConflictHandler; +import org.apache.jackrabbit.oak.api.ConflictHandler.Resolution; import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.Root; import org.apache.jackrabbit.oak.api.Tree; @@ -36,6 +38,7 @@ import org.apache.jackrabbit.oak.spi.sta import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.jackrabbit.oak.api.ConflictHandler.Resolution.*; import static org.apache.jackrabbit.oak.commons.PathUtils.elements; import static org.apache.jackrabbit.oak.commons.PathUtils.getName; import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath; @@ -135,14 +138,14 @@ public class RootImpl implements Root { } @Override - public void rebase() { + public void rebase(ConflictHandler conflictHandler) { purgePendingChanges(); NodeState base = getBaseState(); NodeState head = getCurrentRootState(); currentRootState = null; branch = store.branch(); root = TreeImpl.createRoot(this); - merge(base, head, getRoot()); + merge(base, head, root, conflictHandler); } @Override @@ -153,8 +156,8 @@ public class RootImpl implements Root { } @Override - public void commit() throws CommitFailedException { - rebase(); + public void commit(ConflictHandler conflictHandler) throws CommitFailedException { + rebase(conflictHandler); purgePendingChanges(); branch.merge(); branch = store.branch(); @@ -291,39 +294,160 @@ public class RootImpl implements Root { return child; } - private void merge(NodeState fromState, NodeState toState, final Tree target) { + private void merge(NodeState fromState, NodeState toState, final TreeImpl target, + final ConflictHandler conflictHandler) { + + assert target != null; + store.compare(fromState, toState, new NodeStateDiff() { @Override public void propertyAdded(PropertyState after) { - setProperty(after, target); + Resolution resolution; + PropertyState p = target.getProperty(after.getName()); + + if (p == null) { + resolution = OURS; + } + else if (after.equals(p)) { + resolution = MERGED; + } + else { + resolution = conflictHandler.addExistingProperty(target, after, p); + } + + switch (resolution) { + case OURS: + setProperty(after, target); + break; + case THEIRS: + case MERGED: + break; + } } @Override public void propertyChanged(PropertyState before, PropertyState after) { - setProperty(after, target); + assert before.getName().equals(after.getName()); + + Resolution resolution; + PropertyState p = target.getProperty(after.getName()); + + if (p == null) { + resolution = conflictHandler.changeDeletedProperty(target, after); + } + else if (before.equals(p)) { + resolution = OURS; + } + else if (after.equals(p)) { + resolution = MERGED; + } + else { + resolution = conflictHandler.changeChangedProperty(target, after, p); + } + + switch (resolution) { + case OURS: + setProperty(after, target); + break; + case THEIRS: + case MERGED: + break; + } } @Override public void propertyDeleted(PropertyState before) { - target.removeProperty(before.getName()); + Resolution resolution; + PropertyState p = target.getProperty(before.getName()); + + if (before.equals(p)) { + resolution = OURS; + } + else if (p == null) { + resolution = MERGED; + } + else { + resolution = conflictHandler.deleteChangedProperty(target, p); + } + + switch (resolution) { + case OURS: + target.removeProperty(before.getName()); + break; + case THEIRS: + case MERGED: + break; + } } @Override public void childNodeAdded(String name, NodeState after) { - addChild(name, after, target); + Resolution resolution; + TreeImpl n = target.getChild(name); + + if (n == null) { + resolution = OURS; + } + else { + resolution = conflictHandler.addExistingNode(target, name, after, n.getNodeState()); + } + + switch (resolution) { + case OURS: + addChild(name, after, target); + break; + case THEIRS: + case MERGED: + break; + } } @Override public void childNodeChanged(String name, NodeState before, NodeState after) { - Tree child = target.getChild(name); - if (child != null) { - merge(before, after, child); + Resolution resolution; + TreeImpl n = target.getChild(name); + + if (n == null) { + resolution = conflictHandler.changeDeletedNode(target, name, after); + } + else { + merge(before, after, n, conflictHandler); + resolution = MERGED; + } + + switch (resolution) { + case OURS: + addChild(name, after, target); + break; + case THEIRS: + case MERGED: + break; } } @Override public void childNodeDeleted(String name, NodeState before) { - target.removeChild(name); + Resolution resolution; + TreeImpl n = target.getChild(name); + + if (n == null) { + resolution = MERGED; + } + else if (before.equals(n.getNodeState())) { + resolution = OURS; + } + else { + resolution = conflictHandler.deleteChangedNode(target, name, n.getNodeState()); + } + + switch (resolution) { + case OURS: + target.removeChild(name); + break; + case THEIRS: + case MERGED: + break; + } } private void addChild(String name, NodeState state, Tree target) { Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryImpl.java?rev=1349742&r1=1349741&r2=1349742&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryImpl.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryImpl.java Wed Jun 13 10:45:20 2012 @@ -16,18 +16,19 @@ */ package org.apache.jackrabbit.oak.plugins.name; -import org.apache.jackrabbit.oak.api.CommitFailedException; -import org.apache.jackrabbit.oak.api.ContentSession; -import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.Tree; +import java.util.Arrays; +import java.util.Map; import javax.annotation.Nonnull; import javax.jcr.NamespaceException; import javax.jcr.NamespaceRegistry; import javax.jcr.RepositoryException; -import java.util.Arrays; -import java.util.Map; +import org.apache.jackrabbit.oak.api.CommitFailedException; +import org.apache.jackrabbit.oak.api.ContentSession; +import org.apache.jackrabbit.oak.api.Root; +import org.apache.jackrabbit.oak.api.Tree; +import org.apache.jackrabbit.oak.core.DefaultConflictHandler; /** * Implementation of {@link NamespaceRegistry} based on {@link NamespaceMappings}. @@ -50,7 +51,7 @@ public class NamespaceRegistryImpl imple Tree namespaces = getOrCreate(root, "jcr:system", Namespaces.NSMAPNODENAME); namespaces.setProperty( prefix, session.getCoreValueFactory().createValue(uri)); - root.commit(); + root.commit(DefaultConflictHandler.OURS); } catch (NamespaceValidatorException e) { throw e.getNamespaceException(); } catch (CommitFailedException e) { @@ -72,7 +73,7 @@ public class NamespaceRegistryImpl imple "Namespace mapping from " + prefix + " to " + getURI(prefix) + " can not be unregistered"); } - root.commit(); + root.commit(DefaultConflictHandler.OURS); } catch (NamespaceValidatorException e) { throw e.getNamespaceException(); } catch (CommitFailedException e) { Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplFuzzIT.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplFuzzIT.java?rev=1349742&r1=1349741&r2=1349742&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplFuzzIT.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplFuzzIT.java Wed Jun 13 10:45:20 2012 @@ -18,6 +18,9 @@ */ package org.apache.jackrabbit.oak.core; +import java.util.Iterator; +import java.util.Random; + import org.apache.jackrabbit.mk.api.MicroKernel; import org.apache.jackrabbit.mk.core.MicroKernelImpl; import org.apache.jackrabbit.oak.api.CoreValue; @@ -32,9 +35,6 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Iterator; -import java.util.Random; - import static org.apache.jackrabbit.oak.core.RootImplFuzzIT.Operation.AddNode; import static org.apache.jackrabbit.oak.core.RootImplFuzzIT.Operation.CopyNode; import static org.apache.jackrabbit.oak.core.RootImplFuzzIT.Operation.MoveNode; @@ -97,10 +97,10 @@ public class RootImplFuzzIT { op.apply(root2); checkEqual(root1.getTree("/"), root2.getTree("/")); - root1.commit(); + root1.commit(DefaultConflictHandler.OURS); checkEqual(root1.getTree("/"), root2.getTree("/")); if (op instanceof Save) { - root2.commit(); + root2.commit(DefaultConflictHandler.OURS); assertEquals(store1.getRoot(), store2.getRoot()); } } @@ -273,7 +273,7 @@ public class RootImplFuzzIT { static class Rebase extends Operation { @Override void apply(RootImpl root) { - root.rebase(); + root.rebase(DefaultConflictHandler.OURS); } @Override Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java?rev=1349742&r1=1349741&r2=1349742&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java Wed Jun 13 10:45:20 2012 @@ -18,6 +18,14 @@ */ package org.apache.jackrabbit.oak.core; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.jcr.PropertyType; + import org.apache.jackrabbit.mk.api.MicroKernel; import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.CoreValue; @@ -27,13 +35,6 @@ import org.apache.jackrabbit.oak.api.Tre import org.apache.jackrabbit.oak.spi.state.NodeState; import org.junit.Test; -import javax.jcr.PropertyType; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -128,7 +129,7 @@ public class RootImplTest extends Abstra assertEquals("new", added.getName()); assertTrue(tree.hasChild("new")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertTrue(tree.hasChild("new")); @@ -145,7 +146,7 @@ public class RootImplTest extends Abstra assertFalse(tree.hasChild("new")); tree.addChild("new"); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertTrue(tree.hasChild("new")); @@ -163,7 +164,7 @@ public class RootImplTest extends Abstra tree.removeChild("x"); assertFalse(tree.hasChild("x")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertFalse(tree.hasChild("x")); @@ -182,7 +183,7 @@ public class RootImplTest extends Abstra assertEquals("new", property.getName()); assertEquals(value, property.getValue()); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); property = tree.getProperty("new"); @@ -200,7 +201,7 @@ public class RootImplTest extends Abstra tree.removeProperty("a"); assertFalse(tree.hasProperty("a")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertFalse(tree.hasProperty("a")); @@ -218,7 +219,7 @@ public class RootImplTest extends Abstra assertFalse(tree.hasChild("x")); assertTrue(y.hasChild("xx")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertFalse(tree.hasChild("x")); @@ -250,7 +251,7 @@ public class RootImplTest extends Abstra assertFalse(tree.hasChild("x")); assertTrue(tree.hasChild("xx")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertFalse(tree.hasChild("x")); @@ -269,7 +270,7 @@ public class RootImplTest extends Abstra assertTrue(tree.hasChild("x")); assertTrue(y.hasChild("xx")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertTrue(tree.hasChild("x")); @@ -289,7 +290,7 @@ public class RootImplTest extends Abstra assertTrue(y.hasChild("xx")); assertTrue(y.getChild("xx").hasChild("x1")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertTrue(tree.hasChild("x")); @@ -346,12 +347,12 @@ public class RootImplTest extends Abstra Tree tree = root.getTree("/"); tree.setProperty("P0", valueFactory.createValue("V1")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertTrue(tree.hasProperty("P0")); tree.removeProperty("P0"); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertFalse(tree.hasProperty("P0")); } @@ -363,21 +364,21 @@ public class RootImplTest extends Abstra tree.addChild("new"); assertEquals(Status.NEW, tree.getChildStatus("new")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertEquals(Status.EXISTING, tree.getChildStatus("new")); Tree added = tree.getChild("new"); added.addChild("another"); assertEquals(Status.MODIFIED, tree.getChildStatus("new")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertEquals(Status.EXISTING, tree.getChildStatus("new")); tree.getChild("new").removeChild("another"); assertEquals(Status.MODIFIED, tree.getChildStatus("new")); assertEquals(Status.REMOVED, tree.getChild("new").getChildStatus("another")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertEquals(Status.EXISTING, tree.getChildStatus("new")); @@ -394,19 +395,19 @@ public class RootImplTest extends Abstra tree.setProperty("new", value1); assertEquals(Status.NEW, tree.getPropertyStatus("new")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertEquals(Status.EXISTING, tree.getPropertyStatus("new")); tree.setProperty("new", value2); assertEquals(Status.MODIFIED, tree.getPropertyStatus("new")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertEquals(Status.EXISTING, tree.getPropertyStatus("new")); tree.removeProperty("new"); assertEquals(Status.REMOVED, tree.getPropertyStatus("new")); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); assertNull(tree.getPropertyStatus("new")); @@ -417,7 +418,7 @@ public class RootImplTest extends Abstra RootImpl root = new RootImpl(store, null); Tree tree = root.getTree("/"); tree.addChild("one").addChild("two"); - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); tree.getChild("one").getChild("two").addChild("three"); @@ -435,17 +436,17 @@ public class RootImplTest extends Abstra CoreValue value = valueFactory.createValue("V1"); root2.getTree("/").addChild("one").addChild("two").addChild("three") .setProperty("p1", value); - root2.commit(); + root2.commit(DefaultConflictHandler.OURS); - root1.rebase(); + root1.rebase(DefaultConflictHandler.OURS); checkEqual(root1.getTree("/"), (root2.getTree("/"))); Tree one = root2.getTree("/one"); one.removeChild("two"); one.addChild("four"); - root2.commit(); + root2.commit(DefaultConflictHandler.OURS); - root1.rebase(); + root1.rebase(DefaultConflictHandler.OURS); checkEqual(root1.getTree("/"), (root2.getTree("/"))); } @@ -464,7 +465,7 @@ public class RootImplTest extends Abstra tree.addChild(name); } - root.commit(); + root.commit(DefaultConflictHandler.OURS); tree = root.getTree("/"); tree = tree.getChild("large"); Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java?rev=1349742&r1=1349741&r2=1349742&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (original) +++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java Wed Jun 13 10:45:20 2012 @@ -16,6 +16,26 @@ */ package org.apache.jackrabbit.oak.jcr; +import java.io.IOException; +import java.text.ParseException; +import java.util.Collections; +import java.util.Map; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import javax.jcr.ItemExistsException; +import javax.jcr.Node; +import javax.jcr.PathNotFoundException; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Workspace; +import javax.jcr.lock.LockManager; +import javax.jcr.nodetype.NodeTypeManager; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; +import javax.jcr.version.VersionManager; + import org.apache.jackrabbit.oak.api.AuthInfo; import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.ContentSession; @@ -26,6 +46,7 @@ import org.apache.jackrabbit.oak.api.Res import org.apache.jackrabbit.oak.api.Root; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.commons.PathUtils; +import org.apache.jackrabbit.oak.core.DefaultConflictHandler; import org.apache.jackrabbit.oak.jcr.value.ValueFactoryImpl; import org.apache.jackrabbit.oak.namepath.AbstractNameMapper; import org.apache.jackrabbit.oak.namepath.NameMapper; @@ -34,25 +55,6 @@ import org.apache.jackrabbit.oak.namepat import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; -import javax.jcr.ItemExistsException; -import javax.jcr.Node; -import javax.jcr.PathNotFoundException; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.Workspace; -import javax.jcr.lock.LockManager; -import javax.jcr.nodetype.NodeTypeManager; -import javax.jcr.query.Query; -import javax.jcr.query.QueryManager; -import javax.jcr.version.VersionManager; -import java.io.IOException; -import java.text.ParseException; -import java.util.Collections; -import java.util.Map; - public class SessionDelegate { static final Logger log = LoggerFactory.getLogger(SessionDelegate.class); @@ -166,7 +168,7 @@ public class SessionDelegate { public void save() throws RepositoryException { try { - root.commit(); + root.commit(DefaultConflictHandler.OURS); } catch (CommitFailedException e) { throw new RepositoryException(e); @@ -175,7 +177,7 @@ public class SessionDelegate { public void refresh(boolean keepChanges) { if (keepChanges) { - root.rebase(); + root.rebase(DefaultConflictHandler.OURS); } else { root.refresh(); @@ -285,7 +287,7 @@ public class SessionDelegate { try { Root currentRoot = contentSession.getCurrentRoot(); currentRoot.copy(srcPath, destPath); - currentRoot.commit(); + currentRoot.commit(DefaultConflictHandler.OURS); } catch (CommitFailedException e) { throw new RepositoryException(e); @@ -321,7 +323,7 @@ public class SessionDelegate { try { moveRoot.move(srcPath, destPath); if (!transientOp) { - moveRoot.commit(); + moveRoot.commit(DefaultConflictHandler.OURS); } } catch (CommitFailedException e) { 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=1349742&r1=1349741&r2=1349742&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 Wed Jun 13 10:45:20 2012 @@ -1230,7 +1230,12 @@ public class RepositoryTest extends Abst session2.save(); assertFalse(session1.getRootNode().hasNode("node")); - assertFalse(session2.getRootNode().hasNode("node")); // TODO: is this correct? + assertTrue(session2.getRootNode().hasNode("node")); + assertTrue(session2.getRootNode().getNode("node").hasNode("2")); + + session1.refresh(true); + assertTrue(session1.getRootNode().hasNode("node")); + assertTrue(session1.getRootNode().getNode("node").hasNode("2")); } finally { session1.logout();