Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2009-11-07 09:37:20 +0000
committerEike Stepper2009-11-07 09:37:20 +0000
commitb9d57f215e8203f11d09991a20bcbcdfa7127ad4 (patch)
treeecabc5c258a238ce8fcda21b36937d5c937b2f64 /plugins/org.eclipse.emf.cdo/src/org/eclipse/emf
parentc1ccd51148da5a6e14d5e65002e0737dc6ce7592 (diff)
downloadcdo-b9d57f215e8203f11d09991a20bcbcdfa7127ad4.tar.gz
cdo-b9d57f215e8203f11d09991a20bcbcdfa7127ad4.tar.xz
cdo-b9d57f215e8203f11d09991a20bcbcdfa7127ad4.zip
[294528] Preserve CDOID for re-attached CDOObjects
https://bugs.eclipse.org/bugs/show_bug.cgi?id=294528
Diffstat (limited to 'plugins/org.eclipse.emf.cdo/src/org/eclipse/emf')
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java158
1 files changed, 154 insertions, 4 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
index ca9147b8ee..4266d65bfb 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
@@ -14,9 +14,12 @@ package org.eclipse.emf.internal.cdo;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDeltaUtil;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
@@ -24,6 +27,8 @@ import org.eclipse.emf.cdo.util.InvalidObjectException;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.emf.internal.cdo.transaction.CDOSavepointImpl;
+import org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl;
import org.eclipse.emf.internal.cdo.util.FSMUtil;
import org.eclipse.net4j.util.collection.Pair;
@@ -33,6 +38,7 @@ import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
@@ -78,6 +84,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.TRANSIENT, CDOEvent.RELOAD, IGNORE);
init(CDOState.TRANSIENT, CDOEvent.COMMIT, FAIL);
init(CDOState.TRANSIENT, CDOEvent.ROLLBACK, FAIL);
+ init(CDOState.TRANSIENT, CDOEvent.REATTACH, new ReattachTransition());
init(CDOState.PREPARED, CDOEvent.PREPARE, FAIL);
init(CDOState.PREPARED, CDOEvent.ATTACH, new AttachTransition());
@@ -89,6 +96,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.PREPARED, CDOEvent.RELOAD, FAIL);
init(CDOState.PREPARED, CDOEvent.COMMIT, FAIL);
init(CDOState.PREPARED, CDOEvent.ROLLBACK, FAIL);
+ init(CDOState.PREPARED, CDOEvent.REATTACH, FAIL);
init(CDOState.NEW, CDOEvent.PREPARE, FAIL);
init(CDOState.NEW, CDOEvent.ATTACH, FAIL);
@@ -100,6 +108,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.NEW, CDOEvent.RELOAD, FAIL);
init(CDOState.NEW, CDOEvent.COMMIT, new CommitTransition(false));
init(CDOState.NEW, CDOEvent.ROLLBACK, FAIL);
+ init(CDOState.NEW, CDOEvent.REATTACH, FAIL);
init(CDOState.CLEAN, CDOEvent.PREPARE, FAIL);
init(CDOState.CLEAN, CDOEvent.ATTACH, FAIL);
@@ -111,6 +120,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.CLEAN, CDOEvent.RELOAD, new ReloadTransition());
init(CDOState.CLEAN, CDOEvent.COMMIT, FAIL);
init(CDOState.CLEAN, CDOEvent.ROLLBACK, FAIL);
+ init(CDOState.CLEAN, CDOEvent.REATTACH, FAIL);
init(CDOState.DIRTY, CDOEvent.PREPARE, FAIL);
init(CDOState.DIRTY, CDOEvent.ATTACH, FAIL);
@@ -122,6 +132,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.DIRTY, CDOEvent.RELOAD, new ReloadTransition());
init(CDOState.DIRTY, CDOEvent.COMMIT, new CommitTransition(true));
init(CDOState.DIRTY, CDOEvent.ROLLBACK, new RollbackTransition());
+ init(CDOState.DIRTY, CDOEvent.REATTACH, FAIL);
init(CDOState.PROXY, CDOEvent.PREPARE, FAIL);
init(CDOState.PROXY, CDOEvent.ATTACH, FAIL);
@@ -133,6 +144,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.PROXY, CDOEvent.RELOAD, new ReloadTransition());
init(CDOState.PROXY, CDOEvent.COMMIT, FAIL);
init(CDOState.PROXY, CDOEvent.ROLLBACK, FAIL);
+ init(CDOState.PROXY, CDOEvent.REATTACH, FAIL); // Bug 283985 (Re-attachment) - Not sure about this one
init(CDOState.CONFLICT, CDOEvent.PREPARE, FAIL);
init(CDOState.CONFLICT, CDOEvent.ATTACH, IGNORE);
@@ -144,6 +156,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.CONFLICT, CDOEvent.RELOAD, FAIL);
init(CDOState.CONFLICT, CDOEvent.COMMIT, IGNORE);
init(CDOState.CONFLICT, CDOEvent.ROLLBACK, new RollbackTransition());
+ init(CDOState.CONFLICT, CDOEvent.REATTACH, FAIL); // Bug 283985 (Re-attachment) Not sure about this one
init(CDOState.INVALID, CDOEvent.PREPARE, InvalidTransition.INSTANCE);
init(CDOState.INVALID, CDOEvent.ATTACH, InvalidTransition.INSTANCE);
@@ -155,6 +168,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.INVALID, CDOEvent.RELOAD, InvalidTransition.INSTANCE);
init(CDOState.INVALID, CDOEvent.COMMIT, InvalidTransition.INSTANCE);
init(CDOState.INVALID, CDOEvent.ROLLBACK, InvalidTransition.INSTANCE);
+ init(CDOState.INVALID, CDOEvent.REATTACH, FAIL); // Bug 283985 (Re-attachment) Not sure about this one
init(CDOState.INVALID_CONFLICT, CDOEvent.PREPARE, InvalidTransition.INSTANCE);
init(CDOState.INVALID_CONFLICT, CDOEvent.ATTACH, InvalidTransition.INSTANCE);
@@ -166,6 +180,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.INVALID_CONFLICT, CDOEvent.RELOAD, InvalidTransition.INSTANCE);
init(CDOState.INVALID_CONFLICT, CDOEvent.COMMIT, InvalidTransition.INSTANCE);
init(CDOState.INVALID_CONFLICT, CDOEvent.ROLLBACK, DetachRemoteTransition.INSTANCE);
+ init(CDOState.INVALID_CONFLICT, CDOEvent.REATTACH, FAIL); // Bug 283985 (Re-attachment) Not sure about this one
}
/**
@@ -182,11 +197,11 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
{
List<InternalCDOObject> contents = new ArrayList<InternalCDOObject>();
prepare(object, new Pair<InternalCDOTransaction, List<InternalCDOObject>>(transaction, contents));
- attachObject(object);
+ attachOrReattach(object, transaction);
for (InternalCDOObject content : contents)
{
- attachObject(content);
+ attachOrReattach(content, transaction);
}
}
finally
@@ -195,6 +210,19 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
+ private void attachOrReattach(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ // Bug 283985 (Re-attachment): Special case: re-attachment
+ if (((CDOTransactionImpl)transaction).getFormerRevisions().containsKey(object))
+ {
+ reattachObject(object, transaction);
+ }
+ else
+ {
+ attachObject(object);
+ }
+ }
+
/**
* Phase 1: TRANSIENT --> PREPARED
*/
@@ -222,6 +250,16 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
process(object, CDOEvent.ATTACH, null);
}
+ private void reattachObject(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("REATTACH: {0}", object);
+ }
+
+ process(object, CDOEvent.REATTACH, transaction);
+ }
+
/**
* @since 2.0
*/
@@ -593,6 +631,12 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
InternalCDOTransaction transaction = transactionAndContents.getElement1();
List<InternalCDOObject> contents = transactionAndContents.getElement2();
+ Map<InternalCDOObject, InternalCDORevision> formerRevisionMap = ((CDOTransactionImpl)transaction)
+ .getFormerRevisions();
+ boolean reattaching = formerRevisionMap.containsKey(object);
+
+ if (!reattaching)
+ {
// Prepare object
CDOID id = transaction.getNextTemporaryID();
object.cdoInternalSetID(id);
@@ -611,15 +655,57 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
// Register object
transaction.registerObject(object);
transaction.registerNew(object);
+ }
// Prepare content tree
- for (Iterator<InternalCDOObject> it = FSMUtil.getProperContents(object); it.hasNext();)
+ for (Iterator<InternalCDOObject> it = getProperContents(object,transaction); it.hasNext();)
{
InternalCDOObject content = it.next();
contents.add(content);
INSTANCE.process(content, CDOEvent.PREPARE, transactionAndContents);
}
}
+
+ private Iterator<InternalCDOObject> getProperContents(final InternalCDOObject object, final CDOTransaction transaction)
+ {
+ final boolean isResource = object instanceof Resource;
+ final Iterator<EObject> delegate = object.eContents().iterator();
+
+ return new Iterator<InternalCDOObject>()
+ {
+ private Object next;
+
+ public boolean hasNext()
+ {
+ while (delegate.hasNext())
+ {
+ InternalEObject eObject = (InternalEObject)delegate.next();
+ EStructuralFeature eContainingFeature = eObject.eContainingFeature();
+ if (isResource || eObject.eDirectResource() == null
+ && (eContainingFeature == null || EMFUtil.isPersistent(eContainingFeature)))
+ {
+ next = FSMUtil.adapt(eObject, transaction);
+ if (next instanceof InternalCDOObject)
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public InternalCDOObject next()
+ {
+ return (InternalCDOObject)next;
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
}
/**
@@ -650,6 +736,67 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
+ * Bug 283985 (Re-attachment)
+ *
+ * @author Caspar De Groot
+ */
+ private final class ReattachTransition implements
+ ITransition<CDOState, CDOEvent, InternalCDOObject, InternalCDOTransaction>
+ {
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event, InternalCDOTransaction transaction)
+ {
+ InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
+ InternalCDORevision formerRevision = ((CDOTransactionImpl)transaction).getFormerRevisions().get(object);
+ CDOID id = formerRevision.getID();
+
+ object.cdoInternalSetID(id);
+ object.cdoInternalSetView(transaction);
+
+ // Construct a new revision if the old one is not transactional
+ InternalCDORevision revision;
+ EClass eClass = object.eClass();
+ if (!formerRevision.isTransactional())
+ {
+ CDORevisionFactory factory = revisionManager.getFactory();
+ revision = (InternalCDORevision)factory.createRevision(eClass);
+ revision.setID(id);
+ revision.setVersion(formerRevision.getVersion());
+ revision.setTransactional();
+ }
+ else
+ {
+ // This branch only gets taken if the object that is being re-attached,
+ // was already DIRTY when it was first detached.
+ //
+ revision = formerRevision;
+ for (int i = 0; i < eClass.getFeatureCount(); i++)
+ {
+ EStructuralFeature eFeature = object.cdoInternalDynamicFeature(i);
+ if (!eFeature.isTransient())
+ {
+ revision.clear(eFeature);
+ }
+ }
+ }
+
+ // Populate the revision based on the values in the CDOObject
+ object.cdoInternalSetRevision(revision);
+ object.cdoInternalPostAttach();
+
+ // Compute a revision delta and register it with the tx
+ CDORevision originalRevision = revisionManager.getRevisionByVersion(id, -1, CDORevision.DEPTH_NONE, revision
+ .getVersion() - 1);
+ CDORevisionDelta revisionDelta = CDORevisionDeltaUtil.create(originalRevision, revision);
+ transaction.registerRevisionDelta(revisionDelta);
+ transaction.registerDirty(object, null);
+ changeState(object, CDOState.DIRTY);
+
+ // Add the object to the set of reattached objects
+ ((CDOSavepointImpl)transaction.getLastSavepoint()).getReattachedObjects().put(id, object);
+ }
+ }
+
+ /**
* @author Eike Stepper
*/
private final class DetachTransition implements
@@ -916,5 +1063,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
*/
enum CDOEvent
{
- PREPARE, ATTACH, DETACH, READ, WRITE, INVALIDATE, DETACH_REMOTE, RELOAD, COMMIT, ROLLBACK
+ PREPARE, ATTACH, DETACH, READ, WRITE, INVALIDATE, DETACH_REMOTE, RELOAD, COMMIT, ROLLBACK,
+
+ // Bug 283985 (Re-attachment)
+ REATTACH
}

Back to the top