diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java')
-rw-r--r-- | plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java index f65c28f02d..433d4c50b4 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java @@ -10,15 +10,19 @@ * Simon McDuff - bug 201266 * Simon McDuff - bug 212958 * Simon McDuff - bug 213402 + * Caspar De Groot - bug 341081 */ package org.eclipse.emf.cdo.internal.common.revision; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDTemp; import org.eclipse.emf.cdo.common.model.CDOModelUtil; import org.eclipse.emf.cdo.common.model.CDOType; import org.eclipse.emf.cdo.spi.common.revision.BaseCDORevision; import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EStructuralFeature; @@ -30,6 +34,8 @@ public class CDORevisionImpl extends BaseCDORevision { private Object[] values; + private boolean frozen; + public CDORevisionImpl(EClass eClass) { super(eClass); @@ -80,6 +86,53 @@ public class CDORevisionImpl extends BaseCDORevision @Override protected void setValue(int featureIndex, Object value) { + checkFrozen(featureIndex, value); values[featureIndex] = value; } + + public void freeze() + { + frozen = true; + + EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(getEClass()); + for (int i = 0; i < features.length; i++) + { + EStructuralFeature feature = features[i]; + if (feature.isMany()) + { + InternalCDOList list = (InternalCDOList)values[i]; + if (list != null) + { + list.freeze(); + } + } + } + } + + private void checkFrozen(int featureIndex, Object value) + { + if (frozen) + { + Object oldValue = values[featureIndex]; + + // Exception 1: Setting an empty list as the value for an isMany feature, is + // allowed if the old value is null. This is a case of lazy initialization. + boolean newIsEmptyList = value instanceof EList<?> && ((EList<?>)value).size() == 0; + if (newIsEmptyList && oldValue == null) + { + return; + } + + // Exception 2a: Replacing a temp ID with a regular ID is allowed (happens during + // postCommit of new objects) + // Exception 2b: Replacing a temp ID with another temp ID is also allowed (happens + // when changes are imported in a PushTx). + if (oldValue instanceof CDOIDTemp && value instanceof CDOID) + { + return; + } + + throw new IllegalStateException("Cannot modify a frozen revision"); + } + } } |