diff options
Diffstat (limited to 'plugins')
59 files changed, 3227 insertions, 2000 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOFeatureDelta.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOFeatureDelta.java index 8ae762348f..96a44ab56f 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOFeatureDelta.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOFeatureDelta.java @@ -53,8 +53,17 @@ public interface CDOFeatureDelta */ public EStructuralFeature getFeature(); + /** + * @deprecated As of 4.3 use {@link #applyTo(CDORevision)}. + */ + @Deprecated public void apply(CDORevision revision); + /** + * @since 4.3 + */ + public Object applyTo(CDORevision revision); + public void accept(CDOFeatureDeltaVisitor visitor); /** diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java index a05bbe6be4..d8e4e7c300 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java @@ -83,13 +83,21 @@ public interface CDORevisionDelta extends CDORevisionKey public List<CDOFeatureDelta> getFeatureDeltas(); /** + * @deprecated As of 4.3 use {@link #applyTo(CDORevision)}. + */ + @Deprecated + public void apply(CDORevision revision); + + /** * Applies the {@link #getFeatureDeltas() feature deltas} in this revision delta to the {@link CDORevisionData data} * of the given revision. * <p> * The system data of the given revision, e.g. {@link CDOBranchPoint branch point} or {@link CDOBranchVersion branch * version} of the given revision are <b>not</b> modified. + * + * @since 4.3 */ - public void apply(CDORevision revision); + public void applyTo(CDORevision revision); public void accept(CDOFeatureDeltaVisitor visitor); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOChangeSetDataImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOChangeSetDataImpl.java index 067021dc24..5bae5b09d0 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOChangeSetDataImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOChangeSetDataImpl.java @@ -157,7 +157,7 @@ public class CDOChangeSetDataImpl implements CDOChangeSetData if (oldRevision instanceof CDORevision) { CDORevision newRevision = (CDORevision)oldRevision; - delta.apply(newRevision); + delta.applyTo(newRevision); return; } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOAddFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOAddFeatureDeltaImpl.java index 20f7f2797e..43b42e478d 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOAddFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOAddFeatureDeltaImpl.java @@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.internal.common.revision.delta; import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor; @@ -45,9 +46,16 @@ public class CDOAddFeatureDeltaImpl extends CDOSingleValueFeatureDeltaImpl imple return Type.ADD; } - public void apply(CDORevision revision) + public Object applyTo(CDORevision revision) { - ((InternalCDORevision)revision).getList(getFeature()).add(getIndex(), getValue()); + EStructuralFeature feature = getFeature(); + int index = getIndex(); + Object value = getValue(); + + InternalCDORevision internalRevision = (InternalCDORevision)revision; + CDOList list = internalRevision.getList(feature); + list.add(index, value); + return null; } public void accept(CDOFeatureDeltaVisitor visitor) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOClearFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOClearFeatureDeltaImpl.java index 363082a4cb..f607ba6abd 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOClearFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOClearFeatureDeltaImpl.java @@ -49,9 +49,13 @@ public class CDOClearFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDO return new CDOClearFeatureDeltaImpl(getFeature()); } - public void apply(CDORevision revision) + public Object applyTo(CDORevision revision) { - ((InternalCDORevision)revision).clear(getFeature()); + EStructuralFeature feature = getFeature(); + + InternalCDORevision internalRevision = (InternalCDORevision)revision; + internalRevision.clear(feature); + return null; } public void accept(CDOFeatureDeltaVisitor visitor) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java index a675ff5b3b..1778167045 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java @@ -83,11 +83,13 @@ public class CDOContainerFeatureDeltaImpl extends CDOFeatureDeltaImpl implements return newContainerFeatureID; } - public void apply(CDORevision revision) + public Object applyTo(CDORevision revision) { - ((InternalCDORevision)revision).setResourceID(newResourceID); - ((InternalCDORevision)revision).setContainerID(newContainerID); - ((InternalCDORevision)revision).setContainingFeatureID(newContainerFeatureID); + InternalCDORevision internalRevision = (InternalCDORevision)revision; + internalRevision.setResourceID(newResourceID); + internalRevision.setContainerID(newContainerID); + internalRevision.setContainingFeatureID(newContainerFeatureID); + return null; } @Override diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDODetachedRevisionDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDODetachedRevisionDeltaImpl.java index e0157dbf55..17e3154d6c 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDODetachedRevisionDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDODetachedRevisionDeltaImpl.java @@ -89,11 +89,17 @@ public class CDODetachedRevisionDeltaImpl implements CDORevisionDelta throw new UnsupportedOperationException(); } + @Deprecated public void apply(CDORevision revision) { throw new UnsupportedOperationException(); } + public void applyTo(CDORevision revision) + { + throw new UnsupportedOperationException(); + } + public void accept(CDOFeatureDeltaVisitor visitor) { throw new UnsupportedOperationException(); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaImpl.java index 57fdf08b45..5859dfa34c 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaImpl.java @@ -13,6 +13,7 @@ package org.eclipse.emf.cdo.internal.common.revision.delta; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; import org.eclipse.emf.cdo.spi.common.revision.CDOReferenceAdjuster; import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta; @@ -56,6 +57,12 @@ public abstract class CDOFeatureDeltaImpl implements InternalCDOFeatureDelta return feature; } + @Deprecated + public void apply(CDORevision revision) + { + applyTo(revision); + } + public boolean isStructurallyEqual(Object obj) { if (obj == this) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java index 54a2e0e4c3..e553cd72fe 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java @@ -407,12 +407,14 @@ public class CDOListFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOL } } - public void apply(CDORevision revision) + public Object applyTo(CDORevision revision) { for (CDOFeatureDelta featureDelta : listChanges) { - ((CDOFeatureDeltaImpl)featureDelta).apply(revision); + ((CDOFeatureDeltaImpl)featureDelta).applyTo(revision); } + + return null; } @Override diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOMoveFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOMoveFeatureDeltaImpl.java index dbbca57d65..d935da012c 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOMoveFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOMoveFeatureDeltaImpl.java @@ -13,6 +13,7 @@ package org.eclipse.emf.cdo.internal.common.revision.delta; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor; @@ -32,7 +33,7 @@ import java.text.MessageFormat; * @author Simon McDuff */ public class CDOMoveFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOMoveFeatureDelta, ListIndexAffecting, - WithIndex +WithIndex { private int oldPosition; @@ -106,9 +107,13 @@ public class CDOMoveFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOM return copy; } - public void apply(CDORevision revision) + public Object applyTo(CDORevision revision) { - ((InternalCDORevision)revision).getList(getFeature()).move(newPosition, oldPosition); + EStructuralFeature feature = getFeature(); + + InternalCDORevision internalRevision = (InternalCDORevision)revision; + CDOList list = internalRevision.getList(feature); + return list.move(newPosition, oldPosition); } public void affectIndices(ListTargetAdding[] source, int[] indices) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORemoveFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORemoveFeatureDeltaImpl.java index e767520e7d..1463a133c2 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORemoveFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORemoveFeatureDeltaImpl.java @@ -13,6 +13,7 @@ package org.eclipse.emf.cdo.internal.common.revision.delta; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor; @@ -29,7 +30,7 @@ import java.io.IOException; * @author Simon McDuff */ public class CDORemoveFeatureDeltaImpl extends CDOSingleValueFeatureDeltaImpl implements CDORemoveFeatureDelta, - ListIndexAffecting +ListIndexAffecting { public CDORemoveFeatureDeltaImpl(EStructuralFeature feature, int index) { @@ -65,9 +66,14 @@ public class CDORemoveFeatureDeltaImpl extends CDOSingleValueFeatureDeltaImpl im return delta; } - public void apply(CDORevision revision) + public Object applyTo(CDORevision revision) { - ((InternalCDORevision)revision).getList(getFeature()).remove(getIndex()); + EStructuralFeature feature = getFeature(); + int index = getIndex(); + + InternalCDORevision internalRevision = (InternalCDORevision)revision; + CDOList list = internalRevision.getList(feature); + return list.remove(index); } public void accept(CDOFeatureDeltaVisitor visitor) 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 9fdb264fd4..f88f8e6c3c 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 @@ -30,6 +30,7 @@ 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.CDOOriginSizeProvider; import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; +import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta; import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException; import org.eclipse.emf.cdo.internal.common.revision.CDOListImpl; @@ -248,11 +249,17 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta return new ArrayList<CDOFeatureDelta>(featureDeltas.values()); } + @Deprecated public void apply(CDORevision revision) { + applyTo(revision); + } + + public void applyTo(CDORevision revision) + { for (CDOFeatureDelta featureDelta : featureDeltas.values()) { - ((CDOFeatureDeltaImpl)featureDelta).apply(revision); + ((CDOFeatureDeltaImpl)featureDelta).applyTo(revision); } } @@ -269,7 +276,7 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta CDOListFeatureDelta listDelta = (CDOListFeatureDelta)delta; for (CDOFeatureDelta listChange : listDelta.getListChanges()) { - addFeatureDelta(listChange, listDelta); + addSingleFeatureDelta(listChange, listDelta); } } else @@ -288,7 +295,7 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta { int originSize = originSizeProvider.getOriginSize(); listDelta = new CDOListFeatureDeltaImpl(feature, originSize); - featureDeltas.put(listDelta.getFeature(), listDelta); + featureDeltas.put(feature, listDelta); } // Remove all previous changes @@ -301,7 +308,13 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta } else { - featureDeltas.put(feature, delta); + CDOFeatureDelta oldDelta = featureDeltas.put(feature, delta); + if (oldDelta instanceof CDOSetFeatureDelta && delta instanceof CDOSetFeatureDelta) + { + Object oldValue = ((CDOSetFeatureDelta)oldDelta).getOldValue(); + CDOSetFeatureDeltaImpl newDelta = (CDOSetFeatureDeltaImpl)delta; + newDelta.setOldValue(oldValue); + } } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSetFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSetFeatureDeltaImpl.java index 5ac10c8f2f..ef07cc794e 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSetFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSetFeatureDeltaImpl.java @@ -59,9 +59,14 @@ public class CDOSetFeatureDeltaImpl extends CDOSingleValueFeatureDeltaImpl imple return new CDOSetFeatureDeltaImpl(getFeature(), getIndex(), getValue(), getOldValue()); } - public void apply(CDORevision revision) + public Object applyTo(CDORevision revision) { - ((InternalCDORevision)revision).set(getFeature(), getIndex(), getValue()); + EStructuralFeature feature = getFeature(); + int index = getIndex(); + Object value = getValue(); + + InternalCDORevision internalRevision = (InternalCDORevision)revision; + return internalRevision.set(feature, index, value); } public void accept(CDOFeatureDeltaVisitor visitor) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOUnsetFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOUnsetFeatureDeltaImpl.java index 690e07db2e..9e37b8ea22 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOUnsetFeatureDeltaImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOUnsetFeatureDeltaImpl.java @@ -11,6 +11,8 @@ */ package org.eclipse.emf.cdo.internal.common.revision.delta; +import org.eclipse.emf.cdo.common.model.CDOModelUtil; +import org.eclipse.emf.cdo.common.model.CDOType; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; @@ -23,6 +25,7 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EStructuralFeature; import java.io.IOException; +import java.util.List; /** * @author Simon McDuff @@ -49,9 +52,42 @@ public class CDOUnsetFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDO return new CDOUnsetFeatureDeltaImpl(getFeature()); } - public void apply(CDORevision revision) + public Object applyTo(CDORevision revision) { - ((InternalCDORevision)revision).unset(getFeature()); + EStructuralFeature feature = getFeature(); + + InternalCDORevision internalRevision = (InternalCDORevision)revision; + if (feature.isUnsettable()) + { + internalRevision.unset(feature); + } + else + { + if (feature.isMany()) + { + Object value = internalRevision.getValue(feature); + if (value != null) + { + @SuppressWarnings("unchecked") + List<Object> list = (List<Object>)value; + list.clear(); + } + } + else + { + Object defaultValue = feature.getDefaultValue(); + + CDOType type = CDOModelUtil.getType(feature.getEType()); + if (type != null) + { + defaultValue = type.convertToCDO(feature.getEType(), defaultValue); + } + + internalRevision.set(feature, NO_INDEX, defaultValue); + } + } + + return null; } public void accept(CDOFeatureDeltaVisitor visitor) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/commit/CDOChangeSetDataRevisionProvider.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/commit/CDOChangeSetDataRevisionProvider.java index d3b8c468be..a7ec667c80 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/commit/CDOChangeSetDataRevisionProvider.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/commit/CDOChangeSetDataRevisionProvider.java @@ -155,7 +155,7 @@ public class CDOChangeSetDataRevisionProvider implements CDORevisionProvider, CD { CDOID id = revisionDelta.getID(); CDORevision changedObject = delegate.getRevision(id).copy(); - revisionDelta.apply(changedObject); + revisionDelta.applyTo(changedObject); cachedRevisions.put(id, changedObject); return changedObject; } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java index 0195f21d84..dc76784673 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java @@ -62,7 +62,7 @@ import java.util.Map; * @since 2.0 */ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping implements IClassMappingAuditSupport, - IClassMappingDeltaSupport +IClassMappingDeltaSupport { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalAuditClassMapping.class); @@ -81,605 +81,605 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping private String sqlRawDeleteAttributes; private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>() - { + { @Override protected FeatureDeltaWriter initialValue() { return new FeatureDeltaWriter(); } - }; - - public HorizontalAuditClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) - { - super(mappingStrategy, eClass); - initSQLStrings(); - } - - private void initSQLStrings() - { - // ----------- Select Revision --------------------------- - StringBuilder builder = new StringBuilder(); - builder.append("SELECT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CREATED); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_RESOURCE); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CONTAINER); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_FEATURE); - appendTypeMappingNames(builder, getValueMappings()); - appendFieldNames(builder, getUnsettableFields()); - appendFieldNames(builder, getListSizeFields()); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append("=? AND ("); //$NON-NLS-1$ - String sqlSelectAttributesPrefix = builder.toString(); - builder.append(ATTRIBUTES_REVISED); - builder.append("=0)"); //$NON-NLS-1$ - sqlSelectCurrentAttributes = builder.toString(); - - builder = new StringBuilder(sqlSelectAttributesPrefix); - builder.append(ATTRIBUTES_CREATED); - builder.append("<=? AND ("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0 OR "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(">=?))"); //$NON-NLS-1$ - sqlSelectAttributesByTime = builder.toString(); - - builder = new StringBuilder(sqlSelectAttributesPrefix); - builder.append("ABS("); - builder.append(ATTRIBUTES_VERSION); - builder.append(")=?)"); //$NON-NLS-1$ - sqlSelectAttributesByVersion = builder.toString(); - - // ----------- Insert Attributes ------------------------- - builder = new StringBuilder(); - builder.append("INSERT INTO "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append("("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CREATED); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_RESOURCE); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CONTAINER); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_FEATURE); - appendTypeMappingNames(builder, getValueMappings()); - appendFieldNames(builder, getUnsettableFields()); - appendFieldNames(builder, getListSizeFields()); - builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$ - appendTypeMappingParameters(builder, getValueMappings()); - appendFieldParameters(builder, getUnsettableFields()); - appendFieldParameters(builder, getListSizeFields()); - builder.append(")"); //$NON-NLS-1$ - sqlInsertAttributes = builder.toString(); - - // ----------- Update to set revised ---------------- - builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=? WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0"); //$NON-NLS-1$ - sqlReviseAttributes = builder.toString(); - - // ----------- Select all unrevised Object IDs ------ - builder = new StringBuilder("SELECT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0"); //$NON-NLS-1$ - sqlSelectAllObjectIDs = builder.toString(); - - // ----------- Raw delete one specific revision ------ - builder = new StringBuilder("DELETE FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append("=?"); //$NON-NLS-1$ - sqlRawDeleteAttributes = builder.toString(); - } - - public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = null; - - try - { - long timeStamp = revision.getTimeStamp(); - if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) + }; + + public HorizontalAuditClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) { - stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM); - idHandler.setCDOID(stmt, 1, revision.getID()); - stmt.setLong(2, timeStamp); - stmt.setLong(3, timeStamp); + super(mappingStrategy, eClass); + initSQLStrings(); } - else + + private void initSQLStrings() { - stmt = accessor.getDBConnection().prepareStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH); - idHandler.setCDOID(stmt, 1, revision.getID()); + // ----------- Select Revision --------------------------- + StringBuilder builder = new StringBuilder(); + builder.append("SELECT "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CREATED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_RESOURCE); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CONTAINER); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_FEATURE); + appendTypeMappingNames(builder, getValueMappings()); + appendFieldNames(builder, getUnsettableFields()); + appendFieldNames(builder, getListSizeFields()); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append("=? AND ("); //$NON-NLS-1$ + String sqlSelectAttributesPrefix = builder.toString(); + builder.append(ATTRIBUTES_REVISED); + builder.append("=0)"); //$NON-NLS-1$ + sqlSelectCurrentAttributes = builder.toString(); + + builder = new StringBuilder(sqlSelectAttributesPrefix); + builder.append(ATTRIBUTES_CREATED); + builder.append("<=? AND ("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(">=?))"); //$NON-NLS-1$ + sqlSelectAttributesByTime = builder.toString(); + + builder = new StringBuilder(sqlSelectAttributesPrefix); + builder.append("ABS("); + builder.append(ATTRIBUTES_VERSION); + builder.append(")=?)"); //$NON-NLS-1$ + sqlSelectAttributesByVersion = builder.toString(); + + // ----------- Insert Attributes ------------------------- + builder = new StringBuilder(); + builder.append("INSERT INTO "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append("("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CREATED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_RESOURCE); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CONTAINER); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_FEATURE); + appendTypeMappingNames(builder, getValueMappings()); + appendFieldNames(builder, getUnsettableFields()); + appendFieldNames(builder, getListSizeFields()); + builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$ + appendTypeMappingParameters(builder, getValueMappings()); + appendFieldParameters(builder, getUnsettableFields()); + appendFieldParameters(builder, getListSizeFields()); + builder.append(")"); //$NON-NLS-1$ + sqlInsertAttributes = builder.toString(); + + // ----------- Update to set revised ---------------- + builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" SET "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=? WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0"); //$NON-NLS-1$ + sqlReviseAttributes = builder.toString(); + + // ----------- Select all unrevised Object IDs ------ + builder = new StringBuilder("SELECT "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0"); //$NON-NLS-1$ + sqlSelectAllObjectIDs = builder.toString(); + + // ----------- Raw delete one specific revision ------ + builder = new StringBuilder("DELETE FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append("=?"); //$NON-NLS-1$ + sqlRawDeleteAttributes = builder.toString(); } - // Read singleval-attribute table always (even without modeled attributes!) - boolean success = readValuesFromStatement(stmt, revision, accessor); - - // Read multival tables only if revision exists - if (success && revision.getVersion() >= CDOBranchVersion.FIRST_VERSION) + public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { - readLists(accessor, revision, listChunk); - } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = null; - return success; - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(stmt); - } - } + try + { + long timeStamp = revision.getTimeStamp(); + if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) + { + stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM); + idHandler.setCDOID(stmt, 1, revision.getID()); + stmt.setLong(2, timeStamp); + stmt.setLong(3, timeStamp); + } + else + { + stmt = accessor.getDBConnection().prepareStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH); + idHandler.setCDOID(stmt, 1, revision.getID()); + } - public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesByVersion, - ReuseProbability.HIGH); + // Read singleval-attribute table always (even without modeled attributes!) + boolean success = readValuesFromStatement(stmt, revision, accessor); - try - { - idHandler.setCDOID(stmt, 1, revision.getID()); - stmt.setInt(2, revision.getVersion()); + // Read multival tables only if revision exists + if (success && revision.getVersion() >= CDOBranchVersion.FIRST_VERSION) + { + readLists(accessor, revision, listChunk); + } - // Read singleval-attribute table always (even without modeled attributes!) - boolean success = readValuesFromStatement(stmt, revision, accessor); + return success; + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(stmt); + } + } - // Read multival tables only if revision exists - if (success) + public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { - readLists(accessor, revision, listChunk); + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesByVersion, + ReuseProbability.HIGH); + + try + { + idHandler.setCDOID(stmt, 1, revision.getID()); + stmt.setInt(2, revision.getVersion()); + + // Read singleval-attribute table always (even without modeled attributes!) + boolean success = readValuesFromStatement(stmt, revision, accessor); + + // Read multival tables only if revision exists + if (success) + { + readLists(accessor, revision, listChunk); + } + + return success; + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(stmt); + } } - return success; - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(stmt); - } - } + public IDBPreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name, + boolean exactMatch, CDOBranchPoint branchPoint) + { + EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); + long timeStamp = branchPoint.getTimeStamp(); - public IDBPreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name, - boolean exactMatch, CDOBranchPoint branchPoint) - { - EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); - long timeStamp = branchPoint.getTimeStamp(); + ITypeMapping nameValueMapping = getValueMapping(nameFeature); + if (nameValueMapping == null) + { + throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$ + } - ITypeMapping nameValueMapping = getValueMapping(nameFeature); - if (nameValueMapping == null) - { - throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$ - } + StringBuilder builder = new StringBuilder(); + builder.append("SELECT "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(">0 AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CONTAINER); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(nameValueMapping.getField()); + if (name == null) + { + builder.append(" IS NULL"); //$NON-NLS-1$ + } + else + { + builder.append(exactMatch ? "=? " : " LIKE ? "); //$NON-NLS-1$ //$NON-NLS-2$ + } - StringBuilder builder = new StringBuilder(); - builder.append("SELECT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(">0 AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CONTAINER); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(nameValueMapping.getField()); - if (name == null) - { - builder.append(" IS NULL"); //$NON-NLS-1$ - } - else - { - builder.append(exactMatch ? "=? " : " LIKE ? "); //$NON-NLS-1$ //$NON-NLS-2$ - } + builder.append(" AND ("); //$NON-NLS-1$ - builder.append(" AND ("); //$NON-NLS-1$ + if (timeStamp == CDORevision.UNSPECIFIED_DATE) + { + builder.append(ATTRIBUTES_REVISED); + builder.append("=0)"); //$NON-NLS-1$ + } + else + { + builder.append(ATTRIBUTES_CREATED); + builder.append("<=? AND ("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(">=?))"); //$NON-NLS-1$ + } - if (timeStamp == CDORevision.UNSPECIFIED_DATE) - { - builder.append(ATTRIBUTES_REVISED); - builder.append("=0)"); //$NON-NLS-1$ - } - else - { - builder.append(ATTRIBUTES_CREATED); - builder.append("<=? AND ("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0 OR "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(">=?))"); //$NON-NLS-1$ - } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection() + .prepareStatement(builder.toString(), ReuseProbability.MEDIUM); - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection() - .prepareStatement(builder.toString(), ReuseProbability.MEDIUM); + try + { + int column = 1; + idHandler.setCDOID(stmt, column++, folderId); - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, folderId); + if (name != null) + { + String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$ + nameValueMapping.setValue(stmt, column++, queryName); + } - if (name != null) - { - String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$ - nameValueMapping.setValue(stmt, column++, queryName); + if (timeStamp != CDORevision.UNSPECIFIED_DATE) + { + stmt.setLong(column++, timeStamp); + stmt.setLong(column++, timeStamp); + } + + if (TRACER.isEnabled()) + { + TRACER.format("Created Resource Query: {0}", stmt.toString()); //$NON-NLS-1$ + } + + return stmt; + } + catch (SQLException ex) + { + DBUtil.close(stmt); // only release on error + throw new DBException(ex); + } } - if (timeStamp != CDORevision.UNSPECIFIED_DATE) + public IDBPreparedStatement createObjectIDStatement(IDBStoreAccessor accessor) { - stmt.setLong(column++, timeStamp); - stmt.setLong(column++, timeStamp); + if (TRACER.isEnabled()) + { + TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIDs); //$NON-NLS-1$ + } + + return accessor.getDBConnection().prepareStatement(sqlSelectAllObjectIDs, ReuseProbability.HIGH); } - if (TRACER.isEnabled()) + @Override + protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { - TRACER.format("Created Resource Query: {0}", stmt.toString()); //$NON-NLS-1$ - } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertAttributes, ReuseProbability.HIGH); - return stmt; - } - catch (SQLException ex) - { - DBUtil.close(stmt); // only release on error - throw new DBException(ex); - } - } + try + { + int column = 1; + idHandler.setCDOID(stmt, column++, revision.getID()); + stmt.setInt(column++, revision.getVersion()); + stmt.setLong(column++, revision.getTimeStamp()); + stmt.setLong(column++, revision.getRevised()); + idHandler.setCDOID(stmt, column++, revision.getResourceID()); + idHandler.setCDOID(stmt, column++, (CDOID)revision.getContainerID()); + stmt.setInt(column++, revision.getContainingFeatureID()); + + int isSetCol = column + getValueMappings().size(); + + for (ITypeMapping mapping : getValueMappings()) + { + EStructuralFeature feature = mapping.getFeature(); + if (feature.isUnsettable()) + { + if (revision.getValue(feature) == null) + { + stmt.setBoolean(isSetCol++, false); - public IDBPreparedStatement createObjectIDStatement(IDBStoreAccessor accessor) - { - if (TRACER.isEnabled()) - { - TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIDs); //$NON-NLS-1$ - } + // also set value column to default value + mapping.setDefaultValue(stmt, column++); - return accessor.getDBConnection().prepareStatement(sqlSelectAllObjectIDs, ReuseProbability.HIGH); - } + continue; + } - @Override - protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertAttributes, ReuseProbability.HIGH); + stmt.setBoolean(isSetCol++, true); + } - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, revision.getID()); - stmt.setInt(column++, revision.getVersion()); - stmt.setLong(column++, revision.getTimeStamp()); - stmt.setLong(column++, revision.getRevised()); - idHandler.setCDOID(stmt, column++, revision.getResourceID()); - idHandler.setCDOID(stmt, column++, (CDOID)revision.getContainerID()); - stmt.setInt(column++, revision.getContainingFeatureID()); - - int isSetCol = column + getValueMappings().size(); - - for (ITypeMapping mapping : getValueMappings()) + mapping.setValueFromRevision(stmt, column++, revision); + } + + Map<EStructuralFeature, IDBField> listSizeFields = getListSizeFields(); + if (listSizeFields != null) + { + // isSetCol now points to the first listTableSize-column + column = isSetCol; + + for (EStructuralFeature feature : listSizeFields.keySet()) + { + CDOList list = revision.getList(feature); + stmt.setInt(column++, list.size()); + } + } + + DBUtil.update(stmt, true); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); + } + } + + @Override + protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp, + OMMonitor mon) { - EStructuralFeature feature = mapping.getFeature(); - if (feature.isUnsettable()) + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertAttributes, ReuseProbability.HIGH); + + try { - if (revision.getValue(feature) == null) + int column = 1; + idHandler.setCDOID(stmt, column++, id); + stmt.setInt(column++, -version); // cdo_version + stmt.setLong(column++, timeStamp); // cdo_created + stmt.setLong(column++, CDOBranchPoint.UNSPECIFIED_DATE); // cdo_revised + idHandler.setCDOID(stmt, column++, CDOID.NULL); // resource + idHandler.setCDOID(stmt, column++, CDOID.NULL); // container + stmt.setInt(column++, 0); // containing feature ID + + int isSetCol = column + getValueMappings().size(); + + for (ITypeMapping mapping : getValueMappings()) { - stmt.setBoolean(isSetCol++, false); + EStructuralFeature feature = mapping.getFeature(); + if (feature.isUnsettable()) + { + stmt.setBoolean(isSetCol++, false); + } - // also set value column to default value mapping.setDefaultValue(stmt, column++); + } - continue; + Map<EStructuralFeature, IDBField> listSizeFields = getListSizeFields(); + if (listSizeFields != null) + { + // list size columns begin after isSet-columns + column = isSetCol; + + for (int i = 0; i < listSizeFields.size(); i++) + { + stmt.setInt(column++, 0); + } } - stmt.setBoolean(isSetCol++, true); + DBUtil.update(stmt, true); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); } - - mapping.setValueFromRevision(stmt, column++, revision); } - Map<EStructuralFeature, IDBField> listSizeFields = getListSizeFields(); - if (listSizeFields != null) + @Override + protected void rawDeleteAttributes(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version, OMMonitor fork) { - // isSetCol now points to the first listTableSize-column - column = isSetCol; + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlRawDeleteAttributes, + ReuseProbability.HIGH); - for (EStructuralFeature feature : listSizeFields.keySet()) + try + { + getMappingStrategy().getStore().getIDHandler().setCDOID(stmt, 1, id); + stmt.setInt(2, version); + DBUtil.update(stmt, false); + } + catch (SQLException e) { - CDOList list = revision.getList(feature); - stmt.setInt(column++, list.size()); + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); } } - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } + @Override + protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long revised) + { + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlReviseAttributes, ReuseProbability.HIGH); - @Override - protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp, - OMMonitor mon) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertAttributes, ReuseProbability.HIGH); + try + { + stmt.setLong(1, revised); + idHandler.setCDOID(stmt, 2, id); - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, -version); // cdo_version - stmt.setLong(column++, timeStamp); // cdo_created - stmt.setLong(column++, CDOBranchPoint.UNSPECIFIED_DATE); // cdo_revised - idHandler.setCDOID(stmt, column++, CDOID.NULL); // resource - idHandler.setCDOID(stmt, column++, CDOID.NULL); // container - stmt.setInt(column++, 0); // containing feature ID - - int isSetCol = column + getValueMappings().size(); - - for (ITypeMapping mapping : getValueMappings()) - { - EStructuralFeature feature = mapping.getFeature(); - if (feature.isUnsettable()) + DBUtil.update(stmt, true); + } + catch (SQLException e) { - stmt.setBoolean(isSetCol++, false); + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); } - - mapping.setDefaultValue(stmt, column++); } - Map<EStructuralFeature, IDBField> listSizeFields = getListSizeFields(); - if (listSizeFields != null) + public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, + OMMonitor monitor) { - // list size columns begin after isSet-columns - column = isSetCol; + Async async = null; + monitor.begin(); - for (int i = 0; i < listSizeFields.size(); i++) + try + { + try + { + async = monitor.forkAsync(); + FeatureDeltaWriter writer = deltaWriter.get(); + writer.process(accessor, delta, created); + } + finally + { + if (async != null) + { + async.stop(); + } + } + } + finally { - stmt.setInt(column++, 0); + monitor.done(); } } - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - @Override - protected void rawDeleteAttributes(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version, OMMonitor fork) - { - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlRawDeleteAttributes, - ReuseProbability.HIGH); - - try - { - getMappingStrategy().getStore().getIDHandler().setCDOID(stmt, 1, id); - stmt.setInt(2, version); - DBUtil.update(stmt, false); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - @Override - protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long revised) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlReviseAttributes, ReuseProbability.HIGH); - - try - { - stmt.setLong(1, revised); - idHandler.setCDOID(stmt, 2, id); - - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, - OMMonitor monitor) - { - Async async = null; - monitor.begin(); - - try - { - try + @Override + protected String getListXRefsWhere(QueryXRefsContext context) { - async = monitor.forkAsync(); - FeatureDeltaWriter writer = deltaWriter.get(); - writer.process(accessor, delta, created); - } - finally - { - if (async != null) + if (CDOBranch.MAIN_BRANCH_ID != context.getBranch().getID()) { - async.stop(); + throw new IllegalArgumentException("Non-audit mode does not support branch specification"); } - } - } - finally - { - monitor.done(); - } - } - @Override - protected String getListXRefsWhere(QueryXRefsContext context) - { - if (CDOBranch.MAIN_BRANCH_ID != context.getBranch().getID()) - { - throw new IllegalArgumentException("Non-audit mode does not support branch specification"); - } - - StringBuilder builder = new StringBuilder(); - long timeStamp = context.getTimeStamp(); - if (timeStamp == CDORevision.UNSPECIFIED_DATE) - { - builder.append(ATTRIBUTES_REVISED); - builder.append("=0"); //$NON-NLS-1$ - } - else - { - builder.append(ATTRIBUTES_CREATED); - builder.append("<="); - builder.append(timeStamp); - builder.append(" AND ("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0 OR "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(">="); - builder.append(timeStamp); - builder.append(")"); //$NON-NLS-1$ - } + StringBuilder builder = new StringBuilder(); + long timeStamp = context.getTimeStamp(); + if (timeStamp == CDORevision.UNSPECIFIED_DATE) + { + builder.append(ATTRIBUTES_REVISED); + builder.append("=0"); //$NON-NLS-1$ + } + else + { + builder.append(ATTRIBUTES_CREATED); + builder.append("<="); + builder.append(timeStamp); + builder.append(" AND ("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(">="); + builder.append(timeStamp); + builder.append(")"); //$NON-NLS-1$ + } - return builder.toString(); - } + return builder.toString(); + } - /** - * @author Stefan Winkler - */ - private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor - { - private IDBStoreAccessor accessor; + /** + * @author Stefan Winkler + */ + private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor + { + private IDBStoreAccessor accessor; - private long created; + private long created; - private CDOID id; + private CDOID id; - private int oldVersion; + private int oldVersion; - private InternalCDORevision newRevision; + private InternalCDORevision newRevision; - private int branchId; + private int branchId; - public void process(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created) - { - this.accessor = accessor; - this.created = created; - id = delta.getID(); - branchId = delta.getBranch().getID(); - oldVersion = delta.getVersion(); + public void process(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created) + { + this.accessor = accessor; + this.created = created; + id = delta.getID(); + branchId = delta.getBranch().getID(); + oldVersion = delta.getVersion(); - if (TRACER.isEnabled()) - { - TRACER.format("FeatureDeltaWriter: old version: {0}, new version: {1}", oldVersion, oldVersion + 1); //$NON-NLS-1$ - } + if (TRACER.isEnabled()) + { + TRACER.format("FeatureDeltaWriter: old version: {0}, new version: {1}", oldVersion, oldVersion + 1); //$NON-NLS-1$ + } - InternalCDORevision originalRevision = (InternalCDORevision)accessor.getStore().getRepository() - .getRevisionManager().getRevisionByVersion(id, delta, 0, true); + InternalCDORevision originalRevision = (InternalCDORevision)accessor.getStore().getRepository() + .getRevisionManager().getRevisionByVersion(id, delta, 0, true); - newRevision = originalRevision.copy(); + newRevision = originalRevision.copy(); - newRevision.setVersion(oldVersion + 1); - newRevision.setBranchPoint(delta.getBranch().getPoint(created)); + newRevision.setVersion(oldVersion + 1); + newRevision.setBranchPoint(delta.getBranch().getPoint(created)); - // process revision delta tree - delta.accept(this); + // process revision delta tree + delta.accept(this); - long revised = newRevision.getTimeStamp() - 1; - reviseOldRevision(accessor, id, delta.getBranch(), revised); + long revised = newRevision.getTimeStamp() - 1; + reviseOldRevision(accessor, id, delta.getBranch(), revised); - writeValues(accessor, newRevision); - } + writeValues(accessor, newRevision); + } - public void visit(CDOMoveFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } + public void visit(CDOMoveFeatureDelta delta) + { + throw new ImplementationError("Should not be called"); //$NON-NLS-1$ + } - public void visit(CDOAddFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } + public void visit(CDOAddFeatureDelta delta) + { + throw new ImplementationError("Should not be called"); //$NON-NLS-1$ + } - public void visit(CDORemoveFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } + public void visit(CDORemoveFeatureDelta delta) + { + throw new ImplementationError("Should not be called"); //$NON-NLS-1$ + } - public void visit(CDOSetFeatureDelta delta) - { - delta.apply(newRevision); - } + public void visit(CDOSetFeatureDelta delta) + { + delta.applyTo(newRevision); + } - public void visit(CDOUnsetFeatureDelta delta) - { - delta.apply(newRevision); - } + public void visit(CDOUnsetFeatureDelta delta) + { + delta.applyTo(newRevision); + } - public void visit(CDOListFeatureDelta delta) - { - delta.apply(newRevision); - IListMappingDeltaSupport listMapping = (IListMappingDeltaSupport)getListMapping(delta.getFeature()); - listMapping.processDelta(accessor, id, branchId, oldVersion, oldVersion + 1, created, delta); - } + public void visit(CDOListFeatureDelta delta) + { + delta.applyTo(newRevision); + IListMappingDeltaSupport listMapping = (IListMappingDeltaSupport)getListMapping(delta.getFeature()); + listMapping.processDelta(accessor, id, branchId, oldVersion, oldVersion + 1, created, delta); + } - public void visit(CDOClearFeatureDelta delta) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } + public void visit(CDOClearFeatureDelta delta) + { + throw new ImplementationError("Should not be called"); //$NON-NLS-1$ + } - public void visit(CDOContainerFeatureDelta delta) - { - delta.apply(newRevision); - } - } + public void visit(CDOContainerFeatureDelta delta) + { + delta.applyTo(newRevision); + } + } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java index 2a3f652ae9..a5f34e5788 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java @@ -77,7 +77,7 @@ import java.util.Set; * @since 3.0 */ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapping implements - IClassMappingAuditSupport, IClassMappingDeltaSupport +IClassMappingAuditSupport, IClassMappingDeltaSupport { /** * @author Stefan Winkler @@ -145,17 +145,17 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp public void visit(CDOSetFeatureDelta delta) { - delta.apply(newRevision); + delta.applyTo(newRevision); } public void visit(CDOUnsetFeatureDelta delta) { - delta.apply(newRevision); + delta.applyTo(newRevision); } public void visit(CDOListFeatureDelta delta) { - delta.apply(newRevision); + delta.applyTo(newRevision); IListMappingDeltaSupport listMapping = (IListMappingDeltaSupport)getListMapping(delta.getFeature()); listMapping.processDelta(accessor, id, targetBranch.getID(), oldVersion, newVersion, created, delta); } @@ -167,7 +167,7 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp public void visit(CDOContainerFeatureDelta delta) { - delta.apply(newRevision); + delta.applyTo(newRevision); } } @@ -192,876 +192,876 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp private String sqlRawDeleteAttributes; private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>() - { + { @Override protected FeatureDeltaWriter initialValue() { return new FeatureDeltaWriter(); } - }; - - public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) - { - super(mappingStrategy, eClass); - initSQLStrings(); - } - - @Override - protected IDBField addBranchField(IDBTable table) - { - return table.addField(ATTRIBUTES_BRANCH, DBType.INTEGER, true); - } - - private void initSQLStrings() - { - // ----------- Select Revision --------------------------- - StringBuilder builder = new StringBuilder(); - builder.append("SELECT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CREATED); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_RESOURCE); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CONTAINER); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_FEATURE); - appendTypeMappingNames(builder, getValueMappings()); - appendFieldNames(builder, getUnsettableFields()); - appendFieldNames(builder, getListSizeFields()); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_BRANCH); - builder.append("=? AND ("); //$NON-NLS-1$ - String sqlSelectAttributesPrefix = builder.toString(); - builder.append(ATTRIBUTES_REVISED); - builder.append("=0)"); //$NON-NLS-1$ - sqlSelectCurrentAttributes = builder.toString(); - - builder = new StringBuilder(sqlSelectAttributesPrefix); - builder.append(ATTRIBUTES_CREATED); - builder.append("<=? AND ("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0 OR "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(">=?))"); //$NON-NLS-1$ - sqlSelectAttributesByTime = builder.toString(); - - builder = new StringBuilder(sqlSelectAttributesPrefix); - builder.append("ABS("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(")=?)"); //$NON-NLS-1$ - sqlSelectAttributesByVersion = builder.toString(); - - // ----------- Insert Attributes ------------------------- - builder = new StringBuilder(); - builder.append("INSERT INTO "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append("("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_BRANCH); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CREATED); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_RESOURCE); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CONTAINER); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_FEATURE); - appendTypeMappingNames(builder, getValueMappings()); - appendFieldNames(builder, getUnsettableFields()); - appendFieldNames(builder, getListSizeFields()); - builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$ - appendTypeMappingParameters(builder, getValueMappings()); - appendFieldParameters(builder, getUnsettableFields()); - appendFieldParameters(builder, getListSizeFields()); - builder.append(")"); //$NON-NLS-1$ - sqlInsertAttributes = builder.toString(); - - // ----------- Update to set revised ---------------- - builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" SET "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=? WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0"); //$NON-NLS-1$ - sqlReviseAttributes = builder.toString(); - - // ----------- Select all unrevised Object IDs ------ - builder = new StringBuilder("SELECT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0"); //$NON-NLS-1$ - sqlSelectAllObjectIDs = builder.toString(); - - // ----------- Select all revisions (for handleRevision) --- - builder = new StringBuilder("SELECT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(", "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_BRANCH); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - sqlSelectForHandle = builder.toString(); - - // ----------- Select all revisions (for handleRevision) --- - builder = new StringBuilder("SELECT DISTINCT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - sqlSelectForChangeSet = builder.toString(); - - // ----------- Raw delete one specific revision ------ - builder = new StringBuilder("DELETE FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append("=?"); //$NON-NLS-1$ - sqlRawDeleteAttributes = builder.toString(); - } + }; - public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) - { - long timeStamp = revision.getTimeStamp(); - int branchID = revision.getBranch().getID(); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = null; - - try - { - if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) + public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) { - stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM); - idHandler.setCDOID(stmt, 1, revision.getID()); - stmt.setInt(2, branchID); - stmt.setLong(3, timeStamp); - stmt.setLong(4, timeStamp); + super(mappingStrategy, eClass); + initSQLStrings(); } - else + + @Override + protected IDBField addBranchField(IDBTable table) { - stmt = accessor.getDBConnection().prepareStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH); - idHandler.setCDOID(stmt, 1, revision.getID()); - stmt.setInt(2, branchID); + return table.addField(ATTRIBUTES_BRANCH, DBType.INTEGER, true); } - // Read singleval-attribute table always (even without modeled attributes!) - boolean success = readValuesFromStatement(stmt, revision, accessor); - - // Read multival tables only if revision exists - if (success && revision.getVersion() >= CDOBranchVersion.FIRST_VERSION) + private void initSQLStrings() { - readLists(accessor, revision, listChunk); + // ----------- Select Revision --------------------------- + StringBuilder builder = new StringBuilder(); + builder.append("SELECT "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CREATED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_RESOURCE); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CONTAINER); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_FEATURE); + appendTypeMappingNames(builder, getValueMappings()); + appendFieldNames(builder, getUnsettableFields()); + appendFieldNames(builder, getListSizeFields()); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + builder.append("=? AND ("); //$NON-NLS-1$ + String sqlSelectAttributesPrefix = builder.toString(); + builder.append(ATTRIBUTES_REVISED); + builder.append("=0)"); //$NON-NLS-1$ + sqlSelectCurrentAttributes = builder.toString(); + + builder = new StringBuilder(sqlSelectAttributesPrefix); + builder.append(ATTRIBUTES_CREATED); + builder.append("<=? AND ("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(">=?))"); //$NON-NLS-1$ + sqlSelectAttributesByTime = builder.toString(); + + builder = new StringBuilder(sqlSelectAttributesPrefix); + builder.append("ABS("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(")=?)"); //$NON-NLS-1$ + sqlSelectAttributesByVersion = builder.toString(); + + // ----------- Insert Attributes ------------------------- + builder = new StringBuilder(); + builder.append("INSERT INTO "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append("("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CREATED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_RESOURCE); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CONTAINER); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_FEATURE); + appendTypeMappingNames(builder, getValueMappings()); + appendFieldNames(builder, getUnsettableFields()); + appendFieldNames(builder, getListSizeFields()); + builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$ + appendTypeMappingParameters(builder, getValueMappings()); + appendFieldParameters(builder, getUnsettableFields()); + appendFieldParameters(builder, getListSizeFields()); + builder.append(")"); //$NON-NLS-1$ + sqlInsertAttributes = builder.toString(); + + // ----------- Update to set revised ---------------- + builder = new StringBuilder("UPDATE "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" SET "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=? WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0"); //$NON-NLS-1$ + sqlReviseAttributes = builder.toString(); + + // ----------- Select all unrevised Object IDs ------ + builder = new StringBuilder("SELECT "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0"); //$NON-NLS-1$ + sqlSelectAllObjectIDs = builder.toString(); + + // ----------- Select all revisions (for handleRevision) --- + builder = new StringBuilder("SELECT "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(", "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(getTable()); + sqlSelectForHandle = builder.toString(); + + // ----------- Select all revisions (for handleRevision) --- + builder = new StringBuilder("SELECT DISTINCT "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + sqlSelectForChangeSet = builder.toString(); + + // ----------- Raw delete one specific revision ------ + builder = new StringBuilder("DELETE FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append("=?"); //$NON-NLS-1$ + sqlRawDeleteAttributes = builder.toString(); } - return success; - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(stmt); - } - } - - public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesByVersion, - ReuseProbability.HIGH); - - try - { - idHandler.setCDOID(stmt, 1, revision.getID()); - stmt.setInt(2, revision.getBranch().getID()); - stmt.setInt(3, revision.getVersion()); - - // Read singleval-attribute table always (even without modeled attributes!) - boolean success = readValuesFromStatement(stmt, revision, accessor); - - // Read multival tables only if revision exists - if (success) + public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { - readLists(accessor, revision, listChunk); - } + long timeStamp = revision.getTimeStamp(); + int branchID = revision.getBranch().getID(); - return success; - } - catch (SQLException ex) - { - throw new DBException(ex); - } - finally - { - DBUtil.close(stmt); - } - } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = null; - public IDBPreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name, - boolean exactMatch, CDOBranchPoint branchPoint) - { - EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); + try + { + if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) + { + stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM); + idHandler.setCDOID(stmt, 1, revision.getID()); + stmt.setInt(2, branchID); + stmt.setLong(3, timeStamp); + stmt.setLong(4, timeStamp); + } + else + { + stmt = accessor.getDBConnection().prepareStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH); + idHandler.setCDOID(stmt, 1, revision.getID()); + stmt.setInt(2, branchID); + } - ITypeMapping nameValueMapping = getValueMapping(nameFeature); - if (nameValueMapping == null) - { - throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$ - } + // Read singleval-attribute table always (even without modeled attributes!) + boolean success = readValuesFromStatement(stmt, revision, accessor); - int branchID = branchPoint.getBranch().getID(); - long timeStamp = branchPoint.getTimeStamp(); - - StringBuilder builder = new StringBuilder(); - builder.append("SELECT "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_ID); - builder.append(" FROM "); //$NON-NLS-1$ - builder.append(getTable()); - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_VERSION); - builder.append(">0 AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_CONTAINER); - builder.append("=? AND "); //$NON-NLS-1$ - builder.append(nameValueMapping.getField()); - if (name == null) - { - builder.append(" IS NULL"); //$NON-NLS-1$ - } - else - { - builder.append(exactMatch ? " =?" : " LIKE ?"); //$NON-NLS-1$ //$NON-NLS-2$ - } + // Read multival tables only if revision exists + if (success && revision.getVersion() >= CDOBranchVersion.FIRST_VERSION) + { + readLists(accessor, revision, listChunk); + } - builder.append(" AND ("); //$NON-NLS-1$ + return success; + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(stmt); + } + } - if (timeStamp == CDORevision.UNSPECIFIED_DATE) - { - builder.append(ATTRIBUTES_REVISED); - builder.append("=0)"); //$NON-NLS-1$ - } - else - { - builder.append(ATTRIBUTES_CREATED); - builder.append("<=? AND ("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0 OR "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(">=?))"); //$NON-NLS-1$ - } + public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) + { + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlSelectAttributesByVersion, + ReuseProbability.HIGH); - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection() - .prepareStatement(builder.toString(), ReuseProbability.MEDIUM); + try + { + idHandler.setCDOID(stmt, 1, revision.getID()); + stmt.setInt(2, revision.getBranch().getID()); + stmt.setInt(3, revision.getVersion()); - try - { - int column = 1; - stmt.setInt(column++, branchID); - idHandler.setCDOID(stmt, column++, folderId); + // Read singleval-attribute table always (even without modeled attributes!) + boolean success = readValuesFromStatement(stmt, revision, accessor); - if (name != null) - { - String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$ - nameValueMapping.setValue(stmt, column++, queryName); - } + // Read multival tables only if revision exists + if (success) + { + readLists(accessor, revision, listChunk); + } - if (timeStamp != CDORevision.UNSPECIFIED_DATE) - { - stmt.setLong(column++, timeStamp); - stmt.setLong(column++, timeStamp); + return success; + } + catch (SQLException ex) + { + throw new DBException(ex); + } + finally + { + DBUtil.close(stmt); + } } - if (TRACER.isEnabled()) + public IDBPreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name, + boolean exactMatch, CDOBranchPoint branchPoint) { - TRACER.format("Created Resource Query: {0}", stmt.toString()); //$NON-NLS-1$ - } + EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); - return stmt; - } - catch (SQLException ex) - { - DBUtil.close(stmt); // only release on error - throw new DBException(ex); - } - } + ITypeMapping nameValueMapping = getValueMapping(nameFeature); + if (nameValueMapping == null) + { + throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$ + } - public IDBPreparedStatement createObjectIDStatement(IDBStoreAccessor accessor) - { - if (TRACER.isEnabled()) - { - TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIDs); //$NON-NLS-1$ - } + int branchID = branchPoint.getBranch().getID(); + long timeStamp = branchPoint.getTimeStamp(); + + StringBuilder builder = new StringBuilder(); + builder.append("SELECT "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_ID); + builder.append(" FROM "); //$NON-NLS-1$ + builder.append(getTable()); + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_VERSION); + builder.append(">0 AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CONTAINER); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(nameValueMapping.getField()); + if (name == null) + { + builder.append(" IS NULL"); //$NON-NLS-1$ + } + else + { + builder.append(exactMatch ? " =?" : " LIKE ?"); //$NON-NLS-1$ //$NON-NLS-2$ + } - return accessor.getDBConnection().prepareStatement(sqlSelectAllObjectIDs, ReuseProbability.HIGH); - } + builder.append(" AND ("); //$NON-NLS-1$ - @Override - protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertAttributes, ReuseProbability.HIGH); + if (timeStamp == CDORevision.UNSPECIFIED_DATE) + { + builder.append(ATTRIBUTES_REVISED); + builder.append("=0)"); //$NON-NLS-1$ + } + else + { + builder.append(ATTRIBUTES_CREATED); + builder.append("<=? AND ("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(">=?))"); //$NON-NLS-1$ + } - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, revision.getID()); - stmt.setInt(column++, revision.getVersion()); - stmt.setInt(column++, revision.getBranch().getID()); - stmt.setLong(column++, revision.getTimeStamp()); - stmt.setLong(column++, revision.getRevised()); - idHandler.setCDOID(stmt, column++, revision.getResourceID()); - idHandler.setCDOID(stmt, column++, (CDOID)revision.getContainerID()); - stmt.setInt(column++, revision.getContainingFeatureID()); - - int isSetCol = column + getValueMappings().size(); - - for (ITypeMapping mapping : getValueMappings()) - { - EStructuralFeature feature = mapping.getFeature(); - if (feature.isUnsettable()) + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection() + .prepareStatement(builder.toString(), ReuseProbability.MEDIUM); + + try { - if (revision.getValue(feature) == null) - { - stmt.setBoolean(isSetCol++, false); + int column = 1; + stmt.setInt(column++, branchID); + idHandler.setCDOID(stmt, column++, folderId); - // also set value column to default value - mapping.setDefaultValue(stmt, column++); - continue; + if (name != null) + { + String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$ + nameValueMapping.setValue(stmt, column++, queryName); } - stmt.setBoolean(isSetCol++, true); - } - - mapping.setValueFromRevision(stmt, column++, revision); - } + if (timeStamp != CDORevision.UNSPECIFIED_DATE) + { + stmt.setLong(column++, timeStamp); + stmt.setLong(column++, timeStamp); + } - Map<EStructuralFeature, IDBField> listSizeFields = getListSizeFields(); - if (listSizeFields != null) - { - // isSetCol now points to the first listTableSize-column - column = isSetCol; + if (TRACER.isEnabled()) + { + TRACER.format("Created Resource Query: {0}", stmt.toString()); //$NON-NLS-1$ + } - for (EStructuralFeature feature : listSizeFields.keySet()) + return stmt; + } + catch (SQLException ex) { - CDOList list = revision.getList(feature); - stmt.setInt(column++, list.size()); + DBUtil.close(stmt); // only release on error + throw new DBException(ex); } } - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - @Override - protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp, - OMMonitor mon) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertAttributes, ReuseProbability.HIGH); - - try - { - int column = 1; - idHandler.setCDOID(stmt, column++, id); - stmt.setInt(column++, -version); // cdo_version - stmt.setInt(column++, branch.getID()); - stmt.setLong(column++, timeStamp); // cdo_created - stmt.setLong(column++, CDOBranchPoint.UNSPECIFIED_DATE); // cdo_revised - idHandler.setCDOID(stmt, column++, CDOID.NULL); // resource - idHandler.setCDOID(stmt, column++, CDOID.NULL); // container - stmt.setInt(column++, 0); // containing feature ID - - int isSetCol = column + getValueMappings().size(); - - for (ITypeMapping mapping : getValueMappings()) + public IDBPreparedStatement createObjectIDStatement(IDBStoreAccessor accessor) { - EStructuralFeature feature = mapping.getFeature(); - if (feature.isUnsettable()) + if (TRACER.isEnabled()) { - stmt.setBoolean(isSetCol++, false); + TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIDs); //$NON-NLS-1$ } - mapping.setDefaultValue(stmt, column++); + return accessor.getDBConnection().prepareStatement(sqlSelectAllObjectIDs, ReuseProbability.HIGH); } - Map<EStructuralFeature, IDBField> listSizeFields = getListSizeFields(); - if (listSizeFields != null) + @Override + protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { - // list size columns begin after isSet-columns - column = isSetCol; + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertAttributes, ReuseProbability.HIGH); - for (int i = 0; i < listSizeFields.size(); i++) + try { - stmt.setInt(column++, 0); + int column = 1; + idHandler.setCDOID(stmt, column++, revision.getID()); + stmt.setInt(column++, revision.getVersion()); + stmt.setInt(column++, revision.getBranch().getID()); + stmt.setLong(column++, revision.getTimeStamp()); + stmt.setLong(column++, revision.getRevised()); + idHandler.setCDOID(stmt, column++, revision.getResourceID()); + idHandler.setCDOID(stmt, column++, (CDOID)revision.getContainerID()); + stmt.setInt(column++, revision.getContainingFeatureID()); + + int isSetCol = column + getValueMappings().size(); + + for (ITypeMapping mapping : getValueMappings()) + { + EStructuralFeature feature = mapping.getFeature(); + if (feature.isUnsettable()) + { + if (revision.getValue(feature) == null) + { + stmt.setBoolean(isSetCol++, false); + + // also set value column to default value + mapping.setDefaultValue(stmt, column++); + continue; + } + + stmt.setBoolean(isSetCol++, true); + } + + mapping.setValueFromRevision(stmt, column++, revision); + } + + Map<EStructuralFeature, IDBField> listSizeFields = getListSizeFields(); + if (listSizeFields != null) + { + // isSetCol now points to the first listTableSize-column + column = isSetCol; + + for (EStructuralFeature feature : listSizeFields.keySet()) + { + CDOList list = revision.getList(feature); + stmt.setInt(column++, list.size()); + } + } + + DBUtil.update(stmt, true); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); } } - DBUtil.update(stmt, true); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } - - @Override - protected void rawDeleteAttributes(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version, OMMonitor fork) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlRawDeleteAttributes, - ReuseProbability.HIGH); + @Override + protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp, + OMMonitor mon) + { + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlInsertAttributes, ReuseProbability.HIGH); - try - { - idHandler.setCDOID(stmt, 1, id); - stmt.setInt(2, branch.getID()); - stmt.setInt(3, version); - DBUtil.update(stmt, false); - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } + try + { + int column = 1; + idHandler.setCDOID(stmt, column++, id); + stmt.setInt(column++, -version); // cdo_version + stmt.setInt(column++, branch.getID()); + stmt.setLong(column++, timeStamp); // cdo_created + stmt.setLong(column++, CDOBranchPoint.UNSPECIFIED_DATE); // cdo_revised + idHandler.setCDOID(stmt, column++, CDOID.NULL); // resource + idHandler.setCDOID(stmt, column++, CDOID.NULL); // container + stmt.setInt(column++, 0); // containing feature ID + + int isSetCol = column + getValueMappings().size(); + + for (ITypeMapping mapping : getValueMappings()) + { + EStructuralFeature feature = mapping.getFeature(); + if (feature.isUnsettable()) + { + stmt.setBoolean(isSetCol++, false); + } - @Override - protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long revised) - { - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlReviseAttributes, ReuseProbability.HIGH); + mapping.setDefaultValue(stmt, column++); + } - try - { - stmt.setLong(1, revised); - idHandler.setCDOID(stmt, 2, id); - stmt.setInt(3, branch.getID()); - DBUtil.update(stmt, false); // No row affected if old revision from other branch! - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(stmt); - } - } + Map<EStructuralFeature, IDBField> listSizeFields = getListSizeFields(); + if (listSizeFields != null) + { + // list size columns begin after isSet-columns + column = isSetCol; - @Override - public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise, - OMMonitor monitor) - { - Async async = null; - monitor.begin(10); + for (int i = 0; i < listSizeFields.size(); i++) + { + stmt.setInt(column++, 0); + } + } - try - { - try - { - async = monitor.forkAsync(); - CDOID id = revision.getID(); - if (mapType) + DBUtil.update(stmt, true); + } + catch (SQLException e) { - // Put new objects into objectTypeMapper - long timeStamp = revision.getTimeStamp(); - EClass eClass = getEClass(); - - AbstractHorizontalMappingStrategy mappingStrategy = (AbstractHorizontalMappingStrategy)getMappingStrategy(); - if (!mappingStrategy.putObjectType(accessor, timeStamp, id, eClass)) - { - mapType = false; - } + throw new DBException(e); } - - if (!mapType && revise && revision.getVersion() > CDOBranchVersion.FIRST_VERSION) + finally { - // If revision is not the first one, revise the old revision - long revised = revision.getTimeStamp() - 1; - InternalCDOBranch branch = revision.getBranch(); - - reviseOldRevision(accessor, id, branch, revised); - for (IListMapping mapping : getListMappings()) - { - mapping.objectDetached(accessor, id, revised); - } + DBUtil.close(stmt); } } - finally + + @Override + protected void rawDeleteAttributes(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, int version, OMMonitor fork) { - if (async != null) + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlRawDeleteAttributes, + ReuseProbability.HIGH); + + try + { + idHandler.setCDOID(stmt, 1, id); + stmt.setInt(2, branch.getID()); + stmt.setInt(3, version); + DBUtil.update(stmt, false); + } + catch (SQLException e) + { + throw new DBException(e); + } + finally { - async.stop(); + DBUtil.close(stmt); } } - try + @Override + protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long revised) { - async = monitor.forkAsync(); - if (revision.isResourceFolder() || revision.isResource()) + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(sqlReviseAttributes, ReuseProbability.HIGH); + + try { - checkDuplicateResources(accessor, revision); + stmt.setLong(1, revised); + idHandler.setCDOID(stmt, 2, id); + stmt.setInt(3, branch.getID()); + DBUtil.update(stmt, false); // No row affected if old revision from other branch! } - } - finally - { - if (async != null) + catch (SQLException e) { - async.stop(); + throw new DBException(e); + } + finally + { + DBUtil.close(stmt); } } - try + @Override + public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise, + OMMonitor monitor) { - // Write attribute table always (even without modeled attributes!) - async = monitor.forkAsync(); - writeValues(accessor, revision); - } - finally - { - if (async != null) + Async async = null; + monitor.begin(10); + + try { - async.stop(); + try + { + async = monitor.forkAsync(); + CDOID id = revision.getID(); + if (mapType) + { + // Put new objects into objectTypeMapper + long timeStamp = revision.getTimeStamp(); + EClass eClass = getEClass(); + + AbstractHorizontalMappingStrategy mappingStrategy = (AbstractHorizontalMappingStrategy)getMappingStrategy(); + if (!mappingStrategy.putObjectType(accessor, timeStamp, id, eClass)) + { + mapType = false; + } + } + + if (!mapType && revise && revision.getVersion() > CDOBranchVersion.FIRST_VERSION) + { + // If revision is not the first one, revise the old revision + long revised = revision.getTimeStamp() - 1; + InternalCDOBranch branch = revision.getBranch(); + + reviseOldRevision(accessor, id, branch, revised); + for (IListMapping mapping : getListMappings()) + { + mapping.objectDetached(accessor, id, revised); + } + } + } + finally + { + if (async != null) + { + async.stop(); + } + } + + try + { + async = monitor.forkAsync(); + if (revision.isResourceFolder() || revision.isResource()) + { + checkDuplicateResources(accessor, revision); + } + } + finally + { + if (async != null) + { + async.stop(); + } + } + + try + { + // Write attribute table always (even without modeled attributes!) + async = monitor.forkAsync(); + writeValues(accessor, revision); + } + finally + { + if (async != null) + { + async.stop(); + } + } + + try + { + // Write list tables only if they exist + async = monitor.forkAsync(7); + if (getListMappings() != null) + { + writeLists(accessor, revision); + } + } + finally + { + if (async != null) + { + async.stop(); + } + } + } + finally + { + monitor.done(); } } - try + @Override + public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime, + CDORevisionHandler handler) { - // Write list tables only if they exist - async = monitor.forkAsync(7); - if (getListMappings() != null) + StringBuilder builder = new StringBuilder(sqlSelectForHandle); + boolean whereAppend = false; + + if (branch != null) { - writeLists(accessor, revision); + // TODO: Prepare this string literal + builder.append(" WHERE "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_BRANCH); + builder.append("=?"); //$NON-NLS-1$ + + whereAppend = true; } - } - finally - { - if (async != null) + + int timeParameters = 0; + if (timeStamp != CDOBranchPoint.INVALID_DATE) { - async.stop(); + if (exactTime) + { + if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) + { + builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$ + builder.append(ATTRIBUTES_CREATED); + builder.append("=?"); //$NON-NLS-1$ + timeParameters = 1; + } + } + else + { + builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$ + if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) + { + builder.append(ATTRIBUTES_CREATED); + builder.append("<=? AND ("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(">=?)"); //$NON-NLS-1$ + timeParameters = 2; + } + else + { + builder.append(ATTRIBUTES_REVISED); + builder.append("="); //$NON-NLS-1$ + builder.append(CDOBranchPoint.UNSPECIFIED_DATE); + } + } } - } - } - finally - { - monitor.done(); - } - } - @Override - public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime, - CDORevisionHandler handler) - { - StringBuilder builder = new StringBuilder(sqlSelectForHandle); - boolean whereAppend = false; + IRepository repository = accessor.getStore().getRepository(); + CDORevisionManager revisionManager = repository.getRevisionManager(); + CDOBranchManager branchManager = repository.getBranchManager(); - if (branch != null) - { - // TODO: Prepare this string literal - builder.append(" WHERE "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_BRANCH); - builder.append("=?"); //$NON-NLS-1$ + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(builder.toString(), ReuseProbability.LOW); + ResultSet resultSet = null; - whereAppend = true; - } + try + { + int column = 1; + if (branch != null) + { + stmt.setInt(column++, branch.getID()); + } - int timeParameters = 0; - if (timeStamp != CDOBranchPoint.INVALID_DATE) - { - if (exactTime) - { - if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) + for (int i = 0; i < timeParameters; i++) + { + stmt.setLong(column++, timeStamp); + } + + resultSet = stmt.executeQuery(); + while (resultSet.next()) + { + CDOID id = idHandler.getCDOID(resultSet, 1); + int version = resultSet.getInt(2); + + if (version >= CDOBranchVersion.FIRST_VERSION) + { + int branchID = resultSet.getInt(3); + CDOBranchVersion branchVersion = branchManager.getBranch(branchID).getVersion(Math.abs(version)); + InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchVersion, + CDORevision.UNCHUNKED, true); + + if (!handler.handleRevision(revision)) + { + break; + } + } + else + { + // Tell handler about detached IDs + InternalCDORevision revision = new DetachedCDORevision(null, id, null, version, 0); + handler.handleRevision(revision); + } + } + } + catch (SQLException e) { - builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$ - builder.append(ATTRIBUTES_CREATED); - builder.append("=?"); //$NON-NLS-1$ - timeParameters = 1; + throw new DBException(e); + } + finally + { + DBUtil.close(resultSet); + DBUtil.close(stmt); } } - else + + @Override + public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments) { - builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$ - if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE) + StringBuilder builder = new StringBuilder(sqlSelectForChangeSet); + boolean isFirst = true; + + for (int i = 0; i < segments.length; i++) { + if (isFirst) + { + isFirst = false; + } + else + { + builder.append(" OR "); //$NON-NLS-1$ + } + + builder.append(ATTRIBUTES_BRANCH); + builder.append("=? AND "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_CREATED); - builder.append("<=? AND ("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(">=?"); //$NON-NLS-1$ + builder.append(" AND ("); //$NON-NLS-1$ builder.append(ATTRIBUTES_REVISED); - builder.append(">=?)"); //$NON-NLS-1$ - timeParameters = 2; - } - else - { + builder.append("<=? OR "); //$NON-NLS-1$ builder.append(ATTRIBUTES_REVISED); builder.append("="); //$NON-NLS-1$ builder.append(CDOBranchPoint.UNSPECIFIED_DATE); + builder.append(")"); //$NON-NLS-1$ } - } - } - IRepository repository = accessor.getStore().getRepository(); - CDORevisionManager revisionManager = repository.getRevisionManager(); - CDOBranchManager branchManager = repository.getBranchManager(); - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(builder.toString(), ReuseProbability.LOW); - ResultSet resultSet = null; - - try - { - int column = 1; - if (branch != null) - { - stmt.setInt(column++, branch.getID()); - } + IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); + IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(builder.toString(), ReuseProbability.LOW); + ResultSet resultSet = null; + Set<CDOID> result = new HashSet<CDOID>(); - for (int i = 0; i < timeParameters; i++) - { - stmt.setLong(column++, timeStamp); - } - - resultSet = stmt.executeQuery(); - while (resultSet.next()) - { - CDOID id = idHandler.getCDOID(resultSet, 1); - int version = resultSet.getInt(2); - - if (version >= CDOBranchVersion.FIRST_VERSION) + try { - int branchID = resultSet.getInt(3); - CDOBranchVersion branchVersion = branchManager.getBranch(branchID).getVersion(Math.abs(version)); - InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchVersion, - CDORevision.UNCHUNKED, true); + int column = 1; + for (CDOChangeSetSegment segment : segments) + { + stmt.setInt(column++, segment.getBranch().getID()); + stmt.setLong(column++, segment.getTimeStamp()); + stmt.setLong(column++, segment.getEndTime()); + } - if (!handler.handleRevision(revision)) + resultSet = stmt.executeQuery(); + while (resultSet.next()) { - break; + CDOID id = idHandler.getCDOID(resultSet, 1); + result.add(id); } + + return result; } - else + catch (SQLException e) + { + throw new DBException(e); + } + finally { - // Tell handler about detached IDs - InternalCDORevision revision = new DetachedCDORevision(null, id, null, version, 0); - handler.handleRevision(revision); + DBUtil.close(resultSet); + DBUtil.close(stmt); } } - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(resultSet); - DBUtil.close(stmt); - } - } - @Override - public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments) - { - StringBuilder builder = new StringBuilder(sqlSelectForChangeSet); - boolean isFirst = true; - - for (int i = 0; i < segments.length; i++) - { - if (isFirst) - { - isFirst = false; - } - else + @Override + protected String getListXRefsWhere(QueryXRefsContext context) { - builder.append(" OR "); //$NON-NLS-1$ - } - - builder.append(ATTRIBUTES_BRANCH); - builder.append("=? AND "); //$NON-NLS-1$ - - builder.append(ATTRIBUTES_CREATED); - builder.append(">=?"); //$NON-NLS-1$ - builder.append(" AND ("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("<=? OR "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("="); //$NON-NLS-1$ - builder.append(CDOBranchPoint.UNSPECIFIED_DATE); - builder.append(")"); //$NON-NLS-1$ - } - - IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler(); - IDBPreparedStatement stmt = accessor.getDBConnection().prepareStatement(builder.toString(), ReuseProbability.LOW); - ResultSet resultSet = null; - Set<CDOID> result = new HashSet<CDOID>(); + StringBuilder builder = new StringBuilder(); + builder.append(ATTRIBUTES_BRANCH); + builder.append("="); + builder.append(context.getBranch().getID()); + builder.append(" AND ("); + + long timeStamp = context.getTimeStamp(); + if (timeStamp == CDORevision.UNSPECIFIED_DATE) + { + builder.append(ATTRIBUTES_REVISED); + builder.append("=0)"); //$NON-NLS-1$ + } + else + { + builder.append(ATTRIBUTES_CREATED); + builder.append("<="); + builder.append(timeStamp); + builder.append(" AND ("); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append("=0 OR "); //$NON-NLS-1$ + builder.append(ATTRIBUTES_REVISED); + builder.append(">="); + builder.append(timeStamp); + builder.append("))"); //$NON-NLS-1$ + } - try - { - int column = 1; - for (CDOChangeSetSegment segment : segments) - { - stmt.setInt(column++, segment.getBranch().getID()); - stmt.setLong(column++, segment.getTimeStamp()); - stmt.setLong(column++, segment.getEndTime()); + return builder.toString(); } - resultSet = stmt.executeQuery(); - while (resultSet.next()) + public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, + OMMonitor monitor) { - CDOID id = idHandler.getCDOID(resultSet, 1); - result.add(id); - } - - return result; - } - catch (SQLException e) - { - throw new DBException(e); - } - finally - { - DBUtil.close(resultSet); - DBUtil.close(stmt); - } - } + monitor.begin(); - @Override - protected String getListXRefsWhere(QueryXRefsContext context) - { - StringBuilder builder = new StringBuilder(); - builder.append(ATTRIBUTES_BRANCH); - builder.append("="); - builder.append(context.getBranch().getID()); - builder.append(" AND ("); - - long timeStamp = context.getTimeStamp(); - if (timeStamp == CDORevision.UNSPECIFIED_DATE) - { - builder.append(ATTRIBUTES_REVISED); - builder.append("=0)"); //$NON-NLS-1$ - } - else - { - builder.append(ATTRIBUTES_CREATED); - builder.append("<="); - builder.append(timeStamp); - builder.append(" AND ("); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append("=0 OR "); //$NON-NLS-1$ - builder.append(ATTRIBUTES_REVISED); - builder.append(">="); - builder.append(timeStamp); - builder.append("))"); //$NON-NLS-1$ - } - - return builder.toString(); - } + try + { + if (accessor.getTransaction().getBranch() != delta.getBranch()) + { + // new branch -> decide, if branch should be copied + if (((HorizontalBranchingMappingStrategyWithRanges)getMappingStrategy()).shallCopyOnBranch()) + { + doCopyOnBranch(accessor, delta, created, monitor.fork()); + return; + } + } - public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, - OMMonitor monitor) - { - monitor.begin(); + Async async = null; - try - { - if (accessor.getTransaction().getBranch() != delta.getBranch()) - { - // new branch -> decide, if branch should be copied - if (((HorizontalBranchingMappingStrategyWithRanges)getMappingStrategy()).shallCopyOnBranch()) + try + { + async = monitor.forkAsync(); + FeatureDeltaWriter writer = deltaWriter.get(); + writer.process(accessor, delta, created); + } + finally + { + if (async != null) + { + async.stop(); + } + } + } + finally { - doCopyOnBranch(accessor, delta, created, monitor.fork()); - return; + monitor.done(); } } - Async async = null; - - try - { - async = monitor.forkAsync(); - FeatureDeltaWriter writer = deltaWriter.get(); - writer.process(accessor, delta, created); - } - finally + private void doCopyOnBranch(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, OMMonitor monitor) { - if (async != null) + monitor.begin(2); + try { - async.stop(); - } - } - } - finally - { - monitor.done(); - } - } + InternalRepository repository = (InternalRepository)accessor.getStore().getRepository(); - private void doCopyOnBranch(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, OMMonitor monitor) - { - monitor.begin(2); - try - { - InternalRepository repository = (InternalRepository)accessor.getStore().getRepository(); - - InternalCDORevision oldRevision = (InternalCDORevision)accessor.getTransaction().getRevision(delta.getID()); - if (oldRevision == null) - { - throw new IllegalStateException("Origin revision not found for " + delta); - } + InternalCDORevision oldRevision = (InternalCDORevision)accessor.getTransaction().getRevision(delta.getID()); + if (oldRevision == null) + { + throw new IllegalStateException("Origin revision not found for " + delta); + } - // Make sure all chunks are loaded - repository.ensureChunks(oldRevision, CDORevision.UNCHUNKED); + // Make sure all chunks are loaded + repository.ensureChunks(oldRevision, CDORevision.UNCHUNKED); - InternalCDORevision newRevision = oldRevision.copy(); - newRevision.adjustForCommit(accessor.getTransaction().getBranch(), created); - delta.apply(newRevision); - monitor.worked(); - writeRevision(accessor, newRevision, false, true, monitor.fork()); - } - finally - { - monitor.done(); - } - } + InternalCDORevision newRevision = oldRevision.copy(); + newRevision.adjustForCommit(accessor.getTransaction().getBranch(), created); + delta.applyTo(newRevision); + monitor.worked(); + writeRevision(accessor, newRevision, false, true, monitor.fork()); + } + finally + { + monitor.done(); + } + } } diff --git a/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OStoreAccessor.java index 16eb1fa8b3..1be101b4ce 100644 --- a/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OStoreAccessor.java @@ -725,7 +725,7 @@ public class DB4OStoreAccessor extends LongIDStoreAccessor implements Raw, Durab InternalCDORevision newRevision = revision.copy(); newRevision.adjustForCommit(branch, created); - revisionDelta.apply(newRevision); + revisionDelta.applyTo(newRevision); writeRevision(newRevision, new Monitor()); } diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java index d081c350b6..7f6772a2a8 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java @@ -916,7 +916,7 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS final Serializable idValue = HibernateUtil.getInstance().getIdValue(delta.getID()); final InternalCDORevision cdoRevision = (InternalCDORevision)session.get(entityName, idValue); cdoRevision.setListPreserving(); - delta.apply(cdoRevision); + delta.applyTo(cdoRevision); } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java index d8d68d94f0..48d4667e4c 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java @@ -1164,7 +1164,7 @@ public class TransactionCommitContext implements InternalCommitContext InternalCDORevision newRevision = oldRevision.copy(); newRevision.adjustForCommit(branch, timeStamp); - delta.apply(newRevision); + delta.applyTo(newRevision); return newRevision; } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java index 2b7750e9e1..32cb217075 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java @@ -355,7 +355,7 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl InternalCDORevision newRevision = revision.copy(); newRevision.adjustForCommit(branch, created); - revisionDelta.apply(newRevision); + revisionDelta.applyTo(newRevision); writeRevision(newRevision); } diff --git a/plugins/org.eclipse.emf.cdo.tests/launches/CDO AllTests (MEM legacy).launch b/plugins/org.eclipse.emf.cdo.tests/launches/CDO AllTests (MEM legacy).launch index 5385b79539..bb40a4a35e 100644 --- a/plugins/org.eclipse.emf.cdo.tests/launches/CDO AllTests (MEM legacy).launch +++ b/plugins/org.eclipse.emf.cdo.tests/launches/CDO AllTests (MEM legacy).launch @@ -12,5 +12,5 @@ <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.emf.cdo.tests.AllTestsMEMLegacy"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.emf.cdo.tests"/> -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx1024m -Dorg.eclipse.net4j.util.om.trace.disable=true"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx1024m -Dorg.eclipse.net4j.util.om.trace.disable=true -Dorg.eclipse.emf.cdo.tests.config.impl.RepositoryConfig.enableServerBrowser=false"/> </launchConfiguration> diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java index b42894da13..ff673b6ec8 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java @@ -1171,15 +1171,15 @@ public class ComplexTest extends AbstractCDOTest container2.setElement(element); commit(); - assertEquals(true, element.getParent() == container2); - assertEquals(true, element.eContainer() == container2); - assertEquals(true, CDOUtil.getCDOObject(element).cdoDirectResource() == null); + assertEquals(container2, element.getParent()); + assertEquals(container2, element.eContainer()); + assertEquals(null, CDOUtil.getCDOObject(element).cdoDirectResource()); - assertEquals(true, container1.getElement() == null); - assertEquals(true, CDOUtil.getCDOObject(container1).cdoDirectResource() == resource1); + assertEquals(null, container1.getElement()); + assertEquals(resource1, CDOUtil.getCDOObject(container1).cdoDirectResource()); - assertEquals(true, container2.getElement() == element); - assertEquals(true, CDOUtil.getCDOObject(container2).cdoDirectResource() == resource2); + assertEquals(element, container2.getElement()); + assertEquals(resource2, CDOUtil.getCDOObject(container2).cdoDirectResource()); } public void testMigrateContainmentMulti() @@ -1203,21 +1203,21 @@ public class ComplexTest extends AbstractCDOTest container2.getElements().add(container1.getElements().get(0)); commit(); - assertEquals(true, elementA.getParent() == container2); - assertEquals(true, elementA.eContainer() == container2); - assertEquals(true, CDOUtil.getCDOObject(elementA).cdoDirectResource() == null); - assertEquals(true, elementA.eResource() == resource2); + assertEquals(container2, elementA.getParent()); + assertEquals(container2, elementA.eContainer()); + assertEquals(null, CDOUtil.getCDOObject(elementA).cdoDirectResource()); + assertEquals(resource2, elementA.eResource()); - assertEquals(true, elementB.getParent() == container1); - assertEquals(true, elementB.eContainer() == container1); - assertEquals(true, CDOUtil.getCDOObject(elementB).cdoDirectResource() == null); - assertEquals(true, elementB.eResource() == resource1); + assertEquals(container1, elementB.getParent()); + assertEquals(container1, elementB.eContainer()); + assertEquals(null, CDOUtil.getCDOObject(elementB).cdoDirectResource()); + assertEquals(resource1, elementB.eResource()); - assertEquals(true, CDOUtil.getCDOObject(container1).cdoDirectResource() == resource1); + assertEquals(resource1, CDOUtil.getCDOObject(container1).cdoDirectResource()); assertEquals(1, container1.getElements().size()); assertEquals(elementB, container1.getElements().get(0)); - assertEquals(true, CDOUtil.getCDOObject(container2).cdoDirectResource() == resource2); + assertEquals(resource2, CDOUtil.getCDOObject(container2).cdoDirectResource()); assertEquals(1, container2.getElements().size()); assertEquals(elementA, container2.getElements().get(0)); } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java index 18337ff625..5632c651a5 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java @@ -53,36 +53,28 @@ public class InitialTest extends AbstractCDOTest { final Date date = new Date(); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); assertTransient(supplier); - msg("Setting name"); supplier.setName("Stepper"); assertTransient(supplier); - msg("Verifying name"); assertEquals("Stepper", supplier.getName()); assertTransient(supplier); - msg("Creating purchaseOrder"); PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder(); assertTransient(purchaseOrder); - msg("Setting date"); purchaseOrder.setDate(date); assertTransient(purchaseOrder); - msg("Verifying date"); assertEquals(date, purchaseOrder.getDate()); assertTransient(purchaseOrder); - msg("Setting supplier"); purchaseOrder.setSupplier(supplier); assertTransient(supplier); assertTransient(purchaseOrder); - msg("Verifying supplier"); assertEquals(supplier, purchaseOrder.getSupplier()); assertTransient(supplier); assertTransient(purchaseOrder); @@ -92,27 +84,22 @@ public class InitialTest extends AbstractCDOTest { final URI uri = URI.createURI("cdo:/test1"); - msg("Creating resourceSet"); ResourceSet resourceSet = new ResourceSetImpl(); SessionUtil.prepareResourceSet(resourceSet); - msg("Creating resource"); CDOResource resource = (CDOResource)resourceSet.createResource(uri); assertTransient(resource); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); assertTransient(supplier); assertEquals(null, supplier.eContainer()); - msg("Verifying contents"); EList<EObject> contents = resource.getContents(); assertNotNull(contents); assertEquals(true, contents.isEmpty()); assertEquals(0, contents.size()); assertTransient(resource); - msg("Adding supplier"); contents.add(supplier); assertTransient(resource); assertTransient(supplier); @@ -126,7 +113,6 @@ public class InitialTest extends AbstractCDOTest public void testOpenSession() throws Exception { - msg("Opening session"); CDOSession session = openSession(); assertNotNull(session); assertEquals(false, session.isClosed()); @@ -136,23 +122,22 @@ public class InitialTest extends AbstractCDOTest public void testStartTransaction() throws Exception { - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); assertNotNull(transaction); assertEquals(session, transaction.getSession()); } - public void testAttachResource() throws Exception + public void testCreateResource() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource(getResourcePath("/test1")); assertNew(resource, transaction); - assertEquals(URI.createURI("cdo://" + session.getRepositoryInfo().getUUID() + getResourcePath("/test1")), - resource.getURI()); + + URI uri = URI.createURI("cdo://" + session.getRepositoryInfo().getUUID() + getResourcePath("/test1")); + assertEquals(uri, resource.getURI()); ResourceSet expected = transaction.getResourceSet(); ResourceSet actual = resource.getResourceSet(); @@ -180,25 +165,17 @@ public class InitialTest extends AbstractCDOTest public void testCommitNew() throws Exception { - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); + assertEquals("Stepper", + CDOUtil.getCDOObject(supplier).cdoRevision().data().get(getModel1Package().getAddress_Name(), 0)); + CDOCommitInfo commit = transaction.commit(); assertEquals(CDOState.CLEAN, resource.cdoState()); assertEquals(CDOState.CLEAN, CDOUtil.getCDOObject(supplier).cdoState()); @@ -209,28 +186,16 @@ public class InitialTest extends AbstractCDOTest public void testReadResourceClean() throws Exception { - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); long commitTime = transaction.commit().getTimeStamp(); - msg("Getting supplier"); EList<EObject> contents = resource.getContents(); Supplier s = (Supplier)contents.get(0); assertEquals(1, CDOUtil.getCDOObject(s).cdoRevision().getVersion()); @@ -240,62 +205,34 @@ public class InitialTest extends AbstractCDOTest public void testReadObjectClean() throws Exception { - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); transaction.commit(); - msg("Getting supplier"); Supplier s = (Supplier)resource.getContents().get(0); assertEquals(1, CDOUtil.getCDOObject(s).cdoRevision().getVersion()); - - msg("Verifying name"); assertEquals("Stepper", s.getName()); } public void testWriteClean() throws Exception { - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); transaction.commit(); - msg("Getting supplier"); Supplier s = (Supplier)resource.getContents().get(0); - - msg("Setting name"); s.setName("Eike"); assertEquals("Eike", s.getName()); assertEquals(CDOState.DIRTY, CDOUtil.getCDOObject(supplier).cdoState()); @@ -328,36 +265,23 @@ public class InitialTest extends AbstractCDOTest public void testGetResource() throws Exception { - msg("Opening session"); CDOSession session = openSession(); { disableConsole(); - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); transaction.commit(); enableConsole(); } { - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Getting resource"); CDOResource resource = transaction.getResource(getResourcePath("/test1"), true); assertNotNull(resource); assertEquals(URI.createURI("cdo://" + session.getRepositoryInfo().getUUID() + getResourcePath("/test1")), @@ -370,10 +294,7 @@ public class InitialTest extends AbstractCDOTest } { - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Getting resource"); CDOResource resource = (CDOResource)transaction.getResourceSet().getResource( CDOURIUtil.createResourceURI(transaction, getResourcePath("/test1")), true); assertNotNull(resource); @@ -389,38 +310,24 @@ public class InitialTest extends AbstractCDOTest public void testGetContents() throws Exception { - msg("Opening session"); CDOSession session = openSession(); { disableConsole(); - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); transaction.commit(); enableConsole(); } - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Getting resource"); CDOResource resource = transaction.getResource(getResourcePath("/test1")); - msg("Getting contents"); EList<EObject> contents = resource.getContents(); assertNotNull(contents); @@ -430,45 +337,27 @@ public class InitialTest extends AbstractCDOTest public void testReadObjectProxy() throws Exception { - msg("Opening session"); CDOSession session = openSession(); { disableConsole(); - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); transaction.commit(); enableConsole(); } - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Getting resource"); CDOResource resource = transaction.getResource(getResourcePath("/test1")); - - msg("Getting contents"); EList<EObject> contents = resource.getContents(); - msg("Getting supplier"); Supplier s = (Supplier)contents.get(0); assertNotNull(s); - - msg("Verifying name"); assertEquals("Stepper", s.getName()); } @@ -510,38 +399,19 @@ public class InitialTest extends AbstractCDOTest public void testLoadResource() throws Exception { { - // disableConsole(); - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); transaction.commit(); - // XXX session.close(); - // enableConsole(); } - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Getting resource"); CDOResource resource = transaction.getResource(getResourcePath("/test1")); assertNotNull(resource); @@ -557,48 +427,24 @@ public class InitialTest extends AbstractCDOTest public void testLoadObject() throws Exception { { - // disableConsole(); - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating supplier"); Supplier supplier = getModel1Factory().createSupplier(); - - msg("Setting name"); supplier.setName("Stepper"); - - msg("Adding supplier"); resource.getContents().add(supplier); - msg("Committing"); transaction.commit(); - // XXX session.close(); - enableConsole(); } - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Getting resource"); CDOResource resource = transaction.getResource(getResourcePath("/test1")); - - msg("Getting contents"); EList<EObject> contents = resource.getContents(); - msg("Getting supplier"); Supplier s = (Supplier)contents.get(0); assertNotNull(s); - - msg("Verifying name"); assertEquals("Stepper", s.getName()); } @@ -635,19 +481,17 @@ public class InitialTest extends AbstractCDOTest session.close(); session = openSession(); - - msg("Opening transaction"); transaction = session.openTransaction(); + orderAddress = (OrderAddress)CDOUtil.getEObject(transaction.getObject(CDOUtil.getCDOObject(orderAddress).cdoID(), true)); - assertEquals(2.8f, orderAddress.getPrice()); assertEquals("ALLO", orderAddress.getCity()); orderAddress.setPrice(2.8f); transaction.commit(); - session.close(); + session.close(); session = openSession(); transaction = session.openTransaction(); @@ -658,56 +502,31 @@ public class InitialTest extends AbstractCDOTest assertEquals("ALLO", orderAddress.getCity()); orderAddress.setPrice(2.8f); - - session.close(); } public void testNullReference() throws Exception { { - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Creating resource"); CDOResource resource = transaction.createResource(getResourcePath("/test1")); - msg("Creating orderDetail"); OrderDetail orderDetail = getModel1Factory().createOrderDetail(); - - msg("Setting price"); orderDetail.setPrice(4.75f); - - msg("Adding orderDetail"); resource.getContents().add(orderDetail); - msg("Committing"); transaction.commit(); session.close(); } - msg("Opening session"); CDOSession session = openSession(); - - msg("Opening transaction"); CDOTransaction transaction = session.openTransaction(); - - msg("Getting resource"); CDOResource resource = transaction.getResource(getResourcePath("/test1")); - - msg("Getting contents"); EList<EObject> contents = resource.getContents(); - msg("Getting supplier"); OrderDetail orderDetail = (OrderDetail)contents.get(0); assertNotNull(orderDetail); - - msg("Verifying price"); assertEquals(4.75f, orderDetail.getPrice()); - - msg("Verifying product"); assertEquals(null, orderDetail.getProduct()); } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java index 24c08cb71b..77f1309e5c 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java @@ -410,7 +410,7 @@ public class StateMachineTest extends AbstractCDOTest CDOObject cdoObject = CDOUtil.getCDOObject(object); if (cdoObject != null) { - CDOStateMachine.INSTANCE.write((InternalCDOObject)cdoObject); + CDOStateMachine.INSTANCE.write((InternalCDOObject)cdoObject, null); } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java index 16645b8825..3921312b1c 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/TransactionTest.java @@ -608,13 +608,10 @@ public class TransactionTest extends AbstractCDOTest transaction.commit(); resource.getContents().remove(company); - // transaction.setSavepoint(); - resource.getContents().add(company); transaction.setSavepoint(); company.setName("ESC"); - transaction.commit(); } @@ -624,4 +621,24 @@ public class TransactionTest extends AbstractCDOTest Company company2 = (Company)resource2.getContents().get(0); assertEquals("ESC", company2.getName()); } + + public void testCommitRedundantChanges() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.getOrCreateResource(getResourcePath("/test1")); + + Company company = getModel1Factory().createCompany(); + company.setName("Eclipse"); + + resource.getContents().add(company); + transaction.commit(); + + company.setName("XYZ"); + company.setName("Eclipse"); + transaction.commit(); + + company.setName("ABC"); + transaction.commit(); + } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_279982_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_279982_Test.java index ac69a7d8fd..ae4cdc5b2a 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_279982_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_279982_Test.java @@ -123,7 +123,10 @@ public class Bugzilla_279982_Test extends AbstractCDOTest container.setElement(null); transaction.commit(); assertNull(container.getElement()); - assertNotNull(referencer.getElements().get(0)); + + EObject proxy = referencer.getElements().get(0); + assertNotNull(proxy); + assertEquals(true, CDOUtil.isStaleObject(proxy)); transaction.options().setStaleReferencePolicy(CDOStaleReferencePolicy.EXCEPTION); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_298561_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_298561_Test.java index 877b4929e9..351aa084d2 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_298561_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_298561_Test.java @@ -20,14 +20,13 @@ import org.eclipse.emf.cdo.tests.model4.RefSingleNonContainedNPL; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.util.CommitException; -import org.eclipse.emf.cdo.util.ObjectNotFoundException; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.util.EcoreUtil; /** * See bug 298561 - * + * * @author Eike Stepper */ public class Bugzilla_298561_Test extends AbstractCDOTest @@ -60,23 +59,12 @@ public class Bugzilla_298561_Test extends AbstractCDOTest // Refresh session.refresh(); - // - try - { - EReference ref = getModel4Package().getRefSingleNonContainedNPL_Element(); - boolean isSet = referencer.eIsSet(ref); - if (isSet) - { - assertNull(referencer.getElement()); - } - } - catch (ObjectNotFoundException e) + EReference ref = getModel4Package().getRefSingleNonContainedNPL_Element(); + boolean isSet = referencer.eIsSet(ref); + if (isSet) { - fail("Should not have thrown ObjectNotFoundException"); + assertNull(referencer.getElement()); } - - tx.close(); - session.close(); } public void testDirty() throws CommitException @@ -91,6 +79,7 @@ public class Bugzilla_298561_Test extends AbstractCDOTest // Create referencee and referencer (but no reference yet), and store them ContainedElementNoOpposite referencee = getModel4Factory().createContainedElementNoOpposite(); r1.getContents().add(referencee); + RefSingleNonContainedNPL referencer = getModel4Factory().createRefSingleNonContainedNPL(); r1.getContents().add(referencer); tx.commit(); @@ -105,21 +94,11 @@ public class Bugzilla_298561_Test extends AbstractCDOTest // Refresh session.refresh(); - try - { - boolean isSet = referencer.eIsSet(getModel4Package().getRefSingleNonContainedNPL_Element()); - if (isSet) - { - assertNull(referencer.getElement()); - } - } - catch (ObjectNotFoundException e) + boolean isSet = referencer.eIsSet(getModel4Package().getRefSingleNonContainedNPL_Element()); + if (isSet) { - fail("Should not have thrown ObjectNotFoundException"); + assertNull(referencer.getElement()); } - - tx.close(); - session.close(); } public void testNewMulti() throws CommitException @@ -148,22 +127,11 @@ public class Bugzilla_298561_Test extends AbstractCDOTest // Refresh session.refresh(); - // - try - { - boolean isSet = referencer.eIsSet(getModel4Package().getRefMultiNonContainedNPL_Elements()); - if (isSet && referencer.getElements().size() > 0) - { - assertNull(referencer.getElements().get(0)); - } - } - catch (ObjectNotFoundException e) + boolean isSet = referencer.eIsSet(getModel4Package().getRefMultiNonContainedNPL_Elements()); + if (isSet && referencer.getElements().size() > 0) { - fail("Should not have thrown ObjectNotFoundException"); + assertNull(referencer.getElements().get(0)); } - - tx.close(); - session.close(); } public void testDirtyMulti() throws CommitException @@ -192,22 +160,11 @@ public class Bugzilla_298561_Test extends AbstractCDOTest // Refresh session.refresh(); - // - try + boolean isSet = referencer.eIsSet(getModel4Package().getRefMultiNonContainedNPL_Elements()); + if (isSet && referencer.getElements().size() > 0) { - boolean isSet = referencer.eIsSet(getModel4Package().getRefMultiNonContainedNPL_Elements()); - if (isSet && referencer.getElements().size() > 0) - { - assertNull(referencer.getElements().get(0)); - } + assertNull(referencer.getElements().get(0)); } - catch (ObjectNotFoundException e) - { - fail("Should not have thrown ObjectNotFoundException"); - } - - tx.close(); - session.close(); } private void doSecondSession() throws CommitException diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_310574_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_310574_Test.java index 43140267b5..d7d84e0aae 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_310574_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_310574_Test.java @@ -35,7 +35,7 @@ import java.util.Random; * CDOAddFeatureDelta with null value. * <p> * See bug 310574 - * + * * @author Eike Stepper */ public class Bugzilla_310574_Test extends AbstractCDOTest @@ -144,17 +144,20 @@ public class Bugzilla_310574_Test extends AbstractCDOTest // Inspect the transaction. CDORevisionDelta delta = transaction.getRevisionDeltas().get(CDOUtil.getCDOObject(company).cdoID()); - for (CDOFeatureDelta featureDelta : delta.getFeatureDeltas()) + if (delta != null) { - if (featureDelta instanceof CDOListFeatureDelta) + for (CDOFeatureDelta featureDelta : delta.getFeatureDeltas()) { - CDOListFeatureDelta listFeatureDelta = (CDOListFeatureDelta)featureDelta; - for (CDOFeatureDelta featureDelta2 : listFeatureDelta.getListChanges()) + if (featureDelta instanceof CDOListFeatureDelta) { - if (featureDelta2 instanceof CDOAddFeatureDelta) + CDOListFeatureDelta listFeatureDelta = (CDOListFeatureDelta)featureDelta; + for (CDOFeatureDelta featureDelta2 : listFeatureDelta.getListChanges()) { - CDOAddFeatureDelta addFeatureDelta = (CDOAddFeatureDelta)featureDelta2; - assertNotSame(CDOID.NULL, addFeatureDelta.getValue()); + if (featureDelta2 instanceof CDOAddFeatureDelta) + { + CDOAddFeatureDelta addFeatureDelta = (CDOAddFeatureDelta)featureDelta2; + assertNotSame(CDOID.NULL, addFeatureDelta.getValue()); + } } } } @@ -194,12 +197,15 @@ public class Bugzilla_310574_Test extends AbstractCDOTest // Inspect the transaction. CDORevisionDelta delta = transaction.getRevisionDeltas().get(CDOUtil.getCDOObject(company).cdoID()); - for (CDOFeatureDelta featureDelta : delta.getFeatureDeltas()) + if (delta != null) { - if (featureDelta instanceof CDOListFeatureDelta) + for (CDOFeatureDelta featureDelta : delta.getFeatureDeltas()) { - CDOListFeatureDelta listFeatureDelta = (CDOListFeatureDelta)featureDelta; - assertEquals(0, listFeatureDelta.getListChanges().size()); + if (featureDelta instanceof CDOListFeatureDelta) + { + CDOListFeatureDelta listFeatureDelta = (CDOListFeatureDelta)featureDelta; + assertEquals(0, listFeatureDelta.getListChanges().size()); + } } } @@ -241,12 +247,15 @@ public class Bugzilla_310574_Test extends AbstractCDOTest // Inspect the transaction. CDORevisionDelta delta = transaction.getRevisionDeltas().get(CDOUtil.getCDOObject(company).cdoID()); - for (CDOFeatureDelta featureDelta : delta.getFeatureDeltas()) + if (delta != null) { - if (featureDelta instanceof CDOListFeatureDelta) + for (CDOFeatureDelta featureDelta : delta.getFeatureDeltas()) { - CDOListFeatureDelta listFeatureDelta = (CDOListFeatureDelta)featureDelta; - assertEquals(0, listFeatureDelta.getListChanges().size()); + if (featureDelta instanceof CDOListFeatureDelta) + { + CDOListFeatureDelta listFeatureDelta = (CDOListFeatureDelta)featureDelta; + assertEquals(0, listFeatureDelta.getListChanges().size()); + } } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java index 40e090fe09..028e8c5291 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_347964_Test.java @@ -18,6 +18,9 @@ import org.eclipse.emf.cdo.tests.model1.Company; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CDOUtil; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; + /** * @author Szabolcs Bardy */ @@ -49,10 +52,12 @@ public class Bugzilla_347964_Test extends AbstractCDOTest session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(0, 300)); CDOTransaction newTransaction = session.openTransaction(); - newTransaction.getResource(getResourcePath(RESOURCE_NAME)).getContents().remove(0); + CDOResource resource2 = newTransaction.getResource(getResourcePath(RESOURCE_NAME)); + EList<EObject> contents = resource2.getContents(); + contents.remove(0); newTransaction.commit(); - int contentsSize = newTransaction.getResource(getResourcePath(RESOURCE_NAME)).getContents().size(); + int contentsSize = contents.size(); assertEquals(0, contentsSize); } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_350987_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_350987_Test.java index 413e812f00..60d4bfc322 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_350987_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_350987_Test.java @@ -80,11 +80,14 @@ public class Bugzilla_350987_Test extends AbstractCDOTest .getCleanRevisions(); InternalCDORevision originRevision = cleanRevisions.get(cdoOrderDetail); - CDORevisionDelta delta = revision.compare(originRevision); + if (originRevision != null) + { + CDORevisionDelta delta = revision.compare(originRevision); - // Comparing with clean revision should not give changes - assertEquals(0, delta.size()); - assertEquals(true, delta.isEmpty()); + // Comparing with clean revision should not give changes + assertEquals(0, delta.size()); + assertEquals(true, delta.isEmpty()); + } Product1 product = products.get(0); resource.getContents().remove(1); @@ -98,9 +101,9 @@ public class Bugzilla_350987_Test extends AbstractCDOTest // Element shouldn't be added assertEquals(previousSize, product.getOrderDetails().size()); originRevision = cleanRevisions.get(cdoProduct); - delta = revision.compare(originRevision); + CDORevisionDelta delta2 = revision.compare(originRevision); // Comparing with clean revision should not give changes - assertEquals(true, delta.isEmpty()); + assertEquals(true, delta2.isEmpty()); } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_368223_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_368223_Test.java index 22858662eb..2dd76cf9aa 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_368223_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_368223_Test.java @@ -141,13 +141,12 @@ public class Bugzilla_368223_Test extends AbstractCDOTest CDOResource resource = transaction.getResource(getResourcePath("/test1")); List<Company> listOfCompanies = new ArrayList<Company>(); - int loop = 10; + int loop = 5; while (exception.get() == null && --loop != 0) { - // System.out.println(loop); synchronized (transaction) { - for (int i = 0; i < 100; i++) + for (int i = 0; i < 20; i++) { Company company = createCompanyWithCategories(resource); listOfCompanies.add(company); @@ -180,7 +179,7 @@ public class Bugzilla_368223_Test extends AbstractCDOTest Company company = getModel1Factory().createCompany(); EList<Category> categories = company.getCategories(); - for (int i = 0; i < 10; i++) + for (int i = 0; i < 5; i++) { Category category = getModel1Factory().createCategory(); categories.add(category); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_400311_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_400311_Test.java new file mode 100644 index 0000000000..73f88959f4 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_400311_Test.java @@ -0,0 +1,100 @@ +/* + * 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: + * Simon McDuff - initial API and implementation + * Eike Stepper - maintenance + */ +package org.eclipse.emf.cdo.tests.bugzilla; + +import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.session.CDOSession; +import org.eclipse.emf.cdo.tests.AbstractCDOTest; +import org.eclipse.emf.cdo.tests.model1.Company; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.view.CDOView; + +import org.eclipse.emf.ecore.EObject; + +/** + * Bug 400311 - CDOObject modifies Store even for Touch notifications. + * + * @author Eike Stepper + */ +public class Bugzilla_400311_Test extends AbstractCDOTest +{ + public void testOneFeature() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.getOrCreateResource(getResourcePath("/test1")); + + Company company = getModel1Factory().createCompany(); + company.setName("Eclipse"); + resource.getContents().add(company); + + transaction.commit(); + assertDirty(company, transaction, false); + + company.setName("XYZ"); + assertDirty(company, transaction, true); + + company.setName("Eclipse"); + assertDirty(company, transaction, false); + + transaction.commit(); + assertDirty(company, transaction, false); + + company.setName("ABC"); + assertDirty(company, transaction, true); + + transaction.commit(); + assertDirty(company, transaction, false); + } + + public void testTwoFeaturesUndoOne() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.getOrCreateResource(getResourcePath("/test1")); + + Company company = getModel1Factory().createCompany(); + company.setName("Eclipse"); + company.setStreet("1"); + resource.getContents().add(company); + + transaction.commit(); + assertDirty(company, transaction, false); + + company.setName("XYZ"); + company.setStreet("2"); + assertDirty(company, transaction, true); + + company.setName("Eclipse"); + assertDirty(company, transaction, true); + + company.setStreet("1"); + assertDirty(company, transaction, false); + + transaction.commit(); + assertDirty(company, transaction, false); + } + + private static void assertDirty(EObject eObject, CDOView view, boolean dirty) + { + if (dirty) + { + assertDirty(eObject, view); + } + else + { + assertClean(eObject, view); + } + + assertEquals(dirty, view.isDirty()); + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_400311b_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_400311b_Test.java new file mode 100644 index 0000000000..c9f3da8b3d --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_400311b_Test.java @@ -0,0 +1,619 @@ +/* + * 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: + * Alex Lagarde - initial API and implementation + */ +package org.eclipse.emf.cdo.tests.bugzilla; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionManager; +import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; +import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.internal.common.branch.CDOBranchVersionImpl; +import org.eclipse.emf.cdo.session.CDOSession; +import org.eclipse.emf.cdo.tests.AbstractCDOTest; +import org.eclipse.emf.cdo.tests.config.IModelConfig; +import org.eclipse.emf.cdo.tests.model1.OrderDetail; +import org.eclipse.emf.cdo.tests.model1.Product1; +import org.eclipse.emf.cdo.tests.model1.VAT; +import org.eclipse.emf.cdo.tests.model6.BaseObject; +import org.eclipse.emf.cdo.tests.model6.ContainmentObject; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; + +import java.util.LinkedList; +import java.util.List; + +/** + * Bug 400311 - CDOObject modifies Store even for Touch notifications. + * + * @author Alex Lagarde + */ +public class Bugzilla_400311b_Test extends AbstractCDOTest +{ + private CDOSession session; + + private CDOTransaction transaction; + + private OrderDetail orderDetail1; + + private OrderDetail orderDetail2; + + private Product1 product1; + + private Product1 product2; + + private ContainmentObject containmentObject; + + private BaseObject childObject; + + private int orderDetail1InitialVersion; + + private int product1InitialVersion; + + private int containmentObjectInitialVersion; + + private int childObjectInitialVersion; + + private CDOResource resource; + + @Override + protected void doSetUp() throws Exception + { + super.doSetUp(); + session = openSession(); + transaction = session.openTransaction(); + + orderDetail1 = getModel1Factory().createOrderDetail(); + orderDetail2 = getModel1Factory().createOrderDetail(); + product1 = getModel1Factory().createProduct1(); + product2 = getModel1Factory().createProduct1(); + orderDetail1.setProduct(product1); + product1.getOrderDetails().add(orderDetail1); + product1.getOrderDetails().add(orderDetail2); + product1.setVat(VAT.VAT0); + product1.getOtherVATs().add(VAT.VAT7); + product1.getOtherVATs().add(VAT.VAT15); + containmentObject = getModel6Factory().createContainmentObject(); + containmentObject.getAttributeList().add("attr1"); + containmentObject.getAttributeList().add("attr2"); + childObject = getModel6Factory().createBaseObject(); + containmentObject.getContainmentList().add(childObject); + + resource = transaction.createResource(getResourcePath("/test")); + resource.getContents().add(orderDetail1); + resource.getContents().add(orderDetail2); + resource.getContents().add(product1); + resource.getContents().add(product2); + resource.getContents().add(containmentObject); + + transaction.commit(); + + orderDetail1InitialVersion = CDOUtil.getCDOObject(orderDetail1).cdoRevision().getVersion(); + product1InitialVersion = CDOUtil.getCDOObject(product1).cdoRevision().getVersion(); + containmentObjectInitialVersion = CDOUtil.getCDOObject(containmentObject).cdoRevision().getVersion(); + childObjectInitialVersion = CDOUtil.getCDOObject(childObject).cdoRevision().getVersion(); + } + + @Override + protected void doTearDown() throws Exception + { + // Check that the server never contains 2 adjacent identical revisions + for (EObject element : resource.getContents()) + { + CDOID elementID = CDOUtil.getCDOObject(element).cdoID(); + assertServerDoesNotContainIdenticalAdjacentRevision(elementID, transaction); + } + + transaction.close(); + session.close(); + + super.doTearDown(); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnSingleValuedReference() throws Exception + { + // Step 1: Make touch modification + orderDetail1.setProduct(product1); + assertVersion(orderDetail1InitialVersion, orderDetail1); + + // Step 2: Commit + transaction.commit(); + assertVersion(orderDetail1InitialVersion, orderDetail1); + + // Step 3: make non touch modification + orderDetail1.setProduct(null); + assertDirty(orderDetail1, transaction); + transaction.commit(); + assertVersionIncreased(orderDetail1InitialVersion, orderDetail1); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnMultiValuedReference() throws Exception + { + // Step 1: Make touch modification + product1.getOrderDetails().add(orderDetail1); + assertVersion(product1InitialVersion, product1); + + // Step 2: Commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + + // Step 3: make non touch modification + product1.getOrderDetails().remove(orderDetail1); + assertDirty(product1, transaction); + transaction.commit(); + assertVersionIncreased(product1InitialVersion, product1); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnMultiValuedReferenceMove() throws Exception + { + // Step 1: Make touch modification + product1.getOrderDetails().move(0, orderDetail1); + assertVersion(product1InitialVersion, product1); + + // Step 2: Commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + + // Step 3: make non touch modification + product1.getOrderDetails().remove(orderDetail1); + assertDirty(product1, transaction); + transaction.commit(); + assertVersionIncreased(product1InitialVersion, product1); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnSingleValuedAttribute() throws Exception + { + // Step 1: Make touch modification + product1.setName(product1.getName()); + assertVersion(product1InitialVersion, product1); + + // Step 2: Commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + + // Step 3: make non touch modification + product1.setName(product1.getName() + "-MODIFIED"); + assertDirty(product1, transaction); + transaction.commit(); + assertVersionIncreased(product1InitialVersion, product1); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnMultiValuedAttribute() throws Exception + { + // Step 1: Make touch modification + containmentObject.getAttributeList().add("attr2"); + assertVersion(containmentObjectInitialVersion, containmentObject); + + // Step 2: Commit + transaction.commit(); + assertVersion(containmentObjectInitialVersion, containmentObject); + + // Step 3: make non touch modification + containmentObject.getAttributeList().remove("attr2"); + assertDirty(containmentObject, transaction); + transaction.commit(); + assertVersionIncreased(containmentObjectInitialVersion, containmentObject); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnMultiValuedAttributeMove() throws Exception + { + // Step 1: Make touch modification + containmentObject.getAttributeList().move(1, "attr2"); + assertVersion(containmentObjectInitialVersion, containmentObject); + + // Step 2: Commit + transaction.commit(); + assertVersion(containmentObjectInitialVersion, containmentObject); + + // Step 3: make non touch modification + containmentObject.getAttributeList().move(0, "attr2"); + assertDirty(containmentObject, transaction); + transaction.commit(); + assertVersionIncreased(containmentObjectInitialVersion, containmentObject); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnSingleValuedEnum() throws Exception + { + // Step 1: Make touch modification + product1.setVat(VAT.VAT0); + assertVersion(product1InitialVersion, product1); + + // Step 2: Commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + + // Step 3: make non touch modification + product1.setVat(VAT.VAT7); + assertDirty(product1, transaction); + transaction.commit(); + assertVersionIncreased(product1InitialVersion, product1); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnMultiValuedEnum() throws Exception + { + // Step 1: Make touch modification + product1.getOtherVATs().add(VAT.VAT7); + assertVersion(product1InitialVersion, product1); + + // Step 2: Commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + + // Step 3: make non touch modification + product1.getOtherVATs().remove(VAT.VAT7); + assertDirty(product1, transaction); + transaction.commit(); + assertVersionIncreased(product1InitialVersion, product1); + } + + public void testTouchModificationDoNotMakeObjectsDirtyOnMultiValuedEnumMove() throws Exception + { + // Step 1: Make touch modification + product1.getOtherVATs().move(0, VAT.VAT7); + assertVersion(product1InitialVersion, product1); + + // Step 2: Commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + + // Step 3: make non touch modification + product1.getOtherVATs().move(1, VAT.VAT7); + assertDirty(product1, transaction); + transaction.commit(); + assertVersionIncreased(product1InitialVersion, product1); + } + + public void testUndoRevertsToCleanStateOnSingleValuedReference() throws Exception + { + // Step 1: make modification + orderDetail1.setProduct(product2); + assertDirty(orderDetail1, transaction); + + // Step 2: get back to initial clean state + product1.getOrderDetails().add(0, orderDetail1); + assertVersion(orderDetail1InitialVersion, orderDetail1); + + // Step 3: commit + transaction.commit(); + assertVersion(orderDetail1InitialVersion, orderDetail1); + } + + public void testUndoRevertsToCleanStateOnMultiValuedReference() throws Exception + { + // Step 1: make modification + product1.getOrderDetails().remove(orderDetail1); + assertDirty(product1, transaction); + + // Step 2: get back to initial clean state + product1.getOrderDetails().add(0, orderDetail1); + assertVersion(product1InitialVersion, product1); + + // Step 3: commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + } + + public void testUndoRevertsToCleanStateOnMultiValuedReferenceMove() throws Exception + { + // Step 1: make modification + int oldIndex = product1.getOrderDetails().indexOf(orderDetail1); + product1.getOrderDetails().move(1, orderDetail1); + assertDirty(product1, transaction); + + // Step 2: get back to initial clean state + product1.getOrderDetails().move(oldIndex, orderDetail1); + assertVersion(product1InitialVersion, product1); + + // Step 3: commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + } + + public void testUndoRevertsToCleanStateOnSingleValuedAttribute() throws Exception + { + // Step 1: make modification + String initialValue = product1.getName(); + product1.setName("New name"); + assertDirty(product1, transaction); + + // Step 2: get back to initial clean state + product1.setName(initialValue); + assertVersion(product1InitialVersion, product1); + + // Step 3: commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + } + + public void testUndoRevertsToCleanStateOnMultiValuedAttribute() throws Exception + { + // Step 1: make modification + containmentObject.getAttributeList().add("attr3"); + assertDirty(containmentObject, transaction); + + // Step 2: get back to initial clean state + containmentObject.getAttributeList().remove("attr3"); + assertVersion(containmentObjectInitialVersion, containmentObject); + + // Step 3: commit + transaction.commit(); + assertVersion(containmentObjectInitialVersion, containmentObject); + } + + public void testUndoRevertsToCleanStateOnMultiValuedAttributeMove() throws Exception + { + // Step 1: make modification + int oldIndex = containmentObject.getAttributeList().indexOf("attr2"); + containmentObject.getAttributeList().move(0, "attr2"); + assertDirty(containmentObject, transaction); + + // Step 2: get back to initial clean state + containmentObject.getAttributeList().move(oldIndex, "attr2"); + assertVersion(containmentObjectInitialVersion, containmentObject); + + // Step 3: commit + transaction.commit(); + assertVersion(containmentObjectInitialVersion, containmentObject); + } + + public void testUndoRevertsToCleanStateOnSingleValuedEnum() throws Exception + { + // Step 1: make modification + product1.setVat(VAT.VAT7); + assertDirty(product1, transaction); + + // Step 2: get back to initial clean state + product1.setVat(VAT.VAT0); + assertVersion(product1InitialVersion, product1); + + // Step 3: commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + } + + public void testUndoRevertsToCleanStateOnMultiValuedEnum() throws Exception + { + // Step 1: make modification + product1.getOtherVATs().add(VAT.VAT0); + assertDirty(product1, transaction); + + // Step 2: get back to initial clean state + product1.getOtherVATs().remove(VAT.VAT0); + assertVersion(product1InitialVersion, product1); + + // Step 3: commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + } + + public void testUndoRevertsToCleanStateOnMultiValuedEnumMove() throws Exception + { + // Step 1: make modification + int oldIndex = product1.getOtherVATs().indexOf(VAT.VAT7); + product1.getOtherVATs().move(1, VAT.VAT7); + assertDirty(product1, transaction); + + // Step 2: get back to initial clean state + product1.getOtherVATs().move(oldIndex, VAT.VAT7); + assertVersion(product1InitialVersion, product1); + + // Step 3: commit + transaction.commit(); + assertVersion(product1InitialVersion, product1); + } + + public void testUndoRevertsToCleanStateOnObjectCreation() throws Exception + { + EList<BaseObject> containmentList = containmentObject.getContainmentList(); + + // Step 1: create a new object + BaseObject newObject = getModel6Factory().createBaseObject(); + containmentList.add(newObject); + assertDirty(containmentObject, transaction); + + // Step 2: delete the created object + containmentList.remove(newObject); + assertVersion(containmentObjectInitialVersion, containmentObject); + + // Step 3: commit + transaction.commit(); + assertVersion(containmentObjectInitialVersion, containmentObject); + } + + /** + * CDOLegacyAdapter creates (bogus?) CONTAINER deltas that aren't detected. + */ + @Skips(IModelConfig.CAPABILITY_LEGACY) + public void testUndoRevertsToCleanStateOnObjectDeletion() throws Exception + { + CDOID elementToDeleteID = CDOUtil.getCDOObject(childObject).cdoID(); + EList<BaseObject> containmentList = containmentObject.getContainmentList(); + + // For better debugging: + // Map<InternalCDOObject, InternalCDORevision> cleanRevisions = ((InternalCDOTransaction)transaction) + // .getCleanRevisions(); + // CDOSavepoint savepoint = transaction.getLastSavepoint(); + // Collection<CDORevisionDelta> revisionDeltas = savepoint.getRevisionDeltas2().values(); + + // Step 1: delete object + containmentList.remove(childObject); + assertDirty(containmentObject, transaction); + assertEquals("Element should be detached", true, transaction.getDetachedObjects().containsKey(elementToDeleteID)); + + // Step 2: undo deletion + containmentList.add(childObject); + assertVersion(containmentObjectInitialVersion, containmentObject); + assertVersion(childObjectInitialVersion, childObject); + assertEquals("Element should not be detached", false, + transaction.getDetachedObjects().containsKey(elementToDeleteID)); + + // Step 3: commit + transaction.commit(); + assertVersion(containmentObjectInitialVersion, containmentObject); + assertVersion(childObjectInitialVersion, childObject); + } + + /** + * CDOLegacyAdapter creates (bogus?) CONTAINER deltas that aren't detected. + */ + @Skips(IModelConfig.CAPABILITY_LEGACY) + public void testUndoRevertsToCleanStateOnComplexModifications() throws Exception + { + String oldContainmentObjectAttributeValue = containmentObject.getAttributeOptional(); + CDOID elementToDeleteID = CDOUtil.getCDOObject(childObject).cdoID(); + EList<BaseObject> containmentList = containmentObject.getContainmentList(); + + // Step 1: make several modifications (modifying several features on the same object and several objects) + containmentList.remove(childObject); + BaseObject newObject = getModel6Factory().createBaseObject(); + containmentList.add(newObject); + containmentObject.setAttributeOptional("MODIFIED"); + + String oldProduct1Name = product1.getName(); + product1.setName("New name"); + int oldVATIndexForProduct1 = product1.getOtherVATs().indexOf(VAT.VAT7); + product1.getOtherVATs().move(1, VAT.VAT7); + + orderDetail1.setProduct(product2); + + // Check that all modified objects are dirty/detached + assertDirty(containmentObject, transaction); + assertDirty(product1, transaction); + assertDirty(orderDetail1, transaction); + assertEquals("Element should be detached", true, transaction.getDetachedObjects().containsKey(elementToDeleteID)); + + // Step 2: get back to initial clean state step by step + product1.getOrderDetails().add(0, orderDetail1); + assertVersion(orderDetail1InitialVersion, orderDetail1, true); + + product1.getOtherVATs().move(oldVATIndexForProduct1, VAT.VAT7); + assertDirty(product1, transaction); + + product1.setName(oldProduct1Name); + assertVersion(product1InitialVersion, product1, true); + + containmentList.add(childObject); + assertDirty(containmentObject, transaction); + + containmentList.remove(newObject); + assertDirty(containmentObject, transaction); + + containmentObject.setAttributeOptional(oldContainmentObjectAttributeValue); + assertVersion(containmentObjectInitialVersion, containmentObject); + + // Step 3: commit + transaction.commit(); + assertVersion(orderDetail1InitialVersion, orderDetail1); + assertVersion(product1InitialVersion, product1); + assertVersion(containmentObjectInitialVersion, containmentObject); + } + + /** + * Ensures that the given object is clean and that its version was not increased compared to the given initial version. + * @param initalVersion the initial version of the object before it was modified + * @param element the EObject to test + */ + private void assertVersion(int expectedVersion, EObject element) + { + assertVersion(expectedVersion, element, false); + } + + private void assertVersion(int expectedVersion, EObject element, boolean expectedDirtyTransaction) + { + CDOObject cdoElement = CDOUtil.getCDOObject(element); + assertClean(cdoElement, ((CDOResource)cdoElement.eResource()).cdoView()); + assertEquals(expectedVersion, cdoElement.cdoRevision().getVersion()); + assertEquals("Transaction is not expected to contain revision deltas on the given object", null, transaction + .getRevisionDeltas().get(cdoElement.cdoID())); + + if (expectedDirtyTransaction) + { + assertNotSame("Transaction is expected to contain revision deltas", CDOIDUtil.createMap(), + transaction.getRevisionDeltas()); + } + else + { + assertEquals("Transaction is not expected to contain revision deltas", CDOIDUtil.createMap(), + transaction.getRevisionDeltas()); + } + + assertEquals("Transaction is expected to be " + (expectedDirtyTransaction ? "dirty" : "clean"), + expectedDirtyTransaction, transaction.isDirty()); + } + + /** + * Ensures that the given object is dirty and that its version was increased compared to the given initial version. + * @param initalVersion the initial version of the object before it was modified + * @param element the EObject to test + */ + private static void assertVersionIncreased(int initialVersion, EObject element) + { + CDOObject cdoElement = CDOUtil.getCDOObject(element); + assertEquals(initialVersion + 1, cdoElement.cdoRevision().getVersion()); + } + + /** + * Ensures that the CDOServer does not contain 2 identical Adjacent revisions. + */ + private static void assertServerDoesNotContainIdenticalAdjacentRevision(CDOID targetElement, + CDOTransaction transaction) + { + // Step 1: get all revisions for the given ID through the revision manager + CDORevisionManager revisionManager = transaction.getSession().getRevisionManager(); + int initialChunkSize = transaction.getSession().options().getCollectionLoadingPolicy().getInitialChunkSize(); + + int version = CDOBranchVersion.FIRST_VERSION; + List<CDORevision> revisions = new LinkedList<CDORevision>(); + + boolean noMoreRevisionsAvailable = false; + while (!noMoreRevisionsAvailable) + { + CDOBranchVersion branchVersion = new CDOBranchVersionImpl(transaction.getBranch(), version); + if (revisionManager.containsRevisionByVersion(targetElement, branchVersion)) + { + CDORevision fetched = revisionManager + .getRevisionByVersion(targetElement, branchVersion, initialChunkSize, true); + if (fetched != null) + { + revisions.add(fetched); + } + } + else + { + noMoreRevisionsAvailable = true; + } + + version++; + } + + // Step 2: compare all adjacent revisions and check that there are different + if (revisions.size() > 1) + { + for (int i = 0; i < revisions.size() - 1; i++) + { + CDORevision rev1 = revisions.get(i); + CDORevision rev2 = revisions.get(i + 1); + CDORevisionDelta rDelta = rev1.compare(rev2); + if (rDelta.getFeatureDeltas().size() == 0) + { + // The revision delta contains no feature deltas + // this means the revisions are identical + fail("2 Adjacent Revisions should never be equals."); + } + } + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_411927_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_411927_Test.java index cf5921d530..4c1a9c80e2 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_411927_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_411927_Test.java @@ -39,7 +39,7 @@ public class Bugzilla_411927_Test extends AbstractCDOTest { private static final String RESOURCE_NAME = "res1"; - private static final int CLIENTS = 20; + private static final int CLIENTS = 10; private static final int COMMITS_PER_CLIENT = 3; @@ -112,7 +112,7 @@ public class Bugzilla_411927_Test extends AbstractCDOTest } private void executeTestWith(FailureTime failureTime) throws ConcurrentAccessException, CommitException, - InterruptedException + InterruptedException { disableConsole(); initRepository(failureTime); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_415415_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_415415_Test.java index 839e9b9c31..84343cc8a1 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_415415_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_415415_Test.java @@ -23,7 +23,7 @@ import org.eclipse.emf.cdo.util.CDOUtil; /** * Bug 415415: Stale reference not removed between locally detached object and remotely changed ones - * + * * @author Esteban Dugueperoux */ public class Bugzilla_415415_Test extends AbstractCDOTest @@ -118,9 +118,9 @@ public class Bugzilla_415415_Test extends AbstractCDOTest assertEquals("As child1 is remotelly detached, the stale reference child2.otherNodes:child1 should be removed", 0, child2.getOtherNodes().size()); - String assertMessage = "As the stale reference child2.otherNodes:child1 has been removed and child2 is already dirty child2 should be the only dirty object"; - assertEquals(assertMessage, 1, transaction.getDirtyObjects().size()); - assertEquals(assertMessage, child2CDO, transaction.getDirtyObjects().get(child2ID)); + String assertMessage = "As the stale reference child2.otherNodes:child1 has been removed the transaction should be clean"; + assertEquals(assertMessage, false, transaction.isDirty()); + assertEquals(assertMessage, 0, transaction.getDirtyObjects().size()); transaction.commit(); remoteUser.assertNotStaleReference(); @@ -138,7 +138,7 @@ public class Bugzilla_415415_Test extends AbstractCDOTest assertEquals("As child1 is locally detached, the stale reference child2.otherNodes:child1 should be removed", 0, child2.getOtherNodes().size()); - String assertMessage = "As the stale reference child2.otherNodes:child1 has been removed, child2 should become the only dirty object with the nodeARoot"; + String assertMessage = "As the stale reference child2.otherNodes:child1 has been removed, child2 and nodeARoot should be the only dirty objects"; assertEquals(assertMessage, 2, transaction.getDirtyObjects().size()); assertEquals(assertMessage, child2CDO, transaction.getDirtyObjects().get(child2ID)); assertEquals(assertMessage, rootCDO, transaction.getDirtyObjects().get(rootID)); diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_419962_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_419962_Test.java index 8bdad83f9c..18e580e24f 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_419962_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_419962_Test.java @@ -87,8 +87,8 @@ public class Bugzilla_419962_Test extends AbstractCDOTest transactionB = sessionB.openTransaction(); transactionB.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); - transactionA.options().addConflictResolver(createCdoConflictResolver()); - transactionB.options().addConflictResolver(createCdoConflictResolver()); + transactionA.options().addConflictResolver(createConflictResolver()); + transactionB.options().addConflictResolver(createConflictResolver()); companyA = (Company)transactionA.getOrCreateResource(getResourcePath("/res1")).getContents().get(0); companyB = (Company)transactionB.getOrCreateResource(getResourcePath("/res1")).getContents().get(0); @@ -177,7 +177,7 @@ public class Bugzilla_419962_Test extends AbstractCDOTest assertEquals("Wrong state", state, object.cdoState()); } - private CDOConflictResolver createCdoConflictResolver() + private CDOConflictResolver createConflictResolver() { return new CDOMergingConflictResolver(new DefaultCDOMerger.PerFeature.ManyValued()); } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java index a7ae017bcb..85fb166568 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/SessionConfig.java @@ -182,9 +182,12 @@ public abstract class SessionConfig extends Config implements ISessionConfig @Override protected void onDeactivated(ILifecycle session) { - synchronized (sessions) + if (sessions != null) { - sessions.remove(session); + synchronized (sessions) + { + sessions.remove(session); + } } } }; diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java index ed4104125d..1ff6b99e2c 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java @@ -184,7 +184,7 @@ import java.util.Set; * @generated */ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProvider, ISelectionProvider, - IMenuListener, IViewerProvider +IMenuListener, IViewerProvider { /** * The filters for file extensions supported by the editor. @@ -1104,7 +1104,7 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv { BasicDiagnostic basicDiagnostic = new BasicDiagnostic(Diagnostic.ERROR, "org.eclipse.emf.cdo.ui", 0, getString( "_UI_CreateModelError_message", resource.getURI()), new Object[] { exception == null ? (Object)resource - : exception }); + : exception }); basicDiagnostic.merge(EcoreUtil.computeDiagnostic(resource, true)); return basicDiagnostic; } @@ -1244,6 +1244,12 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv super.setSelection(selection, reveal); } + + @Override + public String toString() + { + return "SelectionViewer"; + } }; selectionViewer.addTreeListener(new ITreeViewerListener() @@ -2308,8 +2314,8 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv final MenuManager submenuManager = new MenuManager(nsURI, imageDescriptor, nsURI); submenuManager.setRemoveAllWhenShown(true); submenuManager.add(new Action(Messages.getString("CDOEditor.27")) //$NON-NLS-1$ - { - }); + { + }); submenuManager.addMenuListener(new IMenuListener() { @@ -2353,12 +2359,12 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv if (!objects.isEmpty()) { Collections.sort(objects, new Comparator<EObject>() - { + { public int compare(EObject o1, EObject o2) { return o1.eClass().getName().compareTo(o2.eClass().getName()); } - }); + }); for (EObject object : objects) { diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOEventHandler.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOEventHandler.java index cc1f0e192b..a27dd98a47 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOEventHandler.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOEventHandler.java @@ -13,12 +13,14 @@ package org.eclipse.emf.cdo.ui; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOState; import org.eclipse.emf.cdo.internal.ui.ItemsProcessor; import org.eclipse.emf.cdo.internal.ui.bundle.OM; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.transaction.CDOTransactionConflictEvent; import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent; import org.eclipse.emf.cdo.transaction.CDOTransactionStartedEvent; +import org.eclipse.emf.cdo.view.CDOObjectHandler; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent; @@ -43,7 +45,7 @@ import java.util.Set; /** * A class that handles {@link org.eclipse.net4j.util.event.IEvent events} on * {@link org.eclipse.jface.viewers.TreeViewer TreeViewer}-based editors or views. - * + * * @author Eike Stepper * @see org.eclipse.net4j.util.event.IEvent * @see org.eclipse.jface.viewers.TreeViewer @@ -123,6 +125,14 @@ public class CDOEventHandler } }; + private CDOObjectHandler objectHandler = new CDOObjectHandler() + { + public void objectStateChanged(CDOView view, CDOObject object, CDOState oldState, CDOState newState) + { + CDOEventHandler.this.objectStateChanged(object); + } + }; + private IListener preferenceListener = new IListener() { public void notifyEvent(IEvent event) @@ -197,6 +207,7 @@ public class CDOEventHandler wirePreferences(); view.getSession().addListener(sessionListener); view.addListener(viewListener); + view.addObjectHandler(objectHandler); } /** @@ -206,6 +217,7 @@ public class CDOEventHandler { if (view != null) { + view.removeObjectHandler(objectHandler); view.removeListener(viewListener); CDOSession session = view.getSession(); if (session != null) @@ -267,6 +279,32 @@ public class CDOEventHandler } /** + * @since 4.3 + */ + public void updateElement(final Object element) + { + try + { + treeViewer.getControl().getDisplay().asyncExec(new Runnable() + { + public void run() + { + try + { + treeViewer.update(element, null); + } + catch (Exception ignore) + { + } + } + }); + } + catch (Exception ignore) + { + } + } + + /** * @since 2.0 */ public boolean isAutoReloadEnabled() @@ -291,6 +329,21 @@ public class CDOEventHandler } /** + * @since 4.3 + */ + protected void objectStateChanged(CDOObject cdoObject) + { + updateElement(cdoObject); + } + + /** + * @since 2.0 + */ + protected void objectInvalidated(InternalCDOObject cdoObject) + { + } + + /** * @since 2.0 */ protected void viewInvalidated(Set<? extends CDOObject> dirtyObjects) @@ -309,13 +362,6 @@ public class CDOEventHandler }.processCDOObjects(treeViewer, dirtyObjects); } - /** - * @since 2.0 - */ - protected void objectInvalidated(InternalCDOObject cdoObject) - { - } - protected void viewDirtyStateChanged() { } 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); /** |