Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo/src/org/eclipse')
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java1
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java22
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java32
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransactionFinishedEvent.java27
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUndoDetector.java37
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java4
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java47
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyListener.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java18
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java16
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java266
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOUndoDetectorImpl.java192
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java3
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java326
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStoreImpl.java286
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java5
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java4
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java16
19 files changed, 918 insertions, 388 deletions
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 6d1da1d676..3b36ffbcc0 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
@@ -744,7 +744,6 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR
return uriFragmentPath;
}
-
private EObject getEObject(List<String> uriFragmentPath)
{
int size = uriFragmentPath.size();
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 4600a68f9d..37c51936df 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 Cause getCause()
+ {
+ return Cause.COMMITTED;
+ }
+
public Map<CDOID, CDOID> getIDMappings()
{
return Collections.emptyMap();
@@ -655,15 +661,15 @@ public class CDOPushTransaction extends Notifier implements CDOTransaction
public void lockObjects(Collection<? extends CDOObject> objects, LockType lockType, long timeout)
throws InterruptedException
- {
+ {
delegate.lockObjects(objects, lockType, timeout);
- }
+ }
public void lockObjects(Collection<? extends CDOObject> objects, LockType lockType, long timeout, boolean recursive)
throws InterruptedException
- {
+ {
delegate.lockObjects(objects, lockType, timeout, recursive);
- }
+ }
public Options options()
{
@@ -677,9 +683,9 @@ public class CDOPushTransaction extends Notifier implements CDOTransaction
public CloseableIterator<CDOResourceNode> queryResourcesAsync(CDOResourceFolder folder, String name,
boolean exactMatch)
- {
+ {
return delegate.queryResourcesAsync(folder, name, exactMatch);
- }
+ }
/**
* @since 4.3
@@ -712,9 +718,9 @@ public class CDOPushTransaction extends Notifier implements CDOTransaction
public CloseableIterator<CDOObjectReference> queryXRefsAsync(Set<CDOObject> targetObjects,
EReference... sourceReferences)
- {
+ {
return delegate.queryXRefsAsync(targetObjects, sourceReferences);
- }
+ }
@Deprecated
public int reload(CDOObject... objects)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java
index d7afe27671..13afc46c5b 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java
@@ -225,6 +225,11 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr
public interface Options extends CDOView.Options
{
/**
+ * @since 4.3
+ */
+ public static final CDOUndoDetector DEFAULT_UNDO_DETECTOR = CDOUndoDetector.ALL_FEATURES;
+
+ /**
* Returns the {@link CDOTransaction transaction} of this options object.
*
* @since 4.0
@@ -232,6 +237,20 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr
public CDOTransaction getContainer();
/**
+ * Returns the undo detector of this transaction.
+ *
+ * @since 4.3
+ */
+ public CDOUndoDetector getUndoDetector();
+
+ /**
+ * Sets the undo detector of this transaction.
+ *
+ * @since 4.3
+ */
+ public void setUndoDetector(CDOUndoDetector undoDetector);
+
+ /**
* Returns a copy of the conflict resolver list of this transaction.
*/
public CDOConflictResolver[] getConflictResolvers();
@@ -271,6 +290,19 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr
/**
* An {@link IOptionsEvent options event} fired from transaction {@link CDOTransaction#options() options} when the
+ * {@link Options#setUndoDetector(CDOUndoDetector) undo detector} option has changed.
+ *
+ * @author Eike Stepper
+ * @since 4.3
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+ public interface UndoDetectorEvent extends IOptionsEvent
+ {
+ }
+
+ /**
+ * An {@link IOptionsEvent options event} fired from transaction {@link CDOTransaction#options() options} when the
* {@link Options#addConflictResolver(CDOConflictResolver) conflict resolvers} option has changed.
*
* @author Eike Stepper
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..9cf0da679f 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
@@ -19,7 +19,7 @@ import java.util.Map;
* A {@link CDOViewEvent view event} fired from a {@link CDOTransaction transaction} when it becomes
* {@link CDOTransaction#isDirty() clean} after a sucessful {@link CDOTransaction#commit() commit} or
* {@link CDOTransaction#rollback() rollback}.
- *
+ *
* @author Eike Stepper
* @since 2.0
* @noextend This interface is not intended to be extended by clients.
@@ -27,18 +27,41 @@ import java.util.Map;
*/
public interface CDOTransactionFinishedEvent extends CDOViewEvent
{
+ /**
+ * @deprecated As of 4.3 use {@link #getCause()}.
+ */
+ @Deprecated
public Type getType();
+ /**
+ * @since 4.3
+ */
+ public Cause getCause();
+
public Map<CDOID, CDOID> getIDMappings();
/**
* 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 Cause}.
*/
+ @Deprecated
public enum Type
{
COMMITTED, ROLLED_BACK
}
+
+ /**
+ * Enumerates the possible {@link CDOTransactionFinishedEvent#getCause() causes} for a {@link CDOTransaction
+ * transaction} to become finished.
+ *
+ * @author Eike Stepper
+ * @since 4.3
+ */
+ public enum Cause
+ {
+ COMMITTED, ROLLED_BACK, UNDONE
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUndoDetector.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUndoDetector.java
new file mode 100644
index 0000000000..93ce378265
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOUndoDetector.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.transaction;
+
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+
+import org.eclipse.emf.internal.cdo.transaction.CDOUndoDetectorImpl;
+
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A strategy used to detect whether the feature of an {@link EObject object} has the original (clean) value after a number of modifications.
+ *
+ * @see CDOTransaction.Options#setUndoDetector(CDOUndoDetector)
+ * @author Eike Stepper
+ * @since 4.3
+ */
+public interface CDOUndoDetector
+{
+ public static final CDOUndoDetector NO_FEATURES = new CDOUndoDetectorImpl.NoFeatures();
+
+ public static final CDOUndoDetector SINGLE_VALUED_FEATURES = new CDOUndoDetectorImpl.SingleValuedFeatures();
+
+ public static final CDOUndoDetector ALL_FEATURES = new CDOUndoDetectorImpl();
+
+ public boolean detectUndo(CDOTransaction transaction, CDORevision cleanRevision, CDORevision revision,
+ CDOFeatureDelta featureDelta);
+}
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 5d6006878d..9ebed60f0e 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
@@ -54,6 +54,7 @@ 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.CDOStoreImpl;
import org.eclipse.net4j.util.AdapterUtil;
import org.eclipse.net4j.util.container.IPluginContainer;
@@ -427,8 +428,7 @@ public final class CDOUtil
try
{
- EStore eStore = cdoObject.eStore();
- eStore.remove(cdoObject, eFeature, index);
+ CDOStoreImpl.removeElement(cdoObject, eFeature, index);
}
catch (ObjectNotFoundException ex)
{
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 d349ba52f4..04ede44ba9 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
@@ -417,7 +417,7 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC
*/
public final void cdoInternalPostInvalidate()
{
- // Do nothing
+ cdoInternalSetRevision(null);
}
public final void cdoInternalPostAttach()
@@ -1217,38 +1217,38 @@ 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>
* was not {@link CDOState#NEW}.
*/
- private static void adjustOppositeReference(InternalCDOObject instance, InternalEObject object, EReference feature)
+ private static void adjustOppositeReference(InternalCDOObject instance, InternalEObject opposite,
+ EReference oppositeReference)
{
- if (object != null)
+ if (opposite != null)
{
- InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(object);
+ InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(opposite);
if (cdoObject != null && !FSMUtil.isTransient(cdoObject))
{
- if (feature.isMany())
+ if (oppositeReference.isMany())
{
EStore eStore = cdoObject.eStore();
- int index = eStore.indexOf(cdoObject, feature, instance.cdoID());
-
+ int index = eStore.indexOf(cdoObject, oppositeReference, instance.cdoID());
if (index != -1)
{
- eStore.set(cdoObject, feature, index, instance);
+ eStore.set(cdoObject, oppositeReference, index, instance);
}
}
else
{
EStore eStore = cdoObject.eStore();
- eStore.set(cdoObject, feature, 0, instance);
+ eStore.set(cdoObject, oppositeReference, 0, instance);
}
}
else
{
- if (feature.isResolveProxies())
+ if (oppositeReference.isResolveProxies())
{
// We should not trigger events. But we have no choice :-(.
- if (feature.isMany())
+ if (oppositeReference.isMany())
{
@SuppressWarnings("unchecked")
- List<Object> list = (List<Object>)object.eGet(feature);
+ List<Object> list = (List<Object>)opposite.eGet(oppositeReference);
int index = list.indexOf(instance);
if (index != -1)
{
@@ -1257,7 +1257,7 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC
}
else
{
- object.eSet(feature, instance);
+ opposite.eSet(oppositeReference, instance);
}
}
}
@@ -1283,6 +1283,7 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC
{
TRACER.format("Filtering value of feature {0}", feature); //$NON-NLS-1$
}
+
setting = filter.getPersistableValue(object, setting);
}
@@ -1298,15 +1299,15 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC
EList<Object> list = (EList<Object>)setting;
for (Object value : list)
{
- value = cdoStore.convertToCDO(object, feature, value);
- revision.add(feature, index++, value);
+ Object cdoValue = cdoStore.convertToCDO(object, feature, value);
+ revision.add(feature, index++, cdoValue);
}
}
}
else
{
- setting = cdoStore.convertToCDO(object, feature, setting);
- revision.set(feature, 0, setting);
+ Object cdoValue = cdoStore.convertToCDO(object, feature, setting);
+ revision.set(feature, 0, cdoValue);
}
}
@@ -1335,21 +1336,21 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC
{
// Do not trigger events
// Do not trigger inverse updates
- Object object = cdoStore.get(instance, eFeature, index);
- eStore.add(instance, eFeature, index, object);
+ Object opposite = cdoStore.get(instance, eFeature, index);
+ eStore.add(instance, eFeature, index, opposite);
if (oppositeReference != null)
{
- adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
+ adjustOppositeReference(instance, (InternalEObject)opposite, oppositeReference);
}
}
}
else
{
- Object object = cdoStore.get(instance, eFeature, EStore.NO_INDEX);
- eStore.set(instance, eFeature, EStore.NO_INDEX, object);
+ Object opposite = cdoStore.get(instance, eFeature, EStore.NO_INDEX);
+ eStore.set(instance, eFeature, EStore.NO_INDEX, opposite);
if (oppositeReference != null)
{
- adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
+ adjustOppositeReference(instance, (InternalEObject)opposite, oppositeReference);
}
}
}
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..5bff08aba4 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
@@ -95,7 +95,7 @@ public final class CDOLegacyListener extends CDOLegacyWrapper
try
{
handlingCallback = true;
- CDOStateMachine.INSTANCE.write(this);
+ CDOStateMachine.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 374194b7f7..62ec57d5dd 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
@@ -369,14 +369,22 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper
public void cdoInternalPostInvalidate()
{
- if (cdoState() != CDOState.CLEAN)
+ if (cdoState() != CDOState.PROXY)
{
- InternalCDORevision revision = cdoView().getRevision(cdoID(), true);
- cdoInternalSetRevision(revision);
+ throw new IllegalStateException();
}
- revisionToInstance();
- cdoInternalSetState(CDOState.CLEAN);
+ InternalCDORevision revision = cdoView().getRevision(cdoID(), true);
+ if (revision == null)
+ {
+ cdoInternalPostDetach(true);
+ }
+ else
+ {
+ cdoInternalSetRevision(revision);
+ revisionToInstance();
+ cdoInternalSetState(CDOState.CLEAN);
+ }
}
protected void instanceToRevision()
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
index 4aa88a6780..efcdb2010e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
@@ -2022,7 +2022,7 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
try
{
- revisionDelta.apply(newRevision);
+ revisionDelta.applyTo(newRevision);
}
finally
{
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 199247be0b..1fd7a2a228 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
@@ -23,11 +23,8 @@ import org.eclipse.emf.cdo.util.OptimisticLockingException;
import org.eclipse.emf.cdo.util.ReferentialIntegrityException;
import org.eclipse.emf.cdo.util.ValidationException;
-import org.eclipse.emf.internal.cdo.bundle.OM;
-
import org.eclipse.net4j.util.om.monitor.EclipseMonitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult;
@@ -48,29 +45,21 @@ public class CDOSingleTransactionStrategyImpl implements CDOTransactionStrategy
{
public static final CDOSingleTransactionStrategyImpl INSTANCE = new CDOSingleTransactionStrategyImpl();
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSACTION,
- CDOSingleTransactionStrategyImpl.class);
-
public CDOSingleTransactionStrategyImpl()
{
}
public CDOCommitInfo commit(InternalCDOTransaction transaction, IProgressMonitor progressMonitor) throws Exception
{
- String comment = transaction.getCommitComment();
InternalCDOCommitContext commitContext = transaction.createCommitContext();
- if (TRACER.isEnabled())
- {
- TRACER.format("CDOCommitContext.preCommit"); //$NON-NLS-1$
- }
+ CDOCommitData commitData = commitContext.getCommitData();
commitContext.preCommit();
- CDOCommitData commitData = commitContext.getCommitData();
InternalCDOSession session = transaction.getSession();
+ CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
OMMonitor monitor = new EclipseMonitor(progressMonitor);
- CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
CommitTransactionResult result = sessionProtocol.commitTransaction(commitContext, monitor);
commitContext.postCommit(result);
@@ -104,6 +93,7 @@ public class CDOSingleTransactionStrategyImpl implements CDOTransactionStrategy
}
}
+ String comment = transaction.getCommitComment();
transaction.setCommitComment(null);
long previousTimeStamp = result.getPreviousTimeStamp();
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 2c1a99e7cf..4706d4ba6c 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
@@ -102,6 +102,7 @@ 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.CDOUndoDetector;
import org.eclipse.emf.cdo.transaction.CDOUserSavepoint;
import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.cdo.util.CDOUtil;
@@ -248,7 +249,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
/**
* 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();
+ private Map<InternalCDOObject, InternalCDORevision> cleanRevisions = new CleanRevisionsMap();
public CDOTransactionImpl(CDOBranch branch)
{
@@ -394,7 +395,17 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
public void setDirty(boolean dirty)
{
- this.dirty = dirty;
+ if (this.dirty != dirty)
+ {
+ this.dirty = dirty;
+
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ IEvent event = dirty ? new StartedEvent() : new FinishedEvent(false);
+ fireEvent(event, listeners);
+ }
+ }
}
@Override
@@ -601,7 +612,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
registerObject(object);
registerAttached(object, true);
result.add(revision);
- dirty = true;
+ setDirty(true);
}
}
}
@@ -618,7 +629,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
result.add(CDOIDUtil.createIDAndVersion(id, CDOBranchVersion.UNSPECIFIED_VERSION));
CDOStateMachine.INSTANCE.detach(object);
detachedSet.add(object);
- dirty = true;
+ setDirty(true);
}
}
@@ -663,7 +674,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
goalRevision.setRevised(CDOBranchPoint.UNSPECIFIED_DATE);
- ancestorGoalDelta.apply(goalRevision);
+ ancestorGoalDelta.applyTo(goalRevision);
InternalCDORevisionDelta targetGoalDelta = goalRevision.compare(targetRevision);
targetGoalDelta.setTarget(null);
@@ -689,7 +700,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
revisionChanged = true;
dirtyObjects.put(id, object);
- dirty = true;
+ setDirty(true);
}
if (revisionChanged)
@@ -1532,16 +1543,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
// here be removed from the collection of reattached objects
lastSavepoint.getReattachedObjects().remove(id);
}
-
- if (!dirty)
- {
- dirty = true;
- IListener[] listeners = getListeners();
- if (listeners != null)
- {
- fireEvent(new StartedEvent(), listeners);
- }
- }
}
/**
@@ -1638,11 +1639,10 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
- Map<CDOID, CDOID> idMappings = Collections.emptyMap();
IListener[] listeners = getListeners();
if (listeners != null)
{
- fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.ROLLED_BACK, idMappings), listeners);
+ fireEvent(new FinishedEvent(true), listeners);
}
CDOTransactionHandler2[] handlers = getTransactionHandlers2();
@@ -1694,6 +1694,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return (InternalCDOSavepoint)getTransactionStrategy().setSavepoint(this);
}
+ public boolean hasMultipleSavepoints()
+ {
+ return lastSavepoint != firstSavepoint;
+ }
+
private void addToBase(Map<CDOID, CDOObject> objects)
{
for (CDOObject object : objects.values())
@@ -1744,18 +1749,53 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
+ private CDOOriginSizeProvider getOriginSizeProvider(InternalCDOObject object, CDOFeatureDelta featureDelta,
+ InternalCDORevision cleanRevision)
+ {
+ EStructuralFeature feature = featureDelta.getFeature();
+ if (feature.isMany())
+ {
+ if (cleanRevision == null)
+ {
+ cleanRevision = cleanRevisions.get(object);
+ if (cleanRevision == null)
+ {
+ cleanRevision = object.cdoRevision();
+ }
+ }
+
+ CDOList list = cleanRevision.getList(feature);
+ final int originSize = list.size();
+
+ return new CDOOriginSizeProvider()
+ {
+ public int getOriginSize()
+ {
+ return originSize;
+ }
+ };
+ }
+
+ return null;
+ }
+
/**
* Receives notification for new and dirty objects
*/
- public synchronized void registerFeatureDelta(final InternalCDOObject object, final CDOFeatureDelta featureDelta)
+ public synchronized void registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ registerFeatureDelta(object, featureDelta, null);
+ }
+
+ public synchronized void registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta,
+ InternalCDORevision cleanRevision)
{
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
+ // Register Delta for new objects only if objectA doesn't belong to this savepoint
if (getLastSavepoint().getPreviousSavepoint() == null || featureDelta == null)
{
needToSaveFeatureDelta = false;
@@ -1769,31 +1809,18 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
if (needToSaveFeatureDelta)
{
- final InternalCDORevision revision = object.cdoRevision();
-
- CDORevisionDelta revisionDelta = lastSavepoint.getRevisionDeltas2().get(id);
+ Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
+ InternalCDORevisionDelta revisionDelta = (InternalCDORevisionDelta)revisionDeltas.get(id);
if (revisionDelta == null)
{
- revisionDelta = CDORevisionUtil.createDelta(revision);
- lastSavepoint.getRevisionDeltas2().put(id, revisionDelta);
- }
+ InternalCDORevision revision = object.cdoRevision();
- ((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;
- }
+ revisionDelta = (InternalCDORevisionDelta)CDORevisionUtil.createDelta(revision);
+ revisionDeltas.put(id, revisionDelta);
+ }
- CDOList list = cleanRevision.getList(feature);
- return list.size();
- }
- });
+ CDOOriginSizeProvider originSizeProvider = getOriginSizeProvider(object, featureDelta, cleanRevision);
+ revisionDelta.addFeatureDelta(featureDelta, originSizeProvider);
}
CDOTransactionHandler1[] handlers = getTransactionHandlers1();
@@ -1814,7 +1841,12 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
- public synchronized void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ public void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ registerDirty(object, featureDelta, null);
+ }
+
+ public void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta, InternalCDORevision cleanRevision)
{
if (TRACER.isEnabled())
{
@@ -1823,7 +1855,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
if (featureDelta != null)
{
- registerFeatureDelta(object, featureDelta);
+ registerFeatureDelta(object, featureDelta, cleanRevision);
}
registerNew(lastSavepoint.getDirtyObjects(), object);
@@ -1841,15 +1873,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
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);
- }
- }
+ setDirty(true);
}
public synchronized List<CDOPackageUnit> analyzeNewPackages()
@@ -2726,24 +2750,60 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
/**
* @author Eike Stepper
*/
- private final class ResolvingRevisionMap extends HashMap<InternalCDOObject, InternalCDORevision>
+ private final class CleanRevisionsMap extends HashMap<InternalCDOObject, InternalCDORevision>
{
private static final long serialVersionUID = 1L;
- public ResolvingRevisionMap()
+ public CleanRevisionsMap()
{
}
@Override
- public InternalCDORevision get(Object cdoObject)
+ public InternalCDORevision get(Object key)
{
- InternalCDORevision revision = super.get(cdoObject);
- if (revision != null)
+ if (key instanceof EObject)
{
- getSession().resolveAllElementProxies(revision);
+ CDOObject cdoObject = CDOUtil.getCDOObject((EObject)key);
+ InternalCDORevision revision = super.get(cdoObject);
+ if (revision != null)
+ {
+ getSession().resolveAllElementProxies(revision);
+ }
+
+ return revision;
}
- return revision;
+ return null;
+ }
+
+ @Override
+ public InternalCDORevision remove(Object key)
+ {
+ if (key instanceof EObject)
+ {
+ CDOObject cdoObject = CDOUtil.getCDOObject((EObject)key);
+ return super.remove(cdoObject);
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean containsKey(Object key)
+ {
+ if (key instanceof EObject)
+ {
+ CDOObject cdoObject = CDOUtil.getCDOObject((EObject)key);
+ return super.containsKey(cdoObject);
+ }
+
+ return false;
+ }
+
+ @Override
+ public Set<InternalCDOObject> keySet()
+ {
+ throw new UnsupportedOperationException();
}
}
@@ -3084,8 +3144,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
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);
}
@@ -3130,7 +3191,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
Map<CDOID, CDOID> idMappings = result.getIDMappings();
- fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.COMMITTED, idMappings), listeners);
+ fireEvent(new FinishedEvent(idMappings), listeners);
}
CDOLockState[] newLockStates = result.getNewLockStates();
@@ -3226,19 +3287,42 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
{
private static final long serialVersionUID = 1L;
- private Type type;
+ private final Cause cause;
- private Map<CDOID, CDOID> idMappings;
+ private final Map<CDOID, CDOID> idMappings;
- private FinishedEvent(Type type, Map<CDOID, CDOID> idMappings)
+ private FinishedEvent(Map<CDOID, CDOID> idMappings)
{
- this.type = type;
+ cause = Cause.COMMITTED;
this.idMappings = idMappings;
}
+ private FinishedEvent(boolean rolledBack)
+ {
+ cause = rolledBack ? Cause.ROLLED_BACK : Cause.UNDONE;
+ idMappings = Collections.emptyMap();
+ }
+
+ @Deprecated
public Type getType()
{
- return type;
+ switch (cause)
+ {
+ case COMMITTED:
+ return Type.COMMITTED;
+
+ case ROLLED_BACK:
+ case UNDONE:
+ return Type.ROLLED_BACK;
+
+ default:
+ throw new IllegalStateException("Illegal cause: " + cause);
+ }
+ }
+
+ public Cause getCause()
+ {
+ return cause;
}
public Map<CDOID, CDOID> getIDMappings()
@@ -3249,8 +3333,8 @@ 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());
+ return MessageFormat.format("CDOTransactionFinishedEvent[source={0}, cause={1}, idMappings={2}]", getSource(), //$NON-NLS-1$
+ getCause(), idMappings == null ? 0 : idMappings.size());
}
}
@@ -3295,6 +3379,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
*/
protected final class OptionsImpl extends CDOViewImpl.OptionsImpl implements CDOTransaction.Options
{
+ private CDOUndoDetector undoDetector = DEFAULT_UNDO_DETECTOR;
+
private List<CDOConflictResolver> conflictResolvers = new ArrayList<CDOConflictResolver>();
private boolean autoReleaseLocksEnabled = true;
@@ -3303,6 +3389,33 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
{
}
+ public CDOUndoDetector getUndoDetector()
+ {
+ return undoDetector;
+ }
+
+ public void setUndoDetector(CDOUndoDetector undoDetector)
+ {
+ checkActive();
+
+ if (undoDetector == null)
+ {
+ undoDetector = DEFAULT_UNDO_DETECTOR;
+ }
+
+ IEvent event = null;
+ synchronized (CDOTransactionImpl.this)
+ {
+ if (this.undoDetector != undoDetector)
+ {
+ this.undoDetector = undoDetector;
+ event = new UndoDetectorEventImpl();
+ }
+ }
+
+ fireEvent(event);
+ }
+
@Override
public CDOTransactionImpl getContainer()
{
@@ -3429,6 +3542,19 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
/**
* @author Eike Stepper
*/
+ private final class UndoDetectorEventImpl extends OptionsEvent implements UndoDetectorEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ public UndoDetectorEventImpl()
+ {
+ super(OptionsImpl.this);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
private final class ConflictResolversEventImpl extends OptionsEvent implements ConflictResolversEvent
{
private static final long serialVersionUID = 1L;
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOUndoDetectorImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOUndoDetectorImpl.java
new file mode 100644
index 0000000000..68947b213b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOUndoDetectorImpl.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2014 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.internal.cdo.transaction;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta.Type;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.transaction.CDOUndoDetector;
+
+import org.eclipse.net4j.util.ObjectUtil;
+
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ * @since 4.3
+ */
+public class CDOUndoDetectorImpl implements CDOUndoDetector
+{
+ public boolean detectUndo(CDOTransaction transaction, CDORevision cleanRevision, CDORevision revision,
+ CDOFeatureDelta featureDelta)
+ {
+ EStructuralFeature feature = featureDelta.getFeature();
+ if (ignore(feature))
+ {
+ return false;
+ }
+
+ if (ignore(cleanRevision))
+ {
+ return false;
+ }
+
+ if (ignore(revision))
+ {
+ return false;
+ }
+
+ InternalCDORevision rev1 = (InternalCDORevision)cleanRevision;
+ InternalCDORevision rev2 = (InternalCDORevision)revision;
+
+ if (featureDelta.getType() == Type.CONTAINER)
+ {
+ // return false;
+ return detectUndoContainer(transaction, rev1, rev2, (CDOContainerFeatureDelta)featureDelta);
+ }
+
+ Object value1 = rev1.getValue(feature);
+ Object value2 = rev2.getValue(feature);
+
+ if (feature instanceof EReference)
+ {
+ if (feature.isMany())
+ {
+ List<?> list1 = (List<?>)value1;
+ List<?> list2 = (List<?>)value2;
+
+ int size1 = size(list1);
+ int size2 = size(list2);
+
+ if (size1 != size2)
+ {
+ return false;
+ }
+
+ if (size1 != 0)
+ {
+ for (Iterator<?> it1 = list1.iterator(), it2 = list2.iterator(); it1.hasNext();)
+ {
+ Object id1 = getID(it1.next());
+ Object id2 = getID(it2.next());
+ if (id1 != id2)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ value1 = getID(value1);
+ value2 = getID(value2);
+ return value1 == value2;
+ }
+
+ return ObjectUtil.equals(value1, value2);
+ }
+
+ protected boolean detectUndoContainer(CDOTransaction transaction, InternalCDORevision cleanRevision,
+ InternalCDORevision revision, CDOContainerFeatureDelta featureDelta)
+ {
+ CDOID resourceID1 = cleanRevision.getResourceID();
+ CDOID resourceID2 = revision.getResourceID();
+ if (resourceID1 != resourceID2)
+ {
+ return false;
+ }
+
+ int containingFeatureID1 = cleanRevision.getContainingFeatureID();
+ int containingFeatureID2 = revision.getContainingFeatureID();
+ if (containingFeatureID1 != containingFeatureID2)
+ {
+ return false;
+ }
+
+ Object c1 = cleanRevision.getContainerID();
+ Object c2 = revision.getContainerID();
+
+ // Potentially most expensive check because of EObject/ID conversion
+ Object containerID1 = getID(c1);
+ Object containerID2 = getID(c2);
+ if (containerID1 != containerID2)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ protected boolean ignore(EStructuralFeature feature)
+ {
+ return false;
+ }
+
+ protected boolean ignore(CDORevision revision)
+ {
+ return !((InternalCDORevision)revision).isUnchunked();
+ }
+
+ private static Object getID(Object value)
+ {
+ // TODO Write tests to see if EObject instead of CDOID instances need special handling
+ // CDOID id = CDOIDUtil.getCDOID(value);
+ // if (id != null)
+ // {
+ // return id;
+ // }
+
+ return value;
+ }
+
+ private static int size(List<?> list)
+ {
+ if (list == null)
+ {
+ return 0;
+ }
+
+ return list.size();
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class NoFeatures extends CDOUndoDetectorImpl
+ {
+ @Override
+ protected boolean ignore(EStructuralFeature feature)
+ {
+ return true;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class SingleValuedFeatures extends CDOUndoDetectorImpl
+ {
+ @Override
+ protected boolean ignore(EStructuralFeature feature)
+ {
+ return feature.isMany();
+ }
+ }
+}
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 e7eb49eaf3..1f265f9142 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
@@ -1291,8 +1291,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
throw new DanglingReferenceException(eObject);
}
- throw new IllegalStateException(MessageFormat.format(
- Messages.getString("CDOViewImpl.16"), idOrObject.getClass().getName())); //$NON-NLS-1$
+ throw new IllegalStateException(MessageFormat.format(Messages.getString("CDOViewImpl.16"), idOrObject)); //$NON-NLS-1$
}
public synchronized Object convertObjectToID(Object potentialObject)
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 e09c8f12c7..5ec19fdc48 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
@@ -31,6 +31,8 @@ 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.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.transaction.CDOUndoDetector;
+import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOInvalidationPolicy;
import org.eclipse.emf.cdo.view.CDOView;
@@ -128,7 +130,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.CLEAN, CDOEvent.DETACH, new DetachTransition());
init(CDOState.CLEAN, CDOEvent.REATTACH, FAIL);
init(CDOState.CLEAN, CDOEvent.READ, IGNORE);
- init(CDOState.CLEAN, CDOEvent.WRITE, new WriteTransition());
+ init(CDOState.CLEAN, CDOEvent.WRITE, new WriteTransition(false));
init(CDOState.CLEAN, CDOEvent.INVALIDATE, new InvalidateTransition());
init(CDOState.CLEAN, CDOEvent.DETACH_REMOTE, DetachRemoteTransition.INSTANCE);
init(CDOState.CLEAN, CDOEvent.COMMIT, FAIL);
@@ -149,8 +151,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.PROXY, CDOEvent.ATTACH, FAIL);
init(CDOState.PROXY, CDOEvent.DETACH, new DetachTransition());
init(CDOState.PROXY, CDOEvent.REATTACH, FAIL);
- init(CDOState.PROXY, CDOEvent.READ, new LoadTransition(false));
- init(CDOState.PROXY, CDOEvent.WRITE, new LoadTransition(true));
+ init(CDOState.PROXY, CDOEvent.READ, new LoadTransition());
+ init(CDOState.PROXY, CDOEvent.WRITE, new WriteTransition(true));
init(CDOState.PROXY, CDOEvent.INVALIDATE, IGNORE);
init(CDOState.PROXY, CDOEvent.DETACH_REMOTE, DetachRemoteTransition.INSTANCE);
init(CDOState.PROXY, CDOEvent.COMMIT, FAIL);
@@ -191,10 +193,7 @@ 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.
*/
public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
{
@@ -263,9 +262,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
process(object, CDOEvent.REATTACH, transaction);
}
- /**
- * @since 2.0
- */
public void detach(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -302,9 +298,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- /**
- * @since 2.0
- */
public InternalCDORevision read(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -315,14 +308,10 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
process(object, CDOEvent.READ, null);
-
return object.cdoRevision();
}
}
- /**
- * @since 2.0
- */
public InternalCDORevision readNoLoad(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -343,38 +332,28 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- /**
- * @since 2.0
- */
- public void write(InternalCDOObject object)
- {
- write(object, null);
- }
-
- /**
- * @since 2.0
- */
- public void write(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ public Object write(InternalCDOObject object, CDOFeatureDelta featureDelta)
{
synchronized (getMonitor(object))
{
- writeWithoutViewLock(object, featureDelta);
+ return writeWithoutViewLock(object, featureDelta);
}
}
- private void writeWithoutViewLock(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ private Object writeWithoutViewLock(InternalCDOObject object, CDOFeatureDelta featureDelta)
{
if (TRACER.isEnabled())
{
trace(object, CDOEvent.WRITE);
}
- process(object, CDOEvent.WRITE, featureDelta);
+ // TODO: Make FeatureDeltaAndResult constant
+ FeatureDeltaAndResult featureDeltaAndResult = new FeatureDeltaAndResult(featureDelta);
+
+ process(object, CDOEvent.WRITE, featureDeltaAndResult);
+ return featureDeltaAndResult.getResult();
}
- /**
- * @since 2.0
- */
public void reload(InternalCDOObject... objects)
{
if (objects == null || objects.length == 0)
@@ -397,9 +376,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- /**
- * @since 3.0
- */
public void invalidate(InternalCDOObject object, CDORevisionKey key)
{
synchronized (getMonitor(object))
@@ -413,9 +389,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- /**
- * @since 2.0
- */
public void detachRemote(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -429,9 +402,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- /**
- * @since 2.0
- */
public void commit(InternalCDOObject object, CommitTransactionResult result)
{
synchronized (getMonitor(object))
@@ -445,9 +415,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- /**
- * @since 2.0
- */
public void rollback(InternalCDOObject object)
{
synchronized (getMonitor(object))
@@ -519,7 +486,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
CDORevisionDelta delta = savepoint.getRevisionDeltas2().get(id);
if (delta != null)
{
- delta.apply(cleanRevision);
+ delta.applyTo(cleanRevision);
}
savepoint = savepoint.getNextSavepoint();
@@ -582,6 +549,60 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
+ private void internalLoad(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);
+ changeState(object, CDOState.CLEAN);
+ object.cdoInternalPostLoad();
+ dispatchLoadNotification(object);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class FeatureDeltaAndResult
+ {
+ private final CDOFeatureDelta featureDelta;
+
+ private Object result;
+
+ public FeatureDeltaAndResult(CDOFeatureDelta featureDelta)
+ {
+ this.featureDelta = featureDelta;
+ }
+
+ public CDOFeatureDelta getFeatureDelta()
+ {
+ return featureDelta;
+ }
+
+ public Object getResult()
+ {
+ return result;
+ }
+
+ public void setResult(Object result)
+ {
+ this.result = result;
+ }
+ }
+
/**
* Prepares a tree of transient objects to be subsequently {@link AttachTransition attached} to a CDOView.
* <p>
@@ -719,11 +740,11 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
internalReattach(object, transaction);
// Bug 385268
- InternalEObject reattachedObject = object.cdoInternalInstance();
+ CDOID reattachedObject = object.cdoID();
processRevisionDeltas(reattachedObject, transaction);
}
- private void processRevisionDeltas(InternalEObject reattachedObject, InternalCDOTransaction transaction)
+ private void processRevisionDeltas(CDOID reattachedObject, InternalCDOTransaction transaction)
{
InternalCDOSavepoint lastSavepoint = transaction.getLastSavepoint();
Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
@@ -741,7 +762,10 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
CDOID id = revisionDelta.getID();
InternalCDOObject cleanObject = (InternalCDOObject)lastSavepoint.getDirtyObjects().remove(id);
- cleanObject.cdoInternalSetState(CDOState.CLEAN);
+ if (cleanObject != null)
+ {
+ cleanObject.cdoInternalSetState(CDOState.CLEAN);
+ }
}
}
@@ -751,7 +775,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- private void processFeatureDeltas(InternalEObject reattachedObject, Map<EStructuralFeature, CDOFeatureDelta> map)
+ private void processFeatureDeltas(CDOID reattachedObject, Map<EStructuralFeature, CDOFeatureDelta> map)
{
for (Iterator<Entry<EStructuralFeature, CDOFeatureDelta>> it = map.entrySet().iterator(); it.hasNext();)
{
@@ -761,22 +785,22 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
- private void processFeatureDelta(InternalEObject reattachedObject, Iterator<?> it, CDOFeatureDelta featureDelta)
+ private void processFeatureDelta(CDOID reattachedObject, Iterator<?> it, CDOFeatureDelta featureDelta)
{
switch (featureDelta.getType())
{
case SET:
CDOSetFeatureDelta setFeatureDelta = (CDOSetFeatureDelta)featureDelta;
Object oldValue = setFeatureDelta.getOldValue();
- if (oldValue instanceof InternalCDOObject)
+ if (oldValue instanceof EObject)
{
- oldValue = ((InternalCDOObject)oldValue).cdoInternalInstance();
+ oldValue = CDOUtil.getCDOObject((EObject)oldValue).cdoID();
}
Object newValue = setFeatureDelta.getValue();
- if (newValue instanceof InternalCDOObject)
+ if (newValue instanceof EObject)
{
- newValue = ((InternalCDOObject)newValue).cdoInternalInstance();
+ newValue = CDOUtil.getCDOObject((EObject)newValue).cdoID();
}
if (reattachedObject == oldValue && reattachedObject == newValue)
@@ -898,61 +922,157 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
/**
* @author Eike Stepper
*/
- private final class WriteTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
+ private static abstract class AbstractWriteTransition implements
+ ITransition<CDOState, CDOEvent, InternalCDOObject, FeatureDeltaAndResult>
{
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object featureDelta)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event,
+ FeatureDeltaAndResult featureDeltaAndResult)
{
- InternalCDORevision cleanRevision = object.cdoRevision();
- if (!cleanRevision.isWritable())
+ InternalCDORevision revision = object.cdoRevision();
+ if (!revision.isWritable())
{
- throw new NoPermissionException(cleanRevision);
+ throw new NoPermissionException(revision);
}
InternalCDOTransaction transaction = object.cdoView().toTransaction();
- transaction.getCleanRevisions().put(object, cleanRevision);
+ CDOFeatureDelta featureDelta = featureDeltaAndResult.getFeatureDelta();
+ Object result = execute(object, transaction, featureDelta, revision);
+ featureDeltaAndResult.setResult(result);
+ }
- // Copy revision
- InternalCDORevision revision = object.cdoRevision().copy();
- object.cdoInternalSetRevision(revision);
+ protected abstract Object execute(InternalCDOObject object, InternalCDOTransaction transaction,
+ CDOFeatureDelta featureDelta, InternalCDORevision revision);
+ }
- transaction.registerDirty(object, (CDOFeatureDelta)featureDelta);
- changeState(object, CDOState.DIRTY);
+ /**
+ * @author Simon McDuff
+ */
+ private final class WriteNewTransition extends AbstractWriteTransition
+ {
+ @Override
+ protected Object execute(InternalCDOObject object, InternalCDOTransaction transaction,
+ CDOFeatureDelta featureDelta, InternalCDORevision revision)
+ {
+ Object result = null;
+ if (featureDelta != null)
+ {
+ result = featureDelta.applyTo(revision);
+ }
+
+ transaction.registerFeatureDelta(object, featureDelta);
+ return result;
}
}
/**
- * @author Simon McDuff
+ * @author Eike Stepper
*/
- private static final class WriteNewTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
+ private final class WriteTransition extends AbstractWriteTransition
{
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object featureDelta)
+ private boolean load;
+
+ public WriteTransition(boolean load)
{
- InternalCDORevision revision = object.cdoRevision();
- if (!revision.isWritable())
+ this.load = load;
+ }
+
+ @Override
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event,
+ FeatureDeltaAndResult featureDeltaAndResult)
+ {
+ if (load)
{
- throw new NoPermissionException(revision);
+ internalLoad(object, true);
}
- InternalCDOTransaction transaction = object.cdoView().toTransaction();
- transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta);
+ super.execute(object, state, event, featureDeltaAndResult);
+ }
+
+ @Override
+ protected Object execute(InternalCDOObject object, InternalCDOTransaction transaction,
+ CDOFeatureDelta featureDelta, InternalCDORevision cleanRevision)
+ {
+ InternalCDORevision revision = cleanRevision.copy();
+
+ Object result = null;
+ if (featureDelta != null)
+ {
+ result = featureDelta.applyTo(revision);
+
+ if (!transaction.hasMultipleSavepoints())
+ {
+ CDOUndoDetector undoDetector = transaction.options().getUndoDetector();
+ if (undoDetector.detectUndo(transaction, cleanRevision, revision, featureDelta))
+ {
+ return null;
+ }
+ }
+ }
+
+ transaction.getCleanRevisions().put(object, cleanRevision);
+ object.cdoInternalSetRevision(revision);
+
+ transaction.registerDirty(object, featureDelta, cleanRevision);
+ changeState(object, CDOState.DIRTY);
+ return result;
}
}
/**
* @author Simon McDuff
*/
- private static final class RewriteTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
+ private final class RewriteTransition extends AbstractWriteTransition
{
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object featureDelta)
+ @Override
+ protected Object execute(InternalCDOObject object, InternalCDOTransaction transaction,
+ CDOFeatureDelta featureDelta, InternalCDORevision revision)
{
- InternalCDORevision revision = object.cdoRevision();
- if (!revision.isWritable())
+ Map<InternalCDOObject, InternalCDORevision> cleanRevisions = transaction.getCleanRevisions();
+ InternalCDORevision cleanRevision = cleanRevisions.get(object);
+
+ Object result = null;
+ if (featureDelta != null)
{
- throw new NoPermissionException(revision);
+ result = featureDelta.applyTo(revision);
+
+ if (!transaction.hasMultipleSavepoints())
+ {
+ CDOUndoDetector undoDetector = transaction.options().getUndoDetector();
+ if (undoDetector.detectUndo(transaction, cleanRevision, revision, featureDelta))
+ {
+ CDOID id = revision.getID();
+
+ InternalCDOSavepoint lastSavepoint = transaction.getLastSavepoint();
+ Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
+ InternalCDORevisionDelta revisionDelta = (InternalCDORevisionDelta)revisionDeltas.get(id);
+ if (revisionDelta != null)
+ {
+ Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = revisionDelta.getFeatureDeltaMap();
+ featureDeltas.remove(featureDelta.getFeature());
+
+ if (featureDeltas.isEmpty())
+ {
+ cleanRevisions.remove(object);
+ revisionDeltas.remove(id);
+ lastSavepoint.getDirtyObjects().remove(id);
+
+ object.cdoInternalSetRevision(cleanRevision);
+ changeState(object, CDOState.CLEAN);
+ }
+ }
+
+ if (revisionDeltas.isEmpty())
+ {
+ transaction.setDirty(false);
+ }
+
+ return result;
+ }
+ }
}
- InternalCDOTransaction transaction = object.cdoView().toTransaction();
- transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta);
+ transaction.registerFeatureDelta(object, featureDelta, cleanRevision);
+ return result;
}
}
@@ -995,7 +1115,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
{
newRevision = oldRevision.copy();
view.getSession().resolveAllElementProxies(newRevision);
- delta.apply(newRevision);
+ delta.applyTo(newRevision);
newRevision.setBranchPoint(target);
cache.addRevision(newRevision);
}
@@ -1020,9 +1140,9 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
newRevision = (InternalCDORevision)cache.getRevisionByVersion(newKey.getID(), newKey);
}
- object.cdoInternalSetRevision(newRevision);
if (newRevision != null)
{
+ object.cdoInternalSetRevision(newRevision);
changeState(object, CDOState.CLEAN);
object.cdoInternalPostLoad();
}
@@ -1056,7 +1176,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
/**
* @author Eike Stepper
- * @since 2.0
*/
private class ConflictTransition extends InvalidateTransition
{
@@ -1093,40 +1212,9 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
*/
private final class LoadTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
- private boolean forWrite;
-
- public LoadTransition(boolean forWrite)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object UNUSED)
{
- this.forWrite = forWrite;
- }
-
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object delta)
- {
- 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);
- changeState(object, CDOState.CLEAN);
- object.cdoInternalPostLoad();
- dispatchLoadNotification(object);
-
- if (forWrite)
- {
- INSTANCE.writeWithoutViewLock(object, (CDOFeatureDelta)delta);
- }
+ internalLoad(object, false);
}
}
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..018ad73d4e 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
@@ -36,6 +36,7 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.cdo.view.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
+import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
import org.eclipse.emf.internal.cdo.bundle.OM;
@@ -75,48 +76,19 @@ public final class CDOStoreImpl implements CDOStore
private InternalCDOView view;
- /**
- * @since 2.0
- */
public CDOStoreImpl(InternalCDOView view)
{
this.view = view;
}
- /**
- * @since 2.0
- */
public InternalCDOView getView()
{
return view;
}
/**
- * @since 2.0
+ * @category READ
*/
- public void setContainer(InternalEObject eObject, CDOResource newResource, InternalEObject newEContainer,
- int newContainerFeatureID)
- {
- synchronized (view)
- {
- InternalCDOObject cdoObject = getCDOObject(eObject);
- if (TRACER.isEnabled())
- {
- TRACER.format("setContainer({0}, {1}, {2}, {3})", cdoObject, newResource, newEContainer, newContainerFeatureID); //$NON-NLS-1$
- }
-
- Object newContainerID = newEContainer == null ? CDOID.NULL : cdoObject.cdoView().convertObjectToID(newEContainer,
- true);
- 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);
- }
- }
-
public InternalEObject getContainer(InternalEObject eObject)
{
synchronized (view)
@@ -127,12 +99,15 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("getContainer({0})", cdoObject); //$NON-NLS-1$
}
- InternalCDORevision revision = getRevisionForReading(cdoObject);
- return (InternalEObject)convertIDToObject(cdoObject.cdoView(), cdoObject,
- EcorePackage.eINSTANCE.eContainingFeature(), -1, revision.getContainerID());
+ InternalCDORevision revision = readRevision(cdoObject);
+ return (InternalEObject)convertIDToObject(view, cdoObject, EcorePackage.eINSTANCE.eContainingFeature(), -1,
+ revision.getContainerID());
}
}
+ /**
+ * @category READ
+ */
public int getContainingFeatureID(InternalEObject eObject)
{
synchronized (view)
@@ -143,13 +118,13 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("getContainingFeatureID({0})", cdoObject); //$NON-NLS-1$
}
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
return revision.getContainingFeatureID();
}
}
/**
- * @since 2.0
+ * @category READ
*/
public InternalEObject getResource(InternalEObject eObject)
{
@@ -161,17 +136,23 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("getResource({0})", cdoObject); //$NON-NLS-1$
}
- InternalCDORevision revision = getRevisionForReading(cdoObject);
- return (InternalEObject)convertIDToObject(cdoObject.cdoView(), cdoObject,
- EcorePackage.eINSTANCE.eContainingFeature(), -1, revision.getResourceID());
+ InternalCDORevision revision = readRevision(cdoObject);
+ return (InternalEObject)convertIDToObject(view, cdoObject, EcorePackage.eINSTANCE.eContainingFeature(), -1,
+ revision.getResourceID());
}
}
+ /**
+ * @category READ
+ */
public EStructuralFeature getContainingFeature(InternalEObject eObject)
{
throw new UnsupportedOperationException("Use getContainingFeatureID() instead"); //$NON-NLS-1$
}
+ /**
+ * @category READ
+ */
public Object get(InternalEObject eObject, EStructuralFeature feature, int index)
{
synchronized (view)
@@ -185,7 +166,7 @@ public final class CDOStoreImpl implements CDOStore
CDOFeatureAnalyzer featureAnalyzer = view.options().getFeatureAnalyzer();
featureAnalyzer.preTraverseFeature(cdoObject, feature, index);
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
Object value = revision.get(feature, index);
value = convertToEMF(eObject, revision, feature, index, value);
@@ -195,6 +176,9 @@ public final class CDOStoreImpl implements CDOStore
}
}
+ /**
+ * @category READ
+ */
public boolean isSet(InternalEObject eObject, EStructuralFeature feature)
{
synchronized (view)
@@ -205,7 +189,7 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("isSet({0}, {1})", cdoObject, feature); //$NON-NLS-1$
}
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
if (feature.isMany())
{
CDOList list = revision.getList(feature);
@@ -229,6 +213,9 @@ public final class CDOStoreImpl implements CDOStore
}
}
+ /**
+ * @category READ
+ */
public int size(InternalEObject eObject, EStructuralFeature feature)
{
synchronized (view)
@@ -239,11 +226,14 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("size({0}, {1})", cdoObject, feature); //$NON-NLS-1$
}
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
return revision.size(feature);
}
}
+ /**
+ * @category READ
+ */
public boolean isEmpty(InternalEObject eObject, EStructuralFeature feature)
{
synchronized (view)
@@ -254,11 +244,14 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("isEmpty({0}, {1})", cdoObject, feature); //$NON-NLS-1$
}
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
return revision.isEmpty(feature);
}
}
+ /**
+ * @category READ
+ */
public boolean contains(InternalEObject eObject, EStructuralFeature feature, Object value)
{
synchronized (view)
@@ -271,7 +264,7 @@ public final class CDOStoreImpl implements CDOStore
Object convertedValue = convertToCDO(cdoObject, feature, value);
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
boolean result = revision.contains(feature, convertedValue);
// Special handling of detached (TRANSIENT) objects, see bug 354395
@@ -284,6 +277,9 @@ public final class CDOStoreImpl implements CDOStore
}
}
+ /**
+ * @category READ
+ */
public int indexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
{
synchronized (view)
@@ -296,11 +292,14 @@ public final class CDOStoreImpl implements CDOStore
value = convertToCDO(cdoObject, feature, value);
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
return revision.indexOf(feature, value);
}
}
+ /**
+ * @category READ
+ */
public int lastIndexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
{
synchronized (view)
@@ -313,11 +312,14 @@ public final class CDOStoreImpl implements CDOStore
value = convertToCDO(cdoObject, feature, value);
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
return revision.lastIndexOf(feature, value);
}
}
+ /**
+ * @category READ
+ */
public int hashCode(InternalEObject eObject, EStructuralFeature feature)
{
synchronized (view)
@@ -328,11 +330,14 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("hashCode({0}, {1})", cdoObject, feature); //$NON-NLS-1$
}
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
return revision.hashCode(feature);
}
}
+ /**
+ * @category READ
+ */
public Object[] toArray(InternalEObject eObject, EStructuralFeature feature)
{
synchronized (view)
@@ -343,7 +348,7 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("toArray({0}, {1})", cdoObject, feature); //$NON-NLS-1$
}
- InternalCDORevision revision = getRevisionForReading(cdoObject);
+ InternalCDORevision revision = readRevision(cdoObject);
Object[] result = revision.toArray(feature);
for (int i = 0; i < result.length; i++)
{
@@ -364,6 +369,9 @@ public final class CDOStoreImpl implements CDOStore
}
}
+ /**
+ * @category READ
+ */
@SuppressWarnings("unchecked")
public <T> T[] toArray(InternalEObject eObject, EStructuralFeature feature, T[] a)
{
@@ -387,6 +395,31 @@ public final class CDOStoreImpl implements CDOStore
}
}
+ /**
+ * @category WRITE
+ */
+ public void setContainer(InternalEObject eObject, CDOResource newResource, InternalEObject newEContainer,
+ int newContainerFeatureID)
+ {
+ synchronized (view)
+ {
+ InternalCDOObject cdoObject = getCDOObject(eObject);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("setContainer({0}, {1}, {2}, {3})", cdoObject, newResource, newEContainer, newContainerFeatureID); //$NON-NLS-1$
+ }
+
+ Object newContainerID = newEContainer == null ? CDOID.NULL : view.convertObjectToID(newEContainer, true);
+ CDOID newResourceID = newResource == null ? CDOID.NULL : newResource.cdoID();
+
+ CDOFeatureDelta delta = new CDOContainerFeatureDeltaImpl(newResourceID, newContainerID, newContainerFeatureID);
+ writeRevision(cdoObject, delta);
+ }
+ }
+
+ /**
+ * @category WRITE RESULT
+ */
public Object set(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
{
synchronized (view)
@@ -399,18 +432,21 @@ public final class CDOStoreImpl implements CDOStore
value = convertToCDO(cdoObject, feature, value);
- InternalCDORevision oldRevision = getRevisionForReading(cdoObject);
+ // TODO: Use writeRevision() result!!
+ InternalCDORevision oldRevision = readRevision(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);
+ writeRevision(cdoObject, delta);
return oldValue;
}
}
+ /**
+ * @category WRITE
+ */
public void unset(InternalEObject eObject, EStructuralFeature feature)
{
synchronized (view)
@@ -422,31 +458,13 @@ 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);
- }
- }
+ writeRevision(cdoObject, delta);
}
}
+ /**
+ * @category WRITE
+ */
public void add(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
{
synchronized (view)
@@ -457,21 +475,16 @@ 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");
- }
+ value = convertToCDO(cdoObject, feature, value);
CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- revision.add(feature, index, value);
+ writeRevision(cdoObject, delta);
}
}
+ /**
+ * @category WRITE RESULT
+ */
public Object remove(InternalEObject eObject, EStructuralFeature feature, int index)
{
synchronized (view)
@@ -482,75 +495,50 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("remove({0}, {1}, {2})", cdoObject, feature, index); //$NON-NLS-1$
}
- Object oldValue = null;
-
- // 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);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
-
- oldValue = revision.get(feature, index);
-
- try
- {
- oldValue = convertToEMF(eObject, revision, feature, index, oldValue);
- }
- finally
- {
- revision.remove(feature, index);
- }
+ Object oldValue = getOldListValue(eObject, cdoObject, feature, index);
+ removeElement(cdoObject, feature, index);
return oldValue;
}
}
- public void clear(InternalEObject eObject, EStructuralFeature feature)
+ /**
+ * @category WRITE RESULT
+ */
+ public Object move(InternalEObject eObject, EStructuralFeature feature, int target, int source)
{
synchronized (view)
{
InternalCDOObject cdoObject = getCDOObject(eObject);
if (TRACER.isEnabled())
{
- TRACER.format("clear({0}, {1})", cdoObject, feature); //$NON-NLS-1$
+ TRACER.format("move({0}, {1}, {2}, {3})", cdoObject, feature, target, source); //$NON-NLS-1$
}
- CDOFeatureDelta delta = new CDOClearFeatureDeltaImpl(feature);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- // TODO Handle containment remove!!!
- revision.clear(feature);
+ Object oldValue = getOldListValue(eObject, cdoObject, feature, source);
+
+ CDOFeatureDelta delta = new CDOMoveFeatureDeltaImpl(feature, target, source);
+ writeRevision(cdoObject, delta);
+
+ return oldValue;
}
}
- public Object move(InternalEObject eObject, EStructuralFeature feature, int target, int source)
+ /**
+ * @category WRITE
+ */
+ public void clear(InternalEObject eObject, EStructuralFeature feature)
{
synchronized (view)
{
InternalCDOObject cdoObject = getCDOObject(eObject);
if (TRACER.isEnabled())
{
- TRACER.format("move({0}, {1}, {2}, {3})", cdoObject, feature, target, source); //$NON-NLS-1$
+ TRACER.format("clear({0}, {1})", cdoObject, feature); //$NON-NLS-1$
}
- CDOFeatureDelta delta = new CDOMoveFeatureDeltaImpl(feature, target, source);
- InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- Object result = revision.move(feature, target, source);
-
- result = convertToEMF(eObject, revision, feature, target, result);
- return result;
+ CDOFeatureDelta delta = new CDOClearFeatureDeltaImpl(feature);
+ writeRevision(cdoObject, delta);
}
}
@@ -694,7 +682,8 @@ public final class CDOStoreImpl implements CDOStore
{
if (value instanceof CDOID)
{
- value = view.options().getStaleReferencePolicy().processStaleReference(eObject, feature, index, ex.getID());
+ CDOStaleReferencePolicy staleReferencePolicy = view.options().getStaleReferencePolicy();
+ value = staleReferencePolicy.processStaleReference(eObject, feature, index, ex.getID());
}
}
@@ -716,21 +705,31 @@ public final class CDOStoreImpl implements CDOStore
return object;
}
- private static InternalCDORevision getRevisionForReading(InternalCDOObject cdoObject)
+ private Object getOldListValue(InternalEObject eObject, InternalCDOObject cdoObject, EStructuralFeature feature,
+ int index)
{
- CDOStateMachine.INSTANCE.read(cdoObject);
- return getRevision(cdoObject);
- }
+ if (!feature.isMany())
+ {
+ throw new UnsupportedOperationException("Not supported for single-valued features");
+ }
- private static InternalCDORevision getRevisionForWriting(InternalCDOObject cdoObject, CDOFeatureDelta delta)
- {
- CDOStateMachine.INSTANCE.write(cdoObject, delta);
- return getRevision(cdoObject);
+ // Bug 293283 / Bug 314387
+ InternalCDORevision revision = readRevision(cdoObject);
+ CDOList list = revision.getList(feature);
+ int size = list.size();
+ if (index < 0 || size <= index)
+ {
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+ }
+
+ Object oldValue = revision.get(feature, index);
+ oldValue = convertToEMF(eObject, revision, feature, index, oldValue);
+ return oldValue;
}
- private static InternalCDORevision getRevision(InternalCDOObject cdoObject)
+ private static InternalCDORevision readRevision(InternalCDOObject cdoObject)
{
- InternalCDORevision revision = cdoObject.cdoRevision();
+ InternalCDORevision revision = CDOStateMachine.INSTANCE.read(cdoObject);
if (revision == null)
{
throw new IllegalStateException("revision == null");
@@ -738,4 +737,15 @@ public final class CDOStoreImpl implements CDOStore
return revision;
}
+
+ private static Object writeRevision(InternalCDOObject cdoObject, CDOFeatureDelta delta)
+ {
+ return CDOStateMachine.INSTANCE.write(cdoObject, delta);
+ }
+
+ public static void removeElement(InternalCDOObject cdoObject, EStructuralFeature feature, int index)
+ {
+ CDOFeatureDelta delta = new CDORemoveFeatureDeltaImpl(feature, index);
+ writeRevision(cdoObject, delta);
+ }
}
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 2dff05fd54..ac55e7fc60 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
@@ -1712,7 +1712,10 @@ public class CDOViewImpl extends AbstractCDOView
}
catch (Exception ex)
{
- OM.LOG.error(ex);
+ if (isActive())
+ {
+ OM.LOG.error(ex);
+ }
}
finally
{
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 0814783223..75c3cb898b 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
@@ -168,7 +168,7 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv
{
InternalCDORevision newLocalRevision = cleanRevision.copy();
newLocalRevision.setVersion(newVersion);
- resultDelta.apply(newLocalRevision);
+ resultDelta.applyTo(newLocalRevision);
return newLocalRevision;
}
@@ -180,7 +180,7 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv
{
InternalCDORevision newCleanRevision = cleanRevision.copy();
newCleanRevision.setVersion(newVersion);
- remoteDelta.apply(newCleanRevision);
+ remoteDelta.applyTo(newCleanRevision);
return newCleanRevision;
}
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..eda49dcb33 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
@@ -48,6 +48,11 @@ public interface InternalCDOTransaction extends CDOTransaction, InternalCDOUserT
public InternalCDOCommitContext createCommitContext();
/**
+ * @since 4.3
+ */
+ public boolean hasMultipleSavepoints();
+
+ /**
* @since 3.0
*/
public InternalCDOSavepoint setSavepoint();
@@ -101,8 +106,19 @@ public interface InternalCDOTransaction extends CDOTransaction, InternalCDOUserT
public void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta);
+ /**
+ * @since 4.3
+ */
+ public void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta, InternalCDORevision cleanRevision);
+
public void registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta);
+ /**
+ * @since 4.3
+ */
+ public void registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta,
+ InternalCDORevision cleanRevision);
+
public void registerRevisionDelta(CDORevisionDelta revisionDelta);
/**

Back to the top