Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java')
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java1102
1 files changed, 551 insertions, 551 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
index bd5b0ba57e..de4a5c3859 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
@@ -1,551 +1,551 @@
-/*
- * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Eike Stepper - initial API and implementation
- * Simon McDuff - bug 201266
- * Simon McDuff - bug 204890
- */
-package org.eclipse.emf.cdo.internal.common.revision.delta;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOWithID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDORevisable;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionData;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
-import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException;
-import org.eclipse.emf.cdo.spi.common.revision.CDOReferenceAdjuster;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-
-import org.eclipse.emf.common.util.ECollections;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.change.ListChange;
-import org.eclipse.emf.ecore.change.util.ListDifferenceAnalyzer;
-
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- */
-public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
-{
- private EClass eClass;
-
- private CDOID id;
-
- private CDOBranch branch;
-
- private int version;
-
- private CDORevisable target;
-
- private Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = new HashMap<EStructuralFeature, CDOFeatureDelta>();
-
- public CDORevisionDeltaImpl(CDORevision revision)
- {
- eClass = revision.getEClass();
- id = revision.getID();
- branch = revision.getBranch();
- version = revision.getVersion();
- }
-
- public CDORevisionDeltaImpl(CDORevisionDelta revisionDelta, boolean copyFeatureDeltas)
- {
- eClass = revisionDelta.getEClass();
- id = revisionDelta.getID();
- branch = revisionDelta.getBranch();
- version = revisionDelta.getVersion();
-
- if (copyFeatureDeltas)
- {
- for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas())
- {
- addFeatureDelta(((InternalCDOFeatureDelta)delta).copy());
- }
- }
- }
-
- public CDORevisionDeltaImpl(CDORevision sourceRevision, CDORevision targetRevision)
- {
- if (sourceRevision.getEClass() != targetRevision.getEClass())
- {
- throw new IllegalArgumentException();
- }
-
- eClass = sourceRevision.getEClass();
- id = sourceRevision.getID();
- branch = sourceRevision.getBranch();
- version = sourceRevision.getVersion();
- target = CDORevisionUtil.copyRevisable(targetRevision);
-
- compare(sourceRevision, targetRevision);
-
- CDORevisionData originData = sourceRevision.data();
- CDORevisionData dirtyData = targetRevision.data();
-
- Object dirtyContainerID = dirtyData.getContainerID();
- if (dirtyContainerID instanceof CDOWithID)
- {
- dirtyContainerID = ((CDOWithID)dirtyContainerID).cdoID();
- }
-
- if (!compare(originData.getContainerID(), dirtyContainerID)
- || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID())
- || !compare(originData.getResourceID(), dirtyData.getResourceID()))
- {
- addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getResourceID(), dirtyContainerID,
- dirtyData.getContainingFeatureID()));
- }
- }
-
- public CDORevisionDeltaImpl(CDODataInput in) throws IOException
- {
- eClass = (EClass)in.readCDOClassifierRefAndResolve();
- id = in.readCDOID();
- branch = in.readCDOBranch();
- version = in.readInt();
- if (version < 0)
- {
- version = -version;
- target = in.readCDORevisable();
- }
-
- int size = in.readInt();
- for (int i = 0; i < size; i++)
- {
- CDOFeatureDelta featureDelta = in.readCDOFeatureDelta(eClass);
- featureDeltas.put(featureDelta.getFeature(), featureDelta);
- }
- }
-
- public void write(CDODataOutput out) throws IOException
- {
- out.writeCDOClassifierRef(eClass);
- out.writeCDOID(id);
- out.writeCDOBranch(branch);
- if (target == null)
- {
- out.writeInt(version);
- }
- else
- {
- out.writeInt(-version);
- out.writeCDORevisable(target);
- }
-
- out.writeInt(featureDeltas.size());
- for (CDOFeatureDelta featureDelta : featureDeltas.values())
- {
- out.writeCDOFeatureDelta(eClass, featureDelta);
- }
- }
-
- public EClass getEClass()
- {
- return eClass;
- }
-
- public CDOID getID()
- {
- return id;
- }
-
- public CDOBranch getBranch()
- {
- return branch;
- }
-
- public void setBranch(CDOBranch branch)
- {
- this.branch = branch;
- }
-
- public int getVersion()
- {
- return version;
- }
-
- public void setVersion(int version)
- {
- this.version = version;
- }
-
- public CDORevisable getTarget()
- {
- return target;
- }
-
- public void setTarget(CDORevisable target)
- {
- this.target = target;
- }
-
- public boolean isEmpty()
- {
- return featureDeltas.isEmpty();
- }
-
- public CDORevisionDelta copy()
- {
- return new CDORevisionDeltaImpl(this, true);
- }
-
- public Map<EStructuralFeature, CDOFeatureDelta> getFeatureDeltaMap()
- {
- return featureDeltas;
- }
-
- public CDOFeatureDelta getFeatureDelta(EStructuralFeature feature)
- {
- return featureDeltas.get(feature);
- }
-
- public List<CDOFeatureDelta> getFeatureDeltas()
- {
- return new ArrayList<CDOFeatureDelta>(featureDeltas.values());
- }
-
- public void apply(CDORevision revision)
- {
- for (CDOFeatureDelta featureDelta : featureDeltas.values())
- {
- ((CDOFeatureDeltaImpl)featureDelta).apply(revision);
- }
- }
-
- public void addFeatureDelta(CDOFeatureDelta delta)
- {
- if (delta instanceof CDOListFeatureDelta)
- {
- CDOListFeatureDelta deltas = (CDOListFeatureDelta)delta;
- for (CDOFeatureDelta childDelta : deltas.getListChanges())
- {
- addFeatureDelta(childDelta);
- }
- }
- else
- {
- addSingleFeatureDelta(delta);
- }
- }
-
- private void addSingleFeatureDelta(CDOFeatureDelta delta)
- {
- EStructuralFeature feature = delta.getFeature();
- if (feature.isMany())
- {
- CDOListFeatureDeltaImpl listDelta = (CDOListFeatureDeltaImpl)featureDeltas.get(feature);
- if (listDelta == null)
- {
- listDelta = new CDOListFeatureDeltaImpl(feature);
- featureDeltas.put(listDelta.getFeature(), listDelta);
- }
-
- // Remove all previous changes
- if (delta instanceof CDOClearFeatureDelta || delta instanceof CDOUnsetFeatureDelta)
- {
- listDelta.getListChanges().clear();
- }
-
- listDelta.add(delta);
- }
- else
- {
- featureDeltas.put(feature, delta);
- }
- }
-
- public boolean adjustReferences(CDOReferenceAdjuster referenceAdjuster)
- {
- boolean changed = false;
- for (CDOFeatureDelta featureDelta : featureDeltas.values())
- {
- changed |= ((CDOFeatureDeltaImpl)featureDelta).adjustReferences(referenceAdjuster);
- }
-
- return changed;
- }
-
- public void accept(CDOFeatureDeltaVisitor visitor)
- {
- for (CDOFeatureDelta featureDelta : featureDeltas.values())
- {
- ((CDOFeatureDeltaImpl)featureDelta).accept(visitor);
- }
- }
-
- private void compare(CDORevision originRevision, CDORevision dirtyRevision)
- {
- CDORevisionData originData = originRevision.data();
- CDORevisionData dirtyData = dirtyRevision.data();
-
- for (final EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
- {
- if (feature.isMany())
- {
- if (originData.size(feature) > 0 && dirtyData.size(feature) == 0)
- {
- addFeatureDelta(new CDOClearFeatureDeltaImpl(feature));
- }
- else
- {
- CDOListFeatureDelta listFeatureDelta = new CDOListFeatureDeltaImpl(feature);
- final List<CDOFeatureDelta> changes = listFeatureDelta.getListChanges();
-
- ListDifferenceAnalyzer analyzer = new ListDifferenceAnalyzer()
- {
- @Override
- public void analyzeLists(EList<Object> oldList, EList<?> newList, EList<ListChange> listChanges)
- {
- checkNoProxies(oldList);
- checkNoProxies(newList);
- super.analyzeLists(oldList, newList, listChanges);
- }
-
- @Override
- protected void createAddListChange(EList<Object> oldList, EList<ListChange> listChanges, Object value,
- int index)
- {
- CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
- changes.add(delta);
- oldList.add(index, value);
- }
-
- @Override
- protected void createRemoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
- int index)
- {
- CDORemoveFeatureDeltaImpl delta = new CDORemoveFeatureDeltaImpl(feature, index);
- // fix until ListDifferenceAnalyzer delivers the correct value (bug #308618).
- delta.setValue(oldList.get(index));
- changes.add(delta);
- oldList.remove(index);
- }
-
- @Override
- protected void createMoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
- int index, int toIndex)
- {
- CDOMoveFeatureDeltaImpl delta = new CDOMoveFeatureDeltaImpl(feature, toIndex, index);
- // fix until ListDifferenceAnalyzer delivers the correct value (same problem as bug #308618).
- delta.setValue(oldList.get(index));
- changes.add(delta);
- oldList.move(toIndex, index);
- }
-
- private void checkNoProxies(EList<?> list)
- {
- for (Object element : list)
- {
- if (element instanceof CDOElementProxy)
- {
- throw new PartialCollectionLoadingNotSupportedException("List contains proxy elements");
- }
- }
- }
- };
-
- CDOList originList = ((InternalCDORevision)originRevision).getList(feature);
- CDOList dirtyList = ((InternalCDORevision)dirtyRevision).getList(feature);
-
- analyzer.analyzeLists(originList, dirtyList, new NOOPList());
- if (!changes.isEmpty())
- {
- featureDeltas.put(feature, listFeatureDelta);
- }
- }
- }
- else
- {
- Object originValue = originData.get(feature, 0);
- Object dirtyValue = dirtyData.get(feature, 0);
- if (!compare(originValue, dirtyValue))
- {
- if (dirtyValue == null)
- {
- addFeatureDelta(new CDOUnsetFeatureDeltaImpl(feature));
- }
- else
- {
- addFeatureDelta(new CDOSetFeatureDeltaImpl(feature, 0, dirtyValue, originValue));
- }
- }
- }
- }
- }
-
- private boolean compare(Object originValue, Object dirtyValue)
- {
- return originValue == dirtyValue || originValue != null && dirtyValue != null && originValue.equals(dirtyValue);
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("CDORevisionDelta[{0}@{1}:{2}v{3} --> {4}]", eClass.getName(), id, branch.getID(),
- version, featureDeltas.values());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class NOOPList implements EList<ListChange>
- {
- private static final EList<ListChange> LIST = ECollections.emptyEList();
-
- public NOOPList()
- {
- }
-
- public int size()
- {
- return 0;
- }
-
- public boolean isEmpty()
- {
- return true;
- }
-
- public boolean contains(Object o)
- {
- return false;
- }
-
- public Iterator<ListChange> iterator()
- {
- return LIST.iterator();
- }
-
- public Object[] toArray()
- {
- return LIST.toArray();
- }
-
- public <T> T[] toArray(T[] a)
- {
- return LIST.toArray(a);
- }
-
- public boolean add(ListChange o)
- {
- return false;
- }
-
- public boolean remove(Object o)
- {
- return false;
- }
-
- public boolean containsAll(Collection<?> c)
- {
- return false;
- }
-
- public boolean addAll(Collection<? extends ListChange> c)
- {
- return false;
- }
-
- public boolean addAll(int index, Collection<? extends ListChange> c)
- {
- return false;
- }
-
- public boolean removeAll(Collection<?> c)
- {
- return false;
- }
-
- public boolean retainAll(Collection<?> c)
- {
- return false;
- }
-
- public void clear()
- {
- }
-
- public ListChange get(int index)
- {
- return LIST.get(index);
- }
-
- public ListChange set(int index, ListChange element)
- {
- return null;
- }
-
- public void add(int index, ListChange element)
- {
- }
-
- public ListChange remove(int index)
- {
- return null;
- }
-
- public int indexOf(Object o)
- {
- return LIST.indexOf(o);
- }
-
- public int lastIndexOf(Object o)
- {
- return LIST.lastIndexOf(o);
- }
-
- public ListIterator<ListChange> listIterator()
- {
- return LIST.listIterator();
- }
-
- public ListIterator<ListChange> listIterator(int index)
- {
- return LIST.listIterator(index);
- }
-
- public List<ListChange> subList(int fromIndex, int toIndex)
- {
- return LIST.subList(fromIndex, toIndex);
- }
-
- public void move(int newPosition, ListChange object)
- {
- }
-
- public ListChange move(int newPosition, int oldPosition)
- {
- return null;
- }
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 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 - bug 201266
+ * Simon McDuff - bug 204890
+ */
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOWithID;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.protocol.CDODataInput;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevisable;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionData;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException;
+import org.eclipse.emf.cdo.spi.common.revision.CDOReferenceAdjuster;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+
+import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.change.ListChange;
+import org.eclipse.emf.ecore.change.util.ListDifferenceAnalyzer;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
+{
+ private EClass eClass;
+
+ private CDOID id;
+
+ private CDOBranch branch;
+
+ private int version;
+
+ private CDORevisable target;
+
+ private Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = new HashMap<EStructuralFeature, CDOFeatureDelta>();
+
+ public CDORevisionDeltaImpl(CDORevision revision)
+ {
+ eClass = revision.getEClass();
+ id = revision.getID();
+ branch = revision.getBranch();
+ version = revision.getVersion();
+ }
+
+ public CDORevisionDeltaImpl(CDORevisionDelta revisionDelta, boolean copyFeatureDeltas)
+ {
+ eClass = revisionDelta.getEClass();
+ id = revisionDelta.getID();
+ branch = revisionDelta.getBranch();
+ version = revisionDelta.getVersion();
+
+ if (copyFeatureDeltas)
+ {
+ for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas())
+ {
+ addFeatureDelta(((InternalCDOFeatureDelta)delta).copy());
+ }
+ }
+ }
+
+ public CDORevisionDeltaImpl(CDORevision sourceRevision, CDORevision targetRevision)
+ {
+ if (sourceRevision.getEClass() != targetRevision.getEClass())
+ {
+ throw new IllegalArgumentException();
+ }
+
+ eClass = sourceRevision.getEClass();
+ id = sourceRevision.getID();
+ branch = sourceRevision.getBranch();
+ version = sourceRevision.getVersion();
+ target = CDORevisionUtil.copyRevisable(targetRevision);
+
+ compare(sourceRevision, targetRevision);
+
+ CDORevisionData originData = sourceRevision.data();
+ CDORevisionData dirtyData = targetRevision.data();
+
+ Object dirtyContainerID = dirtyData.getContainerID();
+ if (dirtyContainerID instanceof CDOWithID)
+ {
+ dirtyContainerID = ((CDOWithID)dirtyContainerID).cdoID();
+ }
+
+ if (!compare(originData.getContainerID(), dirtyContainerID)
+ || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID())
+ || !compare(originData.getResourceID(), dirtyData.getResourceID()))
+ {
+ addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getResourceID(), dirtyContainerID,
+ dirtyData.getContainingFeatureID()));
+ }
+ }
+
+ public CDORevisionDeltaImpl(CDODataInput in) throws IOException
+ {
+ eClass = (EClass)in.readCDOClassifierRefAndResolve();
+ id = in.readCDOID();
+ branch = in.readCDOBranch();
+ version = in.readInt();
+ if (version < 0)
+ {
+ version = -version;
+ target = in.readCDORevisable();
+ }
+
+ int size = in.readInt();
+ for (int i = 0; i < size; i++)
+ {
+ CDOFeatureDelta featureDelta = in.readCDOFeatureDelta(eClass);
+ featureDeltas.put(featureDelta.getFeature(), featureDelta);
+ }
+ }
+
+ public void write(CDODataOutput out) throws IOException
+ {
+ out.writeCDOClassifierRef(eClass);
+ out.writeCDOID(id);
+ out.writeCDOBranch(branch);
+ if (target == null)
+ {
+ out.writeInt(version);
+ }
+ else
+ {
+ out.writeInt(-version);
+ out.writeCDORevisable(target);
+ }
+
+ out.writeInt(featureDeltas.size());
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ out.writeCDOFeatureDelta(eClass, featureDelta);
+ }
+ }
+
+ public EClass getEClass()
+ {
+ return eClass;
+ }
+
+ public CDOID getID()
+ {
+ return id;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return branch;
+ }
+
+ public void setBranch(CDOBranch branch)
+ {
+ this.branch = branch;
+ }
+
+ public int getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion(int version)
+ {
+ this.version = version;
+ }
+
+ public CDORevisable getTarget()
+ {
+ return target;
+ }
+
+ public void setTarget(CDORevisable target)
+ {
+ this.target = target;
+ }
+
+ public boolean isEmpty()
+ {
+ return featureDeltas.isEmpty();
+ }
+
+ public CDORevisionDelta copy()
+ {
+ return new CDORevisionDeltaImpl(this, true);
+ }
+
+ public Map<EStructuralFeature, CDOFeatureDelta> getFeatureDeltaMap()
+ {
+ return featureDeltas;
+ }
+
+ public CDOFeatureDelta getFeatureDelta(EStructuralFeature feature)
+ {
+ return featureDeltas.get(feature);
+ }
+
+ public List<CDOFeatureDelta> getFeatureDeltas()
+ {
+ return new ArrayList<CDOFeatureDelta>(featureDeltas.values());
+ }
+
+ public void apply(CDORevision revision)
+ {
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).apply(revision);
+ }
+ }
+
+ public void addFeatureDelta(CDOFeatureDelta delta)
+ {
+ if (delta instanceof CDOListFeatureDelta)
+ {
+ CDOListFeatureDelta deltas = (CDOListFeatureDelta)delta;
+ for (CDOFeatureDelta childDelta : deltas.getListChanges())
+ {
+ addFeatureDelta(childDelta);
+ }
+ }
+ else
+ {
+ addSingleFeatureDelta(delta);
+ }
+ }
+
+ private void addSingleFeatureDelta(CDOFeatureDelta delta)
+ {
+ EStructuralFeature feature = delta.getFeature();
+ if (feature.isMany())
+ {
+ CDOListFeatureDeltaImpl listDelta = (CDOListFeatureDeltaImpl)featureDeltas.get(feature);
+ if (listDelta == null)
+ {
+ listDelta = new CDOListFeatureDeltaImpl(feature);
+ featureDeltas.put(listDelta.getFeature(), listDelta);
+ }
+
+ // Remove all previous changes
+ if (delta instanceof CDOClearFeatureDelta || delta instanceof CDOUnsetFeatureDelta)
+ {
+ listDelta.getListChanges().clear();
+ }
+
+ listDelta.add(delta);
+ }
+ else
+ {
+ featureDeltas.put(feature, delta);
+ }
+ }
+
+ public boolean adjustReferences(CDOReferenceAdjuster referenceAdjuster)
+ {
+ boolean changed = false;
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ changed |= ((CDOFeatureDeltaImpl)featureDelta).adjustReferences(referenceAdjuster);
+ }
+
+ return changed;
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).accept(visitor);
+ }
+ }
+
+ private void compare(CDORevision originRevision, CDORevision dirtyRevision)
+ {
+ CDORevisionData originData = originRevision.data();
+ CDORevisionData dirtyData = dirtyRevision.data();
+
+ for (final EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
+ {
+ if (feature.isMany())
+ {
+ if (originData.size(feature) > 0 && dirtyData.size(feature) == 0)
+ {
+ addFeatureDelta(new CDOClearFeatureDeltaImpl(feature));
+ }
+ else
+ {
+ CDOListFeatureDelta listFeatureDelta = new CDOListFeatureDeltaImpl(feature);
+ final List<CDOFeatureDelta> changes = listFeatureDelta.getListChanges();
+
+ ListDifferenceAnalyzer analyzer = new ListDifferenceAnalyzer()
+ {
+ @Override
+ public void analyzeLists(EList<Object> oldList, EList<?> newList, EList<ListChange> listChanges)
+ {
+ checkNoProxies(oldList);
+ checkNoProxies(newList);
+ super.analyzeLists(oldList, newList, listChanges);
+ }
+
+ @Override
+ protected void createAddListChange(EList<Object> oldList, EList<ListChange> listChanges, Object value,
+ int index)
+ {
+ CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
+ changes.add(delta);
+ oldList.add(index, value);
+ }
+
+ @Override
+ protected void createRemoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
+ int index)
+ {
+ CDORemoveFeatureDeltaImpl delta = new CDORemoveFeatureDeltaImpl(feature, index);
+ // fix until ListDifferenceAnalyzer delivers the correct value (bug #308618).
+ delta.setValue(oldList.get(index));
+ changes.add(delta);
+ oldList.remove(index);
+ }
+
+ @Override
+ protected void createMoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
+ int index, int toIndex)
+ {
+ CDOMoveFeatureDeltaImpl delta = new CDOMoveFeatureDeltaImpl(feature, toIndex, index);
+ // fix until ListDifferenceAnalyzer delivers the correct value (same problem as bug #308618).
+ delta.setValue(oldList.get(index));
+ changes.add(delta);
+ oldList.move(toIndex, index);
+ }
+
+ private void checkNoProxies(EList<?> list)
+ {
+ for (Object element : list)
+ {
+ if (element instanceof CDOElementProxy)
+ {
+ throw new PartialCollectionLoadingNotSupportedException("List contains proxy elements");
+ }
+ }
+ }
+ };
+
+ CDOList originList = ((InternalCDORevision)originRevision).getList(feature);
+ CDOList dirtyList = ((InternalCDORevision)dirtyRevision).getList(feature);
+
+ analyzer.analyzeLists(originList, dirtyList, new NOOPList());
+ if (!changes.isEmpty())
+ {
+ featureDeltas.put(feature, listFeatureDelta);
+ }
+ }
+ }
+ else
+ {
+ Object originValue = originData.get(feature, 0);
+ Object dirtyValue = dirtyData.get(feature, 0);
+ if (!compare(originValue, dirtyValue))
+ {
+ if (dirtyValue == null)
+ {
+ addFeatureDelta(new CDOUnsetFeatureDeltaImpl(feature));
+ }
+ else
+ {
+ addFeatureDelta(new CDOSetFeatureDeltaImpl(feature, 0, dirtyValue, originValue));
+ }
+ }
+ }
+ }
+ }
+
+ private boolean compare(Object originValue, Object dirtyValue)
+ {
+ return originValue == dirtyValue || originValue != null && dirtyValue != null && originValue.equals(dirtyValue);
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("CDORevisionDelta[{0}@{1}:{2}v{3} --> {4}]", eClass.getName(), id, branch.getID(),
+ version, featureDeltas.values());
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class NOOPList implements EList<ListChange>
+ {
+ private static final EList<ListChange> LIST = ECollections.emptyEList();
+
+ public NOOPList()
+ {
+ }
+
+ public int size()
+ {
+ return 0;
+ }
+
+ public boolean isEmpty()
+ {
+ return true;
+ }
+
+ public boolean contains(Object o)
+ {
+ return false;
+ }
+
+ public Iterator<ListChange> iterator()
+ {
+ return LIST.iterator();
+ }
+
+ public Object[] toArray()
+ {
+ return LIST.toArray();
+ }
+
+ public <T> T[] toArray(T[] a)
+ {
+ return LIST.toArray(a);
+ }
+
+ public boolean add(ListChange o)
+ {
+ return false;
+ }
+
+ public boolean remove(Object o)
+ {
+ return false;
+ }
+
+ public boolean containsAll(Collection<?> c)
+ {
+ return false;
+ }
+
+ public boolean addAll(Collection<? extends ListChange> c)
+ {
+ return false;
+ }
+
+ public boolean addAll(int index, Collection<? extends ListChange> c)
+ {
+ return false;
+ }
+
+ public boolean removeAll(Collection<?> c)
+ {
+ return false;
+ }
+
+ public boolean retainAll(Collection<?> c)
+ {
+ return false;
+ }
+
+ public void clear()
+ {
+ }
+
+ public ListChange get(int index)
+ {
+ return LIST.get(index);
+ }
+
+ public ListChange set(int index, ListChange element)
+ {
+ return null;
+ }
+
+ public void add(int index, ListChange element)
+ {
+ }
+
+ public ListChange remove(int index)
+ {
+ return null;
+ }
+
+ public int indexOf(Object o)
+ {
+ return LIST.indexOf(o);
+ }
+
+ public int lastIndexOf(Object o)
+ {
+ return LIST.lastIndexOf(o);
+ }
+
+ public ListIterator<ListChange> listIterator()
+ {
+ return LIST.listIterator();
+ }
+
+ public ListIterator<ListChange> listIterator(int index)
+ {
+ return LIST.listIterator(index);
+ }
+
+ public List<ListChange> subList(int fromIndex, int toIndex)
+ {
+ return LIST.subList(fromIndex, toIndex);
+ }
+
+ public void move(int newPosition, ListChange object)
+ {
+ }
+
+ public ListChange move(int newPosition, int oldPosition)
+ {
+ return null;
+ }
+ }
+}

Back to the top