Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo/src/org/eclipse/emf')
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOState.java3
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java12
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOSavepoint.java78
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransactionFinishedEvent.java23
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java8
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java8
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyListener.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java25
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java600
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java1064
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java10
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java86
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java260
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine2.java1455
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStoreImpl.java156
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java6
-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/CDOMergingConflictResolver.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/DefaultCDOMerger.java12
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java12
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSavepoint.java98
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java74
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java2
27 files changed, 2958 insertions, 1070 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOState.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOState.java
index 146aad0dbe..8a8d184945 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOState.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOState.java
@@ -31,7 +31,8 @@ public enum CDOState
INVALID_CONFLICT,
/**
- * An intermediary state for internal use only. This state marks the first of two phases during an attach operation.
+ * Indicates that the object had been changed in a transaction,
+ * but has then been changed back to its clean state.
*/
PREPARED
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
index 3ac5c5c9b5..31d14e559e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
@@ -31,7 +31,7 @@ import org.eclipse.emf.cdo.view.CDOViewProvider;
import org.eclipse.emf.cdo.view.CDOViewProviderRegistry;
import org.eclipse.emf.internal.cdo.bundle.OM;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.Pair;
@@ -347,7 +347,6 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR
setPath(newPath);
}
-
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType)
{
@@ -355,7 +354,7 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR
{
case EresourcePackage.CDO_RESOURCE__URI:
return getURI();
-
+
default:
return super.eGet(featureID, resolve, coreType);
}
@@ -369,7 +368,7 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR
case EresourcePackage.CDO_RESOURCE__URI:
setURI((URI)newValue);
break;
-
+
default:
super.eSet(featureID, newValue);
}
@@ -670,7 +669,6 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR
try
{
EObject eObjectByFragment = getEObjectByFragment(uriFragment);
-
if (eObjectByFragment != null)
{
return eObjectByFragment;
@@ -1497,7 +1495,7 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR
*/
private void attached(InternalCDOObject cdoObject, InternalCDOTransaction transaction)
{
- CDOStateMachine.INSTANCE.attach(cdoObject, transaction);
+ CDOStateMachine2.INSTANCE.attach(cdoObject, transaction);
}
/**
@@ -1511,7 +1509,7 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR
if (view instanceof InternalCDOTransaction) // Bug 376075
{
InternalCDOObject cdoObject = FSMUtil.adapt(object, view);
- CDOStateMachine.INSTANCE.detach(cdoObject);
+ CDOStateMachine2.INSTANCE.detach(cdoObject);
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java
index eacfbeeee4..5c2a19c1da 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java
@@ -196,11 +196,17 @@ public class CDOPushTransaction extends Notifier implements CDOTransaction
return CDOPushTransaction.this;
}
+ @Deprecated
public Type getType()
{
return Type.COMMITTED;
}
+ public Reason getReason()
+ {
+ return Reason.COMMITTED;
+ }
+
public Map<CDOID, CDOID> getIDMappings()
{
return Collections.emptyMap();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOSavepoint.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOSavepoint.java
index a572d1f1ea..1be4cb9d15 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOSavepoint.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOSavepoint.java
@@ -39,92 +39,102 @@ public interface CDOSavepoint extends CDOUserSavepoint, CDOChangeSetDataProvider
public CDOSavepoint getPreviousSavepoint();
+ public boolean isEmpty();
+
/**
* @since 3.0
*/
- public boolean wasDirty();
+ public Map<CDOID, CDOObject> getNewObjects();
/**
* @since 3.0
*/
- public Map<CDOID, CDORevision> getBaseNewObjects();
+ public Map<CDOID, CDOObject> getDetachedObjects();
/**
* @since 3.0
*/
- public Map<CDOID, CDOObject> getNewObjects();
+ public Map<CDOID, CDOObject> getDirtyObjects();
/**
+ * @since 4.2
+ */
+ public Map<CDOID, CDORevisionDelta> getRevisionDeltas2();
+
+ /**
+ * Return the list of new objects from this point without objects that are removed.
+ *
* @since 3.0
*/
- public Map<CDOID, CDOObject> getDetachedObjects();
+ public Map<CDOID, CDOObject> getAllNewObjects();
/**
- * Bug 283985 (Re-attachment)
+ * Return the list of new objects from this point.
*
* @since 3.0
*/
- public Map<CDOID, CDOObject> getReattachedObjects();
+ public Map<CDOID, CDOObject> getAllDirtyObjects();
/**
* @since 3.0
*/
- public Map<CDOID, CDOObject> getDirtyObjects();
+ public Map<CDOID, CDOObject> getAllDetachedObjects();
/**
- * The returned map delegates to {@link #getRevisionDeltas2()} and does <b>not</b> support the following methods:
- *
- * <ul>
- * <li> {@link ConcurrentMap#putIfAbsent(Object, Object)}
- * <li> {@link ConcurrentMap#remove(Object, Object)}
- * <li> {@link ConcurrentMap#replace(Object, Object)}
- * <li> {@link ConcurrentMap#replace(Object, Object, Object)}
- * </ul>
+ * Return the list of all deltas without objects that are removed.
*
* @since 3.0
- * @deprecated As of 4.2 use {@link #getRevisionDeltas2()} instead.
*/
- @Deprecated
- public ConcurrentMap<CDOID, CDORevisionDelta> getRevisionDeltas();
+ public Map<CDOID, CDORevisionDelta> getAllRevisionDeltas();
/**
- * @since 4.2
+ * @since 4.0
*/
- public Map<CDOID, CDORevisionDelta> getRevisionDeltas2();
+ public CDOChangeSetData getAllChangeSetData();
/**
* @since 3.0
+ * @deprecated As of 4.3 no longer supported.
*/
- public Map<CDOID, CDORevision> getAllBaseNewObjects();
+ @Deprecated
+ public boolean wasDirty();
/**
- * Return the list of new objects from this point without objects that are removed.
+ * The returned map delegates to {@link #getRevisionDeltas2()} and does <b>not</b> support the following methods:
+ *
+ * <ul>
+ * <li> {@link ConcurrentMap#putIfAbsent(Object, Object)}
+ * <li> {@link ConcurrentMap#remove(Object, Object)}
+ * <li> {@link ConcurrentMap#replace(Object, Object)}
+ * <li> {@link ConcurrentMap#replace(Object, Object, Object)}
+ * </ul>
*
* @since 3.0
+ * @deprecated As of 4.2 use {@link #getRevisionDeltas2()} instead.
*/
- public Map<CDOID, CDOObject> getAllNewObjects();
+ @Deprecated
+ public ConcurrentMap<CDOID, CDORevisionDelta> getRevisionDeltas();
/**
* @since 3.0
+ * @deprecated As of 4.3 no longer supported.
*/
- public Map<CDOID, CDOObject> getAllDetachedObjects();
+ @Deprecated
+ public Map<CDOID, CDORevision> getBaseNewObjects();
/**
- * Return the list of new objects from this point.
- *
* @since 3.0
+ * @deprecated As of 4.3 no longer supported.
*/
- public Map<CDOID, CDOObject> getAllDirtyObjects();
+ @Deprecated
+ public Map<CDOID, CDORevision> getAllBaseNewObjects();
/**
- * Return the list of all deltas without objects that are removed.
+ * Bug 283985 (Re-attachment)
*
* @since 3.0
+ * @deprecated As of 4.3 no longer supported.
*/
- public Map<CDOID, CDORevisionDelta> getAllRevisionDeltas();
-
- /**
- * @since 4.0
- */
- public CDOChangeSetData getAllChangeSetData();
+ @Deprecated
+ public Map<CDOID, CDOObject> getReattachedObjects();
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransactionFinishedEvent.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransactionFinishedEvent.java
index b2d4fb3fb2..1e40cf3b06 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransactionFinishedEvent.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransactionFinishedEvent.java
@@ -27,18 +27,37 @@ import java.util.Map;
*/
public interface CDOTransactionFinishedEvent extends CDOViewEvent
{
+ /**
+ * @deprecated As of 4.3 use {@link #getReason()}.
+ */
+ @Deprecated
public Type getType();
+ public Reason getReason();
+
public Map<CDOID, CDOID> getIDMappings();
/**
- * Enumerates the possible {@link CDOTransactionFinishedEvent#getType() causes} for a {@link CDOTransaction
- * transaction} to become finished.
+ * Enumerates the possible {@link CDOTransactionFinishedEvent#getType() causes} for a
+ * {@link CDOTransaction transaction} to become finished.
*
* @author Eike Stepper
+ * @deprecated As of 4.3 use {@link Reason}.
*/
+ @Deprecated
public enum Type
{
COMMITTED, ROLLED_BACK
}
+
+ /**
+ * Enumerates the possible {@link CDOTransactionFinishedEvent#getReason() causes} for a
+ * {@link CDOTransaction transaction} to become finished.
+ *
+ * @author Eike Stepper
+ */
+ public enum Reason
+ {
+ COMMITTED, ROLLED_BACK, UNDONE, MERGED
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java
index 21a7141534..6ba92ae0ac 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java
@@ -49,7 +49,7 @@ import org.eclipse.emf.internal.cdo.session.CDOCollectionLoadingPolicyImpl;
import org.eclipse.emf.internal.cdo.transaction.CDOXATransactionImpl;
import org.eclipse.emf.internal.cdo.transaction.CDOXATransactionImpl.CDOXAInternalAdapter;
import org.eclipse.emf.internal.cdo.view.CDORevisionPrefetchingPolicyImpl;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2;
import org.eclipse.net4j.util.AdapterUtil;
import org.eclipse.net4j.util.container.IPluginContainer;
@@ -426,7 +426,7 @@ public final class CDOUtil
public static void load(EObject eObject, CDOView view)
{
InternalCDOObject cdoObject = FSMUtil.adapt(eObject, view);
- CDOStateMachine.INSTANCE.read(cdoObject);
+ CDOStateMachine2.INSTANCE.read(cdoObject);
for (Iterator<InternalCDOObject> it = FSMUtil.iterator(cdoObject.eContents(), (InternalCDOView)view); it.hasNext();)
{
@@ -479,7 +479,7 @@ public final class CDOUtil
return null;
}
- CDORevision revision = CDOStateMachine.INSTANCE.read((InternalCDOObject)object);
+ CDORevision revision = CDOStateMachine2.INSTANCE.read((InternalCDOObject)object);
return getRevisionByVersion(object, revision.getBranch(), version, revision);
}
@@ -493,7 +493,7 @@ public final class CDOUtil
return null;
}
- CDORevision revision = CDOStateMachine.INSTANCE.read((InternalCDOObject)object);
+ CDORevision revision = CDOStateMachine2.INSTANCE.read((InternalCDOObject)object);
return getRevisionByVersion(object, branch, version, revision);
}
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 3991de0369..96eabccd10 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
@@ -30,7 +30,7 @@ import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.messages.Messages;
import org.eclipse.emf.internal.cdo.object.CDOLockImpl;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
@@ -198,7 +198,7 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC
@Deprecated
public final void cdoReload()
{
- CDOStateMachine.INSTANCE.reload(this);
+ // CDOStateMachine2.INSTANCE.reload(this);
}
/**
@@ -1186,7 +1186,7 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC
}
/**
- * Adjust the reference ONLY if the opposite reference used CDOID. This is true ONLY if the state of <cdo>this</code>
+ * Adjust the reference ONLY if the opposite reference used CDOID. This is true ONLY if the state of <code>this</code>
* was not {@link CDOState#NEW}.
*/
private static void adjustOppositeReference(InternalCDOObject instance, InternalEObject object, EReference feature)
@@ -1632,7 +1632,7 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC
{
if (!FSMUtil.isTransient(CDOObjectImpl.this))
{
- CDOStateMachine.INSTANCE.read(CDOObjectImpl.this);
+ CDOStateMachine2.INSTANCE.read(CDOObjectImpl.this);
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyListener.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyListener.java
index 81b5f7c254..4f63d6f17d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyListener.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyListener.java
@@ -10,7 +10,7 @@
*/
package org.eclipse.emf.internal.cdo.object;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2;
import org.eclipse.emf.ecore.InternalEObject;
@@ -76,7 +76,7 @@ public final class CDOLegacyListener extends CDOLegacyWrapper
try
{
handlingCallback = true;
- CDOStateMachine.INSTANCE.read(this);
+ CDOStateMachine2.INSTANCE.read(this);
// TODO Optimize this when the list position index is added to the new callbacks
resolveAllProxies();
@@ -95,7 +95,7 @@ public final class CDOLegacyListener extends CDOLegacyWrapper
try
{
handlingCallback = true;
- CDOStateMachine.INSTANCE.write(this);
+ CDOStateMachine2.INSTANCE.write(this, null);
// TODO Optimize this when the list position index is added to the new callbacks
resolveAllProxies();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
index 1805087e1a..9d7f701ffa 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
@@ -35,7 +35,7 @@ import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.internal.cdo.CDOObjectImpl;
import org.eclipse.emf.internal.cdo.bundle.OM;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2;
import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.WrappedException;
@@ -200,7 +200,7 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper
@Deprecated
public void cdoReload()
{
- CDOStateMachine.INSTANCE.reload(this);
+ // CDOStateMachine2.INSTANCE.reload(this);
}
public CDOObjectHistory cdoHistory()
@@ -305,7 +305,7 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper
*/
public void cdoInternalPostRollback()
{
- CDOStateMachine.INSTANCE.read(this);
+ CDOStateMachine2.INSTANCE.read(this);
}
/**
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java
index 3bff4c349b..242e6fa70c 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java
@@ -66,7 +66,7 @@ public class CDOCollectionLoadingPolicyImpl implements CDOCollectionLoadingPolic
doResolveProxy(revision, feature, 0, 0, Integer.MAX_VALUE);
}
- public Object resolveProxy(CDORevision rev, EStructuralFeature feature, int accessIndex, int serverIndex)
+ public Object resolveProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex)
{
int chunkSize = resolveChunkSize;
if (chunkSize == CDORevision.UNCHUNKED)
@@ -75,26 +75,27 @@ public class CDOCollectionLoadingPolicyImpl implements CDOCollectionLoadingPolic
chunkSize = Integer.MAX_VALUE;
}
- return doResolveProxy(rev, feature, accessIndex, serverIndex, chunkSize);
+ return doResolveProxy(revision, feature, accessIndex, serverIndex, chunkSize);
}
- private Object doResolveProxy(CDORevision rev, EStructuralFeature feature, int accessIndex, int serverIndex,
+ private Object doResolveProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex,
int chunkSize)
{
// Get proxy values
- InternalCDORevision revision = (InternalCDORevision)rev;
- int fetchIndex = serverIndex;
-
- MoveableList<Object> list = revision.getList(feature);
+ InternalCDORevision rev = (InternalCDORevision)revision;
+ MoveableList<Object> list = rev.getList(feature);
int size = list.size();
+
int fromIndex = accessIndex;
int toIndex = accessIndex;
+
boolean minReached = false;
boolean maxReached = false;
- boolean alternation = false;
+ boolean towardsEnd = false;
+
for (int i = 0; i < chunkSize; i++)
{
- if (alternation)
+ if (towardsEnd)
{
if (!maxReached && toIndex < size - 1 && list.get(toIndex + 1) instanceof CDOElementProxy)
{
@@ -107,7 +108,7 @@ public class CDOCollectionLoadingPolicyImpl implements CDOCollectionLoadingPolic
if (!minReached)
{
- alternation = false;
+ towardsEnd = false;
}
}
else
@@ -123,7 +124,7 @@ public class CDOCollectionLoadingPolicyImpl implements CDOCollectionLoadingPolic
if (!maxReached)
{
- alternation = true;
+ towardsEnd = true;
}
}
@@ -134,6 +135,6 @@ public class CDOCollectionLoadingPolicyImpl implements CDOCollectionLoadingPolic
}
CDOSessionProtocol protocol = ((InternalCDOSession)session).getSessionProtocol();
- return protocol.loadChunk(revision, feature, accessIndex, fetchIndex, fromIndex, toIndex);
+ return protocol.loadChunk(rev, feature, accessIndex, serverIndex, fromIndex, toIndex);
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
index d6050b513a..a795d9b42f 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
@@ -13,97 +13,59 @@
package org.eclipse.emf.internal.cdo.transaction;
import org.eclipse.emf.cdo.CDOObject;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
-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.commit.CDOChangeSetDataImpl;
-import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta;
-import org.eclipse.net4j.util.collection.MultiMap;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.emf.spi.cdo.CDOTransactionStrategy;
+import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOSavepoint;
+import org.eclipse.emf.spi.cdo.InternalCDOSavepoint.ChangeInfo.ChangeType;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
+import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
+import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author Simon McDuff
+ * @author Eike Stepper
* @since 2.0
*/
public class CDOSavepointImpl extends CDOUserSavepointImpl implements InternalCDOSavepoint
{
- private final InternalCDOTransaction transaction;
+ private final Map<CDOID, ChangeInfo> changeInfos = CDOIDUtil.createMap();
- private Map<CDOID, CDORevision> baseNewObjects = CDOIDUtil.createMap();
+ private final Map<InternalCDOObject, ChangeInfo> detachedInfos = new WeakHashMap<InternalCDOObject, ChangeInfo>();
- private Map<CDOID, CDOObject> newObjects = CDOIDUtil.createMap();
+ private boolean inMemory;
- // Bug 283985 (Re-attachment)
- private Map<CDOID, CDOObject> reattachedObjects = CDOIDUtil.createMap();
+ private File storage;
- private Map<CDOID, CDOObject> detachedObjects = new HashMap<CDOID, CDOObject>()
+ public CDOSavepointImpl(InternalCDOTransaction transaction, InternalCDOSavepoint lastSavepoint)
{
- private static final long serialVersionUID = 1L;
-
- @Override
- public CDOObject put(CDOID key, CDOObject object)
+ super(transaction, lastSavepoint);
+ if (lastSavepoint != null)
{
- synchronized (transaction)
+ for (ChangeInfo lastChangeInfo : lastSavepoint.getChangeInfos().values())
{
- baseNewObjects.remove(key);
- newObjects.remove(key);
- reattachedObjects.remove(key);
- dirtyObjects.remove(key);
- revisionDeltas.remove(key);
- return super.put(key, object);
+ ChangeInfo changeInfo = lastChangeInfo.setSavepoint();
+ changeInfos.put(changeInfo.getID(), changeInfo);
}
}
- };
-
- private Map<CDOID, CDOObject> dirtyObjects = CDOIDUtil.createMap();
-
- private Map<CDOID, CDORevisionDelta> revisionDeltas = new HashMap<CDOID, CDORevisionDelta>()
- {
- private static final long serialVersionUID = 1L;
-
- @Override
- public CDORevisionDelta put(CDOID id, CDORevisionDelta delta)
- {
- transaction.clearResourcePathCacheIfNecessary(delta);
- return super.put(id, delta);
- }
-
- @Override
- public void putAll(Map<? extends CDOID, ? extends CDORevisionDelta> m)
- {
- throw new UnsupportedOperationException();
- }
- };
-
- private boolean wasDirty;
-
- public CDOSavepointImpl(InternalCDOTransaction transaction, InternalCDOSavepoint lastSavepoint)
- {
- super(transaction, lastSavepoint);
- this.transaction = transaction;
- wasDirty = transaction.isDirty();
}
@Override
@@ -115,7 +77,7 @@ public class CDOSavepointImpl extends CDOUserSavepointImpl implements InternalCD
@Override
public InternalCDOSavepoint getFirstSavePoint()
{
- synchronized (transaction)
+ synchronized (super.getTransaction())
{
return (InternalCDOSavepoint)super.getFirstSavePoint();
}
@@ -124,7 +86,7 @@ public class CDOSavepointImpl extends CDOUserSavepointImpl implements InternalCD
@Override
public InternalCDOSavepoint getPreviousSavepoint()
{
- synchronized (transaction)
+ synchronized (super.getTransaction())
{
return (InternalCDOSavepoint)super.getPreviousSavepoint();
}
@@ -133,66 +95,278 @@ public class CDOSavepointImpl extends CDOUserSavepointImpl implements InternalCD
@Override
public InternalCDOSavepoint getNextSavepoint()
{
- synchronized (transaction)
+ synchronized (super.getTransaction())
{
return (InternalCDOSavepoint)super.getNextSavepoint();
}
}
+ public ChangeInfo addChangeInfo(ChangeInfo changeInfo)
+ {
+ if (changeInfo.getType() == ChangeType.DETACHED)
+ {
+ detachedInfos.put(changeInfo.getObject(), changeInfo);
+ }
+
+ return changeInfos.put(changeInfo.getID(), changeInfo);
+ }
+
+ public ChangeInfo removeChangeInfo(CDOID id)
+ {
+ ChangeInfo changeInfo = changeInfos.remove(id);
+ if (changeInfo != null && changeInfo.getType() == ChangeType.DETACHED)
+ {
+ detachedInfos.remove(changeInfo.getObject());
+ }
+
+ return changeInfo;
+ }
+
+ public ChangeInfo removeChangeInfo(CDOObject object)
+ {
+ ChangeInfo changeInfo = detachedInfos.remove(object);
+ if (changeInfo != null)
+ {
+ changeInfos.remove(changeInfo.getID());
+ }
+
+ return changeInfo;
+ }
+
+ public ChangeInfo getChangeInfo(CDOID id)
+ {
+ return changeInfos.get(id);
+ }
+
+ public ChangeInfo getDetachedInfo(CDOObject object)
+ {
+ return detachedInfos.get(object);
+ }
+
+ public Map<CDOID, ChangeInfo> getChangeInfos()
+ {
+ return Collections.unmodifiableMap(changeInfos);
+ }
+
+ public Map<InternalCDOObject, ChangeInfo> getDetachedInfos()
+ {
+ return Collections.unmodifiableMap(detachedInfos);
+ }
+
public void clear()
{
- synchronized (transaction)
+ synchronized (super.getTransaction())
{
- newObjects.clear();
- dirtyObjects.clear();
- revisionDeltas.clear();
- baseNewObjects.clear();
- detachedObjects.clear();
- reattachedObjects.clear();
+ changeInfos.clear();
+ detachedInfos.clear();
}
}
- public boolean wasDirty()
+ public boolean isInMemory()
{
- return wasDirty;
+ return storage == null;
}
- public Map<CDOID, CDOObject> getNewObjects()
+ public void setInMemory(boolean inMemory)
{
- return newObjects;
+ this.inMemory = inMemory;
+ if (isInMemory())
+ {
+ if (!inMemory)
+ {
+ unload();
+ }
+ }
+ else
+ {
+ if (!inMemory)
+ {
+ load();
+ }
+ }
}
- public Map<CDOID, CDOObject> getDetachedObjects()
+ private void load()
{
- return detachedObjects;
}
- // Bug 283985 (Re-attachment)
- public Map<CDOID, CDOObject> getReattachedObjects()
+ private void unload()
+ {
+ }
+
+ public boolean isEmpty()
+ {
+ return changeInfos.isEmpty();
+ }
+
+ public Map<CDOID, CDOObject> getObjects(ChangeInfo.ChangeType type, Map<CDOID, ChangeInfo> baseline)
{
- return reattachedObjects;
+ Map<CDOID, CDOObject> result = CDOIDUtil.createMap();
+ for (ChangeInfo changeInfo : changeInfos.values())
+ {
+ if (changeInfo.getType() == type)
+ {
+ InternalCDOObject object = changeInfo.getObject();
+ if (object != null)
+ {
+ CDOID id = changeInfo.getID();
+ if (baseline != null)
+ {
+ ChangeInfo baselineInfo = baseline.get(id);
+ if (baselineInfo != null && baselineInfo.getType() == type)
+ {
+ // Ignore the object if it has the same change kind in the baseline
+ continue;
+ }
+ }
+
+ result.put(id, object);
+ }
+ }
+ }
+
+ return Collections.unmodifiableMap(result);
+ }
+
+ public Map<CDOID, CDOObject> getNewObjects()
+ {
+ InternalCDOSavepoint previousSavepoint = getPreviousSavepoint();
+ Map<CDOID, ChangeInfo> baseline = previousSavepoint == null ? null : previousSavepoint.getChangeInfos();
+ return getObjects(ChangeType.NEW, baseline);
}
public Map<CDOID, CDOObject> getDirtyObjects()
{
- return dirtyObjects;
+ InternalCDOSavepoint previousSavepoint = getPreviousSavepoint();
+ Map<CDOID, ChangeInfo> baseline = previousSavepoint == null ? null : previousSavepoint.getChangeInfos();
+ return getObjects(ChangeType.DIRTY, baseline);
}
- @Deprecated
- public Set<CDOID> getSharedDetachedObjects()
+ public Map<CDOID, CDOObject> getDetachedObjects()
{
+ InternalCDOSavepoint previousSavepoint = getPreviousSavepoint();
+ Map<CDOID, ChangeInfo> baseline = previousSavepoint == null ? null : previousSavepoint.getChangeInfos();
+ return getObjects(ChangeType.DETACHED, baseline);
+ }
+
+ public Map<CDOID, CDORevisionDelta> getRevisionDeltas2()
+ {
+ int xxx;
throw new UnsupportedOperationException();
}
- @Deprecated
- public void recalculateSharedDetachedObjects()
+ public CDOChangeSetData getChangeSetData()
{
+ int xxx;
throw new UnsupportedOperationException();
}
+ public CDOChangeSetData getAllChangeSetData()
+ {
+ synchronized (super.getTransaction())
+ {
+ List<CDOIDAndVersion> revisions = new ArrayList<CDOIDAndVersion>();
+ List<CDORevisionKey> deltas = new ArrayList<CDORevisionKey>();
+ List<CDOIDAndVersion> detached = new ArrayList<CDOIDAndVersion>();
+
+ for (ChangeInfo changeInfo : changeInfos.values())
+ {
+ switch (changeInfo.getType())
+ {
+ case NEW:
+ revisions.add(changeInfo.getObject().cdoRevision());
+ break;
+
+ case DIRTY:
+ deltas.add(changeInfo.getRevisionDelta());
+ break;
+
+ case DETACHED:
+ detached.add(changeInfo.getCleanRevision());
+ }
+ }
+
+ return new CDOChangeSetDataImpl(revisions, deltas, detached);
+ }
+ }
+
+ /**
+ * Return the list of all deltas without objects that are removed.
+ */
+ public Map<CDOID, CDORevisionDelta> getAllRevisionDeltas()
+ {
+ Map<CDOID, CDORevisionDelta> result = CDOIDUtil.createMap();
+ for (ChangeInfo changeInfo : changeInfos.values())
+ {
+ CDORevisionDelta revisionDelta = changeInfo.getRevisionDelta();
+ if (revisionDelta != null)
+ {
+ result.put(changeInfo.getID(), revisionDelta);
+ }
+ }
+
+ return Collections.unmodifiableMap(result);
+ }
+
+ /**
+ * Return the list of new objects from this point.
+ */
+ public Map<CDOID, CDOObject> getAllDirtyObjects()
+ {
+ return getObjects(ChangeType.DIRTY, null);
+ }
+
+ /**
+ * Return the list of new objects from this point without objects that are removed.
+ */
+ public Map<CDOID, CDOObject> getAllNewObjects()
+ {
+ return getObjects(ChangeType.NEW, null);
+ }
+
+ public Map<CDOID, CDOObject> getAllDetachedObjects()
+ {
+ return getObjects(ChangeType.DETACHED, null);
+ }
+
+ public boolean isNewObject(CDOID id)
+ {
+ if (id.isTemporary())
+ {
+ return true;
+ }
+
+ ChangeInfo changeInfo = changeInfos.get(id);
+ if (changeInfo != null && changeInfo.getType() == ChangeType.NEW)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean isDetachedObject(CDOID id)
+ {
+ ChangeInfo changeInfo = changeInfos.get(id);
+ return changeInfo != null && changeInfo.getType() == ChangeType.DETACHED;
+ }
+
+ public void rollback()
+ {
+ InternalCDOTransaction transaction = getTransaction();
+ synchronized (transaction)
+ {
+ LifecycleUtil.checkActive(transaction);
+
+ CDOTransactionStrategy transactionStrategy = transaction.getTransactionStrategy();
+ transactionStrategy.rollback(transaction, this);
+ }
+ }
+
@Deprecated
public ConcurrentMap<CDOID, CDORevisionDelta> getRevisionDeltas()
{
+ final Map<CDOID, CDORevisionDelta> revisionDeltas = getRevisionDeltas2();
return new ConcurrentMap<CDOID, CDORevisionDelta>()
{
public int size()
@@ -289,277 +463,51 @@ public class CDOSavepointImpl extends CDOUserSavepointImpl implements InternalCD
};
}
- public Map<CDOID, CDORevisionDelta> getRevisionDeltas2()
- {
- return revisionDeltas;
- }
-
- public CDOChangeSetData getChangeSetData()
- {
- synchronized (transaction)
- {
- return createChangeSetData(newObjects, revisionDeltas, detachedObjects);
- }
- }
-
- public CDOChangeSetData getAllChangeSetData()
- {
- synchronized (transaction)
- {
- return createChangeSetData(getAllNewObjects(), getAllRevisionDeltas(), getAllDetachedObjects());
- }
- }
-
- private CDOChangeSetData createChangeSetData(Map<CDOID, CDOObject> newObjects,
- Map<CDOID, CDORevisionDelta> revisionDeltas, Map<CDOID, CDOObject> detachedObjects)
+ @Deprecated
+ public boolean wasDirty()
{
- List<CDOIDAndVersion> newList = new ArrayList<CDOIDAndVersion>(newObjects.size());
- for (CDOObject object : newObjects.values())
- {
- newList.add(object.cdoRevision());
- }
-
- List<CDORevisionKey> changedList = new ArrayList<CDORevisionKey>(revisionDeltas.size());
- for (CDORevisionDelta delta : revisionDeltas.values())
- {
- changedList.add(delta);
- }
-
- List<CDOIDAndVersion> detachedList = new ArrayList<CDOIDAndVersion>(detachedObjects.size());
- for (CDOID id : detachedObjects.keySet())
- {
- detachedList.add(CDOIDUtil.createIDAndVersion(id, CDOBranchVersion.UNSPECIFIED_VERSION));
- }
-
- return new CDOChangeSetDataImpl(newList, changedList, detachedList);
+ throw new UnsupportedOperationException();
}
+ @Deprecated
public Map<CDOID, CDORevision> getBaseNewObjects()
{
- return baseNewObjects;
- }
-
- /**
- * Return the list of new objects from this point.
- */
- public Map<CDOID, CDOObject> getAllDirtyObjects()
- {
- synchronized (transaction)
- {
- if (getPreviousSavepoint() == null)
- {
- return Collections.unmodifiableMap(getDirtyObjects());
- }
-
- MultiMap.ListBased<CDOID, CDOObject> dirtyObjects = new MultiMap.ListBased<CDOID, CDOObject>();
- for (InternalCDOSavepoint savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
- {
- dirtyObjects.getDelegates().add(savepoint.getDirtyObjects());
- }
-
- return dirtyObjects;
- }
+ throw new UnsupportedOperationException();
}
- /**
- * Return the list of new objects from this point without objects that are removed.
- */
- public Map<CDOID, CDOObject> getAllNewObjects()
+ @Deprecated
+ public Map<CDOID, CDORevision> getAllBaseNewObjects()
{
- synchronized (transaction)
- {
- if (getPreviousSavepoint() == null)
- {
- return Collections.unmodifiableMap(getNewObjects());
- }
-
- Map<CDOID, CDOObject> newObjects = CDOIDUtil.createMap();
- for (InternalCDOSavepoint savepoint = getFirstSavePoint(); savepoint != null; savepoint = savepoint
- .getNextSavepoint())
- {
- newObjects.putAll(savepoint.getNewObjects());
- for (CDOID removedID : savepoint.getDetachedObjects().keySet())
- {
- newObjects.remove(removedID);
- }
- }
-
- return newObjects;
- }
+ throw new UnsupportedOperationException();
}
- /**
- * @since 2.0
- */
- public Map<CDOID, CDORevision> getAllBaseNewObjects()
+ @Deprecated
+ public Map<CDOID, CDOObject> getReattachedObjects()
{
- synchronized (transaction)
- {
- if (getPreviousSavepoint() == null)
- {
- return Collections.unmodifiableMap(getBaseNewObjects());
- }
-
- MultiMap.ListBased<CDOID, CDORevision> newObjects = new MultiMap.ListBased<CDOID, CDORevision>();
- for (InternalCDOSavepoint savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
- {
- newObjects.getDelegates().add(savepoint.getBaseNewObjects());
- }
-
- return newObjects;
- }
+ throw new UnsupportedOperationException();
}
- /**
- * Return the list of all deltas without objects that are removed.
- */
- public Map<CDOID, CDORevisionDelta> getAllRevisionDeltas()
+ @Deprecated
+ public Set<CDOID> getSharedDetachedObjects()
{
- synchronized (transaction)
- {
- if (getPreviousSavepoint() == null)
- {
- return Collections.unmodifiableMap(getRevisionDeltas2());
- }
-
- // We need to combined the result for all delta in different Savepoint
- Map<CDOID, CDORevisionDelta> allRevisionDeltas = CDOIDUtil.createMap();
- for (InternalCDOSavepoint savepoint = getFirstSavePoint(); savepoint != null; savepoint = savepoint
- .getNextSavepoint())
- {
- for (CDORevisionDelta revisionDelta : savepoint.getRevisionDeltas2().values())
- {
- CDOID id = revisionDelta.getID();
- if (!isNewObject(id))
- {
- CDORevisionDeltaImpl oldRevisionDelta = (CDORevisionDeltaImpl)allRevisionDeltas.get(id);
- if (oldRevisionDelta == null)
- {
- allRevisionDeltas.put(id, revisionDelta.copy());
- }
- else
- {
- for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas())
- {
- CDOFeatureDelta copy = ((InternalCDOFeatureDelta)delta).copy();
- oldRevisionDelta.addFeatureDelta(copy, null);
- }
- }
- }
- }
-
- Set<CDOID> reattachedObjects = savepoint.getReattachedObjects().keySet();
- for (CDOID detachedID : savepoint.getDetachedObjects().keySet())
- {
- if (!reattachedObjects.contains(detachedID))
- {
- allRevisionDeltas.remove(detachedID);
- }
- }
- }
-
- return Collections.unmodifiableMap(allRevisionDeltas);
- }
+ throw new UnsupportedOperationException();
}
- public Map<CDOID, CDOObject> getAllDetachedObjects()
+ @Deprecated
+ public void recalculateSharedDetachedObjects()
{
- synchronized (transaction)
- {
- if (getPreviousSavepoint() == null && reattachedObjects.isEmpty())
- {
- return Collections.unmodifiableMap(getDetachedObjects());
- }
-
- Map<CDOID, CDOObject> detachedObjects = CDOIDUtil.createMap();
- for (InternalCDOSavepoint savepoint = getFirstSavePoint(); savepoint != null; savepoint = savepoint
- .getNextSavepoint())
- {
- for (Entry<CDOID, CDOObject> entry : savepoint.getDetachedObjects().entrySet())
- {
- CDOID detachedID = entry.getKey();
- if (!isNewObject(detachedID))
- {
- CDOObject detachedObject = entry.getValue();
- detachedObjects.put(detachedID, detachedObject);
- }
- }
-
- for (CDOID reattachedID : savepoint.getReattachedObjects().keySet())
- {
- detachedObjects.remove(reattachedID);
- }
- }
-
- return detachedObjects;
- }
+ throw new UnsupportedOperationException();
}
- public boolean isNewObject(CDOID id)
+ @Deprecated
+ public void attachObject(InternalCDOObject object)
{
- if (id.isTemporary())
- {
- return true;
- }
-
- synchronized (transaction)
- {
- for (InternalCDOSavepoint savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
- {
- if (savepoint.getNewObjects().containsKey(id))
- {
- return true;
- }
- }
- }
-
- return false;
+ throw new UnsupportedOperationException();
}
- // TODO Not sure if this new implementation is needed. The existing one passes all tests.
- // public boolean isNewObject(CDOID id)
- // {
- // if (id.isTemporary())
- // {
- // return true;
- // }
- //
- // boolean isNew = false;
- // boolean wasNew = false;
- // synchronized (transaction)
- // {
- // for (InternalCDOSavepoint savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
- // {
- // if (savepoint.getNewObjects().containsKey(id))
- // {
- // isNew = true;
- // wasNew = true;
- // }
- //
- // if (isNew && savepoint.getDetachedObjects().containsKey(id))
- // {
- // isNew = false;
- // }
- //
- // if (!isNew && wasNew && savepoint.getReattachedObjects().containsKey(id))
- // {
- // isNew = true;
- // }
- // }
- // }
- //
- // return isNew;
- // }
-
- public void rollback()
+ @Deprecated
+ public void removeObject(InternalCDOObject object)
{
- synchronized (transaction)
- {
- InternalCDOTransaction transaction = getTransaction();
- LifecycleUtil.checkActive(transaction);
-
- CDOTransactionStrategy transactionStrategy = transaction.getTransactionStrategy();
- transactionStrategy.rollback(transaction, this);
- }
+ throw new UnsupportedOperationException();
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java
index bcd2ace85a..baf3936435 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java
@@ -95,7 +95,7 @@ public class CDOSingleTransactionStrategyImpl implements CDOTransactionStrategy
throw new CommitException(rollbackMessage);
default:
- throw new IllegalStateException("Invalid rollbackreason: " + rollbackReason);
+ throw new IllegalStateException("Invalid rollback reason: " + rollbackReason);
}
}
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 360e004d7d..c6f5df5a7f 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
@@ -53,9 +53,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.CDORevisionProvider;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOOriginSizeProvider;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.eresource.CDOBinaryResource;
@@ -80,6 +78,7 @@ import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.protocol.CDODataInputImpl;
import org.eclipse.emf.cdo.spi.common.protocol.CDODataOutputImpl;
import org.eclipse.emf.cdo.spi.common.revision.CDOIDMapper;
+import org.eclipse.emf.cdo.spi.common.revision.CDOReferenceAdjuster;
import org.eclipse.emf.cdo.spi.common.revision.CDORevisionUnchunker;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
@@ -92,13 +91,13 @@ import org.eclipse.emf.cdo.transaction.CDOSavepoint;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.transaction.CDOTransactionConflictEvent;
import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent;
+import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent.Reason;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler1;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler2;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler3;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandlerBase;
import org.eclipse.emf.cdo.transaction.CDOTransactionStartedEvent;
-import org.eclipse.emf.cdo.transaction.CDOUserSavepoint;
import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
@@ -117,7 +116,7 @@ import org.eclipse.emf.internal.cdo.query.CDOQueryImpl;
import org.eclipse.emf.internal.cdo.util.CommitIntegrityCheck;
import org.eclipse.emf.internal.cdo.util.CompletePackageClosure;
import org.eclipse.emf.internal.cdo.util.IPackageClosure;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2;
import org.eclipse.emf.internal.cdo.view.CDOViewImpl;
import org.eclipse.net4j.util.CheckUtil;
@@ -145,7 +144,6 @@ import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.impl.EClassImpl.FeatureSubsetSupplier;
import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.Resource.Internal;
import org.eclipse.emf.ecore.util.EContentsEList;
import org.eclipse.emf.ecore.util.EContentsEList.FeatureIterator;
import org.eclipse.emf.ecore.util.ECrossReferenceEList;
@@ -156,6 +154,8 @@ import org.eclipse.emf.spi.cdo.CDOTransactionStrategy;
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.InternalCDOSavepoint.ChangeInfo;
+import org.eclipse.emf.spi.cdo.InternalCDOSavepoint.ChangeInfo.ChangeType;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOSession.MergeData;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
@@ -242,9 +242,12 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
private Set<? extends EObject> committables;
/**
- * A map to hold a clean (i.e. unmodified) revision for objects that have been modified or detached.
- */
- private Map<InternalCDOObject, InternalCDORevision> cleanRevisions = new ResolvingRevisionMap();
+ * A map to hold a clean (i.e. unmodified) revision for objects that have been modified or detached.
+ */
+ // private Map<InternalCDOObject, InternalCDORevision> cleanRevisions = new HashMap<InternalCDOObject,
+ // InternalCDORevision>();
+
+ // private Map<InternalCDOObject, InternalCDORevision> _cleanRevisions = new ResolvingRevisionMap();
public CDOTransactionImpl(CDOBranch branch)
{
@@ -377,6 +380,36 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
+ public void handleAttachingObject(CDOObject object)
+ {
+ CDOTransactionHandler1[] handlers = getTransactionHandlers1();
+ for (int i = 0; i < handlers.length; i++)
+ {
+ CDOTransactionHandler1 handler = handlers[i];
+ handler.attachingObject(this, object);
+ }
+ }
+
+ public void handleModifyingObject(CDOObject object, CDOFeatureDelta featureDelta)
+ {
+ CDOTransactionHandler1[] handlers = getTransactionHandlers1();
+ for (int i = 0; i < handlers.length; i++)
+ {
+ CDOTransactionHandler1 handler = handlers[i];
+ handler.modifyingObject(this, object, featureDelta);
+ }
+ }
+
+ public void handleDetachingObject(CDOObject object)
+ {
+ CDOTransactionHandler1[] handlers = getTransactionHandlers1();
+ for (int i = 0; i < handlers.length; i++)
+ {
+ CDOTransactionHandler1 handler = handlers[i];
+ handler.detachingObject(this, object);
+ }
+ }
+
@Override
public boolean isDirty()
{
@@ -388,9 +421,52 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return dirty;
}
+ public IListener[] updateDirtyState(boolean undone)
+ {
+ if (lastSavepoint.isEmpty())
+ {
+ // Becomes clean
+ if (dirty)
+ {
+ dirty = false;
+
+ IListener[] listeners = getListeners();
+ if (undone)
+ {
+ if (listeners != null)
+ {
+ fireEvent(new FinishedEvent(Reason.UNDONE, null), listeners);
+ }
+ }
+ else
+ {
+ // Let the caller fire a specific CDOTransactionFinishedEvent
+ return listeners;
+ }
+ }
+ }
+ else
+ {
+ // Becomes dirty
+ if (!dirty)
+ {
+ dirty = true;
+
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ fireEvent(new StartedEvent(), listeners);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Deprecated
public void setDirty(boolean dirty)
{
- this.dirty = dirty;
+ throw new UnsupportedOperationException();
}
@Override
@@ -437,9 +513,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return conflicts;
}
- public synchronized CDOChangeSetData getChangeSetData()
+ public CDOChangeSetData getChangeSetData()
{
- checkActive();
return lastSavepoint.getAllChangeSetData();
}
@@ -524,8 +599,14 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
Map<CDOID, InternalCDORevision> oldRevisions = applyChangedObjects(changeSetData.getChangedObjects(),
ancestorProvider, targetProvider, keepVersions, resultData.getChangedObjects());
+ IListener[] listeners = updateDirtyState(false);
+ if (listeners != null)
+ {
+ fireEvent(new FinishedEvent(Reason.MERGED, null), listeners);
+ }
+
// Delta notifications
- Collection<CDORevisionDelta> notificationDeltas = lastSavepoint.getRevisionDeltas2().values();
+ Collection<CDORevisionDelta> notificationDeltas = lastSavepoint.getAllRevisionDeltas().values();
if (!notificationDeltas.isEmpty() || !detachedSet.isEmpty())
{
sendDeltaNotifications(notificationDeltas, detachedSet, oldRevisions);
@@ -594,10 +675,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
object.cdoInternalSetState(CDOState.NEW);
object.cdoInternalPostLoad();
- registerObject(object);
- registerAttached(object, true);
+ int xxx;
+ // registerAttached(object, true);
result.add(revision);
- dirty = true;
}
}
}
@@ -612,9 +692,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
if (object != null)
{
result.add(CDOIDUtil.createIDAndVersion(id, CDOBranchVersion.UNSPECIFIED_VERSION));
- CDOStateMachine.INSTANCE.detach(object);
+ CDOStateMachine2.INSTANCE.detach(object);
detachedSet.add(object);
- dirty = true;
}
}
@@ -627,10 +706,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
{
Map<CDOID, InternalCDORevision> oldRevisions = CDOIDUtil.createMap();
- Map<CDOID, CDOObject> detachedObjects = lastSavepoint.getDetachedObjects();
- Map<CDOID, CDOObject> dirtyObjects = lastSavepoint.getDirtyObjects();
- Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
-
for (CDORevisionKey key : changedObjects)
{
InternalCDORevisionDelta ancestorGoalDelta = (InternalCDORevisionDelta)key;
@@ -671,21 +746,17 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
throw new ChangeSetOutdatedException();
}
- revisionDeltas.put(id, targetGoalDelta);
result.add(targetGoalDelta);
- // handle reattached objects.
- if (detachedObjects.containsKey(id))
+ // Handle reattached objects.
+ if (lastSavepoint.isDetachedObject(id))
{
- CDOStateMachine.INSTANCE.internalReattach(object, this);
+ CDOStateMachine2.INSTANCE.attach(object, this);
}
object.cdoInternalSetRevision(goalRevision);
object.cdoInternalSetState(CDOState.DIRTY);
revisionChanged = true;
-
- dirtyObjects.put(id, object);
- dirty = true;
}
if (revisionChanged)
@@ -793,8 +864,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
else
{
- Map<CDOID, CDOObject> dirtyObjects = getLastSavepoint().getDirtyObjects();
- setDirty(!dirtyObjects.isEmpty());
+ setDirty(!lastSavepoint.isEmpty());
}
}
@@ -1028,7 +1098,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
{
if (node.isRoot())
{
- CDOStateMachine.INSTANCE.attach(node, this);
+ CDOStateMachine2.INSTANCE.attach(node, this);
}
else
{
@@ -1046,7 +1116,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
*/
public synchronized void detach(CDOResourceImpl cdoResource)
{
- CDOStateMachine.INSTANCE.detach(cdoResource);
+ CDOStateMachine2.INSTANCE.detach(cdoResource);
}
/**
@@ -1120,7 +1190,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
CDOID id = super.getRootOrTopLevelResourceNodeID(name);
- if (getLastSavepoint().getAllDetachedObjects().containsKey(id) || getDirtyObjects().containsKey(id))
+ if (lastSavepoint.getAllDetachedObjects().containsKey(id) || getDirtyObjects().containsKey(id))
{
throw new CDOException(MessageFormat.format(Messages.getString("CDOTransactionImpl.1"), name)); //$NON-NLS-1$
}
@@ -1157,10 +1227,17 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return null;
}
- if (isObjectNew(id) && isObjectDetached(id))
- {
- throw new ObjectNotFoundException(id, this);
- }
+ // ChangeInfo changeInfo = lastSavepoint.getChangeInfo(id);
+ // if (changeInfo != null)
+ // {
+ // return changeInfo.getObject();
+ // }
+
+ int xxx;
+ // if (/* isObjectNew(id) && */isObjectDetached(id))
+ // {
+ // throw new ObjectNotFoundException(id, this);
+ // }
return super.getObject(id, loadOnDemand);
}
@@ -1173,7 +1250,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
private boolean isObjectDetached(CDOID id)
{
- return lastSavepoint.getAllDetachedObjects().containsKey(id);
+ return lastSavepoint.isDetachedObject(id);
}
/**
@@ -1181,7 +1258,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
*/
public synchronized InternalCDOCommitContext createCommitContext()
{
- return new CDOCommitContextImpl(this);
+ return new CDOCommitContextImpl();
}
public/* synchronized */CDOCommitInfo commit() throws CommitException
@@ -1247,8 +1324,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
finally
{
- getSession().endLocalCommit(token);
clearResourcePathCacheIfNecessary(null);
+ getSession().endLocalCommit(token);
}
}
@@ -1262,7 +1339,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
CDOTransactionStrategy strategy = getTransactionStrategy();
strategy.rollback(this, firstSavepoint);
- cleanUp(null);
+ cleanUp(null, null);
}
private void removeObject(CDOID id, final CDOObject object)
@@ -1289,7 +1366,143 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
internal.cdoInternalSetState(CDOState.TRANSIENT);
}
- private Set<CDOID> rollbackCompletely(CDOUserSavepoint savepoint)
+ /**
+ * @author Eike Stepper
+ */
+ private static final class RollbackSupport
+ {
+ private static final int CLEAN = 0;
+
+ private static final int NEW = 1;
+
+ private static final int CHANGED = 2;
+
+ private static final int DETACHED = 3;
+
+ /**
+ * Finite state machine for rollback transitions.
+ */
+ private static final Transition[][] FSM = new Transition[4][4];
+
+ static
+ {
+ FSM[CLEAN][CLEAN] = Transition.FAIL;
+ FSM[CLEAN][NEW] = new UndoTransition();
+ FSM[CLEAN][CHANGED] = new UndoTransition();
+ FSM[CLEAN][DETACHED] = new UndoTransition();
+
+ FSM[NEW][CLEAN] = null;
+ FSM[NEW][NEW] = Transition.IGNORE;
+ FSM[NEW][CHANGED] = Transition.FAIL;
+ FSM[NEW][DETACHED] = Transition.FAIL;
+
+ FSM[CHANGED][CLEAN] = null;
+ FSM[CHANGED][NEW] = Transition.FAIL;
+ FSM[CHANGED][CHANGED] = Transition.IGNORE;
+ FSM[CHANGED][DETACHED] = null;
+
+ FSM[DETACHED][CLEAN] = null;
+ FSM[DETACHED][NEW] = Transition.FAIL;
+ FSM[DETACHED][CHANGED] = null;
+ FSM[DETACHED][DETACHED] = Transition.IGNORE;
+ }
+
+ public static Set<CDOID> rollbackTo(InternalCDOSavepoint formerSavepoint, InternalCDOSavepoint latestSavepoint)
+ {
+ Set<CDOID> idsOfNewObjectsWithDeltas = new HashSet<CDOID>();
+
+ Map<CDOID, ChangeInfo> latestChangeInfos = latestSavepoint.getChangeInfos();
+ Map<CDOID, ChangeInfo> formerChangeInfos = formerSavepoint.getChangeInfos();
+
+ // Handle all former infos and remove the corresponding latest infos
+ for (ChangeInfo formerChangeInfo : formerChangeInfos.values())
+ {
+ ChangeInfo latestChangeInfo = latestChangeInfos.remove(formerChangeInfo.getID());
+ rollbackTo(formerChangeInfo, latestChangeInfo);
+ }
+
+ // Handle remanining latest infos
+ for (ChangeInfo latestChangeInfo : latestChangeInfos.values())
+ {
+ ChangeInfo formerChangeInfo = formerChangeInfos.get(latestChangeInfo.getID());
+ rollbackTo(formerChangeInfo, latestChangeInfo);
+ }
+
+ return idsOfNewObjectsWithDeltas;
+ }
+
+ private static void rollbackTo(ChangeInfo formerChangeInfo, ChangeInfo latestChangeInfo)
+ {
+ int formerKind = getIndex(formerChangeInfo);
+ int latestKind = getIndex(latestChangeInfo);
+
+ Transition transition = FSM[formerKind][latestKind];
+ if (transition != null)
+ {
+ transition.execute(formerChangeInfo, latestChangeInfo);
+ }
+ }
+
+ private static int getIndex(ChangeInfo changeInfo)
+ {
+ if (changeInfo == null)
+ {
+ return CLEAN;
+ }
+
+ ChangeType type = changeInfo.getType();
+ switch (type)
+ {
+ case NEW:
+ return NEW;
+
+ case DIRTY:
+ return CHANGED;
+
+ case DETACHED:
+ return DETACHED;
+
+ default:
+ throw new IllegalStateException("Illegal change kind: " + type);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface Transition
+ {
+ public static final Transition IGNORE = new Transition()
+ {
+ public void execute(ChangeInfo formerChangeInfo, ChangeInfo latestChangeInfo)
+ {
+ // Do nothing
+ }
+ };
+
+ public static final Transition FAIL = new Transition()
+ {
+ public void execute(ChangeInfo formerChangeInfo, ChangeInfo latestChangeInfo)
+ {
+ throw new IllegalStateException("Impossible to rollback from " + latestChangeInfo + " to " + formerChangeInfo);
+ }
+ };
+
+ public void execute(ChangeInfo formerChangeInfo, ChangeInfo latestChangeInfo);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class UndoTransition implements Transition
+ {
+ public void execute(ChangeInfo formerChangeInfo, ChangeInfo latestChangeInfo)
+ {
+ }
+ }
+ }
+
+ private Set<CDOID> rollbackCompletely(InternalCDOSavepoint savepoint)
{
Set<CDOID> idsOfNewObjectsWithDeltas = new HashSet<CDOID>();
@@ -1330,7 +1543,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
if (idOrObject instanceof CDOObjectImpl)
{
CDOObjectImpl impl = (CDOObjectImpl)idOrObject;
- Internal directResource = impl.eDirectResource();
+ Resource.Internal directResource = impl.eDirectResource();
EObject container = impl.eContainer();
if (!toBeDetached.contains(directResource) && !toBeDetached.contains(container))
{
@@ -1341,7 +1554,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
else if (idOrObject instanceof CDOObjectWrapper)
{
CDOObjectWrapper wrapper = (CDOObjectWrapper)idOrObject;
- Internal directResource = wrapper.eDirectResource();
+ Resource.Internal directResource = wrapper.eDirectResource();
EObject container = wrapper.eContainer();
if (!toBeDetached.contains(directResource) && !toBeDetached.contains(container))
{
@@ -1378,7 +1591,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
else
{
InternalCDOObject detachedObject = (InternalCDOObject)detachedObjectEntry.getValue();
- InternalCDORevision cleanRev = cleanRevisions.get(detachedObject);
+ InternalCDORevision cleanRev = getCleanRevision(detachedObject);
cleanObject(detachedObject, cleanRev);
}
}
@@ -1395,7 +1608,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
// they were already reset to TRANSIENT earlier in this method
if (!reattachedObjectsMap.values().contains(internalDirtyObject))
{
- CDOStateMachine.INSTANCE.rollback(internalDirtyObject);
+ CDOStateMachine2.INSTANCE.rollback(internalDirtyObject);
}
}
}
@@ -1487,63 +1700,70 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
- dirty = savepoint.wasDirty();
+ IListener[] listeners = updateDirtyState(false);
+ if (listeners != null)
+ {
+ fireEvent(new FinishedEvent(Reason.ROLLED_BACK, null), listeners);
+ }
}
/**
* @since 2.0
*/
+ @Deprecated
public synchronized void detachObject(InternalCDOObject object)
{
- CDOTransactionHandler1[] handlers = getTransactionHandlers1();
- for (int i = 0; i < handlers.length; i++)
- {
- CDOTransactionHandler1 handler = handlers[i];
- handler.detachingObject(this, object);
- }
-
- // deregister object
- CDOID id = object.cdoID();
- if (object.cdoState() == CDOState.NEW)
- {
- Map<CDOID, CDOObject> map = lastSavepoint.getNewObjects();
+ throw new UnsupportedOperationException();
- // Determine if we added object
- if (map.containsKey(id))
- {
- map.remove(id);
- }
- else
- {
- lastSavepoint.getDetachedObjects().put(id, object);
- }
+ // CDOTransactionHandler1[] handlers = getTransactionHandlers1();
+ // for (int i = 0; i < handlers.length; i++)
+ // {
+ // CDOTransactionHandler1 handler = handlers[i];
+ // handler.detachingObject(this, object);
+ // }
+ //
+ // if (lastSavepoint.detachObject(object))
+ // {
+ // deregisterObject(object);
+ // }
+ //
+ // if (!dirty)
+ // {
+ // dirty = true;
+ // IListener[] listeners = getListeners();
+ // if (listeners != null)
+ // {
+ // fireEvent(new StartedEvent(), listeners);
+ // }
+ // }
+ }
- // deregister object
- deregisterObject(object);
- }
- else
- {
- if (!cleanRevisions.containsKey(object))
- {
- cleanRevisions.put(object, object.cdoRevision());
- }
+ public String dumpSavepoint()
+ {
+ int xxx;
- lastSavepoint.getDetachedObjects().put(id, object);
+ StringBuilder builder = new StringBuilder();
+ dumpSavepoint(builder, "Dirty", dirty);
+ dumpSavepoint(builder, "Objects", getObjects().size());
- // Object may have been reattached previously, in which case it must
- // here be removed from the collection of reattached objects
- lastSavepoint.getReattachedObjects().remove(id);
- }
+ Map<CDOID, ChangeInfo> changeInfos = lastSavepoint.getChangeInfos();
+ List<CDOID> ids = new ArrayList<CDOID>(changeInfos.keySet());
+ Collections.sort(ids);
- if (!dirty)
+ for (CDOID id : ids)
{
- dirty = true;
- IListener[] listeners = getListeners();
- if (listeners != null)
- {
- fireEvent(new StartedEvent(), listeners);
- }
+ dumpSavepoint(builder, id.toString(), changeInfos.get(id));
}
+
+ return builder.toString();
+ }
+
+ private void dumpSavepoint(StringBuilder builder, String property, Object value)
+ {
+ builder.append(property);
+ builder.append(" = ");
+ builder.append(value);
+ builder.append("\n");
}
/**
@@ -1644,7 +1864,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
IListener[] listeners = getListeners();
if (listeners != null)
{
- fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.ROLLED_BACK, idMappings), listeners);
+ fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Reason.ROLLED_BACK, idMappings), listeners);
}
CDOTransactionHandler2[] handlers = getTransactionHandlers2();
@@ -1677,12 +1897,14 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
*/
public synchronized InternalCDOSavepoint handleSetSavepoint()
{
- addToBase(lastSavepoint.getNewObjects());
+ // addToBase(lastSavepoint.getNewObjects());
+ InternalCDOSavepoint previousSavepoint = lastSavepoint;
lastSavepoint = createSavepoint(lastSavepoint);
+
return lastSavepoint;
}
- private CDOSavepointImpl createSavepoint(InternalCDOSavepoint lastSavepoint)
+ protected CDOSavepointImpl createSavepoint(InternalCDOSavepoint lastSavepoint)
{
return new CDOSavepointImpl(this, lastSavepoint);
}
@@ -1712,16 +1934,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return "CDOTransaction"; //$NON-NLS-1$
}
- public synchronized void registerAttached(InternalCDOObject object, boolean isNew)
+ public synchronized void attachObject(InternalCDOObject object)
{
if (TRACER.isEnabled())
{
- TRACER.format("Registering new object {0}", object); //$NON-NLS-1$
- }
-
- if (isNew)
- {
- registerNewPackage(object.eClass().getEPackage());
+ TRACER.format("Attaching object {0}", object); //$NON-NLS-1$
}
CDOTransactionHandler1[] handlers = getTransactionHandlers1();
@@ -1731,10 +1948,38 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
handler.attachingObject(this, object);
}
- if (isNew)
- {
- registerNew(lastSavepoint.getNewObjects(), object);
- }
+ registerNewPackage(object.eClass().getEPackage());
+ registerObject(object);
+ }
+
+ public synchronized void _registerAttached(InternalCDOObject object, boolean isNew)
+ {
+ throw new UnsupportedOperationException();
+
+ // if (TRACER.isEnabled())
+ // {
+ // TRACER.format("Registering new object {0}", object); //$NON-NLS-1$
+ // }
+ //
+ // if (isNew)
+ // {
+ // registerNewPackage(object.eClass().getEPackage());
+ // }
+ //
+ // registerObject(object);
+ //
+ // CDOTransactionHandler1[] handlers = getTransactionHandlers1();
+ // for (int i = 0; i < handlers.length; i++)
+ // {
+ // CDOTransactionHandler1 handler = handlers[i];
+ // handler.attachingObject(this, object);
+ // }
+ //
+ // int xxx;
+ // // if (isNew)
+ // // {
+ // // registerNew(lastSavepoint.getNewObjects(), object);
+ // // }
}
private void registerNewPackage(EPackage ePackage)
@@ -1749,109 +1994,122 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
/**
* Receives notification for new and dirty objects
*/
- public synchronized void registerFeatureDelta(final InternalCDOObject object, final CDOFeatureDelta featureDelta)
+ public synchronized void _registerFeatureDelta(final InternalCDOObject object, final CDOFeatureDelta featureDelta)
{
- CDOID id = object.cdoID();
- boolean needToSaveFeatureDelta = true;
-
- if (object.cdoState() == CDOState.NEW)
- {
- // Register Delta for new objects only if objectA doesn't belong to
- // this savepoint
- if (getLastSavepoint().getPreviousSavepoint() == null || featureDelta == null)
- {
- needToSaveFeatureDelta = false;
- }
- else
- {
- Map<CDOID, CDOObject> map = getLastSavepoint().getNewObjects();
- needToSaveFeatureDelta = !map.containsKey(id);
- }
- }
-
- if (needToSaveFeatureDelta)
- {
- final InternalCDORevision revision = object.cdoRevision();
-
- CDORevisionDelta revisionDelta = lastSavepoint.getRevisionDeltas2().get(id);
- if (revisionDelta == null)
- {
- revisionDelta = CDORevisionUtil.createDelta(revision);
- lastSavepoint.getRevisionDeltas2().put(id, revisionDelta);
- }
-
- ((InternalCDORevisionDelta)revisionDelta).addFeatureDelta(featureDelta, new CDOOriginSizeProvider()
- {
- public int getOriginSize()
- {
- EStructuralFeature feature = featureDelta.getFeature();
- InternalCDORevision cleanRevision = cleanRevisions.get(object);
- if (cleanRevision == null)
- {
- // Clean revision has *not yet* been registered, in this case the object revision *is still clean*
- cleanRevision = revision;
- }
-
- CDOList list = cleanRevision.getList(feature);
- return list.size();
- }
- });
- }
-
- CDOTransactionHandler1[] handlers = getTransactionHandlers1();
- for (int i = 0; i < handlers.length; i++)
- {
- CDOTransactionHandler1 handler = handlers[i];
- handler.modifyingObject(this, object, featureDelta);
- }
- }
+ throw new UnsupportedOperationException();
- public synchronized void registerRevisionDelta(CDORevisionDelta revisionDelta)
+ // CDOID id = object.cdoID();
+ // boolean needToSaveFeatureDelta = true;
+ //
+ // if (object.cdoState() == CDOState.NEW)
+ // {
+ // // Register Delta for new objects only if objectA doesn't belong to
+ // // this savepoint
+ // if (lastSavepoint.getPreviousSavepoint() == null || featureDelta == null)
+ // {
+ // needToSaveFeatureDelta = false;
+ // }
+ // else
+ // {
+ // Map<CDOID, CDOObject> map = lastSavepoint.getNewObjects();
+ // needToSaveFeatureDelta = !map.containsKey(id);
+ // }
+ // }
+ //
+ // if (needToSaveFeatureDelta)
+ // {
+ // final InternalCDORevision revision = object.cdoRevision();
+ //
+ // CDORevisionDelta revisionDelta = lastSavepoint.getRevisionDeltas2().get(id);
+ // if (revisionDelta == null)
+ // {
+ // revisionDelta = CDORevisionUtil.createDelta(revision);
+ // lastSavepoint.getRevisionDeltas2().put(id, revisionDelta);
+ // }
+ //
+ // ((InternalCDORevisionDelta)revisionDelta).addFeatureDelta(featureDelta, new CDOOriginSizeProvider()
+ // {
+ // public int getOriginSize()
+ // {
+ // EStructuralFeature feature = featureDelta.getFeature();
+ // InternalCDORevision cleanRevision = _cleanRevisions.get(object);
+ // if (cleanRevision == null)
+ // {
+ // // Clean revision has *not yet* been registered, in this case the object revision *is still clean*
+ // cleanRevision = revision;
+ // }
+ //
+ // CDOList list = cleanRevision.getList(feature);
+ // return list.size();
+ // }
+ // });
+ // }
+ //
+ // CDOTransactionHandler1[] handlers = getTransactionHandlers1();
+ // for (int i = 0; i < handlers.length; i++)
+ // {
+ // CDOTransactionHandler1 handler = handlers[i];
+ // handler.modifyingObject(this, object, featureDelta);
+ // }
+ }
+
+ public synchronized void _registerRevisionDelta(CDORevisionDelta revisionDelta)
{
- Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
- CDOID id = revisionDelta.getID();
- if (!revisionDeltas.containsKey(id))
- {
- revisionDeltas.put(id, revisionDelta);
- }
+ throw new UnsupportedOperationException();
+
+ // Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
+ // CDOID id = revisionDelta.getID();
+ // if (!revisionDeltas.containsKey(id))
+ // {
+ // revisionDeltas.put(id, revisionDelta);
+ // }
}
- public synchronized void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ public synchronized void _registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta)
{
- if (TRACER.isEnabled())
- {
- TRACER.format("Registering dirty object {0}", object); //$NON-NLS-1$
- }
-
- if (featureDelta != null)
- {
- registerFeatureDelta(object, featureDelta);
- }
+ throw new UnsupportedOperationException();
- registerNew(lastSavepoint.getDirtyObjects(), object);
+ // if (TRACER.isEnabled())
+ // {
+ // TRACER.format("Registering dirty object {0}", object); //$NON-NLS-1$
+ // }
+ //
+ // if (featureDelta != null)
+ // {
+ // registerFeatureDelta(object, featureDelta);
+ // }
+ //
+ // int xxx;
+ // // registerNew(lastSavepoint.getDirtyObjects(), object);
+ // registerNew(null, object);
}
/**
* TODO Simon: Should this method go to CDOSavePointImpl?
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
- private void registerNew(Map map, InternalCDOObject object)
+ private void _registerNew(Map map, InternalCDOObject object)
{
- Object old = map.put(object.cdoID(), object);
- if (old != null)
- {
- throw new IllegalStateException(MessageFormat.format(Messages.getString("CDOTransactionImpl.10"), object)); //$NON-NLS-1$
- }
+ throw new UnsupportedOperationException();
- if (!dirty)
- {
- dirty = true;
- IListener[] listeners = getListeners();
- if (listeners != null)
- {
- fireEvent(new StartedEvent(), listeners);
- }
- }
+ // if (map != null)
+ // {
+ // Object old = map.put(object.cdoID(), object);
+ // if (old != null)
+ // {
+ // throw new IllegalStateException(MessageFormat.format(Messages.getString("CDOTransactionImpl.10"), object)); //$NON-NLS-1$
+ // }
+ // }
+ //
+ // if (!dirty)
+ // {
+ // dirty = true;
+ // IListener[] listeners = getListeners();
+ // if (listeners != null)
+ // {
+ // fireEvent(new StartedEvent(), listeners);
+ // }
+ // }
}
public synchronized List<CDOPackageUnit> analyzeNewPackages()
@@ -1923,45 +2181,51 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return newPackages;
}
- private void cleanUp(CDOCommitContext commitContext)
+ private IListener[] cleanUp(CDOCommitContext commitContext, CommitTransactionResult result)
{
- if (commitContext == null || !commitContext.isPartialCommit())
+ if (commitContext != null)
{
- if (commitContext != null)
+ for (CDOObject object : commitContext.getDetachedObjects().values())
{
- for (CDOObject object : commitContext.getDetachedObjects().values())
- {
- cleanUpLockState(object);
- }
+ cleanUpLockState(object);
+ lastSavepoint.removeChangeInfo(object);
}
+ }
- lastSavepoint = firstSavepoint;
- firstSavepoint.clear();
- firstSavepoint.setNextSavepoint(null);
+ firstSavepoint = lastSavepoint; // Last savepoint may contain left-overs from partial commit
+ lastSavepoint.setPreviousSavepoint(null);
+ conflict = 0; // TODO Left-overs from partial commit?
- cleanRevisions.clear();
- dirty = false;
- conflict = 0;
- idGenerator.reset();
+ if (commitContext != null && commitContext.isPartialCommit())
+ {
+ // collapseSavepoints(commitContext);
}
else
{
- collapseSavepoints(commitContext);
+ // lastSavepoint = firstSavepoint;
+ // firstSavepoint.clear();
+ // firstSavepoint.setNextSavepoint(null);
+ // conflict = 0;
+ idGenerator.reset();
+ }
- for (CDOObject object : commitContext.getDetachedObjects().values())
+ // Reset partial-commit filter
+ committables = null;
+
+ IListener[] listeners = updateDirtyState(false);
+ if (listeners != null)
+ {
+ if (result != null)
{
- cleanRevisions.remove(object);
- cleanUpLockState(object);
+ fireEvent(new FinishedEvent(Reason.COMMITTED, result.getIDMappings()), listeners);
}
-
- for (CDOObject object : commitContext.getDirtyObjects().values())
+ else
{
- cleanRevisions.remove(object);
+ fireEvent(new FinishedEvent(Reason.ROLLED_BACK, null), listeners);
}
}
- // Reset partial-commit filter
- committables = null;
+ return listeners;
}
private void cleanUpLockState(CDOObject object)
@@ -2156,7 +2420,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
{
InternalCDOObject object = newInstance(revision);
registerObject(object);
- registerAttached(object, true);
+ int xxx;
+ // registerAttached(object, true);
newObjects.add(object);
}
@@ -2176,8 +2441,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
int oldVersion = object.cdoRevision().getVersion();
merger.merge(object, delta);
- registerRevisionDelta(delta);
- registerDirty(object, null);
+ int xxx;
+ // registerRevisionDelta(delta);
+ // registerDirty(object, null);
if (delta.getVersion() < oldVersion)
{
@@ -2268,13 +2534,24 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return lastSavepoint.getAllDetachedObjects();
}
+ private CDOID getDetachedID(CDOObject object)
+ {
+ ChangeInfo changeInfo = lastSavepoint.getDetachedInfo(object);
+ if (changeInfo != null)
+ {
+ return changeInfo.getID();
+ }
+
+ return null;
+ }
+
@Override
protected synchronized CDOID getXRefTargetID(CDOObject target)
{
- CDORevisionKey key = cleanRevisions.get(target);
- if (key != null)
+ CDOID detachedID = getDetachedID(target);
+ if (detachedID != null)
{
- return key.getID();
+ return detachedID;
}
return super.getXRefTargetID(target);
@@ -2301,12 +2578,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
// The super implementation will return null for a transient (unattached) object;
- // but in a tx, an transient object may previously have been attached. So we consult
- // the cleanRevisions if that's the case.
- CDORevisionKey revKey = cleanRevisions.get(object);
- if (revKey != null && getDetachedObjects().containsValue(object))
+ // but in a tx, an transient object may previously have been attached.
+ CDOID detachedID = getDetachedID(object);
+ if (detachedID != null)
{
- id = revKey.getID();
+ id = detachedID;
}
return id;
@@ -2467,7 +2743,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
// doesn't apply: it must be removed for sure.)
if (referencer.cdoState() == CDOState.DIRTY && referencerClassInfo.isPersistent(reference))
{
- InternalCDORevision cleanRevision = cleanRevisions.get(referencer);
+ InternalCDORevision cleanRevision = getCleanRevision(referencer);
if (reference.isMany())
{
@@ -2567,27 +2843,63 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return committables;
}
- public synchronized Map<InternalCDOObject, InternalCDORevision> getCleanRevisions()
+ @Deprecated
+ public synchronized Map<InternalCDOObject, InternalCDORevision> _getCleanRevisions()
{
- return cleanRevisions;
+ throw new UnsupportedOperationException();
+
+ // new AbstractMap<InternalCDOObject, InternalCDORevision>()
+ // {
+ // @Override
+ // public Set<java.util.Map.Entry<InternalCDOObject, InternalCDORevision>> entrySet()
+ // {
+ // return new AbstractSet<java.util.Map.Entry<InternalCDOObject, InternalCDORevision>>()
+ // {
+ // @Override
+ // public Iterator<java.util.Map.Entry<InternalCDOObject, InternalCDORevision>> iterator()
+ // {
+ // return null;
+ // }
+ //
+ // @Override
+ // public int size()
+ // {
+ // return 0;
+ // }
+ // };
+ // }
+ // };
+ //
+ // return cleanRevisions;
+ }
+
+ public InternalCDORevision getCleanRevision(CDOObject object)
+ {
+ ChangeInfo changeInfo = lastSavepoint.getChangeInfos().get(object.cdoID());
+ if (changeInfo != null)
+ {
+ return changeInfo.getCleanRevision();
+ }
+
+ return null;
}
@Override
protected InternalCDORevision getViewedRevision(InternalCDOObject object)
{
- InternalCDORevision rev = super.getViewedRevision(object);
+ InternalCDORevision revision = super.getViewedRevision(object);
// Bug 336590: If we have a clean revision for this object, return that instead
- if (rev != null)
+ if (revision != null)
{
- InternalCDORevision cleanRev = cleanRevisions.get(object);
- if (cleanRev != null)
+ InternalCDORevision cleanRevision = getCleanRevision(object);
+ if (cleanRevision != null)
{
- return cleanRev;
+ return cleanRevision;
}
}
- return rev;
+ return revision;
}
@Override
@@ -2595,7 +2907,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
{
if (object.cdoState() == CDOState.TRANSIENT)
{
- InternalCDORevision revision = cleanRevisions.get(object);
+ InternalCDORevision revision = getCleanRevision(object);
if (revision == null)
{
throw new IllegalStateException("No revision for transient object " + object);
@@ -2729,8 +3041,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
*/
private final class CDOCommitContextImpl implements InternalCDOCommitContext
{
- private InternalCDOTransaction transaction;
-
/**
* Tracks whether this commit is *actually* partial or not. (Having tx.committables != null does not in itself mean
* that the commit will be partial, because the committables could cover all dirty/new/detached objects. But this
@@ -2752,104 +3062,87 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
private Map<ByteArrayWrapper, CDOLob<?>> lobs = new HashMap<ByteArrayWrapper, CDOLob<?>>();
- public CDOCommitContextImpl(InternalCDOTransaction transaction)
+ public CDOCommitContextImpl()
{
- this.transaction = transaction;
calculateCommitData();
}
private void calculateCommitData()
{
- List<CDOPackageUnit> newPackageUnits = analyzeNewPackages();
+ newObjects = CDOIDUtil.createMap();
+ revisionDeltas = CDOIDUtil.createMap();
+ detachedObjects = CDOIDUtil.createMap();
+ dirtyObjects = CDOIDUtil.createMap();
- newObjects = filterCommittables(transaction.getNewObjects());
- List<CDOIDAndVersion> revisions = new ArrayList<CDOIDAndVersion>(newObjects.size());
- for (CDOObject newObject : newObjects.values())
- {
- revisions.add(newObject.cdoRevision());
- }
+ List<CDOPackageUnit> newPackageUnits = analyzeNewPackages();
- revisionDeltas = filterCommittables(transaction.getRevisionDeltas());
- List<CDORevisionKey> deltas = new ArrayList<CDORevisionKey>(revisionDeltas.size());
- for (CDORevisionDelta delta : revisionDeltas.values())
- {
- deltas.add(delta);
- }
+ List<CDOIDAndVersion> revisions = new ArrayList<CDOIDAndVersion>();
+ List<CDORevisionKey> deltas = new ArrayList<CDORevisionKey>();
+ List<CDOIDAndVersion> detached = new ArrayList<CDOIDAndVersion>();
- detachedObjects = filterCommittables(transaction.getDetachedObjects());
- List<CDOIDAndVersion> detached = new ArrayList<CDOIDAndVersion>(detachedObjects.size());
- for (Entry<CDOID, CDOObject> entry : detachedObjects.entrySet())
+ Collection<ChangeInfo> changeInfos = getLastSavepoint().getChangeInfos().values();
+ for (ChangeInfo changeInfo : changeInfos)
{
- CDOObject object = entry.getValue();
- InternalCDORevision cleanRevision = cleanRevisions.get(object);
- if (cleanRevision == null)
+ InternalCDOObject object = changeInfo.getObject();
+ if (committables != null)
{
- // Can happen after merged detachments
- CDORevision revision = object.cdoRevision();
- detached.add(CDOIDUtil.createIDAndVersion(revision));
- }
- else if (cleanRevision.getBranch() == getBranch())
- {
- detached.add(CDOIDUtil.createIDAndVersion(cleanRevision));
+ isPartialCommit = true;
+ if (!committables.contains(object))
+ {
+ continue;
+ }
}
- else
+
+ CDOID id = changeInfo.getID();
+ switch (changeInfo.getType())
{
- detached.add(cleanRevision);
+ case NEW:
+ InternalCDORevision revision = object.cdoRevision();
+ revisions.add(revision);
+ newObjects.put(id, object);
+ break;
+
+ case DIRTY:
+ InternalCDORevisionDelta revisionDelta = changeInfo.getRevisionDelta();
+ deltas.add(revisionDelta);
+ revisionDeltas.put(changeInfo.getID(), revisionDelta);
+ dirtyObjects.put(id, object);
+ break;
+
+ case DETACHED:
+ InternalCDORevision key = changeInfo.getCleanRevision();
+ detached.add(key);
+ if (object != null)
+ {
+ detachedObjects.put(id, object);
+ }
}
}
- dirtyObjects = filterCommittables(transaction.getDirtyObjects());
-
CDOLockState[] locksOnNewObjectsArray = getLockStates(newObjects.keySet(), false);
locksOnNewObjects = Arrays.asList(locksOnNewObjectsArray);
commitData = CDOCommitInfoUtil.createCommitData(newPackageUnits, revisions, deltas, detached);
}
- private <T> Map<CDOID, T> filterCommittables(Map<CDOID, T> map)
- {
- if (committables == null)
- {
- // No partial commit filter -- nothing to do
- return map;
- }
-
- Map<CDOID, T> newMap = CDOIDUtil.createMap();
- for (Entry<CDOID, T> entry : map.entrySet())
- {
- CDOID id = entry.getKey();
- CDOObject o = getObject(id);
- if (committables.contains(o))
- {
- newMap.put(id, entry.getValue());
- }
- else
- {
- isPartialCommit = true;
- }
- }
-
- return newMap;
- }
-
public String getUserID()
{
- return transaction.getSession().getUserID();
+ return getSession().getUserID();
}
public int getViewID()
{
- return transaction.getViewID();
+ return CDOTransactionImpl.this.getViewID();
}
public CDOBranch getBranch()
{
- return transaction.getBranch();
+ return CDOTransactionImpl.this.getBranch();
}
public InternalCDOTransaction getTransaction()
{
- return transaction;
+ return CDOTransactionImpl.this;
}
public boolean isPartialCommit()
@@ -2859,12 +3152,12 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
public boolean isAutoReleaseLocks()
{
- return transaction.options().isAutoReleaseLocksEnabled();
+ return options().isAutoReleaseLocksEnabled();
}
public String getCommitComment()
{
- return transaction.getCommitComment();
+ return CDOTransactionImpl.this.getCommitComment();
}
public CDOCommitData getCommitData()
@@ -2984,18 +3277,29 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
+ private void preCommit(Map<CDOID, CDOObject> objects, Map<ByteArrayWrapper, CDOLob<?>> lobs)
+ {
+ if (!objects.isEmpty())
+ {
+ for (CDOObject object : objects.values())
+ {
+ collectLobs((InternalCDORevision)object.cdoRevision(), lobs);
+ ((InternalCDOObject)object).cdoInternalPreCommit();
+ }
+ }
+ }
+
public void postCommit(CommitTransactionResult result)
{
try
{
InternalCDOSession session = getSession();
- long timeStamp = result.getTimeStamp();
boolean clearResourcePathCache = result.isClearResourcePathCache();
if (result.getRollbackMessage() != null)
{
- CDOCommitInfo commitInfo = new FailureCommitInfo(timeStamp, result.getPreviousTimeStamp());
- session.invalidate(commitInfo, transaction, clearResourcePathCache);
+ CDOCommitInfo commitInfo = new FailureCommitInfo(result.getTimeStamp(), result.getPreviousTimeStamp());
+ session.invalidate(commitInfo, CDOTransactionImpl.this, clearResourcePathCache);
return;
}
@@ -3012,31 +3316,22 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
((InternalCDOPackageUnit)newPackageUnit).setState(CDOPackageUnit.State.LOADED);
}
- postCommit(getNewObjects(), result);
- postCommit(getDirtyObjects(), result);
+ transitionObjects(getNewObjects(), result);
+ transitionObjects(getDirtyObjects(), result);
- for (CDORevisionDelta delta : getRevisionDeltas().values())
- {
- ((InternalCDORevisionDelta)delta).adjustReferences(result.getReferenceAdjuster());
- }
-
- for (CDOID id : getDetachedObjects().keySet())
- {
- removeObject(id);
- }
-
- CDOCommitInfo commitInfo = makeCommitInfo(timeStamp, result.getPreviousTimeStamp());
+ CDOCommitInfo commitInfo = makeCommitInfo(result);
if (!commitInfo.isEmpty())
{
- session.invalidate(commitInfo, transaction, clearResourcePathCache);
+ session.invalidate(commitInfo, CDOTransactionImpl.this, clearResourcePathCache);
}
// Bug 290032 - Sticky views
if (session.isSticky())
{
CDOBranchPoint commitBranchPoint = CDOBranchUtil.copyBranchPoint(result);
- for (CDOObject object : getNewObjects().values()) // Note: keyset() does not work because ID mappings are
- // not applied there!
+
+ // Note: keyset() does not work because ID mappings are not applied there!
+ for (CDOObject object : getNewObjects().values())
{
session.setCommittedSinceLastRefresh(object.cdoID(), commitBranchPoint);
}
@@ -3059,29 +3354,21 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
if (handler instanceof CDOTransactionHandler3)
{
CDOTransactionHandler3 handler3 = (CDOTransactionHandler3)handler;
- handler3.committedTransaction(transaction, this, commitInfo);
+ handler3.committedTransaction(CDOTransactionImpl.this, this, commitInfo);
}
else
{
- handler.committedTransaction(transaction, this);
+ handler.committedTransaction(CDOTransactionImpl.this, this);
}
}
- getChangeSubscriptionManager().committedTransaction(transaction, this);
- getAdapterManager().committedTransaction(transaction, this);
+ getChangeSubscriptionManager().committedTransaction(CDOTransactionImpl.this, this);
+ getAdapterManager().committedTransaction(CDOTransactionImpl.this, this);
- cleanUp(this);
-
- IListener[] listeners = getListeners();
- if (listeners != null)
+ IListener[] listeners = cleanUp(this, result);
+ if (listeners != null && branchChanged)
{
- if (branchChanged)
- {
- fireViewTargetChangedEvent(oldBranch.getHead(), listeners);
- }
-
- Map<CDOID, CDOID> idMappings = result.getIDMappings();
- fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.COMMITTED, idMappings), listeners);
+ fireViewTargetChangedEvent(oldBranch.getHead(), listeners);
}
CDOLockState[] newLockStates = result.getNewLockStates();
@@ -3100,27 +3387,67 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
- private CDOCommitInfo makeCommitInfo(long timeStamp, long previousTimeStamp)
+ private void transitionObjects(Map<CDOID, CDOObject> objects, CommitTransactionResult result)
{
- InternalCDOSession session = getSession();
- CDOBranch branch = getBranch();
- String userID = session.getUserID();
- String comment = getCommitComment();
-
- InternalCDOCommitInfoManager commitInfoManager = session.getCommitInfoManager();
- return commitInfoManager.createCommitInfo(branch, timeStamp, previousTimeStamp, userID, comment, commitData);
+ if (!objects.isEmpty())
+ {
+ for (CDOObject object : objects.values())
+ {
+ CDOStateMachine2.INSTANCE.commit((InternalCDOObject)object, result);
+ }
+ }
}
- private void preCommit(Map<CDOID, CDOObject> objects, Map<ByteArrayWrapper, CDOLob<?>> lobs)
+ private CDOCommitInfo makeCommitInfo(CommitTransactionResult result)
{
- if (!objects.isEmpty())
+ final CDOReferenceAdjuster defaultReferenceAdjuster = result.getReferenceAdjuster();
+ CDOReferenceAdjuster referenceAdjuster = new CDOReferenceAdjuster()
{
- for (CDOObject object : objects.values())
+ public Object adjustReference(Object idOrObject, EStructuralFeature feature, int index)
{
- collectLobs((InternalCDORevision)object.cdoRevision(), lobs);
- ((InternalCDOObject)object).cdoInternalPreCommit();
+ if (idOrObject == null || idOrObject == CDOID.NULL)
+ {
+ return idOrObject;
+ }
+
+ // Adjust remaining CDOIDs to detached objects
+ if (idOrObject instanceof CDOID)
+ {
+ ChangeInfo changeInfo = lastSavepoint.getChangeInfo((CDOID)idOrObject);
+ if (changeInfo != null && changeInfo.getType() == ChangeType.DETACHED)
+ {
+ return changeInfo.getObject();
+ }
+ }
+
+ // Return detached objects to avoid dangling reference exceptions below
+ if (idOrObject instanceof InternalCDOObject)
+ {
+ ChangeInfo changeInfo = lastSavepoint.getDetachedInfo((InternalCDOObject)idOrObject);
+ if (changeInfo != null)
+ {
+ return changeInfo.getObject();
+ }
+ }
+
+ return defaultReferenceAdjuster.adjustReference(idOrObject, feature, index);
}
+ };
+
+ for (CDORevisionDelta delta : getRevisionDeltas().values())
+ {
+ ((InternalCDORevisionDelta)delta).adjustReferences(referenceAdjuster);
}
+
+ InternalCDOSession session = getSession();
+ CDOBranch branch = getBranch();
+ String userID = session.getUserID();
+ String comment = getCommitComment();
+ long timeStamp = result.getTimeStamp();
+ long previousTimeStamp = result.getPreviousTimeStamp();
+
+ InternalCDOCommitInfoManager commitInfoManager = session.getCommitInfoManager();
+ return commitInfoManager.createCommitInfo(branch, timeStamp, previousTimeStamp, userID, comment, commitData);
}
private void collectLobs(InternalCDORevision revision, Map<ByteArrayWrapper, CDOLob<?>> lobs)
@@ -3139,17 +3466,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
}
-
- private void postCommit(Map<CDOID, CDOObject> objects, CommitTransactionResult result)
- {
- if (!objects.isEmpty())
- {
- for (CDOObject object : objects.values())
- {
- CDOStateMachine.INSTANCE.commit((InternalCDOObject)object, result);
- }
- }
- }
}
/**
@@ -3177,19 +3493,32 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
{
private static final long serialVersionUID = 1L;
- private Type type;
+ private Reason reason;
private Map<CDOID, CDOID> idMappings;
- private FinishedEvent(Type type, Map<CDOID, CDOID> idMappings)
+ private FinishedEvent(Reason type, Map<CDOID, CDOID> idMappings)
{
- this.type = type;
+ reason = type;
this.idMappings = idMappings;
}
+ @Deprecated
public Type getType()
{
- return type;
+ switch (reason)
+ {
+ case COMMITTED:
+ return Type.COMMITTED;
+
+ default:
+ return Type.ROLLED_BACK;
+ }
+ }
+
+ public Reason getReason()
+ {
+ return reason;
}
public Map<CDOID, CDOID> getIDMappings()
@@ -3200,8 +3529,13 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
@Override
public String toString()
{
- return MessageFormat.format("CDOTransactionFinishedEvent[source={0}, type={1}, idMappings={2}]", getSource(), //$NON-NLS-1$
- getType(), idMappings == null ? 0 : idMappings.size());
+ String prefix = "CDOTransactionFinishedEvent[source={0}, reason={1}";
+ if (idMappings == null)
+ {
+ return MessageFormat.format(prefix + "]", getSource(), getReason());
+ }
+
+ return MessageFormat.format(prefix + ", idMappings={2}]", getSource(), getReason(), idMappings.size());
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java
index 38658f4b00..4d55407789 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java
@@ -139,7 +139,7 @@ public class CommitIntegrityCheck
{
// Getting the deltas from the TX is not a good idea...
// We better recompute a fresh delta:
- InternalCDORevision cleanRev = transaction.getCleanRevisions().get(dirtyObject);
+ InternalCDORevision cleanRev = transaction.getCleanRevision(dirtyObject);
CheckUtil.checkNull(cleanRev, "Could not obtain clean revision for dirty object " + dirtyObject);
InternalCDOClassInfo classInfo = dirtyObject.cdoClassInfo();
@@ -275,7 +275,7 @@ public class CommitIntegrityCheck
else if (featureDelta instanceof CDOClearFeatureDelta)
{
EStructuralFeature feat = ((CDOClearFeatureDelta)featureDelta).getFeature();
- InternalCDORevision cleanRev = transaction.getCleanRevisions().get(dirtyObject);
+ InternalCDORevision cleanRev = transaction.getCleanRevision(dirtyObject);
int n = cleanRev.size(feat);
for (int i = 0; i < n; i++)
{
@@ -287,7 +287,7 @@ public class CommitIntegrityCheck
else if (featureDelta instanceof CDOUnsetFeatureDelta)
{
EStructuralFeature feat = ((CDOUnsetFeatureDelta)featureDelta).getFeature();
- InternalCDORevision cleanRev = transaction.getCleanRevisions().get(dirtyObject);
+ InternalCDORevision cleanRev = transaction.getCleanRevision(dirtyObject);
Object idOrObject = cleanRev.getValue(feat);
CDOID id = (CDOID)transaction.convertObjectToID(idOrObject);
checkIncluded(id, "removed child / refTarget of", dirtyObject);
@@ -436,7 +436,7 @@ public class CommitIntegrityCheck
// that we can find the pre-detach revision in tx.getFormerRevisions(). However,
// the object may have already been dirty prior to detachment, so we check the
// clean revisions first.
- InternalCDORevision cleanRev = transaction.getCleanRevisions().get(referencer);
+ InternalCDORevision cleanRev = transaction.getCleanRevision(referencer);
CheckUtil.checkState(cleanRev, "cleanRev");
InternalCDOClassInfo referencerClassInfo = ((InternalCDOObject)referencer).cdoClassInfo();
@@ -491,7 +491,7 @@ public class CommitIntegrityCheck
private void checkFormerContainerIncluded(CDOObject detachedObject) throws CommitIntegrityException
{
- InternalCDORevision rev = transaction.getCleanRevisions().get(detachedObject);
+ InternalCDORevision rev = transaction.getCleanRevision(detachedObject);
CheckUtil.checkNull(rev, "Could not obtain clean revision for detached object " + detachedObject);
CDOID id = getContainerOrResourceID(rev);
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 4c114278ad..ad90c58834 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
@@ -37,6 +37,7 @@ import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
import org.eclipse.emf.cdo.common.util.CDOException;
+import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException;
import org.eclipse.emf.cdo.eresource.CDOBinaryResource;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.CDOResourceFolder;
@@ -66,6 +67,7 @@ import org.eclipse.emf.cdo.view.CDOViewTargetChangedEvent;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.messages.Messages;
import org.eclipse.emf.internal.cdo.object.CDOLegacyAdapter;
+import org.eclipse.emf.internal.cdo.object.CDONotificationBuilder;
import org.eclipse.emf.internal.cdo.query.CDOQueryImpl;
import org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl;
@@ -90,6 +92,7 @@ import org.eclipse.net4j.util.ref.ReferenceValueMap2;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
@@ -111,7 +114,6 @@ import org.eclipse.core.runtime.Platform;
import java.text.MessageFormat;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -1131,10 +1133,35 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
}
cleanObject(object, revision);
- CDOStateMachine.INSTANCE.dispatchLoadNotification(object);
+ dispatchLoadNotification(object);
return object;
}
+ public void dispatchLoadNotification(InternalCDOObject object)
+ {
+ if (options().isLoadNotificationEnabled())
+ {
+ try
+ {
+ InternalCDORevision revision = object.cdoRevision();
+ CDONotificationBuilder builder = new CDONotificationBuilder(this);
+
+ NotificationChain notification = builder.buildNotification(object, revision);
+ if (notification != null)
+ {
+ notification.dispatch();
+ }
+ }
+ catch (PartialCollectionLoadingNotSupportedException ex)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(ex);
+ }
+ }
+ }
+ }
+
private CDOResource newResourceInstance(InternalCDORevision revision)
{
String path = getResourcePath(revision);
@@ -1510,7 +1537,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
Pair<CDORevision, CDORevisionDelta> oldInfo = Pair.create(changedObject.cdoRevision(), delta);
// if (!isLocked(changedObject))
{
- CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)changedObject, key);
+ CDOStateMachine2.INSTANCE.invalidate((InternalCDOObject)changedObject, key);
}
revisionDeltas.put(changedObject, delta);
@@ -1535,7 +1562,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
CDORevisionDelta.DETACHED);
// if (!isLocked(detachedObject))
{
- CDOStateMachine.INSTANCE.detachRemote(detachedObject);
+ CDOStateMachine2.INSTANCE.detachRemote(detachedObject);
}
detachedObjects.add(detachedObject);
@@ -1590,30 +1617,31 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
@Deprecated
public synchronized int reload(CDOObject... objects)
{
- Collection<InternalCDOObject> internalObjects;
- if (objects != null && objects.length != 0)
- {
- internalObjects = new ArrayList<InternalCDOObject>(objects.length);
- for (CDOObject object : objects)
- {
- if (object instanceof InternalCDOObject)
- {
- internalObjects.add((InternalCDOObject)object);
- }
- }
- }
- else
- {
- internalObjects = new ArrayList<InternalCDOObject>(this.objects.values());
- }
-
- int result = internalObjects.size();
- if (result != 0)
- {
- CDOStateMachine.INSTANCE.reload(internalObjects.toArray(new InternalCDOObject[result]));
- }
-
- return result;
+ // Collection<InternalCDOObject> internalObjects;
+ // if (objects != null && objects.length != 0)
+ // {
+ // internalObjects = new ArrayList<InternalCDOObject>(objects.length);
+ // for (CDOObject object : objects)
+ // {
+ // if (object instanceof InternalCDOObject)
+ // {
+ // internalObjects.add((InternalCDOObject)object);
+ // }
+ // }
+ // }
+ // else
+ // {
+ // internalObjects = new ArrayList<InternalCDOObject>(this.objects.values());
+ // }
+ //
+ // int result = internalObjects.size();
+ // if (result != 0)
+ // {
+ // CDOStateMachine2.INSTANCE.reload(internalObjects.toArray(new InternalCDOObject[result]));
+ // }
+ //
+ // return result;
+ return 0;
}
public void close()
@@ -1733,7 +1761,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
protected InternalCDORevision getViewedRevision(InternalCDOObject object)
{
- return CDOStateMachine.INSTANCE.readNoLoad(object);
+ return CDOStateMachine2.INSTANCE.readNoLoad(object);
}
public synchronized CDOChangeSetData compareRevisions(CDOBranchPoint source)
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 22d87db5e2..8fc8e81ba9 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
@@ -101,17 +101,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.TRANSIENT, CDOEvent.COMMIT, FAIL);
init(CDOState.TRANSIENT, CDOEvent.ROLLBACK, FAIL);
- init(CDOState.PREPARED, CDOEvent.PREPARE, FAIL);
- init(CDOState.PREPARED, CDOEvent.ATTACH, new AttachTransition());
- init(CDOState.PREPARED, CDOEvent.DETACH, FAIL);
- init(CDOState.PREPARED, CDOEvent.REATTACH, FAIL);
- init(CDOState.PREPARED, CDOEvent.READ, IGNORE);
- init(CDOState.PREPARED, CDOEvent.WRITE, FAIL);
- init(CDOState.PREPARED, CDOEvent.INVALIDATE, FAIL);
- init(CDOState.PREPARED, CDOEvent.DETACH_REMOTE, FAIL);
- init(CDOState.PREPARED, CDOEvent.COMMIT, FAIL);
- init(CDOState.PREPARED, CDOEvent.ROLLBACK, FAIL);
-
init(CDOState.NEW, CDOEvent.PREPARE, FAIL);
init(CDOState.NEW, CDOEvent.ATTACH, FAIL);
init(CDOState.NEW, CDOEvent.DETACH, new DetachTransition());
@@ -191,11 +180,11 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * The object is already attached in EMF world. It contains all the information needed to know where it will be
- * connected.
- *
- * @since 2.0
- */
+ * The object is already attached in EMF world. It contains all the information needed to know where it will be
+ * connected.
+ *
+ * @since 2.0
+ */
public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
{
synchronized (transaction)
@@ -211,24 +200,9 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- private void attachOrReattach(InternalCDOObject object, InternalCDOTransaction transaction)
- {
- // Bug 283985 (Re-attachment):
- // If the object going through a prepareTransition is present in cleanRevisions,
- // then it was detached earlier, and so we can infer that it is being re-attached
- if (transaction.getCleanRevisions().containsKey(object))
- {
- reattachObject(object, transaction);
- }
- else
- {
- attachObject(object);
- }
- }
-
/**
- * Phase 1: TRANSIENT --> PREPARED
- */
+ * Phase 1: TRANSIENT --> PREPARED
+ */
private void prepare(InternalCDOObject object,
Pair<InternalCDOTransaction, List<InternalCDOObject>> transactionAndContents)
{
@@ -240,32 +214,34 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
process(object, CDOEvent.PREPARE, transactionAndContents);
}
- /**
- * Phase 2: PREPARED --> NEW
- */
- private void attachObject(InternalCDOObject object)
+ private void attachOrReattach(InternalCDOObject object, InternalCDOTransaction transaction)
{
- if (TRACER.isEnabled())
+ // Bug 283985 (Re-attachment):
+ // If the object going through a prepareTransition is present in cleanRevisions,
+ // then it was detached earlier, and so we can infer that it is being re-attached
+ if (transaction.getCleanRevision(object) != null)
{
- TRACER.format("ATTACH: {0}", object); //$NON-NLS-1$
- }
-
- process(object, CDOEvent.ATTACH, null);
- }
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("REATTACH: {0}", object);
+ }
- private void reattachObject(InternalCDOObject object, InternalCDOTransaction transaction)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("REATTACH: {0}", object);
+ process(object, CDOEvent.REATTACH, transaction);
}
+ else
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("ATTACH: {0}", object); //$NON-NLS-1$
+ }
- process(object, CDOEvent.REATTACH, transaction);
+ process(object, CDOEvent.ATTACH, null);
+ }
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public void detach(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -303,8 +279,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public InternalCDORevision read(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -321,8 +297,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public InternalCDORevision readNoLoad(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -344,16 +320,16 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public void write(InternalCDOObject object)
{
write(object, null);
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public void write(InternalCDOObject object, CDOFeatureDelta featureDelta)
{
synchronized (getMonitor(object))
@@ -373,8 +349,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public void reload(InternalCDOObject... objects)
{
if (objects == null || objects.length == 0)
@@ -398,8 +374,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @since 3.0
- */
+ * @since 3.0
+ */
public void invalidate(InternalCDOObject object, CDORevisionKey key)
{
synchronized (getMonitor(object))
@@ -414,8 +390,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public void detachRemote(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -430,8 +406,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public void commit(InternalCDOObject object, CommitTransactionResult result)
{
synchronized (getMonitor(object))
@@ -446,8 +422,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @since 2.0
- */
+ * @since 2.0
+ */
public void rollback(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -486,8 +462,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * Removes clutter from the trace log
- */
+ * Removes clutter from the trace log
+ */
private void trace(InternalCDOObject object, CDOEvent event)
{
CDOState state = object.cdoState();
@@ -509,7 +485,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
public void internalReattach(InternalCDOObject object, InternalCDOTransaction transaction)
{
InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
- InternalCDORevision cleanRevision = transaction.getCleanRevisions().get(object).copy();
+ InternalCDORevision cleanRevision = transaction.getCleanRevision(object).copy();
CDOID id = cleanRevision.getID();
// Bug 373096: Determine clean revision of the CURRENT/LAST savepoint
@@ -546,8 +522,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
else
{
- transaction.registerRevisionDelta(revisionDelta);
- transaction.registerDirty(object, (CDOFeatureDelta)null);
+ // transaction.registerRevisionDelta(revisionDelta);
+ // transaction.registerDirty(object, (CDOFeatureDelta)null);
changeState(object, CDOState.DIRTY);
}
@@ -583,20 +559,20 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * Prepares a tree of transient objects to be subsequently {@link AttachTransition attached} to a CDOView.
- * <p>
- * Execution is recursive and includes:
- * <ol>
- * <li>Assignment of a new {@link CDOIDTemp}
- * <li>Assignment of a new {@link CDORevision}
- * <li>Bidirectional association with the {@link CDOView}
- * <li>Registration with the {@link CDOTransaction}
- * <li>Changing state to {@link CDOState#PREPARED PREPARED}
- * </ol>
- *
- * @see AttachTransition
- * @author Eike Stepper
- */
+ * Prepares a tree of transient objects to be subsequently {@link AttachTransition attached} to a CDOView.
+ * <p>
+ * Execution is recursive and includes:
+ * <ol>
+ * <li>Assignment of a new {@link CDOIDTemp}
+ * <li>Assignment of a new {@link CDORevision}
+ * <li>Bidirectional association with the {@link CDOView}
+ * <li>Registration with the {@link CDOTransaction}
+ * <li>Changing state to {@link CDOState#PREPARED PREPARED}
+ * </ol>
+ *
+ * @see AttachTransition
+ * @author Eike Stepper
+ */
private final class PrepareTransition implements
ITransition<CDOState, CDOEvent, InternalCDOObject, Pair<InternalCDOTransaction, List<InternalCDOObject>>>
{
@@ -608,10 +584,12 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
// If the object going through a prepareTransition is present in cleanRevisions,
// then it was detached earlier, and so we can infer that it is being re-attached
- boolean reattaching = transaction.getCleanRevisions().containsKey(object);
+ boolean reattaching = transaction.getCleanRevision(object) != null;
if (!reattaching)
{
+ // TRANSIENT
+
// Prepare object
CDOID id = transaction.createIDForNewObject(object.cdoInternalInstance());
object.cdoInternalSetView(transaction);
@@ -633,7 +611,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
transaction.registerObject(object);
}
- transaction.registerAttached(object, !reattaching);
+ // transaction.registerAttached(object, !reattaching);
// Prepare content tree
for (Iterator<InternalEObject> it = getPersistentContents(object); it.hasNext();)
@@ -680,23 +658,23 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * Attaches a tree of {@link PrepareTransition prepared} objects to a CDOView.
- * <p>
- * Execution is recursive and includes:
- * <ol>
- * <li>Calling {@link InternalCDOObject#cdoInternalPostAttach()},<br>
- * which includes for {@link CDOObjectImpl}:
- * <ol>
- * <li>Population of the CDORevision with the current values in
- * {@link EStoreEObjectImpl#eSetting(org.eclipse.emf.ecore.EStructuralFeature) eSettings}
- * <li>Unsetting {@link EStoreEObjectImpl#eSetting(org.eclipse.emf.ecore.EStructuralFeature) eSettings}
- * </ol>
- * <li>Changing state to {@link CDOState#NEW NEW}
- * </ol>
- *
- * @see PrepareTransition
- * @author Eike Stepper
- */
+ * Attaches a tree of {@link PrepareTransition prepared} objects to a CDOView.
+ * <p>
+ * Execution is recursive and includes:
+ * <ol>
+ * <li>Calling {@link InternalCDOObject#cdoInternalPostAttach()},<br>
+ * which includes for {@link CDOObjectImpl}:
+ * <ol>
+ * <li>Population of the CDORevision with the current values in
+ * {@link EStoreEObjectImpl#eSetting(org.eclipse.emf.ecore.EStructuralFeature) eSettings}
+ * <li>Unsetting {@link EStoreEObjectImpl#eSetting(org.eclipse.emf.ecore.EStructuralFeature) eSettings}
+ * </ol>
+ * <li>Changing state to {@link CDOState#NEW NEW}
+ * </ol>
+ *
+ * @see PrepareTransition
+ * @author Eike Stepper
+ */
private final class AttachTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
@@ -707,10 +685,10 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * Bug 283985 (Re-attachment)
- *
- * @author Caspar De Groot
- */
+ * Bug 283985 (Re-attachment)
+ *
+ * @author Caspar De Groot
+ */
private final class ReattachTransition implements
ITransition<CDOState, CDOEvent, InternalCDOObject, InternalCDOTransaction>
{
@@ -806,8 +784,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Eike Stepper
- */
+ * @author Eike Stepper
+ */
private static final class DetachTransition implements
ITransition<CDOState, CDOEvent, InternalCDOObject, List<InternalCDOObject>>
{
@@ -836,8 +814,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Eike Stepper
- */
+ * @author Eike Stepper
+ */
final private class CommitTransition implements
ITransition<CDOState, CDOEvent, InternalCDOObject, CommitTransactionResult>
{
@@ -873,8 +851,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Eike Stepper
- */
+ * @author Eike Stepper
+ */
private final class RollbackTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
@@ -896,8 +874,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Eike Stepper
- */
+ * @author Eike Stepper
+ */
private final class WriteTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object featureDelta)
@@ -909,20 +887,20 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
throw new NoPermissionException(cleanRevision);
}
- transaction.getCleanRevisions().put(object, cleanRevision);
+ // transaction.getCleanRevisions().put(object, cleanRevision);
// Copy revision
InternalCDORevision revision = object.cdoRevision().copy();
object.cdoInternalSetRevision(revision);
- transaction.registerDirty(object, (CDOFeatureDelta)featureDelta);
+ // transaction.registerDirty(object, (CDOFeatureDelta)featureDelta);
changeState(object, CDOState.DIRTY);
}
}
/**
- * @author Simon McDuff
- */
+ * @author Simon McDuff
+ */
private static final class WriteNewTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object featureDelta)
@@ -934,13 +912,13 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
InternalCDOTransaction transaction = object.cdoView().toTransaction();
- transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta);
+ // transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta);
}
}
/**
- * @author Simon McDuff
- */
+ * @author Simon McDuff
+ */
private static final class RewriteTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object featureDelta)
@@ -952,20 +930,20 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
InternalCDOTransaction transaction = object.cdoView().toTransaction();
- transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta);
+ // transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta);
}
}
/**
- * @author Simon McDuff
- */
+ * @author Simon McDuff
+ */
private static class DetachRemoteTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
static final DetachRemoteTransition INSTANCE = new DetachRemoteTransition();
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
{
- CDOStateMachine.INSTANCE.changeState(object, CDOState.INVALID);
+ // INSTANCE.changeState(object, CDOState.INVALID);
InternalCDOView view = object.cdoView();
view.deregisterObject(object);
@@ -974,8 +952,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Eike Stepper
- */
+ * @author Eike Stepper
+ */
private class InvalidateTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, CDORevisionKey>
{
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, CDORevisionKey key)
@@ -1054,9 +1032,9 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Eike Stepper
- * @since 2.0
- */
+ * @author Eike Stepper
+ * @since 2.0
+ */
private class ConflictTransition extends InvalidateTransition
{
@Override
@@ -1073,8 +1051,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Simon McDuff
- */
+ * @author Simon McDuff
+ */
private final class InvalidConflictTransition extends ConflictTransition
{
@Override
@@ -1088,8 +1066,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Eike Stepper
- */
+ * @author Eike Stepper
+ */
private final class LoadTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
private boolean forWrite;
@@ -1130,8 +1108,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Simon McDuff
- */
+ * @author Simon McDuff
+ */
private static final class InvalidTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
public static final InvalidTransition INSTANCE = new InvalidTransition();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine2.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine2.java
new file mode 100644
index 0000000000..a9a700a4e0
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine2.java
@@ -0,0 +1,1455 @@
+/*
+ * Copyright (c) 2011-2013 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
+ * Simon McDuff - maintenance
+ */
+package org.eclipse.emf.internal.cdo.view;
+
+import org.eclipse.emf.cdo.CDOState;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevisable;
+import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOOriginSizeProvider;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.security.NoPermissionException;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.view.CDOInvalidationPolicy;
+
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Attached.Clean;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Attached.Conflict;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Attached.Dirty;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Attached.New;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Attached.Proxy;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Attached.Undone;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Unattached.Detached;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Unattached.Transient;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Unusable.Invalid;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2.Unusable.Invalid_Conflict;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EContentsEList;
+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.InternalCDOSavepoint.ChangeInfo;
+import org.eclipse.emf.spi.cdo.InternalCDOSession;
+import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
+import org.eclipse.emf.spi.cdo.InternalCDOView;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public final class CDOStateMachine2
+{
+ public static final CDOStateMachine2 INSTANCE = new CDOStateMachine2();
+
+ private static final State TRANSIENT = new Transient();
+
+ private static final State CLEAN = new Clean();
+
+ private static final State PROXY = new Proxy();
+
+ private static final State CONFLICT = new Conflict();
+
+ private static final State INVALID = new Invalid();
+
+ private static final State INVALID_CONFLICT = new Invalid_Conflict();
+
+ static final ThreadLocal<Boolean> SWITCHING_TARGET = new InheritableThreadLocal<Boolean>();
+
+ private CDOStateMachine2()
+ {
+ }
+
+ public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ synchronized (transaction)
+ {
+ State state = getState(object, transaction, false);
+ traceEvent("Attach", object, state);
+ state.attach(object, transaction);
+ }
+ }
+
+ public void detach(InternalCDOObject object)
+ {
+ synchronized (getMonitor(object))
+ {
+ // Accumulate objects that need to be detached.
+ // In case of errors, we will keep the graph exactly like it was before.
+ List<Runnable> runnables = new ArrayList<Runnable>();
+ detach(object, runnables);
+
+ for (Runnable runnable : runnables)
+ {
+ runnable.run();
+ }
+ }
+ }
+
+ private void detach(InternalCDOObject object, List<Runnable> runnables)
+ {
+ State state = getState(object, null, false);
+ traceEvent("Detach", object, state);
+ state.detach(object, runnables);
+ }
+
+ public InternalCDORevision read(InternalCDOObject object)
+ {
+ synchronized (getMonitor(object))
+ {
+ State state = getState(object, null, false);
+ traceEvent("Read", object, state);
+ return state.read(object);
+ }
+ }
+
+ public InternalCDORevision readNoLoad(InternalCDOObject object)
+ {
+ synchronized (getMonitor(object))
+ {
+ switch (object.cdoState())
+ {
+ case TRANSIENT:
+ case NEW:
+ case CONFLICT:
+ case INVALID_CONFLICT:
+ case INVALID:
+ case PROXY:
+ return null;
+ }
+
+ return object.cdoRevision();
+ }
+ }
+
+ public InternalCDORevision write(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ synchronized (getMonitor(object))
+ {
+ return writeWithoutViewLock(object, featureDelta);
+ }
+ }
+
+ private InternalCDORevision writeWithoutViewLock(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ State state = getState(object, null, false);
+ traceEvent("Write", object, state);
+ return state.write(object, featureDelta);
+ }
+
+ public void commit(InternalCDOObject object, CommitTransactionResult result)
+ {
+ synchronized (getMonitor(object))
+ {
+ State state = getState(object, null, false);
+ traceEvent("Commit", object, state);
+ state.commit(object, result);
+ }
+ }
+
+ public void rollback(InternalCDOObject object)
+ {
+ synchronized (getMonitor(object))
+ {
+ State state = getState(object, null, true);
+ traceEvent("Rollback", object, state);
+ state.rollback(object);
+ }
+ }
+
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ synchronized (getMonitor(object))
+ {
+ State state = getState(object, null, false);
+ traceEvent("Invalidate", object, state);
+ state.invalidate(object, key);
+ }
+ }
+
+ public void detachRemote(InternalCDOObject object)
+ {
+ synchronized (getMonitor(object))
+ {
+ State state = getState(object, null, false);
+ traceEvent("DetachRemote", object, state);
+ state.detachRemote(object);
+ }
+ }
+
+ private void transition(InternalCDOObject object, State state)
+ {
+ trace(" Transition " + getLabel(object) + " to " + state);
+ object.cdoInternalSetState(state.getCDOState());
+ }
+
+ private Object getMonitor(InternalCDOObject object)
+ {
+ InternalCDOView view = object.cdoView();
+ if (view != null)
+ {
+ return view;
+ }
+
+ // In TRANSIENT and PREPARED the object is not yet attached to a view
+ return object;
+ }
+
+ private State getState(InternalCDOObject object, InternalCDOTransaction transaction, boolean remove)
+ {
+ CDOState cdoState = object.cdoState();
+ switch (cdoState)
+ {
+ case TRANSIENT:
+ return getUnattachedState(object, transaction);
+
+ case NEW:
+ case DIRTY:
+ case PREPARED:
+ return getAttachedState(object, remove);
+
+ case CLEAN:
+ return CLEAN;
+
+ case PROXY:
+ return PROXY;
+
+ case CONFLICT:
+ return CONFLICT;
+
+ case INVALID:
+ return INVALID;
+
+ case INVALID_CONFLICT:
+ return INVALID_CONFLICT;
+
+ default:
+ throw new IllegalStateException("Illegal state: " + cdoState);
+ }
+ }
+
+ private State getUnattachedState(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ if (transaction != null)
+ {
+ ChangeInfo detachedInfo = transaction.getLastSavepoint().getDetachedInfo(object);
+ if (detachedInfo != null)
+ {
+ return (State)detachedInfo;
+ }
+ }
+
+ return TRANSIENT;
+ }
+
+ private State getAttachedState(InternalCDOObject object, boolean remove)
+ {
+ InternalCDOSavepoint savepoint = object.cdoView().toTransaction().getLastSavepoint();
+ CDOID id = object.cdoID();
+
+ if (remove)
+ {
+ return (State)savepoint.removeChangeInfo(id);
+ }
+
+ return (State)savepoint.getChangeInfo(id);
+ }
+
+ private static String getLabel(InternalCDOObject object)
+ {
+ String label = object.toString();
+
+ int pos = label.indexOf('[');
+ if (pos != -1)
+ {
+ label = label.substring(0, pos);
+ }
+
+ return label;
+ }
+
+ private static void traceEvent(String event, InternalCDOObject object, State state)
+ {
+ int xxx;
+ // trace(event + " for " + getLabel(object) + " in " + state);
+ }
+
+ private static void trace(String message)
+ {
+ int xxx;
+ // System.out.println(message);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class State
+ {
+ public static final String FAIL_PREFIX = "Impossible to handle ";
+
+ public abstract CDOState getCDOState();
+
+ public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ throw fail(object, "Attach");
+ }
+
+ public void detach(InternalCDOObject object, List<Runnable> runnables)
+ {
+ throw fail(object, "Detach");
+ }
+
+ public InternalCDORevision read(InternalCDOObject object)
+ {
+ throw fail(object, "Read");
+ }
+
+ public InternalCDORevision write(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ throw fail(object, "Write");
+ }
+
+ public void commit(InternalCDOObject object, CommitTransactionResult result)
+ {
+ throw fail(object, "Commit");
+ }
+
+ public void rollback(InternalCDOObject object)
+ {
+ throw fail(object, "Rollback");
+ }
+
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ throw fail(object, "Invalidate");
+ }
+
+ public void detachRemote(InternalCDOObject object)
+ {
+ throw fail(object, "DetachRemote");
+ }
+
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName().toUpperCase();
+ }
+
+ protected void doRemoteDetach(InternalCDOObject object)
+ {
+ INSTANCE.transition(object, INVALID);
+
+ InternalCDOView view = object.cdoView();
+ view.deregisterObject(object);
+ object.cdoInternalPostDetach(true);
+ }
+
+ protected final void ignore()
+ {
+ // trace(" IGNORE");
+ }
+
+ private IllegalStateException fail(InternalCDOObject object, String event)
+ {
+ String message = FAIL_PREFIX + event + " for " + getLabel(object) + " in " + this;
+ return new IllegalStateException(message);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class Unattached extends State
+ {
+ @Override
+ public final CDOState getCDOState()
+ {
+ return CDOState.TRANSIENT;
+ }
+
+ @Override
+ public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ // Prepare content tree
+ for (Iterator<InternalEObject> it = getPersistentContents(object); it.hasNext();)
+ {
+ InternalEObject content = it.next();
+ Resource.Internal directResource = content.eDirectResource();
+
+ boolean objectIsResource = directResource == object;
+ if (objectIsResource || directResource == null)
+ {
+ InternalCDOObject adapted = FSMUtil.adapt(content, transaction);
+ INSTANCE.attach(adapted, transaction);
+ }
+ }
+ }
+
+ @Override
+ public void detach(InternalCDOObject object, List<Runnable> runnables)
+ {
+ ignore();
+ }
+
+ @Override
+ public final InternalCDORevision read(InternalCDOObject object)
+ {
+ // Can happen during detach
+ return object.cdoRevision();
+ }
+
+ @Override
+ public final InternalCDORevision write(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ // Can happen during detach
+ return object.cdoRevision();
+ }
+
+ @Override
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ ignore();
+ }
+
+ @Override
+ public void detachRemote(InternalCDOObject object)
+ {
+ ignore();
+ }
+
+ protected void registerNewPackage(EClass eClass, InternalCDOSession session)
+ {
+ checkPackageRegistrationProblems(session, eClass);
+
+ EPackage ePackage = eClass.getEPackage();
+ CDOPackageRegistry packageRegistry = session.getPackageRegistry();
+ if (!packageRegistry.containsKey(ePackage.getNsURI()))
+ {
+ packageRegistry.putEPackage(ePackage);
+ }
+ }
+
+ private void checkPackageRegistrationProblems(InternalCDOSession session, EClass eClass)
+ {
+ if (session.options().isGeneratedPackageEmulationEnabled())
+ {
+ // Check that there are no multiple EPackages with the same URI in system. Bug 335004
+ String packageURI = eClass.getEPackage().getNsURI();
+ Object packageObject = session.getPackageRegistry().get(packageURI);
+ if (packageObject instanceof InternalCDOPackageInfo)
+ {
+ packageObject = ((InternalCDOPackageInfo)packageObject).getEPackage(false);
+ }
+
+ if (packageObject instanceof EPackage && packageObject != eClass.getEPackage())
+ {
+ throw new IllegalStateException(MessageFormat.format(
+ "Global EPackage {0} for EClass {1} is different from EPackage found in CDOPackageRegistry", packageURI,
+ eClass));
+ }
+ }
+ }
+
+ private Iterator<InternalEObject> getPersistentContents(InternalCDOObject object)
+ {
+ EStructuralFeature[] features = object.cdoClassInfo().getAllPersistentContainments();
+ return new EContentsEList.ResolvingFeatureIteratorImpl<InternalEObject>(object, features);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Transient extends Unattached
+ {
+ @Override
+ public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ // TODO Permission check needed?
+ transaction.handleAttachingObject(object);
+
+ EClass eClass = object.eClass();
+ CDOID id = transaction.createIDForNewObject(object.cdoInternalInstance());
+ CDOBranchPoint branchPoint = transaction.getBranch().getHead();
+
+ InternalCDOSession session = transaction.getSession();
+ registerNewPackage(eClass, session);
+
+ // Create new revision
+ CDORevisionFactory revisionFactory = session.getRevisionManager().getFactory();
+ InternalCDORevision revision = (InternalCDORevision)revisionFactory.createRevision(eClass);
+ revision.setID(id);
+ revision.setBranchPoint(branchPoint);
+
+ object.cdoInternalSetView(transaction);
+ object.cdoInternalSetRevision(revision);
+
+ transaction.registerObject(object); // Object must have ID
+ object.cdoInternalPostAttach(); // Object must have CDOState.TRANSIENT and an empty revision
+
+ New newState = new New(object, null);
+ transaction.getLastSavepoint().addChangeInfo(newState);
+ INSTANCE.transition(object, newState);
+ super.attach(object, transaction);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Detached extends Unattached implements ChangeInfo
+ {
+ private final InternalCDOObject object;
+
+ private final InternalCDORevision cleanRevision;
+
+ private final InternalCDORevision baseRevision;
+
+ public Detached(InternalCDOObject object, InternalCDORevision cleanRevision, InternalCDORevision baseRevision)
+ {
+ if (cleanRevision == null)
+ {
+ throw new IllegalArgumentException("cleanRevision is null");
+ }
+
+ this.object = object;
+ this.cleanRevision = cleanRevision;
+ this.baseRevision = baseRevision;
+ }
+
+ public ChangeType getType()
+ {
+ return ChangeType.DETACHED;
+ }
+
+ public CDOID getID()
+ {
+ return cleanRevision.getID();
+ }
+
+ public int getVersion()
+ {
+ return cleanRevision.getVersion();
+ }
+
+ public InternalCDOObject getObject()
+ {
+ return object;
+ }
+
+ public InternalCDORevision getCleanRevision()
+ {
+ return cleanRevision;
+ }
+
+ public InternalCDORevision getBaseRevision()
+ {
+ return baseRevision;
+ }
+
+ public InternalCDORevisionDelta getRevisionDelta()
+ {
+ return null;
+ }
+
+ public ChangeInfo setSavepoint()
+ {
+ InternalCDORevision newBaseRevision = null; // TODO Compute from instance
+ return new Detached(object, cleanRevision, newBaseRevision);
+ }
+
+ @Override
+ public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ // TODO Permission check needed?
+ transaction.handleAttachingObject(object);
+
+ CDOID id = getID();
+ EClass eClass = object.eClass();
+ CDOBranchPoint branchPoint = transaction.getBranch().getHead();
+
+ InternalCDOSession session = transaction.getSession();
+ registerNewPackage(eClass, session);
+
+ InternalCDORevision cleanRevision = getCleanRevision();
+
+ // Create new revision
+ CDORevisionFactory revisionFactory = session.getRevisionManager().getFactory();
+ InternalCDORevision revision = (InternalCDORevision)revisionFactory.createRevision(eClass);
+ revision.setID(id);
+ revision.setVersion(cleanRevision.getVersion());
+ revision.setBranchPoint(branchPoint);
+
+ object.cdoInternalSetView(transaction);
+ object.cdoInternalSetRevision(revision);
+
+ transaction.registerObject(object); // Object must have ID
+ object.cdoInternalPostAttach(); // Object must have CDOState.TRANSIENT and an empty revision
+
+ InternalCDOSavepoint savepoint = transaction.getLastSavepoint();
+ savepoint.removeChangeInfo(id);
+
+ State newState;
+ InternalCDORevisionDelta revisionDelta = revision.compare(cleanRevision);
+ if (revisionDelta.isEmpty())
+ {
+ if (savepoint.getPreviousSavepoint() != null)
+ {
+ newState = new Undone(object, cleanRevision, baseRevision);
+ savepoint.addChangeInfo((ChangeInfo)newState);
+ }
+ else
+ {
+ newState = CLEAN;
+ savepoint.removeChangeInfo(id);
+ }
+ }
+ else
+ {
+ newState = new Dirty(object, cleanRevision, baseRevision, revisionDelta);
+ savepoint.addChangeInfo((ChangeInfo)newState);
+ }
+
+ INSTANCE.transition(object, newState);
+ transaction.updateDirtyState(true);
+ super.attach(object, transaction);
+ }
+
+ @Override
+ protected void registerNewPackage(EClass eClass, InternalCDOSession session)
+ {
+ // Do nothing
+ }
+
+ @Override
+ public String toString()
+ {
+ return super.toString() + "[" + cleanRevision + "]";
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class Attached extends State
+ {
+ public InternalCDORevision getCleanRevision(InternalCDOObject object)
+ {
+ // TODO What about states that are no ChangeInfo (i.e. not New or Dirty)?
+ return null;
+ }
+
+ public InternalCDORevision getBaseRevision()
+ {
+ // TODO What about states that are no ChangeInfo (i.e. not New or Dirty)?
+ return null;
+ }
+
+ @Override
+ public final void detach(final InternalCDOObject object, List<Runnable> runnables)
+ {
+ final InternalCDOTransaction transaction = object.cdoView().toTransaction();
+ transaction.handleDetachingObject(object);
+
+ runnables.add(new Runnable()
+ {
+ public void run()
+ {
+ State newState = doDetach(object, transaction.getLastSavepoint());
+
+ transaction.deregisterObject(object);
+ object.cdoInternalSetView(null);
+ object.cdoInternalSetID(null);
+
+ INSTANCE.transition(object, newState);
+ }
+ });
+
+ boolean isResource = object instanceof Resource;
+
+ // Prepare content tree
+ for (Iterator<EObject> it = object.eContents().iterator(); it.hasNext();)
+ {
+ InternalEObject eObject = (InternalEObject)it.next();
+ boolean isDirectlyConnected = isResource && eObject.eDirectResource() == object;
+ if (isDirectlyConnected || eObject.eDirectResource() == null)
+ {
+ InternalCDOObject adapted = FSMUtil.adapt(eObject, transaction);
+ if (adapted != null)
+ {
+ INSTANCE.detach(adapted, runnables);
+ }
+ }
+ }
+ }
+
+ protected State doDetach(InternalCDOObject object, InternalCDOSavepoint savepoint)
+ {
+ revisionToInstance(object);
+
+ InternalCDORevision cleanRevision = getCleanRevision(object);
+ InternalCDORevision baseRevision = getBaseRevision();
+
+ Detached detached = new Detached(object, cleanRevision, baseRevision);
+ savepoint.addChangeInfo(detached);
+ return detached;
+ }
+
+ private void revisionToInstance(InternalCDOObject object)
+ {
+ object.cdoInternalSetState(CDOState.TRANSIENT);
+
+ try
+ {
+ object.cdoInternalPostDetach(false); // postDetach() requires the object to be TRANSIENT
+ }
+ finally
+ {
+ object.cdoInternalSetState(getCDOState());
+ }
+ }
+
+ @Override
+ public InternalCDORevision read(InternalCDOObject object)
+ {
+ // Ignore
+ return object.cdoRevision();
+ }
+
+ protected final InternalCDORevision getWritableRevision(InternalCDOObject object)
+ {
+ InternalCDORevision cleanRevision = object.cdoRevision();
+ if (!cleanRevision.isWritable())
+ {
+ throw new NoPermissionException(cleanRevision);
+ }
+
+ return cleanRevision;
+ }
+
+ protected final void doCommit(InternalCDOObject object, CommitTransactionResult result)
+ {
+ InternalCDOTransaction transaction = object.cdoView().toTransaction();
+ InternalCDORevision revision = object.cdoRevision();
+ Map<CDOID, CDOID> idMappings = result.getIDMappings();
+
+ // Adjust object
+ CDOID oldID = object.cdoID();
+ CDOID newID = idMappings.get(oldID);
+ if (newID != null)
+ {
+ revision.setID(newID);
+ transaction.remapObject(oldID);
+ }
+
+ // Adjust revision
+ revision.adjustForCommit(transaction.getBranch(), result.getTimeStamp());
+ revision.adjustReferences(result.getReferenceAdjuster());
+ // TODO Adjust possible CDOElementProxies!
+ revision.freeze();
+
+ InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
+ revisionManager.addRevision(revision);
+
+ transaction.getLastSavepoint().removeChangeInfo(oldID);
+ INSTANCE.transition(object, CLEAN);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Proxy extends Attached
+ {
+ @Override
+ public CDOState getCDOState()
+ {
+ return CDOState.PROXY;
+ }
+
+ @Override
+ public InternalCDORevision read(InternalCDOObject object)
+ {
+ load(object, false);
+ return object.cdoRevision();
+ }
+
+ @Override
+ public InternalCDORevision write(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ load(object, true);
+ return INSTANCE.writeWithoutViewLock(object, featureDelta);
+ }
+
+ @Override
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ ignore();
+ }
+
+ @Override
+ public void detachRemote(InternalCDOObject object)
+ {
+ doRemoteDetach(object);
+ }
+
+ protected final void load(InternalCDOObject object, boolean forWrite)
+ {
+ object.cdoInternalPreLoad();
+
+ InternalCDOView view = object.cdoView();
+ InternalCDORevision revision = view.getRevision(object.cdoID(), true);
+ if (revision == null)
+ {
+ INSTANCE.detachRemote(object);
+ CDOInvalidationPolicy policy = view.options().getInvalidationPolicy();
+ policy.handleInvalidObject(object);
+ }
+
+ if (forWrite && !revision.isWritable())
+ {
+ throw new NoPermissionException(revision);
+ }
+
+ object.cdoInternalSetRevision(revision);
+ INSTANCE.transition(object, CLEAN);
+ object.cdoInternalPostLoad();
+ view.dispatchLoadNotification(object);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Clean extends Attached
+ {
+ @Override
+ public CDOState getCDOState()
+ {
+ return CDOState.CLEAN;
+ }
+
+ @Override
+ public InternalCDORevision getCleanRevision(InternalCDOObject object)
+ {
+ return object.cdoRevision();
+ }
+
+ @Override
+ public InternalCDORevision write(InternalCDOObject object, final CDOFeatureDelta featureDelta)
+ {
+ final InternalCDORevision cleanRevision = getWritableRevision(object);
+
+ InternalCDOTransaction transaction = object.cdoView().toTransaction();
+ transaction.handleModifyingObject(object, featureDelta);
+
+ InternalCDORevisionDelta revisionDelta = (InternalCDORevisionDelta)CDORevisionUtil.createDelta(cleanRevision);
+ boolean mergeIsEmpty = revisionDelta.mergeFeatureDelta(featureDelta, new CDOOriginSizeProvider.Caching()
+ {
+ @Override
+ protected CDOList getList()
+ {
+ EStructuralFeature feature = featureDelta.getFeature();
+ return cleanRevision.getList(feature);
+ }
+ });
+
+ if (mergeIsEmpty)
+ {
+ return cleanRevision;
+ }
+
+ // Copy revision
+ InternalCDORevision revision = cleanRevision.copy();
+ featureDelta.apply(revision);
+ object.cdoInternalSetRevision(revision);
+
+ Dirty dirty = new Dirty(object, cleanRevision, cleanRevision, revisionDelta);
+ transaction.getLastSavepoint().addChangeInfo(dirty);
+
+ INSTANCE.transition(object, dirty);
+ transaction.updateDirtyState(false);
+
+ return revision;
+ }
+
+ @Override
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ InternalCDORevision oldRevision = object.cdoRevision();
+ InternalCDORevision newRevision = null;
+
+ InternalCDOView view = object.cdoView();
+ InternalCDORevisionCache cache = view.getSession().getRevisionManager().getCache();
+
+ if (SWITCHING_TARGET.get() == Boolean.TRUE)
+ {
+ CDORevisionDelta delta = (CDORevisionDelta)key;
+ CDORevisable target = delta.getTarget();
+ newRevision = (InternalCDORevision)cache.getRevisionByVersion(delta.getID(), target);
+ if (newRevision == null)
+ {
+ newRevision = oldRevision.copy();
+ view.getSession().resolveAllElementProxies(newRevision);
+ delta.apply(newRevision);
+ newRevision.setBranchPoint(target);
+ cache.addRevision(newRevision);
+ }
+
+ object.cdoInternalSetRevision(newRevision);
+ INSTANCE.transition(object, CLEAN);
+ object.cdoInternalPostLoad();
+ return;
+ }
+
+ if (key == null || key.getVersion() >= oldRevision.getVersion())
+ {
+ CDORevisionKey newKey = null;
+ if (key != null)
+ {
+ int newVersion = getNewVersion(key);
+ newKey = CDORevisionUtil.createRevisionKey(key.getID(), key.getBranch(), newVersion);
+ }
+
+ if (newKey != null)
+ {
+ newRevision = (InternalCDORevision)cache.getRevisionByVersion(newKey.getID(), newKey);
+ }
+
+ if (newRevision != null)
+ {
+ object.cdoInternalSetRevision(newRevision);
+ INSTANCE.transition(object, CLEAN);
+ object.cdoInternalPostLoad();
+ }
+ else
+ {
+ INSTANCE.transition(object, PROXY);
+
+ CDOInvalidationPolicy policy = view.options().getInvalidationPolicy();
+ policy.handleInvalidation(object, key);
+ object.cdoInternalPostInvalidate();
+ }
+ }
+ }
+
+ @Override
+ public void detachRemote(InternalCDOObject object)
+ {
+ doRemoteDetach(object);
+ }
+
+ private static int getNewVersion(CDORevisionKey key)
+ {
+ if (key instanceof CDORevisionDelta)
+ {
+ CDORevisionDelta delta = (CDORevisionDelta)key;
+ CDORevisable target = delta.getTarget();
+ if (target != null && key.getBranch() == target.getBranch())
+ {
+ return target.getVersion();
+ }
+ }
+
+ return key.getVersion() + 1;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Undone extends Clean implements ChangeInfo
+ {
+ private final InternalCDOObject object;
+
+ private final InternalCDORevision cleanRevision;
+
+ private final InternalCDORevision baseRevision;
+
+ public Undone(InternalCDOObject object, InternalCDORevision cleanRevision, InternalCDORevision baseRevision)
+ {
+ this.object = object;
+ this.cleanRevision = cleanRevision;
+ this.baseRevision = baseRevision;
+ }
+
+ @Override
+ public CDOState getCDOState()
+ {
+ return CDOState.PREPARED;
+ }
+
+ public ChangeType getType()
+ {
+ return ChangeType.UNDONE;
+ }
+
+ public CDOID getID()
+ {
+ return object.cdoID();
+ }
+
+ public InternalCDOObject getObject()
+ {
+ return object;
+ }
+
+ @Override
+ public InternalCDORevision getCleanRevision(InternalCDOObject object)
+ {
+ return cleanRevision;
+ }
+
+ public InternalCDORevision getCleanRevision()
+ {
+ return cleanRevision;
+ }
+
+ @Override
+ public InternalCDORevision getBaseRevision()
+ {
+ return baseRevision;
+ }
+
+ public InternalCDORevisionDelta getRevisionDelta()
+ {
+ return null;
+ }
+
+ public ChangeInfo setSavepoint()
+ {
+ InternalCDORevision newBaseRevision = object.cdoRevision().copy();
+ return new Undone(object, cleanRevision, newBaseRevision);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class New extends Attached implements ChangeInfo
+ {
+ private final InternalCDOObject object;
+
+ private final InternalCDORevision baseRevision;
+
+ public New(InternalCDOObject object, InternalCDORevision baseRevision)
+ {
+ this.object = object;
+ this.baseRevision = baseRevision;
+ }
+
+ @Override
+ public CDOState getCDOState()
+ {
+ return CDOState.NEW;
+ }
+
+ public ChangeType getType()
+ {
+ return ChangeType.NEW;
+ }
+
+ public CDOID getID()
+ {
+ return object.cdoID();
+ }
+
+ public int getVersion()
+ {
+ return CDOBranchVersion.UNSPECIFIED_VERSION;
+ }
+
+ public InternalCDOObject getObject()
+ {
+ return object;
+ }
+
+ @Override
+ public InternalCDORevision getCleanRevision(InternalCDOObject object)
+ {
+ return null;
+ }
+
+ public InternalCDORevision getCleanRevision()
+ {
+ return null;
+ }
+
+ @Override
+ public InternalCDORevision getBaseRevision()
+ {
+ return baseRevision;
+ }
+
+ public InternalCDORevisionDelta getRevisionDelta()
+ {
+ return null;
+ }
+
+ public ChangeInfo setSavepoint()
+ {
+ InternalCDORevision newBaseRevision = object.cdoRevision().copy();
+ return new New(object, newBaseRevision);
+ }
+
+ @Override
+ public InternalCDORevision write(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ InternalCDORevision revision = getWritableRevision(object); // Check write permission
+
+ InternalCDOTransaction transaction = object.cdoView().toTransaction();
+ transaction.handleModifyingObject(object, featureDelta);
+
+ featureDelta.apply(revision);
+ return revision;
+ }
+
+ @Override
+ public void commit(InternalCDOObject object, CommitTransactionResult result)
+ {
+ doCommit(object, result);
+ }
+
+ @Override
+ public String toString()
+ {
+ return super.toString() + "[" + object.cdoRevision() + "]";
+ }
+
+ @Override
+ protected State doDetach(InternalCDOObject object, InternalCDOSavepoint savepoint)
+ {
+ savepoint.removeChangeInfo(object.cdoID());
+ return TRANSIENT;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Dirty extends Attached implements ChangeInfo
+ {
+ private final InternalCDOObject object;
+
+ private final InternalCDORevision cleanRevision;
+
+ private final InternalCDORevision baseRevision;
+
+ private InternalCDORevisionDelta revisionDelta;
+
+ public Dirty(InternalCDOObject object, InternalCDORevision cleanRevision, InternalCDORevision baseRevision,
+ InternalCDORevisionDelta revisionDelta)
+ {
+ this.object = object;
+ this.cleanRevision = cleanRevision;
+ this.baseRevision = baseRevision;
+ this.revisionDelta = revisionDelta;
+ }
+
+ @Override
+ public CDOState getCDOState()
+ {
+ return CDOState.DIRTY;
+ }
+
+ public ChangeType getType()
+ {
+ return ChangeType.DIRTY;
+ }
+
+ public CDOID getID()
+ {
+ return cleanRevision.getID();
+ }
+
+ public int getVersion()
+ {
+ return cleanRevision.getVersion();
+ }
+
+ public InternalCDOObject getObject()
+ {
+ return object;
+ }
+
+ @Override
+ public InternalCDORevision getCleanRevision(InternalCDOObject object)
+ {
+ return cleanRevision;
+ }
+
+ public InternalCDORevision getCleanRevision()
+ {
+ return cleanRevision;
+ }
+
+ @Override
+ public InternalCDORevision getBaseRevision()
+ {
+ return baseRevision;
+ }
+
+ public InternalCDORevisionDelta getRevisionDelta()
+ {
+ return revisionDelta;
+ }
+
+ public ChangeInfo setSavepoint()
+ {
+ InternalCDORevision newBaseRevision = object.cdoRevision().copy();
+ return new Dirty(object, cleanRevision, newBaseRevision, revisionDelta);
+ }
+
+ @Override
+ public InternalCDORevision write(InternalCDOObject object, final CDOFeatureDelta featureDelta)
+ {
+ InternalCDORevision revision = getWritableRevision(object);
+
+ InternalCDOTransaction transaction = object.cdoView().toTransaction();
+ transaction.handleModifyingObject(object, featureDelta);
+
+ final EStructuralFeature feature = featureDelta.getFeature();
+ featureDelta.apply(revision);
+
+ if (revision.isUnchunked())
+ {
+ if (isOnlyFeatureDelta(feature))
+ {
+ if (isClean(revision, feature))
+ {
+ undo(object, transaction);
+ return cleanRevision;
+ }
+ }
+ }
+
+ boolean mergeIsEmpty = revisionDelta.mergeFeatureDelta(featureDelta, new CDOOriginSizeProvider.Caching()
+ {
+ @Override
+ protected CDOList getList()
+ {
+ return cleanRevision.getList(feature);
+ }
+ });
+
+ if (mergeIsEmpty && revisionDelta.isEmpty())
+ {
+ undo(object, transaction);
+ return cleanRevision;
+ }
+
+ return revision;
+ }
+
+ private boolean isOnlyFeatureDelta(final EStructuralFeature feature)
+ {
+ Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = revisionDelta.getFeatureDeltaMap();
+ return featureDeltas.size() == 1 && featureDeltas.containsKey(feature);
+ }
+
+ private boolean isClean(InternalCDORevision revision, EStructuralFeature feature)
+ {
+ if (feature.isMany())
+ {
+ CDOList list = revision.getList(feature);
+ CDOList cleanList = cleanRevision.getList(feature);
+
+ int size = list.size();
+ if (size != cleanList.size())
+ {
+ return false;
+ }
+
+ for (int i = size - 1; i >= 0; --i)
+ {
+ Object value = list.get(i);
+ Object cleanValue = cleanList.get(i);
+ if (!CDORevisionUtil.areValuesEqual(value, cleanValue))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ Object value = revision.getValue(feature);
+ Object cleanValue = cleanRevision.getValue(feature);
+ return CDORevisionUtil.areValuesEqual(value, cleanValue);
+ }
+
+ private void undo(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ object.cdoInternalSetRevision(cleanRevision);
+
+ State newState;
+ InternalCDOSavepoint savepoint = transaction.getLastSavepoint();
+ if (savepoint.getPreviousSavepoint() != null)
+ {
+ newState = new Undone(object, cleanRevision, baseRevision);
+ savepoint.addChangeInfo((ChangeInfo)newState);
+ }
+ else
+ {
+ newState = CLEAN;
+ savepoint.removeChangeInfo(getID());
+ }
+
+ INSTANCE.transition(object, newState);
+ transaction.updateDirtyState(true);
+ }
+
+ @Override
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ InternalCDORevision oldRevision = object.cdoRevision();
+ if (key == null || key.getVersion() >= oldRevision.getVersion() - 1)
+ {
+ INSTANCE.transition(object, CONFLICT);
+ InternalCDOTransaction transaction = object.cdoView().toTransaction();
+ transaction.setConflict(object);
+ }
+ }
+
+ @Override
+ public void commit(InternalCDOObject object, CommitTransactionResult result)
+ {
+ doCommit(object, result);
+ }
+
+ @Override
+ public void detachRemote(InternalCDOObject object)
+ {
+ INSTANCE.transition(object, INVALID_CONFLICT);
+
+ InternalCDOTransaction transaction = object.cdoView().toTransaction();
+ transaction.setConflict(object);
+ }
+
+ @Override
+ public String toString()
+ {
+ return super.toString() + "[" + getRevisionDelta() + "]";
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Conflict extends Attached
+ {
+ @Override
+ public CDOState getCDOState()
+ {
+ return CDOState.CONFLICT;
+ }
+
+ @Override
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ ignore();
+ }
+
+ @Override
+ public void detachRemote(InternalCDOObject object)
+ {
+ ignore();
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class Unusable extends State
+ {
+ @Override
+ public void detach(InternalCDOObject object, List<Runnable> runnables)
+ {
+ ignore();
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Invalid extends Unusable
+ {
+ @Override
+ public CDOState getCDOState()
+ {
+ return CDOState.INVALID;
+ }
+
+ @Override
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ ignore();
+ }
+
+ @Override
+ public void detachRemote(InternalCDOObject object)
+ {
+ ignore();
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Invalid_Conflict extends Unusable
+ {
+ @Override
+ public CDOState getCDOState()
+ {
+ return CDOState.INVALID_CONFLICT;
+ }
+
+ @Override
+ public void invalidate(InternalCDOObject object, CDORevisionKey key)
+ {
+ ignore();
+ }
+
+ @Override
+ public void rollback(InternalCDOObject object)
+ {
+ doRemoteDetach(object);
+ }
+
+ @Override
+ public void detachRemote(InternalCDOObject object)
+ {
+ ignore();
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStoreImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStoreImpl.java
index 9b9cabd551..58d64c9db3 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStoreImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStoreImpl.java
@@ -54,6 +54,7 @@ import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.spi.cdo.CDOStore;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
+import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOView;
import java.text.MessageFormat;
@@ -110,10 +111,7 @@ public final class CDOStoreImpl implements CDOStore
CDOID newResourceID = newResource == null ? CDOID.NULL : newResource.cdoID();
CDOFeatureDelta delta = new CDOContainerFeatureDeltaImpl(newResourceID, newContainerID, newContainerFeatureID);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- revision.setResourceID(newResourceID);
- revision.setContainerID(newContainerID);
- revision.setContainingFeatureID(newContainerFeatureID);
+ getRevisionForWriting(cdoObject, delta);
}
}
@@ -397,15 +395,18 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("set({0}, {1}, {2}, {3})", cdoObject, feature, index, value); //$NON-NLS-1$
}
- value = convertToCDO(cdoObject, feature, value);
-
InternalCDORevision oldRevision = getRevisionForReading(cdoObject);
Object oldValue = oldRevision.get(feature, index);
oldValue = convertToEMF(eObject, oldRevision, feature, index, oldValue);
- CDOFeatureDelta delta = new CDOSetFeatureDeltaImpl(feature, index, value, oldValue);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- revision.set(feature, index, value);
+ if (!ObjectUtil.equals(value, oldValue))
+ {
+ value = convertToCDO(cdoObject, feature, value);
+
+ CDOFeatureDelta delta = new CDOSetFeatureDeltaImpl(feature, index, value, oldValue);
+ InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
+ revision.set(feature, index, value);
+ }
return oldValue;
}
@@ -422,28 +423,7 @@ public final class CDOStoreImpl implements CDOStore
}
CDOFeatureDelta delta = new CDOUnsetFeatureDeltaImpl(feature);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
-
- if (feature.isUnsettable())
- {
- revision.unset(feature);
- }
- else
- {
- if (feature.isMany())
- {
- Object value = revision.getValue(feature);
-
- @SuppressWarnings("unchecked")
- List<Object> list = (List<Object>)value;
- list.clear();
- }
- else
- {
- Object defaultValue = convertToCDO(cdoObject, feature, feature.getDefaultValue());
- revision.set(feature, NO_INDEX, defaultValue);
- }
- }
+ getRevisionForWriting(cdoObject, delta);
}
}
@@ -457,18 +437,13 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("add({0}, {1}, {2}, {3})", cdoObject, feature, index, value); //$NON-NLS-1$
}
- if (feature.isMany())
- {
- value = convertToCDO(cdoObject, feature, value);
- }
- else
- {
- throw new UnsupportedOperationException("ADD is not supported for single-valued features");
- }
+ checkManyValued(feature);
+ value = convertToCDO(cdoObject, feature, value);
CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- revision.add(feature, index, value);
+ getRevisionForWriting(cdoObject, delta);
+ // InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
+ // revision.add(feature, index, value);
}
}
@@ -482,39 +457,47 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("remove({0}, {1}, {2})", cdoObject, feature, index); //$NON-NLS-1$
}
- Object oldValue = null;
+ Object oldValue = getListElement(cdoObject, feature, index);
+ oldValue = convertToEMF(eObject, cdoObject.cdoRevision(), feature, index, oldValue);
- // Bug 293283 / Bug 314387
- if (feature.isMany())
- {
- InternalCDORevision readLockedRevision = getRevisionForReading(cdoObject);
- CDOList list = readLockedRevision.getList(feature);
- int size = list.size();
- if (index < 0 || size <= index)
- {
- throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
- }
- }
- else
- {
- throw new UnsupportedOperationException("REMOVE is not supported for single-valued features");
- }
+ CDOFeatureDelta delta = new CDORemoveFeatureDeltaImpl(feature, index, oldValue);
+ getRevisionForWriting(cdoObject, delta);
- CDOFeatureDelta delta = new CDORemoveFeatureDeltaImpl(feature, index);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
+ // InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
+ // try
+ // {
+ // oldValue = convertToEMF(eObject, revision, feature, index, oldValue);
+ // }
+ // finally
+ // {
+ // revision.remove(feature, index);
+ // }
- oldValue = revision.get(feature, index);
+ return oldValue;
+ }
+ }
- try
- {
- oldValue = convertToEMF(eObject, revision, feature, index, oldValue);
- }
- finally
- {
- revision.remove(feature, index);
- }
+ private Object getListElement(InternalCDOObject object, EStructuralFeature feature, int index)
+ {
+ checkManyValued(feature);
- return oldValue;
+ // Bug 293283 / Bug 314387
+ InternalCDORevision readLockedRevision = getRevisionForReading(object);
+ CDOList list = readLockedRevision.getList(feature);
+ int size = list.size();
+ if (index < 0 || size <= index)
+ {
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+ }
+
+ return readLockedRevision.get(feature, index);
+ }
+
+ private void checkManyValued(EStructuralFeature feature)
+ {
+ if (!feature.isMany())
+ {
+ throw new UnsupportedOperationException("Single-valued features have no list elements");
}
}
@@ -529,9 +512,10 @@ public final class CDOStoreImpl implements CDOStore
}
CDOFeatureDelta delta = new CDOClearFeatureDeltaImpl(feature);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- // TODO Handle containment remove!!!
- revision.clear(feature);
+ getRevisionForWriting(cdoObject, delta);
+ // InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
+ // // TODO Handle containment remove!!!
+ // revision.clear(feature);
}
}
@@ -545,12 +529,14 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("move({0}, {1}, {2}, {3})", cdoObject, feature, target, source); //$NON-NLS-1$
}
- CDOFeatureDelta delta = new CDOMoveFeatureDeltaImpl(feature, target, source);
+ Object value = getListElement(cdoObject, feature, source);
+ CDOFeatureDelta delta = new CDOMoveFeatureDeltaImpl(feature, target, source, value);
+
InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- Object result = revision.move(feature, target, source);
+ // value = revision.move(feature, target, source);
- result = convertToEMF(eObject, revision, feature, target, result);
- return result;
+ value = convertToEMF(eObject, revision, feature, target, value);
+ return value;
}
}
@@ -644,11 +630,13 @@ public final class CDOStoreImpl implements CDOStore
CDOID id = (CDOID)value;
CDOList list = revision.getList(feature);
CDORevisionPrefetchingPolicy policy = view.options().getRevisionPrefetchingPolicy();
- InternalCDORevisionManager revisionManager = view.getSession().getRevisionManager();
+
+ InternalCDOSession session = view.getSession();
+ InternalCDORevisionManager revisionManager = session.getRevisionManager();
List<CDOID> listOfIDs = policy.loadAhead(revisionManager, view, eObject, feature, list, index, id);
if (!listOfIDs.isEmpty())
{
- int initialChunkSize = view.getSession().options().getCollectionLoadingPolicy().getInitialChunkSize();
+ int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize();
revisionManager.getRevisions(listOfIDs, view, initialChunkSize, CDORevision.DEPTH_NONE, true);
}
}
@@ -718,19 +706,21 @@ public final class CDOStoreImpl implements CDOStore
private static InternalCDORevision getRevisionForReading(InternalCDOObject cdoObject)
{
- CDOStateMachine.INSTANCE.read(cdoObject);
- return getRevision(cdoObject);
+ return safe(CDOStateMachine2.INSTANCE.read(cdoObject));
}
private static InternalCDORevision getRevisionForWriting(InternalCDOObject cdoObject, CDOFeatureDelta delta)
{
- CDOStateMachine.INSTANCE.write(cdoObject, delta);
- return getRevision(cdoObject);
+ return safe(CDOStateMachine2.INSTANCE.write(cdoObject, delta));
}
private static InternalCDORevision getRevision(InternalCDOObject cdoObject)
{
- InternalCDORevision revision = cdoObject.cdoRevision();
+ return safe(cdoObject.cdoRevision());
+ }
+
+ private static InternalCDORevision safe(InternalCDORevision revision)
+ {
if (revision == null)
{
throw new IllegalStateException("revision == null");
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 7d0c16ad58..4a0916c31f 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
@@ -242,13 +242,13 @@ public class CDOViewImpl extends AbstractCDOView
try
{
- CDOStateMachine.SWITCHING_TARGET.set(Boolean.TRUE);
+ CDOStateMachine2.SWITCHING_TARGET.set(Boolean.TRUE);
doInvalidate(branchPoint.getBranch(), CDOBranchPoint.UNSPECIFIED_DATE, allChangedObjects, allDetachedObjects,
oldRevisions, true);
}
finally
{
- CDOStateMachine.SWITCHING_TARGET.remove();
+ CDOStateMachine2.SWITCHING_TARGET.remove();
}
IListener[] listeners = getListeners();
@@ -504,7 +504,7 @@ public class CDOViewImpl extends AbstractCDOView
InternalCDORevision revision = (InternalCDORevision)object.cdoRevision();
if (revision == null)
{
- revision = CDOStateMachine.INSTANCE.read((InternalCDOObject)object);
+ revision = CDOStateMachine2.INSTANCE.read((InternalCDOObject)object);
}
return revision;
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 e806f97c9a..08e64b74a3 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
@@ -36,7 +36,7 @@ import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.messages.Messages;
import org.eclipse.emf.internal.cdo.object.CDOObjectMerger;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.event.IEvent;
@@ -129,12 +129,12 @@ public abstract class AbstractObjectConflictResolver extends AbstractConflictRes
@Deprecated
public static void rollbackObject(CDOObject object)
{
- CDOStateMachine.INSTANCE.rollback((InternalCDOObject)object);
+ CDOStateMachine2.INSTANCE.rollback((InternalCDOObject)object);
}
public static void readObject(CDOObject object)
{
- CDOStateMachine.INSTANCE.read((InternalCDOObject)object);
+ CDOStateMachine2.INSTANCE.read((InternalCDOObject)object);
}
/**
@@ -377,7 +377,7 @@ public abstract class AbstractObjectConflictResolver extends AbstractConflictRes
for (CDOFeatureDelta remoteFeatureDelta : remoteDelta.getFeatureDeltas())
{
// TODO Add public API for this:
- ((InternalCDORevisionDelta)localDelta).addFeatureDelta(remoteFeatureDelta, null);
+ ((InternalCDORevisionDelta)localDelta).mergeFeatureDelta(remoteFeatureDelta, null);
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java
index debb6d3035..d7ff1efc0f 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java
@@ -105,7 +105,6 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv
InternalCDOTransaction transaction = (InternalCDOTransaction)getTransaction();
InternalCDOSavepoint savepoint = transaction.getLastSavepoint();
- Map<InternalCDOObject, InternalCDORevision> cleanRevisions = transaction.getCleanRevisions();
Map<CDOID, CDOObject> dirtyObjects = savepoint.getDirtyObjects();
// final ObjectsMapUpdater newObjectsUpdater = new ObjectsMapUpdater(savepoint.getNewObjects());
final ObjectsMapUpdater detachedObjectsUpdater = new ObjectsMapUpdater(savepoint.getDetachedObjects());
@@ -125,7 +124,7 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv
int newVersion = localRevision.getVersion() + 1;
// Compute new local revision
- InternalCDORevision cleanRevision = cleanRevisions.get(object);
+ InternalCDORevision cleanRevision = transaction.getCleanRevision(object);
if (cleanRevision == null)
{
// In this case the object revision *is clean*
@@ -159,7 +158,8 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv
localDeltas.put(id, newLocalDelta);
object.cdoInternalSetState(CDOState.DIRTY);
- cleanRevisions.put(object, newCleanRevision);
+ int xxx;
+ // cleanRevisions.put(object, newCleanRevision);
dirtyObjects.put(id, object);
newLocalDelta.accept(new CDOFeatureDeltaVisitorImpl()
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/DefaultCDOMerger.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/DefaultCDOMerger.java
index 71298728de..03219df1bb 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/DefaultCDOMerger.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/DefaultCDOMerger.java
@@ -548,7 +548,7 @@ public class DefaultCDOMerger implements CDOMerger
CDOFeatureDelta featureDelta = changedInTarget(targetFeatureDelta);
if (featureDelta != null)
{
- result.addFeatureDelta(featureDelta, null);
+ result.mergeFeatureDelta(featureDelta, null);
}
}
else
@@ -556,7 +556,7 @@ public class DefaultCDOMerger implements CDOMerger
CDOFeatureDelta featureDelta = changedInSourceAndTarget(targetFeatureDelta, sourceFeatureDelta);
if (featureDelta != null)
{
- result.addFeatureDelta(featureDelta, null);
+ result.mergeFeatureDelta(featureDelta, null);
}
else
{
@@ -583,8 +583,8 @@ public class DefaultCDOMerger implements CDOMerger
}
}
- ((InternalCDORevisionDelta)conflict.getTargetDelta()).addFeatureDelta(targetFeatureDelta, null);
- ((InternalCDORevisionDelta)conflict.getSourceDelta()).addFeatureDelta(sourceFeatureDelta, null);
+ ((InternalCDORevisionDelta)conflict.getTargetDelta()).mergeFeatureDelta(targetFeatureDelta, null);
+ ((InternalCDORevisionDelta)conflict.getSourceDelta()).mergeFeatureDelta(sourceFeatureDelta, null);
}
}
}
@@ -599,7 +599,7 @@ public class DefaultCDOMerger implements CDOMerger
CDOFeatureDelta featureDelta = changedInSource(sourceFeatureDelta);
if (featureDelta != null)
{
- result.addFeatureDelta(featureDelta, null);
+ result.mergeFeatureDelta(featureDelta, null);
}
}
}
@@ -781,7 +781,7 @@ public class DefaultCDOMerger implements CDOMerger
for (int i = 0; i < originSize; i++)
{
- expandedDeltas.add(new CDORemoveFeatureDeltaImpl(feature, 0));
+ expandedDeltas.add(new CDORemoveFeatureDeltaImpl(feature, 0, CDOFeatureDelta.UNKNOWN_VALUE));
}
return expandedDeltas;
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java
index 3628e4a80b..4e875db3b1 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java
@@ -43,7 +43,7 @@ public final class FSMUtil
public static boolean isTransient(CDOObject object)
{
CDOState state = object.cdoState();
- return state == CDOState.TRANSIENT || state == CDOState.PREPARED;
+ return state == CDOState.TRANSIENT;
}
public static boolean isInvalid(CDOObject object)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java
index d025792d30..d6ef1b59e0 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOObject.java
@@ -42,9 +42,19 @@ public interface InternalCDOObject extends CDOObject, InternalEObject, InternalC
public InternalCDORevision cdoRevision();
+ /**
+ * Migrates the object values from the instance to the revision.
+ * <p>
+ * This object must be in state PREPARED, so that eStore() uses the instance and cdoStore() uses the revision.
+ */
public void cdoInternalPostAttach();
- public void cdoInternalPostDetach(boolean remote);
+ /**
+ * Migrates the object values from the revision to the instance.
+ * <p>
+ * This object must be in state TRANSIENT, so that eStore() uses the instance and cdoStore() uses the revision.
+ */
+ public void cdoInternalPostDetach(boolean remote); // TODO Rename to preDetach
public void cdoInternalPostInvalidate();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSavepoint.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSavepoint.java
index 3e1469c605..91d6b3090d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSavepoint.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSavepoint.java
@@ -10,14 +10,28 @@
*/
package org.eclipse.emf.spi.cdo;
+import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIdentifiable;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.cdo.transaction.CDOSavepoint;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine2;
+
+import java.util.Map;
import java.util.Set;
/**
- * If the meaning of this type isn't clear, there really should be more of a description here...
- *
+ * A {@link CDOSavepoint} has to capture enough data to support the following use cases:
+ * <ul>
+ * <li> <b>Detection</b> of undo operations (netted out deltas) in comparison to the transaction's baseline.
+ * <li> <b>Commit</b> of the entire {@link CDOTransaction}.
+ * <li> <b>Rollback</b> to the initial state of this savepoint.
+ * <li> <b>Support</b> of all other {@link CDOStateMachine2} transitions.
+ * </ul>
+ *
* @author Eike Stepper
* @since 3.0
* @noextend This interface is not intended to be extended by clients.
@@ -33,8 +47,33 @@ public interface InternalCDOSavepoint extends CDOSavepoint, InternalCDOUserSavep
public InternalCDOSavepoint getNextSavepoint();
+ public ChangeInfo addChangeInfo(ChangeInfo changeInfo);
+
+ public ChangeInfo removeChangeInfo(CDOObject object);
+
+ public ChangeInfo removeChangeInfo(CDOID id);
+
+ public ChangeInfo getChangeInfo(CDOID id);
+
+ public ChangeInfo getDetachedInfo(CDOObject object);
+
+ public Map<CDOID, ChangeInfo> getChangeInfos();
+
+ public Map<InternalCDOObject, ChangeInfo> getDetachedInfos();
+
+ /**
+ * @since 4.1
+ */
+ public boolean isNewObject(CDOID id);
+
+ public boolean isDetachedObject(CDOID id);
+
public void clear();
+ public boolean isInMemory();
+
+ public void setInMemory(boolean inMemory);
+
@Deprecated
public Set<CDOID> getSharedDetachedObjects();
@@ -42,7 +81,58 @@ public interface InternalCDOSavepoint extends CDOSavepoint, InternalCDOUserSavep
public void recalculateSharedDetachedObjects();
/**
- * @since 4.1
+ * Adds the given object to this savepoint and returns <code>true</code> if it was TRANSIENT,
+ * <code>false</code> otherwise (DETACHED).
+ *
+ * @deprecated As of 4.3 no longer supported.
*/
- public boolean isNewObject(CDOID id);
+ @Deprecated
+ public void attachObject(InternalCDOObject object);
+
+ /**
+ * Removes the given object from this savepoint and returns <code>true</code> if it was NEW,
+ * <code>false</code> otherwise (CLEAN | DIRTY).
+ *
+ * @deprecated As of 4.3 no longer supported.
+ */
+ @Deprecated
+ public void removeObject(InternalCDOObject object);
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface ChangeInfo extends CDOIdentifiable
+ {
+ public ChangeType getType();
+
+ /**
+ * Returns the object or <code>null</code>.
+ */
+ public InternalCDOObject getObject();
+
+ /**
+ * Returns the revision delta or <code>null</code>.
+ */
+ public InternalCDORevisionDelta getRevisionDelta();
+
+ /**
+ * Returns the clean revision or <code>null</code>. The clean revision is used to identify undoing operations.
+ */
+ public InternalCDORevision getCleanRevision();
+
+ /**
+ * Returns the base revision or <code>null</code>. The base revision is used to rollback to savepoints.
+ */
+ public InternalCDORevision getBaseRevision();
+
+ public ChangeInfo setSavepoint();
+
+ /**
+ * @author Eike Stepper
+ */
+ public enum ChangeType
+ {
+ NEW, DIRTY, CONFLICT, UNDONE, DETACHED
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java
index d8aceb5b95..5021434097 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java
@@ -11,6 +11,7 @@
*/
package org.eclipse.emf.spi.cdo;
+import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
@@ -27,6 +28,7 @@ import org.eclipse.emf.cdo.transaction.CDOCommitContext;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.event.IListener;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult;
@@ -77,38 +79,37 @@ public interface InternalCDOTransaction extends CDOTransaction, InternalCDOUserT
public void setTransactionStrategy(CDOTransactionStrategy transactionStrategy);
/**
- * @return never <code>null</code>;
+ * @return Never <code>null</code>;
*/
public CDOResourceFolder getOrCreateResourceFolder(List<String> names);
- public void detachObject(InternalCDOObject object);
+ public void attachObject(InternalCDOObject object);
- /**
- * @deprecated {@link #createIDForNewObject(EObject)} is called since 4.1.
- */
- @Deprecated
- public CDOIDTemp getNextTemporaryID();
+ public void detachObject(InternalCDOObject object);
/**
* @since 4.1
*/
public CDOID createIDForNewObject(EObject object);
+ public void handleAttachingObject(CDOObject object);
+
+ public void handleModifyingObject(CDOObject object, CDOFeatureDelta featureDelta);
+
+ public void handleDetachingObject(CDOObject object);
+
/**
* @since 4.0
*/
- public void registerAttached(InternalCDOObject object, boolean isNew);
+ public void _registerAttached(InternalCDOObject object, boolean isNew);
- public void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta);
+ public void _registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta);
- public void registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta);
+ public void _registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta);
- public void registerRevisionDelta(CDORevisionDelta revisionDelta);
+ public void _registerRevisionDelta(CDORevisionDelta revisionDelta);
- /**
- * @since 4.2
- */
- public void setDirty(boolean dirty);
+ public IListener[] updateDirtyState(boolean undone);
public void setConflict(InternalCDOObject object);
@@ -117,30 +118,47 @@ public interface InternalCDOTransaction extends CDOTransaction, InternalCDOUserT
* May be <code>null</code> if changeSetData does not result from a
* {@link #merge(CDOBranchPoint, org.eclipse.emf.cdo.transaction.CDOMerger) merge} or if the merge was not in
* a {@link CDOBranch#isLocal() local} branch.
+ * @since 4.1
+ */
+ public ApplyChangeSetResult applyChangeSet(CDOChangeSetData changeSetData, CDORevisionProvider ancestorProvider,
+ CDORevisionProvider targetProvider, CDOBranchPoint source, boolean keepVersions)
+ throws ChangeSetOutdatedException;
+
+ /**
* @since 4.0
- * @deprecated Use
- * {@link #applyChangeSet(CDOChangeSetData, CDORevisionProvider, CDORevisionProvider, CDOBranchPoint, boolean)}
+ * @deprecated As of 4.3 use {@link #getCleanRevision(InternalCDOObject)}.
*/
@Deprecated
- public Pair<CDOChangeSetData, Pair<Map<CDOID, CDOID>, List<CDOID>>> applyChangeSetData(
- CDOChangeSetData changeSetData, CDORevisionProvider ancestorProvider, CDORevisionProvider targetProvider,
- CDOBranchPoint source);
+ public Map<InternalCDOObject, InternalCDORevision> _getCleanRevisions();
+
+ public InternalCDORevision getCleanRevision(CDOObject object);
+
+ /**
+ * @deprecated As of 4.1 use {@link #createIDForNewObject(EObject)}.
+ */
+ @Deprecated
+ public CDOIDTemp getNextTemporaryID();
+
+ /**
+ * @since 4.2
+ * @deprecated As of 4.3 use {@link #updateDirtyState(boolean)}.
+ */
+ @Deprecated
+ public void setDirty(boolean dirty);
/**
* @param source
* May be <code>null</code> if changeSetData does not result from a
* {@link #merge(CDOBranchPoint, org.eclipse.emf.cdo.transaction.CDOMerger) merge} or if the merge was not in
* a {@link CDOBranch#isLocal() local} branch.
- * @since 4.1
- */
- public ApplyChangeSetResult applyChangeSet(CDOChangeSetData changeSetData, CDORevisionProvider ancestorProvider,
- CDORevisionProvider targetProvider, CDOBranchPoint source, boolean keepVersions)
- throws ChangeSetOutdatedException;
-
- /**
* @since 4.0
+ * @deprecated Use
+ * {@link #applyChangeSet(CDOChangeSetData, CDORevisionProvider, CDORevisionProvider, CDOBranchPoint, boolean)}
*/
- public Map<InternalCDOObject, InternalCDORevision> getCleanRevisions();
+ @Deprecated
+ public Pair<CDOChangeSetData, Pair<Map<CDOID, CDOID>, List<CDOID>>> applyChangeSetData(
+ CDOChangeSetData changeSetData, CDORevisionProvider ancestorProvider, CDORevisionProvider targetProvider,
+ CDOBranchPoint source);
/**
* Provides a context for a commit operation.
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 a9b4e7259e..35e25f229c 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
@@ -106,6 +106,8 @@ public interface InternalCDOView extends CDOView, CDOIDProvider, ILifecycle
*/
public void collectViewedRevisions(Map<CDOID, InternalCDORevision> revisions);
+ public void dispatchLoadNotification(InternalCDOObject object);
+
public void remapObject(CDOID oldID);
/**

Back to the top