Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2008-12-13 21:29:44 +0000
committerEike Stepper2008-12-13 21:29:44 +0000
commit9f42414414409ee0af9b16b53d63255f2c7a2a51 (patch)
tree53577f51a7680a68e18798ef06240133f8a9db65 /plugins/org.eclipse.emf.cdo
parent6b56bd26a06e71265f8e8434981c5f31f13e05e6 (diff)
downloadcdo-9f42414414409ee0af9b16b53d63255f2c7a2a51.tar.gz
cdo-9f42414414409ee0af9b16b53d63255f2c7a2a51.tar.xz
cdo-9f42414414409ee0af9b16b53d63255f2c7a2a51.zip
[257372] Handle conflict object without rollback the view completely
https://bugs.eclipse.org/bugs/show_bug.cgi?id=257372
Diffstat (limited to 'plugins/org.eclipse.emf.cdo')
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOConflictResolver.java3
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java11
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java84
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java4
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/ObjectConflictResolver.java60
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/TakeRemoteChangesAndReApplyLocalChangesConflictResolver.java37
7 files changed, 137 insertions, 68 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOConflictResolver.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOConflictResolver.java
index 61e032cabc..060e1f5028 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOConflictResolver.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOConflictResolver.java
@@ -35,9 +35,6 @@ public interface CDOConflictResolver
* Resolves conflicts after remote invalidations arrived for objects that are locally dirty or detached.
* <p>
* The implementor might want to use/extend {@link ObjectConflictResolver}.
- * <p>
- * <b>Important:</b> Those conflicts that are resolved by the implementation of this method <b>must</b> be removed
- * from the passed set of conflicts!
*/
public void resolveConflicts(CDOTransaction transaction, Set<CDOObject> conflicts);
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
index 1ad7af3165..5b5d8d3961 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
@@ -23,6 +23,7 @@ import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.resource.ResourceSet;
import java.util.Map;
+import java.util.Set;
/**
* A read-write view to the <em>current</em> (i.e. latest) state of the object graph in the repository.
@@ -53,6 +54,16 @@ public interface CDOTransaction extends CDOView, CDOUserTransaction
public boolean hasConflict();
/**
+ * @since 2.0
+ */
+ public Set<CDOObject> getConflicts();
+
+ /**
+ * @since 2.0
+ */
+ public void resolveConflicts(CDOConflictResolver resolver);
+
+ /**
* @see ResourceSet#createResource(URI)
*/
public CDOResource createResource(String path);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
index e1e76d2d6d..b2782e5b2f 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
@@ -50,6 +50,7 @@ import org.eclipse.emf.internal.cdo.util.ModelUtil;
import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.event.Notifier;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.transaction.TransactionException;
@@ -65,6 +66,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -88,7 +90,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
private boolean dirty;
- private boolean conflict;
+ private int conflict;
private CDOConflictResolver conflictResolver;
@@ -161,19 +163,53 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
public boolean hasConflict()
{
checkOpen();
- return conflict;
+ return conflict != 0;
}
public void setConflict(InternalCDOObject object)
{
- ConflictEvent event = new ConflictEvent(object, !conflict);
- conflict = true;
+ ConflictEvent event = new ConflictEvent(object, conflict == 0);
+ ++conflict;
fireEvent(event);
}
/**
* @since 2.0
*/
+ public Set<CDOObject> getConflicts()
+ {
+ Set<CDOObject> conflicts = new HashSet<CDOObject>();
+ for (CDOObject object : getDirtyObjects().values())
+ {
+ if (FSMUtil.isConflict(object))
+ {
+ conflicts.add(object);
+ }
+ }
+
+ for (CDOObject object : getDetachedObjects().values())
+ {
+ if (FSMUtil.isConflict(object))
+ {
+ conflicts.add(object);
+ }
+ }
+
+ return conflicts;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void resolveConflicts(CDOConflictResolver resolver)
+ {
+ Set<CDOObject> conflicts = getConflicts();
+ handleConflicts(conflicts, resolver);
+ }
+
+ /**
+ * @since 2.0
+ */
public synchronized CDOConflictResolver getConflictResolver()
{
if (conflictResolver == null)
@@ -203,10 +239,42 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
@Override
protected void handleConflicts(Set<CDOObject> conflicts)
{
- getConflictResolver().resolveConflicts(this, conflicts);
- if (conflicts.isEmpty())
+ handleConflicts(conflicts, getConflictResolver());
+ }
+
+ private void handleConflicts(Set<CDOObject> conflicts, CDOConflictResolver resolver)
+ {
+ List<CDOState> states = new ArrayList<CDOState>(conflicts.size());
+ List<CDORevision> revisions = new ArrayList<CDORevision>(conflicts.size());
+ for (CDOObject conflict : conflicts)
+ {
+ states.add(conflict.cdoState());
+ revisions.add(conflict.cdoRevision());
+ }
+
+ try
+ {
+ resolver.resolveConflicts(this, Collections.unmodifiableSet(conflicts));
+ }
+ catch (Exception ex)
+ {
+ Iterator<CDOState> state = states.iterator();
+ Iterator<CDORevision> revision = revisions.iterator();
+ for (CDOObject object : conflicts)
+ {
+ ((InternalCDOObject)object).cdoInternalSetState(state.next());
+ ((InternalCDOObject)object).cdoInternalSetRevision(revision.next());
+ }
+
+ throw WrappedException.wrap(ex);
+ }
+
+ for (CDOObject object : conflicts)
{
- conflict = false;
+ if (!FSMUtil.isConflict(object))
+ {
+ --conflict;
+ }
}
}
@@ -1030,7 +1098,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
firstSavepoint.setNextSavepoint(null);
firstSavepoint.getSharedDetachedObjects().clear();
dirty = false;
- conflict = false;
+ conflict = 0;
lastTemporaryID = 0;
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
index 1797aa7044..8d01324b0e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
@@ -1187,7 +1187,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
{
CDOStateMachine.INSTANCE.invalidate(dirtyObject, dirtyOID.getVersion());
dirtyObjects.add(dirtyObject);
- if (dirtyObject.cdoState() == CDOState.CONFLICT)
+ if (FSMUtil.isConflict(dirtyObject))
{
if (conflicts == null)
{
@@ -1207,7 +1207,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
{
CDOStateMachine.INSTANCE.detachRemote(detachedObject);
detachedObjects.add(detachedObject);
- if (detachedObject.cdoState() == CDOState.INVALID_CONFLICT)
+ if (FSMUtil.isConflict(detachedObject))
{
if (conflicts == null)
{
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java
index c51d3df97e..1e30fb82e4 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java
@@ -57,6 +57,12 @@ public final class FSMUtil
return state == CDOState.INVALID || state == CDOState.INVALID_CONFLICT;
}
+ public static boolean isConflict(CDOObject object)
+ {
+ CDOState state = object.cdoState();
+ return state == CDOState.CONFLICT || state == CDOState.INVALID_CONFLICT;
+ }
+
public static boolean isNew(CDOObject object)
{
CDOState state = object.cdoState();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/ObjectConflictResolver.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/ObjectConflictResolver.java
index 885022c68c..ab32787473 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/ObjectConflictResolver.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/ObjectConflictResolver.java
@@ -14,13 +14,15 @@ import org.eclipse.emf.cdo.CDOConflictResolver;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOTransaction;
import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionMerger;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevisionDelta;
+import org.eclipse.emf.internal.cdo.CDOObjectMerger;
import org.eclipse.emf.internal.cdo.CDOStateMachine;
import org.eclipse.emf.internal.cdo.InternalCDOObject;
-import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -30,6 +32,8 @@ import java.util.Set;
*/
public abstract class ObjectConflictResolver implements CDOConflictResolver
{
+ public static final CDORevisionMerger REVISION_MERGER = new CDORevisionMerger();
+
public ObjectConflictResolver()
{
}
@@ -37,39 +41,59 @@ public abstract class ObjectConflictResolver implements CDOConflictResolver
public void resolveConflicts(CDOTransaction transaction, Set<CDOObject> conflicts)
{
Map<CDOID, CDORevisionDelta> revisionDeltas = transaction.getRevisionDeltas();
- for (Iterator<CDOObject> it = conflicts.iterator(); it.hasNext();)
+ for (CDOObject conflict : conflicts)
{
- CDOObject conflict = it.next();
CDORevisionDelta revisionDelta = revisionDeltas.get(conflict.cdoID());
- if (resolveConflict(transaction, conflict, revisionDelta))
- {
- it.remove();
- }
+ resolveConflict(transaction, conflict, revisionDelta);
}
}
/**
- * Resolves the conflict of a single object in the current transaction and returns <code>true</code> if successful,
- * <code>false</code> otherwise.
+ * Resolves the conflict of a single object in the current transaction.
*/
- protected abstract boolean resolveConflict(CDOTransaction transaction, CDOObject conflict,
- CDORevisionDelta revisionDelta);
+ protected abstract void resolveConflict(CDOTransaction transaction, CDOObject conflict, CDORevisionDelta revisionDelta);
public static void rollbackObject(CDOObject object)
{
CDOStateMachine.INSTANCE.rollback((InternalCDOObject)object);
}
+ /**
+ * TODO See {@link CDOObjectMerger}!!!
+ */
public static void changeObject(CDOObject object, CDORevisionDelta revisionDelta)
{
- for (CDOFeatureDelta featureDelta : revisionDelta.getFeatureDeltas())
- {
- changeObject(object, featureDelta);
- }
+ CDOStateMachine.INSTANCE.read((InternalCDOObject)object);
+
+ InternalCDORevision revision = (InternalCDORevision)object.cdoRevision().copy();
+ int originVersion = revision.getVersion();
+ revision.setTransactional();
+
+ ((InternalCDORevisionDelta)revisionDelta).setOriginVersion(originVersion);
+ ((InternalCDORevisionDelta)revisionDelta).setDirtyVersion(revision.getVersion());
+
+ REVISION_MERGER.merge(revision, revisionDelta);
+ ((InternalCDOObject)object).cdoInternalSetRevision(revision);
}
- public static void changeObject(CDOObject object, CDOFeatureDelta featureDelta)
+ /**
+ * A conflict resolver implementation that takes all the new remote state of the conflicting objects and then applies
+ * the locally existing changes of the current transaction.
+ *
+ * @author Eike Stepper
+ * @since 2.0
+ */
+ public static class TakeRemoteChangesThenApplyLocalChanges extends ObjectConflictResolver
{
- CDOStateMachine.INSTANCE.write((InternalCDOObject)object, featureDelta);
+ public TakeRemoteChangesThenApplyLocalChanges()
+ {
+ }
+
+ @Override
+ protected void resolveConflict(CDOTransaction transaction, CDOObject conflict, CDORevisionDelta revisionDelta)
+ {
+ rollbackObject(conflict);
+ changeObject(conflict, revisionDelta);
+ }
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/TakeRemoteChangesAndReApplyLocalChangesConflictResolver.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/TakeRemoteChangesAndReApplyLocalChangesConflictResolver.java
deleted file mode 100644
index e7bfe7251d..0000000000
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/TakeRemoteChangesAndReApplyLocalChangesConflictResolver.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- **************************************************************************/
-package org.eclipse.emf.spi.cdo;
-
-import org.eclipse.emf.cdo.CDOObject;
-import org.eclipse.emf.cdo.CDOTransaction;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-
-/**
- * A conflict resolver implementation that takes all the new remote state of the conflicting objects and then applies
- * the locally existing changes of the current transaction.
- *
- * @author Eike Stepper
- * @since 2.0
- */
-public class TakeRemoteChangesAndReApplyLocalChangesConflictResolver extends ObjectConflictResolver
-{
- public TakeRemoteChangesAndReApplyLocalChangesConflictResolver()
- {
- }
-
- @Override
- protected boolean resolveConflict(CDOTransaction transaction, CDOObject conflict, CDORevisionDelta revisionDelta)
- {
- rollbackObject(conflict);
- changeObject(conflict, revisionDelta);
- return true;
- }
-}

Back to the top