Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2013-09-02 10:17:36 +0000
committerEike Stepper2013-09-02 10:17:36 +0000
commit74ceb220da0444f0e5bfcbb5c163d83f110b1502 (patch)
treeed5b3b0e512d596d07722065352d5a50a3df552f
parentabefd583047c0b12a232885511c573e3478ae41f (diff)
downloadcdo-74ceb220da0444f0e5bfcbb5c163d83f110b1502.tar.gz
cdo-74ceb220da0444f0e5bfcbb5c163d83f110b1502.tar.xz
cdo-74ceb220da0444f0e5bfcbb5c163d83f110b1502.zip
[396804] CDOMergingConflictResolver tests
https://bugs.eclipse.org/bugs/show_bug.cgi?id=396804
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ConflictResolverExtendedTest.java155
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOConflictResolver.java11
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java17
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java10
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractChangeSetsConflictResolver.java29
6 files changed, 87 insertions, 141 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ConflictResolverExtendedTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ConflictResolverExtendedTest.java
index cf1af1b831..754b337e54 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ConflictResolverExtendedTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ConflictResolverExtendedTest.java
@@ -14,10 +14,8 @@ import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.CDOCommonSession;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
-import org.eclipse.emf.cdo.tests.config.IConfig;
import org.eclipse.emf.cdo.tests.config.IModelConfig;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
-import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Skips;
import org.eclipse.emf.cdo.tests.model6.BaseObject;
import org.eclipse.emf.cdo.tests.model6.ContainmentObject;
@@ -41,8 +39,6 @@ import java.util.List;
/**
* @author Pascal Lehmann
*/
-// TODO Remove Me
-@Requires(IConfig.CAPABILITY_UNAVAILABLE)
@Skips(IModelConfig.CAPABILITY_LEGACY)
@CleanRepositoriesBefore
public class ConflictResolverExtendedTest extends AbstractCDOTest
@@ -3186,10 +3182,12 @@ public class ConflictResolverExtendedTest extends AbstractCDOTest
CDOTransaction thatTransaction = session.openTransaction();
addConflictResolver(thatTransaction);
+ // Access objects.
Root thisRoot = getTestModelRoot(thisTransaction);
- EList<BaseObject> thisList = thisRoot.getListB();
-
Root thatRoot = thatTransaction.getObject(thisRoot);
+
+ // Access lists.
+ EList<BaseObject> thisList = thisRoot.getListB();
EList<BaseObject> thatList = thatRoot.getListB();
// Attach adapters
@@ -3197,9 +3195,7 @@ public class ConflictResolverExtendedTest extends AbstractCDOTest
thatRoot.eAdapters().add(new ListPrintingAdapter("That root: "));
// Remove containment
- ContainmentObject thisToRemoveContainment = (ContainmentObject)thisList.get(0);
thisList.remove(0);
- ContainmentObject thisAfterRemoveContainment = (ContainmentObject)thisList.get(0);
ContainmentObject thatAddContainment = createContainmentObject("AddContainmentObject 0");
thatAddContainment.setAttributeRequired("AddContainmentObject 0");
@@ -3218,21 +3214,10 @@ public class ConflictResolverExtendedTest extends AbstractCDOTest
thatParentList.add(thatReattachContainment);
commitAndSync(thisTransaction, thatTransaction);
- commitAndSync(thatTransaction, thisTransaction);
-
- // Print contents of lists
- printList("This ", thisList);
- printList("That ", thatList);
-
- // Check indices
assertEquals(false, thisTransaction.isDirty());
- assertEquals(false, thatTransaction.isDirty());
- assertEquals(thisAfterRemoveContainment, thisList.get(0));
- assertEquals(thatTransaction.getObject(thisAfterRemoveContainment), thatList.get(0));
- assertEquals(CDOState.TRANSIENT, CDOUtil.getCDOObject(thisToRemoveContainment).cdoState());
- assertEquals(CDOState.INVALID, CDOUtil.getCDOObject(thatParent).cdoState());
- assertEquals(CDOState.INVALID, CDOUtil.getCDOObject(thatReattachContainment).cdoState());
- assertEquals(CDOState.NEW, CDOUtil.getCDOObject(thatAddContainment).cdoState());
+ assertEquals(false, thisTransaction.hasConflict());
+ assertEquals(true, thatTransaction.isDirty());
+ assertEquals(true, thatTransaction.hasConflict());
}
public void testRemoveHeadSetChildHead() throws Exception
@@ -3324,8 +3309,6 @@ public class ConflictResolverExtendedTest extends AbstractCDOTest
thatRoot.eAdapters().add(new ListPrintingAdapter("That root: "));
// Remove containment.
- ContainmentObject thisToRemoveContainment = (ContainmentObject)thisRoot.getListB().get(0);
- ContainmentObject thisAfterRemoveContainment = (ContainmentObject)thisRoot.getListB().get(1);
thisRoot.getListB().remove(0);
// Get parent object.
@@ -3335,24 +3318,13 @@ public class ConflictResolverExtendedTest extends AbstractCDOTest
ContainmentObject thatChildContainment = (ContainmentObject)thatParent.getContainmentList().get(0);
// Remove child from containment child.
- BaseObject thatDetachContainment = thatChildContainment.getContainmentList().remove(0);
+ thatChildContainment.getContainmentList().remove(0);
commitAndSync(thisTransaction, thatTransaction);
- commitAndSync(thatTransaction, thisTransaction);
-
- // Print contents of lists
- printList("This ", thisRoot.getListB());
- printList("That ", thatRoot.getListB());
-
- // Check indices.
assertEquals(false, thisTransaction.isDirty());
- assertEquals(false, thatTransaction.isDirty());
- assertEquals(thisAfterRemoveContainment, thisRoot.getListB().get(0));
- assertEquals(thatTransaction.getObject(thisAfterRemoveContainment), thatRoot.getListB().get(0));
-
- assertEquals(CDOState.TRANSIENT, CDOUtil.getCDOObject(thisToRemoveContainment).cdoState());
- assertEquals(CDOState.INVALID, CDOUtil.getCDOObject(thatParent).cdoState());
- assertEquals(CDOState.TRANSIENT, CDOUtil.getCDOObject(thatDetachContainment).cdoState());
+ assertEquals(false, thisTransaction.hasConflict());
+ assertEquals(true, thatTransaction.isDirty());
+ assertEquals(true, thatTransaction.hasConflict());
}
public void testRemoveHeadMoveChildHead() throws Exception
@@ -3373,8 +3345,6 @@ public class ConflictResolverExtendedTest extends AbstractCDOTest
thatRoot.eAdapters().add(new ListPrintingAdapter("That root: "));
// Remove containment.
- ContainmentObject thisToRemoveContainment = (ContainmentObject)thisRoot.getListB().get(0);
- ContainmentObject thisAfterRemoveContainment = (ContainmentObject)thisRoot.getListB().get(1);
thisRoot.getListB().remove(0);
// Add child to containment.
@@ -3394,22 +3364,10 @@ public class ConflictResolverExtendedTest extends AbstractCDOTest
thatParent.getContainmentList().add(thatReattachContainment);
commitAndSync(thisTransaction, thatTransaction);
- commitAndSync(thatTransaction, thisTransaction);
-
- // Print contents of lists
- printList("This ", thisRoot.getListB());
- printList("That ", thatRoot.getListB());
-
- // Check indices.
assertEquals(false, thisTransaction.isDirty());
- assertEquals(false, thatTransaction.isDirty());
- assertEquals(thisAfterRemoveContainment, thisRoot.getListB().get(0));
- assertEquals(thatTransaction.getObject(thisAfterRemoveContainment), thatRoot.getListB().get(0));
-
- assertEquals(CDOState.TRANSIENT, CDOUtil.getCDOObject(thisToRemoveContainment).cdoState());
- assertEquals(CDOState.INVALID, CDOUtil.getCDOObject(thatParent).cdoState());
- assertEquals(CDOState.INVALID, CDOUtil.getCDOObject(thatReattachContainment).cdoState());
- assertEquals(CDOState.NEW, CDOUtil.getCDOObject(thatAddContainment).cdoState());
+ assertEquals(false, thisTransaction.hasConflict());
+ assertEquals(true, thatTransaction.isDirty());
+ assertEquals(true, thatTransaction.hasConflict());
}
public void testRemoveHeadReAttachHead() throws Exception
@@ -3466,75 +3424,52 @@ public class ConflictResolverExtendedTest extends AbstractCDOTest
addConflictResolver(thatTransaction);
// Create initial model.
- Root root = getTestModelRoot(thisTransaction);
- ContainmentObject group1 = createContainmentObject("Group 1");
- group1.setAttributeRequired("Group 1");
+ Root thisRoot = getTestModelRoot(thisTransaction);
+ EList<BaseObject> thisListC = thisRoot.getListC();
+
+ ContainmentObject thisGroup1 = createContainmentObject("Group 1");
+ thisGroup1.setAttributeRequired("Group 1");
- ContainmentObject group2 = createContainmentObject("Group 2");
- group2.setAttributeRequired("Group 2");
+ ContainmentObject thisGroup2 = createContainmentObject("Group 2");
+ thisGroup2.setAttributeRequired("Group 2");
- BaseObject element0 = createBaseObject("Element 0");
- element0.setAttributeRequired("Element 0");
+ BaseObject thisElement0 = createBaseObject("Element 0");
+ thisElement0.setAttributeRequired("Element 0");
- BaseObject element1 = createBaseObject("Element 1");
- element1.setAttributeRequired("Element 1");
+ BaseObject thisElement1 = createBaseObject("Element 1");
+ thisElement1.setAttributeRequired("Element 1");
- BaseObject element2 = createBaseObject("Element 2");
- element2.setAttributeRequired("Element 2");
+ BaseObject thisElement2 = createBaseObject("Element 2");
+ thisElement2.setAttributeRequired("Element 2");
- root.getListC().add(group1);
- root.getListC().add(group2);
- root.getListC().add(element0);
- root.getListC().add(element1);
- root.getListC().add(element2);
+ thisListC.add(thisGroup1);
+ thisListC.add(thisGroup2);
+ thisListC.add(thisElement0);
+ thisListC.add(thisElement1);
+ thisListC.add(thisElement2);
commitAndSync(thisTransaction, thatTransaction);
// Get objects from that transaction.
- ContainmentObject thatGroup1 = thatTransaction.getObject(group1);
- ContainmentObject thatGroup2 = thatTransaction.getObject(group2);
- BaseObject thatElement0 = thatTransaction.getObject(element0);
- BaseObject thatElement1 = thatTransaction.getObject(element1);
- BaseObject thatElement2 = thatTransaction.getObject(element2);
- Root thatRoot = thatTransaction.getObject(root);
+ ContainmentObject thatGroup2 = thatTransaction.getObject(thisGroup2);
+ BaseObject thatElement1 = thatTransaction.getObject(thisElement1);
+ BaseObject thatElement2 = thatTransaction.getObject(thisElement2);
- // Create group 1 (element 0 & 1).
- root.getListC().remove(element0);
- group1.getContainmentList().add(element0);
- root.getListC().remove(element1);
- group1.getContainmentList().add(element1);
+ // THIS: Create group 1 (element 0 & 1).
+ thisGroup1.getContainmentList().add(thisElement0); // Move element0 from listC to group1
+ thisGroup1.getContainmentList().add(thisElement1); // Move element1 from listC to group1
- // Create group 2 (element 1 & 2).
- thatRoot.getListC().remove(thatElement1);
- thatGroup2.getContainmentList().add(thatElement1);
- thatRoot.getListC().remove(thatElement2);
- thatGroup2.getContainmentList().add(thatElement2);
+ // THAT: Create group 2 (element 1 & 2).
+ thatGroup2.getContainmentList().add(thatElement1); // Move element1 from listC to group2 (CONFLICT)
+ thatGroup2.getContainmentList().add(thatElement2); // Move element2 from listC to group2
commitAndSync(thisTransaction, thatTransaction);
- commitAndSync(thatTransaction, thisTransaction);
-
- // -- Check:
- assertEquals(2, root.getListC().size()); // 2 groups.
- assertEquals(group1, element0.eContainer());
- assertEquals(group2, element1.eContainer());
- assertEquals(group2, element2.eContainer());
- assertEquals(1, group1.getContainmentList().size()); // 1 element.
- assertEquals(2, group2.getContainmentList().size()); // 2 elements.
-
- assertEquals(2, thatRoot.getListC().size()); // 2 groups.
- assertEquals(thatGroup1, thatElement0.eContainer());
- assertEquals(thatGroup2, thatElement1.eContainer());
- assertEquals(thatGroup2, thatElement2.eContainer());
- assertEquals(1, thatGroup1.getContainmentList().size()); // 1 element.
- assertEquals(2, thatGroup2.getContainmentList().size()); // 2 elements.
+ assertEquals(false, thisTransaction.isDirty());
+ assertEquals(false, thisTransaction.hasConflict());
+ assertEquals(true, thatTransaction.isDirty());
+ assertEquals(true, thatTransaction.hasConflict());
}
- // --- container conflict resolver tests -----------------------------------
- // TODO: convert them into CDOTests
-
- // --- random conflict resolver tests --------------------------------------
- // TODO: convert them into CDOTests
-
// ========== HELPERS ======================================================
protected BaseObject createBaseObject(String attribute)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOConflictResolver.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOConflictResolver.java
index 69906fdf48..6ed4ddec96 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOConflictResolver.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOConflictResolver.java
@@ -37,4 +37,15 @@ public interface CDOConflictResolver
* Resolves conflicts after remote invalidations arrived for objects that are locally dirty or detached.
*/
public void resolveConflicts(Set<CDOObject> conflicts);
+
+ /**
+ * A mix-in interface for {@link CDOConflictResolver conflict resolvers} that need to know about non-conflicting invalidations.
+ *
+ * @author Eike Stepper
+ * @since 4.3
+ */
+ public interface NonConflictAware extends CDOConflictResolver
+ {
+ public void handleNonConflict(long updateTime);
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
index 150f169b18..360e004d7d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
@@ -713,8 +713,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
* Synchronized through InvalidationRunnable.run()
*/
@Override
- protected synchronized void handleConflicts(Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts,
- List<CDORevisionDelta> deltas)
+ protected synchronized void handleConflicts(long lastUpdateTime,
+ Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts, List<CDORevisionDelta> deltas)
{
CDOConflictResolver[] resolvers = options().getConflictResolvers();
if (resolvers.length == 0)
@@ -722,6 +722,19 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return;
}
+ if (conflicts == null)
+ {
+ for (CDOConflictResolver resolver : resolvers)
+ {
+ if (resolver instanceof CDOConflictResolver.NonConflictAware)
+ {
+ ((CDOConflictResolver.NonConflictAware)resolver).handleNonConflict(lastUpdateTime);
+ }
+ }
+
+ return;
+ }
+
// Remember original state to be able to restore it after an exception
List<CDOState> states = new ArrayList<CDOState>(conflicts.size());
List<CDORevision> revisions = new ArrayList<CDORevision>(conflicts.size());
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java
index 5fb41eb109..32ff383646 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java
@@ -1536,10 +1536,10 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
}
/**
- * Overridden by {@link CDOTransactionImpl#handleConflicts(Map, List)}.
+ * Overridden by {@link CDOTransactionImpl#handleConflicts(long, Map, List)}.
*/
- protected synchronized void handleConflicts(Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts,
- List<CDORevisionDelta> deltas)
+ protected synchronized void handleConflicts(long lastUpdateTime,
+ Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts, List<CDORevisionDelta> deltas)
{
// Do nothing
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
index 2068ff09eb..00a088899d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
@@ -867,13 +867,9 @@ public class CDOViewImpl extends AbstractCDOView
Map<CDOObject, CDORevisionDelta> revisionDeltas = new HashMap<CDOObject, CDORevisionDelta>();
Set<CDOObject> detachedObjects = new HashSet<CDOObject>();
- Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> //
- conflicts = invalidate(allChangedObjects, allDetachedObjects, deltas, revisionDeltas, detachedObjects);
- if (conflicts != null)
- {
- // First handle the conflicts, if any.
- handleConflicts(conflicts, deltas);
- }
+ Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts = invalidate(allChangedObjects,
+ allDetachedObjects, deltas, revisionDeltas, detachedObjects);
+ handleConflicts(lastUpdateTime, conflicts, deltas);
sendInvalidationNotifications(revisionDeltas.keySet(), detachedObjects);
fireInvalidationEvent(lastUpdateTime, Collections.unmodifiableMap(revisionDeltas),
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractChangeSetsConflictResolver.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractChangeSetsConflictResolver.java
index 2e0c8f306e..f4b405a798 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractChangeSetsConflictResolver.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractChangeSetsConflictResolver.java
@@ -17,13 +17,10 @@ import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.transaction.CDOCommitContext;
+import org.eclipse.emf.cdo.transaction.CDOConflictResolver.NonConflictAware;
import org.eclipse.emf.cdo.transaction.CDODefaultTransactionHandler;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler;
-import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
-
-import org.eclipse.net4j.util.event.IEvent;
-import org.eclipse.net4j.util.event.IListener;
/**
* If the meaning of this type isn't clear, there really should be more of a description here...
@@ -31,7 +28,7 @@ import org.eclipse.net4j.util.event.IListener;
* @author Eike Stepper
* @since 4.0
*/
-public abstract class AbstractChangeSetsConflictResolver extends AbstractConflictResolver
+public abstract class AbstractChangeSetsConflictResolver extends AbstractConflictResolver implements NonConflictAware
{
private CDOTransactionHandler handler = new CDODefaultTransactionHandler()
{
@@ -66,18 +63,6 @@ public abstract class AbstractChangeSetsConflictResolver extends AbstractConflic
}
};
- private IListener listener = new IListener()
- {
- public void notifyEvent(IEvent event)
- {
- if (event instanceof CDOViewInvalidationEvent)
- {
- long timeStamp = ((CDOViewInvalidationEvent)event).getTimeStamp();
- remoteInvalidationEvents.remove(timeStamp);
- }
- }
- };
-
private CDOChangeSubscriptionAdapter adapter;
private RemoteInvalidationEventQueue remoteInvalidationEvents;
@@ -113,6 +98,14 @@ public abstract class AbstractChangeSetsConflictResolver extends AbstractConflic
return createChangeSet(changeSetData);
}
+ /**
+ * @since 4.3
+ */
+ public void handleNonConflict(long updateTime)
+ {
+ remoteInvalidationEvents.remove(updateTime);
+ }
+
@Override
protected void hookTransaction(CDOTransaction transaction)
{
@@ -120,13 +113,11 @@ public abstract class AbstractChangeSetsConflictResolver extends AbstractConflic
remoteInvalidationEvents = new RemoteInvalidationEventQueue();
transaction.addTransactionHandler(handler);
- transaction.addListener(listener);
}
@Override
protected void unhookTransaction(CDOTransaction transaction)
{
- transaction.removeListener(listener);
transaction.removeTransactionHandler(handler);
remoteInvalidationEvents.dispose();

Back to the top