summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEgidijus Vaisnora2012-01-04 09:59:40 (EST)
committerEgidijus Vaisnora2012-01-04 09:59:40 (EST)
commit4e1ba595bab91ce57475455e513399fcd42d6e16 (patch)
treea7c573069a209f6d22b9aeacba724e90f86fc9ec
parentc4d77b54ea1984b36ed152f69e920f9d0fade919 (diff)
downloadcdo-4e1ba595bab91ce57475455e513399fcd42d6e16.zip
cdo-4e1ba595bab91ce57475455e513399fcd42d6e16.tar.gz
cdo-4e1ba595bab91ce57475455e513399fcd42d6e16.tar.bz2
Patch applied from the
https://bugs.eclipse.org/bugs/show_bug.cgi?id=350120
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_252214_Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_350120_Test.java165
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyAdapter.java3
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java7
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java35
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java56
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractObjectConflictResolver.java8
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java5
12 files changed, 274 insertions, 29 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
index f5a7173..0bc31c9 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
@@ -74,7 +74,6 @@ public abstract class AbstractCDOTest extends ConfigTest
assertEquals(true, FSMUtil.isTransient(object));
assertNull(object.cdoID());
assertNull(object.cdoRevision());
- assertNull(object.cdoView());
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java
index 18f2d5e..96ab935 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java
@@ -25,6 +25,7 @@ import org.eclipse.emf.cdo.tests.model1.Product1;
import org.eclipse.emf.cdo.tests.model1.Supplier;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
@@ -137,8 +138,13 @@ public class StateMachineTest extends AbstractCDOTest
Supplier supplier = getModel1Factory().createSupplier();
supplier.setName("Stepper");
assertTransient(supplier);
- invalidate(supplier);
- assertTransient(supplier);
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ invalidate(supplier, transaction);
+ CDOObject object = CDOUtil.getCDOObject(supplier);
+ assertEquals(CDOState.CONFLICT, object.cdoState());
+ session.close();
}
public void test_TRANSIENT_with_COMMIT() throws Exception
@@ -255,7 +261,7 @@ public class StateMachineTest extends AbstractCDOTest
try
{
- invalidate(supplier);
+ invalidate(supplier, CDOUtil.getCDOObject(supplier).cdoView());
fail("IllegalStateException expected");
}
catch (IllegalStateException expected)
@@ -455,12 +461,12 @@ public class StateMachineTest extends AbstractCDOTest
}
}
- private static void invalidate(EObject object)
+ private static void invalidate(EObject object, CDOView view)
{
CDOObject cdoObject = CDOUtil.getCDOObject(object);
if (cdoObject != null)
{
- CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)cdoObject, null, CDOBranchPoint.UNSPECIFIED_DATE);
+ CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)cdoObject, null, CDOBranchPoint.UNSPECIFIED_DATE, view);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_252214_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_252214_Test.java
index ee89695..0f0b334 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_252214_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_252214_Test.java
@@ -76,7 +76,8 @@ public class Bugzilla_252214_Test extends AbstractCDOTest
CDOResource auditResource = audit.getResource(getResourcePath("/res1"));
Company auditCompany = (Company)auditResource.getContents().get(0);
CDOObject cdoAuditCompany = CDOUtil.getCDOObject(auditCompany);
- CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)cdoAuditCompany, null, CDOBranchPoint.UNSPECIFIED_DATE);
+ CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)cdoAuditCompany, null, CDOBranchPoint.UNSPECIFIED_DATE,
+ cdoAuditCompany.cdoView());
}
audit.setTimeStamp(commitTime2);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_350120_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_350120_Test.java
new file mode 100644
index 0000000..e8d9f7e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_350120_Test.java
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others.
+ * 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.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.CDOState;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.model1.Category;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.CommitException;
+
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.spi.cdo.AbstractObjectConflictResolver;
+
+import java.util.List;
+
+/**
+ * @author Egidijus Vaisnora
+ */
+public class Bugzilla_350120_Test extends AbstractCDOTest
+{
+ public void testConflict() throws CommitException
+ {
+ CDOSession user1Session = openSession();
+ user1Session.options().setPassiveUpdateEnabled(false);
+
+ CDOTransaction user1Transaction = user1Session.openTransaction();
+ CDOResource createResource = user1Transaction.createResource(getResourcePath("test"));
+ Category user1RootCategory = getModel1Factory().createCategory();
+ createResource.getContents().add(user1RootCategory);
+ user1Transaction.commit();
+
+ // User 2
+ CDOSession user2Session = openSession();
+ user2Session.options().setPassiveUpdateEnabled(false);
+ CDOTransaction user2Transaction = user2Session.openTransaction();
+ CDOObject user2RootCatecory = user2Transaction.getObject(CDOUtil.getCDOObject(user1RootCategory).cdoID());
+
+ // User 1
+ Category user1ChildCategory = getModel1Factory().createCategory();
+ user1RootCategory.getCategories().add(user1ChildCategory);
+ user1Transaction.commit();
+
+ // User 2
+ EcoreUtil.delete(user2RootCatecory);
+ assertEquals(CDOState.TRANSIENT, user2RootCatecory.cdoState());
+ user2Transaction.options().addConflictResolver(new AbstractObjectConflictResolver()
+ {
+
+ @Override
+ protected void resolveConflict(CDOObject conflict, CDORevision oldRemoteRevision, CDORevisionDelta localDelta,
+ CDORevisionDelta remoteDelta, List<CDORevisionDelta> allRemoteDeltas)
+ {
+ // do nothing. It just test AbstractObjectConflictResolver from NPE
+ }
+
+ });
+ user2Session.refresh();
+
+ boolean expected = true;
+ if (expected)
+ {
+ assertEquals(CDOState.CONFLICT, user2RootCatecory.cdoState());
+ }
+ else
+ {
+ // current flow
+ assertEquals(CDOState.TRANSIENT, user2RootCatecory.cdoState());
+ CDOObject user2ChildCategory = user2Transaction.getObject(CDOUtil.getCDOObject(user1ChildCategory).cdoID());
+ assertEquals(CDOState.CLEAN, user2ChildCategory.cdoState());
+ user2Transaction.commit();
+
+ // User 1
+ user1Session.refresh();
+ assertEquals(CDOState.CLEAN, CDOUtil.getCDOObject(user1ChildCategory).cdoState());
+ }
+
+ user2Session.close();
+ user1Session.close();
+ }
+
+ public void testMoveToOtherRepository() throws CommitException
+ {
+ CDOSession user1Session = openSession();
+ user1Session.options().setPassiveUpdateEnabled(false);
+
+ CDOTransaction user1Transaction = user1Session.openTransaction();
+ CDOResource createResource = user1Transaction.createResource(getResourcePath("test"));
+ Category user1RootCategory = getModel1Factory().createCategory();
+ createResource.getContents().add(user1RootCategory);
+ user1Transaction.commit();
+
+ // User 2
+ CDOSession user2Session = openSession();
+ user2Session.options().setPassiveUpdateEnabled(false);
+ CDOTransaction user2Transaction = user2Session.openTransaction();
+ CDOObject user2RootCatecory = user2Transaction.getObject(CDOUtil.getCDOObject(user1RootCategory).cdoID());
+
+ // User 1
+ Category user1ChildCategory = getModel1Factory().createCategory();
+ user1RootCategory.getCategories().add(user1ChildCategory);
+ user1Transaction.commit();
+
+ // User 2
+ EcoreUtil.delete(user2RootCatecory);
+ assertEquals(CDOState.TRANSIENT, user2RootCatecory.cdoState());
+
+ getRepository("repo2");
+ CDOSession repo2Session = openSession("repo2");
+ CDOTransaction user3Repo2Transaction = repo2Session.openTransaction();
+ CDOResource repo2Resource = user3Repo2Transaction.createResource(getResourcePath("repo2Res"));
+ repo2Resource.getContents().add(user2RootCatecory);
+ assertEquals(CDOState.NEW, user2RootCatecory.cdoState());
+
+ user3Repo2Transaction.commit();
+ assertEquals(CDOState.CLEAN, user2RootCatecory.cdoState());
+
+ user2Session.refresh();
+
+ boolean expected = true;
+ if (expected)
+ {
+ assertEquals(CDOState.CLEAN, user2RootCatecory.cdoState());
+ assertEquals(user3Repo2Transaction, user2RootCatecory.cdoView());
+
+ }
+ else
+ {
+ // current flow - object was invalidated updating another session
+ assertEquals(CDOState.PROXY, user2RootCatecory.cdoState());
+ assertEquals(user3Repo2Transaction, user2RootCatecory.cdoView());
+ }
+
+ // make rollback
+ user2Transaction.rollback();
+ if (expected)
+ {
+ assertEquals(CDOState.CLEAN, user2RootCatecory.cdoState());
+ assertEquals(user3Repo2Transaction, user2RootCatecory.cdoView());
+
+ }
+ else
+ {
+ // current flow - object switched transaction
+ assertEquals(CDOState.CLEAN, user2RootCatecory.cdoState());
+ assertEquals(user2Transaction, user2RootCatecory.cdoView());
+ }
+
+ user2Session.close();
+ user1Session.close();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
index 5865718..bf872f0 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
@@ -653,7 +653,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
CDOView newView = newResource != null && newResource instanceof CDOResource ? ((CDOResource)newResource).cdoView()
: null;
- boolean moved = oldView != null && oldView == newView;
+ boolean moved = oldView != null && oldView == newView && cdoState() != CDOState.TRANSIENT;
if (!moved && oldResource != null && !isResourceRoot)
{
oldResource.detached(this);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyAdapter.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyAdapter.java
index 9f9740a..91885be 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyAdapter.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyAdapter.java
@@ -12,6 +12,7 @@
package org.eclipse.emf.internal.cdo.object;
import org.eclipse.emf.cdo.CDONotification;
+import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
@@ -80,7 +81,7 @@ public class CDOLegacyAdapter extends CDOLegacyWrapper implements Adapter.Intern
}
EStructuralFeature feature = (EStructuralFeature)msg.getFeature();
- if (view == null || feature == null || !(view instanceof CDOTransaction))
+ if (view == null || feature == null || !(view instanceof CDOTransaction) || cdoState() == CDOState.TRANSIENT)
{
return;
}
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 f8d18c7..42de90f 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
@@ -2179,7 +2179,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
@Override
protected Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> invalidate(long lastUpdateTime,
List<CDORevisionKey> allChangedObjects, List<CDOIDAndVersion> allDetachedObjects, List<CDORevisionDelta> deltas,
- Map<CDOObject, CDORevisionDelta> revisionDeltas, Set<CDOObject> detachedObjects)
+ Map<CDOObject, CDORevisionDelta> revisionDeltas, Set<CDOObject> detachedObjects,
+ Map<CDOID, InternalCDORevision> oldRevisions)
{
if (!allDetachedObjects.isEmpty())
{
@@ -2204,7 +2205,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
return super.invalidate(lastUpdateTime, allChangedObjects, allDetachedObjects, deltas, revisionDeltas,
- detachedObjects);
+ detachedObjects, oldRevisions);
}
private void removeCrossReferences(Collection<CDOObject> referencers, Set<CDOID> referencedOIDs)
@@ -2326,7 +2327,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
InternalCDORevision rev = super.getViewedRevision(object);
// Bug 336590: If we have a clean revision for this object, return that instead
- if (rev != null)
+ if (rev != null || object.cdoState() == CDOState.TRANSIENT)
{
InternalCDORevision cleanRev = cleanRevisions.get(object);
if (cleanRev != null)
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 acad1f2..dc0374a 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
@@ -1125,7 +1125,17 @@ public abstract class AbstractCDOView extends Lifecycle implements InternalCDOVi
TRACER.format("Deregistering {0}", object); //$NON-NLS-1$
}
- removeObject(object.cdoID());
+ deregisterObject(object.cdoID());
+ }
+
+ public synchronized void deregisterObject(CDOID id)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Deregistering {0}", id); //$NON-NLS-1$
+ }
+
+ removeObject(id);
}
public synchronized void remapObject(CDOID oldID)
@@ -1178,7 +1188,8 @@ public abstract class AbstractCDOView extends Lifecycle implements InternalCDOVi
*/
protected Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> invalidate(long lastUpdateTime,
List<CDORevisionKey> allChangedObjects, List<CDOIDAndVersion> allDetachedObjects, List<CDORevisionDelta> deltas,
- Map<CDOObject, CDORevisionDelta> revisionDeltas, Set<CDOObject> detachedObjects)
+ Map<CDOObject, CDORevisionDelta> revisionDeltas, Set<CDOObject> detachedObjects,
+ Map<CDOID, InternalCDORevision> oldRevisions)
{
Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts = null;
for (CDORevisionKey key : allChangedObjects)
@@ -1200,11 +1211,20 @@ public abstract class AbstractCDOView extends Lifecycle implements InternalCDOVi
if (changedObject != null)
{
- Pair<CDORevision, CDORevisionDelta> oldInfo = new Pair<CDORevision, CDORevisionDelta>(
- changedObject.cdoRevision(), delta);
+ CDOID cdoID = key.getID();
+ Pair<CDORevision, CDORevisionDelta> oldInfo;
+ if (changedObject.cdoState() == CDOState.TRANSIENT)
+ {
+ oldInfo = new Pair<CDORevision, CDORevisionDelta>(oldRevisions.get(cdoID), delta);
+ }
+ else
+ {
+ oldInfo = new Pair<CDORevision, CDORevisionDelta>(changedObject.cdoRevision(), delta);
+ }
+
// if (!isLocked(changedObject))
{
- CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)changedObject, key, lastUpdateTime);
+ CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)changedObject, key, lastUpdateTime, this);
}
revisionDeltas.put(changedObject, delta);
@@ -1391,12 +1411,13 @@ public abstract class AbstractCDOView extends Lifecycle implements InternalCDOVi
for (InternalCDOObject object : objects.values())
{
CDOState state = object.cdoState();
- if (state != CDOState.CLEAN && state != CDOState.DIRTY && state != CDOState.CONFLICT)
+ if (state != CDOState.CLEAN && state != CDOState.DIRTY && state != CDOState.CONFLICT
+ && state != CDOState.TRANSIENT)
{
continue;
}
- CDOID id = object.cdoID();
+ CDOID id = getID(object, true);
if (revisions.containsKey(id))
{
continue;
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
index 80ea51a..47b12d2 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
@@ -35,6 +35,7 @@ import org.eclipse.emf.internal.cdo.CDOObjectImpl;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.collection.Triplet;
import org.eclipse.net4j.util.fsm.FiniteStateMachine;
import org.eclipse.net4j.util.fsm.ITransition;
import org.eclipse.net4j.util.om.trace.ContextTracer;
@@ -49,6 +50,7 @@ import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
+import org.eclipse.emf.spi.cdo.InternalCDOSavepoint;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
import org.eclipse.emf.spi.cdo.InternalCDOView;
@@ -86,7 +88,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.TRANSIENT, CDOEvent.REATTACH, new ReattachTransition());
init(CDOState.TRANSIENT, CDOEvent.READ, IGNORE);
init(CDOState.TRANSIENT, CDOEvent.WRITE, IGNORE);
- init(CDOState.TRANSIENT, CDOEvent.INVALIDATE, IGNORE);
+ init(CDOState.TRANSIENT, CDOEvent.INVALIDATE, new TransientConflictTransition());
init(CDOState.TRANSIENT, CDOEvent.DETACH_REMOTE, IGNORE);
init(CDOState.TRANSIENT, CDOEvent.COMMIT, FAIL);
init(CDOState.TRANSIENT, CDOEvent.ROLLBACK, FAIL);
@@ -286,7 +288,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
transaction.detachObject(content);
content.cdoInternalSetState(CDOState.TRANSIENT);
- content.cdoInternalSetView(null);
content.cdoInternalSetID(null);
content.cdoInternalSetRevision(null);
}
@@ -391,7 +392,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
/**
* @since 3.0
*/
- public void invalidate(InternalCDOObject object, CDORevisionKey key, long lastUpdateTime)
+ public void invalidate(InternalCDOObject object, CDORevisionKey key, long lastUpdateTime, CDOView view)
{
synchronized (getMonitor(object))
{
@@ -400,7 +401,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
trace(object, CDOEvent.INVALIDATE);
}
- process(object, CDOEvent.INVALIDATE, new Pair<CDORevisionKey, Long>(key, lastUpdateTime));
+ process(object, CDOEvent.INVALIDATE, new Triplet<CDORevisionKey, Long, CDOView>(key, lastUpdateTime, view));
}
}
@@ -528,6 +529,25 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
if (!reattaching)
{
+ InternalCDOView oldView = object.cdoView();
+ if (oldView != null && oldView != transaction && object.cdoState() == CDOState.TRANSIENT)
+ {
+ // transfer to another transaction, make cleanup in old view
+ InternalCDOTransaction oldTransaction = oldView.toTransaction();
+ CDORevisionKey revKey = oldTransaction.getCleanRevisions().get(object);
+ if (revKey != null)
+ {
+ InternalCDOSavepoint lastSavepoint = oldTransaction.getLastSavepoint();
+ for (InternalCDOSavepoint savepoint = lastSavepoint; savepoint != null; savepoint = savepoint
+ .getPreviousSavepoint())
+ {
+ savepoint.getDetachedObjects().remove(revKey.getID());
+ }
+
+ oldTransaction.deregisterObject(revKey.getID());
+ }
+ }
+
// Prepare object
CDOID id = transaction.createIDForNewObject(object.cdoInternalInstance());
object.cdoInternalSetID(id);
@@ -841,9 +861,10 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
* @author Eike Stepper
*/
private class InvalidateTransition implements
- ITransition<CDOState, CDOEvent, InternalCDOObject, Pair<CDORevisionKey, Long>>
+ ITransition<CDOState, CDOEvent, InternalCDOObject, Triplet<CDORevisionKey, Long, InternalCDOView>>
{
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Pair<CDORevisionKey, Long> keyAndTime)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event,
+ Triplet<CDORevisionKey, Long, InternalCDOView> keyAndTime)
{
CDORevisionKey key = keyAndTime.getElement1();
InternalCDORevision oldRevision = object.cdoRevision();
@@ -905,10 +926,12 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
private class ConflictTransition extends InvalidateTransition
{
@Override
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Pair<CDORevisionKey, Long> keyAndTime)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event,
+ Triplet<CDORevisionKey, Long, InternalCDOView> keyAndTime)
{
CDORevisionKey key = keyAndTime.getElement1();
InternalCDORevision oldRevision = object.cdoRevision();
+
if (key == null || key.getVersion() >= oldRevision.getVersion() - 1)
{
changeState(object, CDOState.CONFLICT);
@@ -919,12 +942,29 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+ private class TransientConflictTransition extends InvalidateTransition
+ {
+ @Override
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event,
+ Triplet<CDORevisionKey, Long, InternalCDOView> keyAndTime)
+ {
+ InternalCDOTransaction transaction = keyAndTime.getElement3().toTransaction();
+ changeState(object, CDOState.CONFLICT);
+ transaction.setConflict(object);
+ }
+ }
+
+ /**
* @author Simon McDuff
*/
private final class InvalidConflictTransition extends ConflictTransition
{
@Override
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Pair<CDORevisionKey, Long> UNUSED)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event,
+ Triplet<CDORevisionKey, Long, InternalCDOView> UNUSED)
{
changeState(object, CDOState.INVALID_CONFLICT);
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 3524857..83bf125 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
@@ -805,7 +805,7 @@ public class CDOViewImpl extends AbstractCDOView
Set<CDOObject> detachedObjects = new HashSet<CDOObject>();
conflicts = invalidate(lastUpdateTime, allChangedObjects, allDetachedObjects, deltas, revisionDeltas,
- detachedObjects);
+ detachedObjects, oldRevisions);
sendInvalidationNotifications(revisionDeltas.keySet(), detachedObjects);
fireInvalidationEvent(lastUpdateTime, Collections.unmodifiableMap(revisionDeltas),
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractObjectConflictResolver.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractObjectConflictResolver.java
index b23d07f..4992409 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractObjectConflictResolver.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/AbstractObjectConflictResolver.java
@@ -95,7 +95,13 @@ public abstract class AbstractObjectConflictResolver extends AbstractConflictRes
CDOObject conflict = entry.getKey();
CDORevision oldRevision = entry.getValue().getElement1();
CDORevisionDelta remoteDelta = entry.getValue().getElement2();
- CDORevisionDelta localDelta = localDeltas.get(conflict.cdoID());
+ CDOID cdoID = conflict.cdoID();
+ if (cdoID == null)
+ {
+ // we have detached object in CONFLICT state. But ID we can obtain from old revision
+ cdoID = oldRevision.getID();
+ }
+ CDORevisionDelta localDelta = localDeltas.get(cdoID);
try
{
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
index 0d694c1..50e9bca 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
@@ -103,6 +103,11 @@ public interface InternalCDOView extends CDOView, CDOIDProvider, ILifecycle
public void deregisterObject(InternalCDOObject object);
+ /**
+ * @since 4.1
+ */
+ public void deregisterObject(CDOID object);
+
public InternalCDORevision getRevision(CDOID id, boolean loadOnDemand);
/**