diff options
author | Eike Stepper | 2018-04-23 11:06:31 +0000 |
---|---|---|
committer | Eike Stepper | 2018-04-23 11:06:31 +0000 |
commit | 03800f7122fd19ca49170de208e97742a57047da (patch) | |
tree | a31ec908fbbb9ebb01c2faa9da67878b645ee9fb | |
parent | 5f582b20c8a4602fc0cc4f554e5098aa2cc7e8c9 (diff) | |
download | cdo-03800f7122fd19ca49170de208e97742a57047da.tar.gz cdo-03800f7122fd19ca49170de208e97742a57047da.tar.xz cdo-03800f7122fd19ca49170de208e97742a57047da.zip |
[405543] An unsettable many-valued reference that is set to an empty list is unset on new transaction
https://bugs.eclipse.org/bugs/show_bug.cgi?id=405543
67 files changed, 1048 insertions, 330 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF index f1fa0c410d..2f7f8e640c 100644 --- a/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.emf.cdo.common -Bundle-Version: 4.6.100.qualifier +Bundle-Version: 4.7.0.qualifier Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -14,21 +14,21 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)";visibili org.eclipse.emf.ecore.change;bundle-version="[2.5.0,3.0.0)";visibility:=reexport, org.eclipse.emf.ecore.xmi;bundle-version="[2.5.0,3.0.0)";visibility:=reexport, org.eclipse.net4j.util;bundle-version="[3.0.0,4.0.0)";visibility:=reexport -Export-Package: org.eclipse.emf.cdo.common;version="4.6.100", - org.eclipse.emf.cdo.common.admin;version="4.6.100", - org.eclipse.emf.cdo.common.branch;version="4.6.100", - org.eclipse.emf.cdo.common.commit;version="4.6.100", - org.eclipse.emf.cdo.common.commit.handler;version="4.6.100", - org.eclipse.emf.cdo.common.id;version="4.6.100", - org.eclipse.emf.cdo.common.lob;version="4.6.100", - org.eclipse.emf.cdo.common.lock;version="4.6.100", - org.eclipse.emf.cdo.common.model;version="4.6.100", - org.eclipse.emf.cdo.common.protocol;version="4.6.100", - org.eclipse.emf.cdo.common.revision;version="4.6.100", - org.eclipse.emf.cdo.common.revision.delta;version="4.6.100", - org.eclipse.emf.cdo.common.security;version="4.6.100", - org.eclipse.emf.cdo.common.util;version="4.6.100", - org.eclipse.emf.cdo.internal.common;version="4.6.100"; +Export-Package: org.eclipse.emf.cdo.common;version="4.7.0", + org.eclipse.emf.cdo.common.admin;version="4.7.0", + org.eclipse.emf.cdo.common.branch;version="4.7.0", + org.eclipse.emf.cdo.common.commit;version="4.7.0", + org.eclipse.emf.cdo.common.commit.handler;version="4.7.0", + org.eclipse.emf.cdo.common.id;version="4.7.0", + org.eclipse.emf.cdo.common.lob;version="4.7.0", + org.eclipse.emf.cdo.common.lock;version="4.7.0", + org.eclipse.emf.cdo.common.model;version="4.7.0", + org.eclipse.emf.cdo.common.protocol;version="4.7.0", + org.eclipse.emf.cdo.common.revision;version="4.7.0", + org.eclipse.emf.cdo.common.revision.delta;version="4.7.0", + org.eclipse.emf.cdo.common.security;version="4.7.0", + org.eclipse.emf.cdo.common.util;version="4.7.0", + org.eclipse.emf.cdo.internal.common;version="4.7.0"; x-friends:="org.eclipse.emf.cdo.common, org.eclipse.emf.cdo.common.db, org.eclipse.emf.cdo, @@ -38,11 +38,11 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.6.100", org.eclipse.emf.cdo.ui, org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.server.hibernate", - org.eclipse.emf.cdo.internal.common.branch;version="4.6.100"; + org.eclipse.emf.cdo.internal.common.branch;version="4.7.0"; x-friends:="org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.server.hibernate", - org.eclipse.emf.cdo.internal.common.bundle;version="4.6.100";x-internal:=true, - org.eclipse.emf.cdo.internal.common.commit;version="4.6.100"; + org.eclipse.emf.cdo.internal.common.bundle;version="4.7.0";x-internal:=true, + org.eclipse.emf.cdo.internal.common.commit;version="4.7.0"; x-friends:="org.eclipse.emf.cdo.common, org.eclipse.emf.cdo.common.db, org.eclipse.emf.cdo, @@ -51,7 +51,7 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.6.100", org.eclipse.emf.cdo.server.net4j, org.eclipse.emf.cdo.ui, org.eclipse.emf.cdo.tests", - org.eclipse.emf.cdo.internal.common.id;version="4.6.100"; + org.eclipse.emf.cdo.internal.common.id;version="4.7.0"; x-friends:="org.eclipse.emf.cdo.common, org.eclipse.emf.cdo.common.db, org.eclipse.emf.cdo, @@ -62,9 +62,9 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.6.100", org.eclipse.emf.cdo.tests, org.eclipse.emf.cdo.admin, org.eclipse.emf.cdo.server.admin", - org.eclipse.emf.cdo.internal.common.lock;version="4.6.100";x-internal:=true, - org.eclipse.emf.cdo.internal.common.messages;version="4.6.100";x-internal:=true, - org.eclipse.emf.cdo.internal.common.model;version="4.6.100"; + org.eclipse.emf.cdo.internal.common.lock;version="4.7.0";x-internal:=true, + org.eclipse.emf.cdo.internal.common.messages;version="4.7.0";x-internal:=true, + org.eclipse.emf.cdo.internal.common.model;version="4.7.0"; x-friends:="org.eclipse.emf.cdo.common, org.eclipse.emf.cdo.common.db, org.eclipse.emf.cdo, @@ -73,7 +73,7 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.6.100", org.eclipse.emf.cdo.server.net4j, org.eclipse.emf.cdo.ui, org.eclipse.emf.cdo.tests", - org.eclipse.emf.cdo.internal.common.revision;version="4.6.100"; + org.eclipse.emf.cdo.internal.common.revision;version="4.7.0"; x-friends:="org.eclipse.emf.cdo.common, org.eclipse.emf.cdo.common.db, org.eclipse.emf.cdo, @@ -82,7 +82,7 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.6.100", org.eclipse.emf.cdo.server.net4j, org.eclipse.emf.cdo.ui, org.eclipse.emf.cdo.tests", - org.eclipse.emf.cdo.internal.common.revision.delta;version="4.6.100"; + org.eclipse.emf.cdo.internal.common.revision.delta;version="4.7.0"; x-friends:="org.eclipse.emf.cdo.common, org.eclipse.emf.cdo.common.db, org.eclipse.emf.cdo, @@ -91,14 +91,14 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.6.100", org.eclipse.emf.cdo.server.net4j, org.eclipse.emf.cdo.ui, org.eclipse.emf.cdo.tests", - org.eclipse.emf.cdo.spi.common;version="4.6.100", - org.eclipse.emf.cdo.spi.common.admin;version="4.6.100", - org.eclipse.emf.cdo.spi.common.branch;version="4.6.100", - org.eclipse.emf.cdo.spi.common.commit;version="4.6.100", - org.eclipse.emf.cdo.spi.common.id;version="4.6.100", - org.eclipse.emf.cdo.spi.common.lock;version="4.6.100", - org.eclipse.emf.cdo.spi.common.model;version="4.6.100", - org.eclipse.emf.cdo.spi.common.protocol;version="4.6.100", - org.eclipse.emf.cdo.spi.common.revision;version="4.6.100" + org.eclipse.emf.cdo.spi.common;version="4.7.0", + org.eclipse.emf.cdo.spi.common.admin;version="4.7.0", + org.eclipse.emf.cdo.spi.common.branch;version="4.7.0", + org.eclipse.emf.cdo.spi.common.commit;version="4.7.0", + org.eclipse.emf.cdo.spi.common.id;version="4.7.0", + org.eclipse.emf.cdo.spi.common.lock;version="4.7.0", + org.eclipse.emf.cdo.spi.common.model;version="4.7.0", + org.eclipse.emf.cdo.spi.common.protocol;version="4.7.0", + org.eclipse.emf.cdo.spi.common.revision;version="4.7.0" Automatic-Module-Name: org.eclipse.emf.cdo.common Eclipse-RegisterBuddy: org.eclipse.net4j.util diff --git a/plugins/org.eclipse.emf.cdo.common/pom.xml b/plugins/org.eclipse.emf.cdo.common/pom.xml index f08eab9cb6..d6515a09b9 100644 --- a/plugins/org.eclipse.emf.cdo.common/pom.xml +++ b/plugins/org.eclipse.emf.cdo.common/pom.xml @@ -25,7 +25,7 @@ <groupId>org.eclipse.emf.cdo</groupId> <artifactId>org.eclipse.emf.cdo.common</artifactId> - <version>4.6.100-SNAPSHOT</version> + <version>4.7.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java index 5ce24b2bd4..be19f375a0 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java @@ -33,7 +33,7 @@ public interface CDOID extends Comparable<CDOID>, Serializable public static final CDOID NULL = org.eclipse.emf.cdo.internal.common.id.CDOIDNullImpl.INSTANCE; /** - * @since 4.6 + * @since 4.7 */ public static final CDOID NIL = org.eclipse.emf.cdo.internal.common.id.CDOIDNilImpl.INSTANCE; @@ -42,7 +42,7 @@ public interface CDOID extends Comparable<CDOID>, Serializable public boolean isNull(); /** - * @since 4.6 + * @since 4.7 */ public boolean isNil(); @@ -77,7 +77,7 @@ public interface CDOID extends Comparable<CDOID>, Serializable NULL('N'), // /** - * @since 4.6 + * @since 4.7 */ NIL('I'), // diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java index 204471bee0..c607b37ef7 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java @@ -454,7 +454,7 @@ public final class CDORevisionUtil { if (feature.isMany()) { - CDOList list = revisionData.getList(feature); + CDOList list = revisionData.getListOrNull(feature); if (list != null) { for (Object value : list) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java index a6d150c0f8..5ca36d23ee 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java @@ -405,12 +405,14 @@ public final class CDOClassInfoImpl implements InternalCDOClassInfo, Adapter.Int { out.println(eClass.getName()); + out.println(); out.println("\t\t\tallPersistentFeatures"); for (EStructuralFeature feature : getAllPersistentFeatures()) { out.println("\t" + eClass.getFeatureID(feature) + "\t" + feature.getName() + "\t" + (feature.isTransient() ? "transient" : "persistent")); } + out.println(); out.println("\t\t\tsettingsFeatureIndices\tpersistentFeatureIndices\ttransientFeatureIndices"); for (int featureID = 0; featureID < settingsFeatureIndices.length; featureID++) { diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDOListImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDOListImpl.java index 06e77c786d..f52e607554 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDOListImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDOListImpl.java @@ -208,4 +208,22 @@ public class CDOListImpl extends BasicEList<Object> implements InternalCDOList.C flags &= ~USE_EQUALS_FLAG; } } + + /** + * An IndexOutOfBoundsException that constructs a message from the argument data. + * <p> + * Having this avoids having the byte code that computes the message repeated/in-lined at the creation site. + * + * @author Eike Stepper + * @since 4.7 + */ + public static class IndexOutOfBoundsException extends BasicIndexOutOfBoundsException + { + private static final long serialVersionUID = 1L; + + public IndexOutOfBoundsException(int index, int size) + { + super(index, size); + } + } } 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 d1adfeaa53..325fb8d5c0 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 @@ -52,7 +52,7 @@ public class CDOAddFeatureDeltaImpl extends CDOSingleValueFeatureDeltaImpl imple Object value = getValue(); InternalCDORevision internalRevision = (InternalCDORevision)revision; - CDOList list = internalRevision.getList(feature); + CDOList list = internalRevision.getOrCreateList(feature); if (index < 0) { 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 dd9f949584..14d9a6274e 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 @@ -563,6 +563,18 @@ public class CDOListFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOL { listChanges.add(featureDelta); } + + if (featureDelta.getType() != CDOFeatureDelta.Type.UNSET) + { + EStructuralFeature feature = featureDelta.getFeature(); + if (feature.isMany() && feature.isUnsettable()) + { + if (listChanges.isEmpty()) + { + listChanges.add(new CDOClearFeatureDeltaImpl(feature)); + } + } + } } public Object applyTo(CDORevision revision) 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 5a50399db4..bd8c0a65b5 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 @@ -120,7 +120,7 @@ public class CDOMoveFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOM EStructuralFeature feature = getFeature(); InternalCDORevision internalRevision = (InternalCDORevision)revision; - CDOList list = internalRevision.getList(feature); + CDOList list = internalRevision.getListOrNull(feature); if (oldPosition < 0) { 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 6af546a07a..b48cd7224a 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 @@ -71,7 +71,12 @@ public class CDORemoveFeatureDeltaImpl extends CDOSingleValueFeatureDeltaImpl im int index = getIndex(); InternalCDORevision internalRevision = (InternalCDORevision)revision; - CDOList list = internalRevision.getList(feature); + CDOList list = internalRevision.getListOrNull(feature); + if (list == null) + { + return null; + } + return list.remove(index); } 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 123c59bdbd..b47b69f69d 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 @@ -455,7 +455,7 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta private void checkNoProxies(EList<?> list, CDORevision revision) { - if (!((InternalCDORevision)revision).isUnchunked()) + if (list != null && !((InternalCDORevision)revision).isUnchunked()) { for (Object element : list) { @@ -468,8 +468,17 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta } }; - CDOList originList = originRevision.getList(feature); - CDOList dirtyList = dirtyRevision.getList(feature); + CDOList originList = originRevision.getListOrNull(feature); + if (originList == null) + { + originList = new CDOListImpl(0, 0); + } + + CDOList dirtyList = dirtyRevision.getListOrNull(feature); + if (dirtyList == null) + { + dirtyList = new CDOListImpl(0, 0); + } analyzer.analyzeLists(originList, dirtyList, new NOOPList()); if (!changes.isEmpty()) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java index 050788c09e..455308b5f3 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java @@ -192,11 +192,14 @@ public abstract class AbstractCDORevision implements InternalCDORevision { if (feature.isMany()) { - int index = 0; - CDOList list = getList(feature); - for (Object value : list) + CDOList list = getListOrNull(feature); + if (list != null) { - visitor.visit(feature, value, index++); + int index = 0; + for (Object value : list) + { + visitor.visit(feature, value, index++); + } } } else @@ -281,6 +284,18 @@ public abstract class AbstractCDORevision implements InternalCDORevision return string; } + @Deprecated + public CDOList getList(EStructuralFeature feature) + { + return getOrCreateList(feature); + } + + @Deprecated + public CDOList getList(EStructuralFeature feature, int initialCapacity) + { + return getOrCreateList(feature, initialCapacity); + } + /** * @since 4.2 */ diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java index 38caa46944..d422ff1989 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java @@ -39,6 +39,7 @@ import org.eclipse.emf.cdo.common.security.NoPermissionException; import org.eclipse.emf.cdo.common.util.CDOCommonUtil; import org.eclipse.emf.cdo.internal.common.bundle.OM; import org.eclipse.emf.cdo.internal.common.messages.Messages; +import org.eclipse.emf.cdo.internal.common.revision.CDOListImpl; import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl; import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil; import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch; @@ -57,6 +58,7 @@ import org.eclipse.emf.ecore.util.FeatureMap.Entry; import org.eclipse.emf.ecore.util.FeatureMapUtil; import java.io.IOException; +import java.lang.reflect.Array; import java.text.MessageFormat; import java.util.Map; @@ -99,6 +101,8 @@ public abstract class BaseCDORevision extends AbstractCDORevision private static final byte PERMISSION_MASK = READ_PERMISSION_FLAG | WRITE_PERMISSION_FLAG; // 3 + private static final Object[] EMPTY_ARRAY = {}; + private CDOID id; private CDOBranchPoint branchPoint; @@ -663,7 +667,12 @@ public abstract class BaseCDORevision extends AbstractCDORevision { if (feature.isMany()) { - CDOList list = getList(feature); + CDOList list = getListOrNull(feature); + if (list == null) + { + throw new CDOListImpl.IndexOutOfBoundsException(index, 0); + } + return list.get(index); } @@ -672,32 +681,32 @@ public abstract class BaseCDORevision extends AbstractCDORevision public boolean contains(EStructuralFeature feature, Object value) { - CDOList list = getList(feature); - return list.contains(value); + CDOList list = getListOrNull(feature); + return list != null && list.contains(value); } public int indexOf(EStructuralFeature feature, Object value) { - CDOList list = getList(feature); - return list.indexOf(value); + CDOList list = getListOrNull(feature); + return list == null ? -1 : list.indexOf(value); } public int lastIndexOf(EStructuralFeature feature, Object value) { - CDOList list = getList(feature); - return list.lastIndexOf(value); + CDOList list = getListOrNull(feature); + return list == null ? -1 : list.lastIndexOf(value); } public boolean isEmpty(EStructuralFeature feature) { - CDOList list = getList(feature); - return list.isEmpty(); + CDOList list = getListOrNull(feature); + return list == null || list.isEmpty(); } public int size(EStructuralFeature feature) { - CDOList list = getList(feature); - return list.size(); + CDOList list = getListOrNull(feature); + return list == null ? 0 : list.size(); } public Object[] toArray(EStructuralFeature feature) @@ -707,8 +716,8 @@ public abstract class BaseCDORevision extends AbstractCDORevision throw new IllegalStateException("!feature.isMany()"); } - CDOList list = getList(feature); - return list.toArray(); + CDOList list = getListOrNull(feature); + return list == null ? EMPTY_ARRAY : list.toArray(); } public <T> T[] toArray(EStructuralFeature feature, T[] array) @@ -718,21 +727,33 @@ public abstract class BaseCDORevision extends AbstractCDORevision throw new IllegalStateException("!feature.isMany()"); } - CDOList list = getList(feature); + CDOList list = getListOrNull(feature); + if (list == null) + { + if (array.length != 0) + { + @SuppressWarnings("unchecked") + T[] emptyArray = (T[])Array.newInstance(array.getClass().getComponentType(), 0); + return emptyArray; + } + + return array; + } + return list.toArray(array); } public void add(EStructuralFeature feature, int index, Object value) { - CDOList list = getList(feature); + CDOList list = getOrCreateList(feature); list.add(index, value); } public void clear(EStructuralFeature feature) { - if (feature.isMany() && isListPreserving()) + if (feature.isMany() && feature.isUnsettable()) { - getList(feature).clear(); + getOrCreateList(feature).clear(); } else { @@ -742,13 +763,23 @@ public abstract class BaseCDORevision extends AbstractCDORevision public Object move(EStructuralFeature feature, int targetIndex, int sourceIndex) { - CDOList list = getList(feature); + CDOList list = getListOrNull(feature); + if (list == null) + { + throw new CDOListImpl.IndexOutOfBoundsException(sourceIndex, 0); + } + return list.move(targetIndex, sourceIndex); } public Object remove(EStructuralFeature feature, int index) { - CDOList list = getList(feature); + CDOList list = getListOrNull(feature); + if (list == null) + { + throw new CDOListImpl.IndexOutOfBoundsException(index, 0); + } + return list.remove(index); } @@ -756,7 +787,7 @@ public abstract class BaseCDORevision extends AbstractCDORevision { if (feature.isMany()) { - CDOList list = getList(feature); + CDOList list = getOrCreateList(feature); return list.set(index, value); } @@ -767,7 +798,9 @@ public abstract class BaseCDORevision extends AbstractCDORevision { if (feature.isMany() && isListPreserving()) { - getList(feature).clear(); + // isListPreserving() is always false except for HibernateStoreAccessor. + // For performance reasons this Hibernate-specific feature should probably be implemented via a custom revision factory. + getOrCreateList(feature).clear(); } else { @@ -872,19 +905,32 @@ public abstract class BaseCDORevision extends AbstractCDORevision } } - public CDOList getList(EStructuralFeature feature) + /** + * @since 4.7 + */ + public CDOList getListOrNull(EStructuralFeature feature) + { + return getOrCreateList(feature, DO_NOT_CREATE_LIST); + } + + public CDOList getOrCreateList(EStructuralFeature feature) { - return getList(feature, 0); + return getOrCreateList(feature, 0); } - public CDOList getList(EStructuralFeature feature, int size) + public CDOList getOrCreateList(EStructuralFeature feature, int size) { checkReadable(feature); int featureIndex = getFeatureIndex(feature); InternalCDOList list = (InternalCDOList)getValue(featureIndex); - if (list == null && size != -1) + if (list == null) { + if (size == DO_NOT_CREATE_LIST) + { + return null; + } + list = (InternalCDOList)CDOListFactory.DEFAULT.createList(size, 0, 0); if (feature instanceof EReference && list instanceof ConfigurableEquality) { diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java index 425ef7b162..dcc87974be 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java @@ -327,14 +327,31 @@ public abstract class DelegatingCDORevision implements InternalCDORevision getDelegate().setList(feature, list); } + @Deprecated public CDOList getList(EStructuralFeature feature) { return getDelegate().getList(feature); } - public CDOList getList(EStructuralFeature feature, int size) + @Deprecated + public CDOList getList(EStructuralFeature feature, int initialCapacity) { - return getDelegate().getList(feature, size); + return getDelegate().getList(feature, initialCapacity); + } + + public CDOList getListOrNull(EStructuralFeature feature) + { + return getDelegate().getListOrNull(feature); + } + + public CDOList getOrCreateList(EStructuralFeature feature) + { + return getDelegate().getOrCreateList(feature); + } + + public CDOList getOrCreateList(EStructuralFeature feature, int size) + { + return getDelegate().getOrCreateList(feature, size); } public void read(CDODataInput in) throws IOException diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDOList.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDOList.java index 1e69748144..fd61811bbe 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDOList.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDOList.java @@ -50,7 +50,7 @@ public interface InternalCDOList extends CDOList public void setWithoutFrozenCheck(int i, Object value); /** - * A mixin interface for {@link InternalCDOList} that allows to optimize the speed of equality checks. + * A mix-in interface for {@link InternalCDOList} that allows to optimize the speed of equality checks. * * @author Eike Stepper * @since 4.2 diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java index ae190bc242..b2c586d81c 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java @@ -41,6 +41,11 @@ import java.util.List; public interface InternalCDORevision extends CDORevision, CDORevisionData, CDOReferenceAdjustable, CDOBranchAdjustable { /** + * @since 4.7 + */ + public static final int DO_NOT_CREATE_LIST = -1; + + /** * @since 4.2 */ public InternalCDOClassInfo getClassInfo(); @@ -103,14 +108,47 @@ public interface InternalCDORevision extends CDORevision, CDORevisionData, CDORe public void setList(EStructuralFeature feature, InternalCDOList list); + /** + * @deprecated As of 4.7 use either {@link #getListOrNull(EStructuralFeature)} or {@link #getOrCreateList(EStructuralFeature)}. + */ + @Deprecated public CDOList getList(EStructuralFeature feature); /** + * @deprecated As of 4.7 use either {@link #getListOrNull(EStructuralFeature)} or {@link #getOrCreateList(EStructuralFeature, int)}. + */ + @Deprecated + public CDOList getList(EStructuralFeature feature, int initialCapacity); + + /** + * @since 4.7 + */ + public CDOList getListOrNull(EStructuralFeature feature); + + /** + * Same as {@link #getOrCreateList(EStructuralFeature, int) getOrCreateList(feature, 0)}. + * <p> + * <b>Warning</b>: Must be used with caution because list creation for an {@link EStructuralFeature#isUnsettable() unsettable} + * feature implies a transition from UNSET to SET! + * + * @since 4.7 + */ + public CDOList getOrCreateList(EStructuralFeature feature); + + /** + * Returns the list that represents the passed feature, possibly creates it if needed. + * <p> + * <b>Warning</b>: Must be used with caution because list creation for an {@link EStructuralFeature#isUnsettable() unsettable} + * feature implies a transition from UNSET to SET! + * * @param initialCapacity * the initialCapacity of a new list to be created if this revision has no list so far (its size will always * be 0), or -1 to skip list creation and return <code>null</code> in this case. + * + * @see #DO_NOT_CREATE_LIST + * @since 4.7 */ - public CDOList getList(EStructuralFeature feature, int initialCapacity); + public CDOList getOrCreateList(EStructuralFeature feature, int initialCapacity); /** * @since 3.0 diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java index 90e5f56bf2..c8dd04e1d2 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java @@ -134,12 +134,17 @@ public class StubCDORevision extends AbstractCDORevision throw new UnsupportedOperationException(getExceptionMessage()); } - public CDOList getList(EStructuralFeature feature) + public CDOList getListOrNull(EStructuralFeature feature) { throw new UnsupportedOperationException(getExceptionMessage()); } - public CDOList getList(EStructuralFeature feature, int size) + public CDOList getOrCreateList(EStructuralFeature feature) + { + throw new UnsupportedOperationException(getExceptionMessage()); + } + + public CDOList getOrCreateList(EStructuralFeature feature, int size) { throw new UnsupportedOperationException(getExceptionMessage()); } diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutContentProvider.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutContentProvider.java index e53487fefe..6fe4168b92 100644 --- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutContentProvider.java +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutContentProvider.java @@ -972,10 +972,13 @@ public class CDOCheckoutContentProvider implements ICommonContentProvider, IProp { if (feature.isMany()) { - CDOList list = revision.getList(feature); - for (Object object : list) + CDOList list = revision.getListOrNull(feature); + if (list != null) { - determineChildRevision(loadedRevisions, missingIDs, view, revisionCache, object); + for (Object object : list) + { + determineChildRevision(loadedRevisions, missingIDs, view, revisionCache, object); + } } } else diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LoadChunkRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LoadChunkRequest.java index 33bbfe9168..4f466380d1 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LoadChunkRequest.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LoadChunkRequest.java @@ -109,7 +109,7 @@ public class LoadChunkRequest extends CDOClientRequest<Object> { CDOType type = CDOModelUtil.getType(feature); Object accessID = null; - InternalCDOList list = (InternalCDOList)revision.getList(feature); + InternalCDOList list = (InternalCDOList)revision.getListOrNull(feature); for (int i = fromIndex; i <= toIndex; i++) { Object value = type.readValue(in); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java index bbb8163fc6..c579cd8377 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractBasicListTableMapping.java @@ -252,10 +252,9 @@ public abstract class AbstractBasicListTableMapping implements IListMapping3, IM public void visit(CDOUnsetFeatureDelta delta) { - // TODO Shouldn't that be "!unsettable"?! - if (delta.getFeature().isUnsettable()) + if (!delta.getFeature().isUnsettable()) { - throw new IllegalArgumentException("Feature is unsettable: " + delta); + throw new IllegalArgumentException("Feature is not unsettable: " + delta); } if (TRACER.isEnabled()) diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java index e70bb8024f..f8889bc24c 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java @@ -306,10 +306,16 @@ public abstract class AbstractFeatureMapTableMapping extends AbstractBasicListTa public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { - MoveableList<Object> list = revision.getList(getFeature()); + MoveableList<Object> list = revision.getListOrNull(getFeature()); + if (list == null) + { + // Nothing to read take shortcut. + return; + } + if (listChunk == 0 || list.size() == 0) { - // nothing to read take shortcut + // Nothing to read take shortcut. return; } @@ -464,12 +470,14 @@ public abstract class AbstractFeatureMapTableMapping extends AbstractBasicListTa public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { - CDOList values = revision.getList(getFeature()); - - int idx = 0; - for (Object element : values) + CDOList values = revision.getListOrNull(getFeature()); + if (values != null) { - writeValue(accessor, revision, idx++, element); + int idx = 0; + for (Object element : values) + { + writeValue(accessor, revision, idx++, element); + } } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java index cb0d7519f7..f885e7a5d4 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java @@ -70,8 +70,6 @@ import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.FeatureMapUtil; -import org.eclipse.core.runtime.Assert; - import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -91,6 +89,8 @@ import java.util.Set; */ public abstract class AbstractHorizontalClassMapping implements IClassMapping, IMappingConstants, IDeactivateable { + protected static final int UNSET_LIST = -1; + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractHorizontalClassMapping.class); private EClass eClass; @@ -455,19 +455,19 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping, I { EStructuralFeature feature = listSizeEntry.getKey(); IDBField field = listSizeEntry.getValue(); - int size = resultSet.getInt(field.getName()); - // ensure the listSize (TODO: remove assertion) - CDOList list = revision.getList(feature, size); - - for (int i = 0; i < size; i++) + int size = resultSet.getInt(field.getName()); + if (size == UNSET_LIST) { - list.add(InternalCDOList.UNINITIALIZED); + // Leave the list slot in the revision null. + continue; } - if (list.size() != size) + // Ensure the list size. + CDOList list = revision.getOrCreateList(feature, size); + for (int i = 0; i < size; i++) { - Assert.isTrue(false); + list.add(InternalCDOList.UNINITIALIZED); } } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java index 901c0cdfee..07778bef59 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractListTableMapping.java @@ -233,9 +233,14 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { - MoveableList<Object> list = revision.getList(getFeature()); + if (listChunk == 0) + { + // Nothing to read. Take shortcut. + return; + } - if (listChunk == 0 || list.size() == 0) + MoveableList<Object> list = revision.getListOrNull(getFeature()); + if (list == null || list.size() == 0) { // Nothing to read. Take shortcut. return; @@ -391,12 +396,14 @@ public abstract class AbstractListTableMapping extends AbstractBasicListTableMap public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { - CDOList values = revision.getList(getFeature()); - - int idx = 0; - for (Object element : values) + CDOList values = revision.getListOrNull(getFeature()); + if (values != null) { - writeValue(accessor, revision, idx++, element); + int idx = 0; + for (Object element : values) + { + writeValue(accessor, revision, idx++, element); + } } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java index 1567dd5a94..77c6a46f0e 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java @@ -389,10 +389,16 @@ public class AuditFeatureMapTableMappingWithRanges extends AbstractBasicListTabl public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { - MoveableList<Object> list = revision.getList(getFeature()); + MoveableList<Object> list = revision.getListOrNull(getFeature()); + if (list == null) + { + // Nothing to read take shortcut. + return; + } + if (listChunk == 0 || list.size() == 0) { - // nothing to read take shortcut + // Nothing to read take shortcut. return; } @@ -553,17 +559,19 @@ public class AuditFeatureMapTableMappingWithRanges extends AbstractBasicListTabl public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { - CDOList values = revision.getList(getFeature()); - - int idx = 0; - for (Object element : values) + CDOList values = revision.getListOrNull(getFeature()); + if (values != null) { - writeValue(accessor, revision, idx++, element); - } + int idx = 0; + for (Object element : values) + { + writeValue(accessor, revision, idx++, element); + } - if (TRACER.isEnabled()) - { - TRACER.format("Writing done"); //$NON-NLS-1$ + if (TRACER.isEnabled()) + { + TRACER.format("Writing done"); //$NON-NLS-1$ + } } } @@ -712,7 +720,7 @@ public class AuditFeatureMapTableMappingWithRanges extends AbstractBasicListTabl InternalCDORevision originalRevision = (InternalCDORevision)repo.getRevisionManager().getRevision(id, repo.getBranchManager().getMainBranch().getHead(), /* chunksize = */0, CDORevision.DEPTH_NONE, true); - int oldListSize = originalRevision.getList(getFeature()).size(); + int oldListSize = originalRevision.size(getFeature()); if (TRACER.isEnabled()) { @@ -757,7 +765,7 @@ public class AuditFeatureMapTableMappingWithRanges extends AbstractBasicListTabl id = this.originalRevision.getID(); this.oldVersion = oldVersion; this.newVersion = newVersion; - lastIndex = originalRevision.getList(getFeature()).size() - 1; + lastIndex = originalRevision.size(getFeature()) - 1; this.timestamp = timestamp; } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java index a3d6b6720b..ac85dac311 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditListTableMappingWithRanges.java @@ -314,10 +314,16 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { - MoveableList<Object> list = revision.getList(getFeature()); + MoveableList<Object> list = revision.getListOrNull(getFeature()); + if (list == null) + { + // Nothing to read take shortcut. + return; + } + if (listChunk == 0 || list.size() == 0) { - // nothing to read take shortcut + // Nothing to read take shortcut. return; } @@ -463,17 +469,19 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { - CDOList values = revision.getList(getFeature()); - - int idx = 0; - for (Object element : values) + CDOList values = revision.getListOrNull(getFeature()); + if (values != null) { - writeValue(accessor, revision, idx++, element); - } + int idx = 0; + for (Object element : values) + { + writeValue(accessor, revision, idx++, element); + } - if (TRACER.isEnabled()) - { - TRACER.format("Writing done"); //$NON-NLS-1$ + if (TRACER.isEnabled()) + { + TRACER.format("Writing done"); //$NON-NLS-1$ + } } } @@ -545,8 +553,8 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi CDOBranch main = getMappingStrategy().getStore().getRepository().getBranchManager().getMainBranch(); // get revision from cache to find out version number - CDORevision revision = getMappingStrategy().getStore().getRepository().getRevisionManager().getRevision(id, main.getHead(), - /* chunksize = */0, CDORevision.DEPTH_NONE, true); + CDORevision revision = getMappingStrategy().getStore().getRepository().getRevisionManager().getRevision(id, main.getHead(), /* chunksize = */0, + CDORevision.DEPTH_NONE, true); // set cdo_revision_removed for all list items (so we have no NULL values) clearList(accessor, id, revision.getVersion(), FINAL_VERSION); @@ -817,7 +825,7 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi InternalCDORevision originalRevision = (InternalCDORevision)repo.getRevisionManager().getRevision(id, repo.getBranchManager().getMainBranch().getHead(), /* chunksize = */0, CDORevision.DEPTH_NONE, true); - int oldListSize = originalRevision.getList(getFeature()).size(); + int oldListSize = originalRevision.size(getFeature()); if (TRACER.isEnabled()) { @@ -864,7 +872,7 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi id = originalRevision.getID(); this.oldVersion = oldVersion; this.newVersion = newVersion; - lastIndex = originalRevision.getList(getFeature()).size() - 1; + lastIndex = originalRevision.size(getFeature()) - 1; lastRemovedIndex = -1; } @@ -975,11 +983,6 @@ public class AuditListTableMappingWithRanges extends AbstractBasicListTableMappi public void visit(CDOUnsetFeatureDelta delta) { - if (delta.getFeature().isUnsettable()) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - if (TRACER.isEnabled()) { TRACER.format("Delta Unsetting"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java index 8cc6faab63..6a02a748c8 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingFeatureMapTableMappingWithRanges.java @@ -394,7 +394,13 @@ public class BranchingFeatureMapTableMappingWithRanges extends AbstractBasicList public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk) { - MoveableList<Object> list = revision.getList(getFeature()); + MoveableList<Object> list = revision.getListOrNull(getFeature()); + if (list == null) + { + // Nothing to read take shortcut. + return; + } + int valuesToRead = list.size(); if (listChunk != CDORevision.UNCHUNKED && listChunk < valuesToRead) @@ -404,7 +410,7 @@ public class BranchingFeatureMapTableMappingWithRanges extends AbstractBasicList if (valuesToRead == 0) { - // nothing to read take shortcut + // Nothing to read take shortcut. return; } @@ -680,17 +686,19 @@ public class BranchingFeatureMapTableMappingWithRanges extends AbstractBasicList public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { - CDOList values = revision.getList(getFeature()); - - int idx = 0; - for (Object element : values) + CDOList values = revision.getListOrNull(getFeature()); + if (values != null) { - writeValue(accessor, revision, idx++, element); - } + int idx = 0; + for (Object element : values) + { + writeValue(accessor, revision, idx++, element); + } - if (TRACER.isEnabled()) - { - TRACER.format("Writing done"); //$NON-NLS-1$ + if (TRACER.isEnabled()) + { + TRACER.format("Writing done"); //$NON-NLS-1$ + } } } @@ -830,7 +838,7 @@ public class BranchingFeatureMapTableMappingWithRanges extends AbstractBasicList TRACER.format("objectDetached {1}", revision); //$NON-NLS-1$ } - clearList(accessor, id, branchId, revision.getVersion(), FINAL_VERSION, revision.getList(getFeature()).size() - 1, revised); + clearList(accessor, id, branchId, revision.getVersion(), FINAL_VERSION, revision.size(getFeature()) - 1, revised); } @Override @@ -850,7 +858,7 @@ public class BranchingFeatureMapTableMappingWithRanges extends AbstractBasicList } InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id); - int oldListSize = originalRevision.getList(getFeature()).size(); + int oldListSize = originalRevision.size(getFeature()); if (TRACER.isEnabled()) { @@ -911,7 +919,7 @@ public class BranchingFeatureMapTableMappingWithRanges extends AbstractBasicList branchID = targetBranchID; this.oldVersion = oldVersion; this.newVersion = newVersion; - lastIndex = originalRevision.getList(getFeature()).size() - 1; + lastIndex = originalRevision.size(getFeature()) - 1; this.timestamp = timestamp; } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java index 24e18cac26..aac4f79ff2 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/BranchingListTableMappingWithRanges.java @@ -296,7 +296,13 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM public void readValues(IDBStoreAccessor accessor, InternalCDORevision revision, final int listChunk) { - MoveableList<Object> list = revision.getList(getFeature()); + MoveableList<Object> list = revision.getListOrNull(getFeature()); + if (list == null) + { + // Nothing to read take shortcut. + return; + } + int valuesToRead = list.size(); if (listChunk != CDORevision.UNCHUNKED && listChunk < valuesToRead) { @@ -305,7 +311,7 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM if (valuesToRead == 0) { - // nothing to read take shortcut + // Nothing to read take shortcut. return; } @@ -610,17 +616,19 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM public void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision) { - CDOList values = revision.getList(getFeature()); - - int idx = 0; - for (Object element : values) + CDOList values = revision.getListOrNull(getFeature()); + if (values != null) { - writeValue(accessor, revision, idx++, element); - } + int idx = 0; + for (Object element : values) + { + writeValue(accessor, revision, idx++, element); + } - if (TRACER.isEnabled()) - { - TRACER.format("Writing done"); //$NON-NLS-1$ + if (TRACER.isEnabled()) + { + TRACER.format("Writing done"); //$NON-NLS-1$ + } } } @@ -698,7 +706,7 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM int branchID = transaction.getBranch().getID(); int version = revision.getVersion(); - int lastIndex = revision.getList(getFeature()).size() - 1; + int lastIndex = revision.size(getFeature()) - 1; clearList(accessor, id, branchID, version, FINAL_VERSION, lastIndex); } @@ -720,7 +728,7 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM } InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id); - int oldListSize = originalRevision.getList(getFeature()).size(); + int oldListSize = originalRevision.size(getFeature()); if (TRACER.isEnabled()) { @@ -784,7 +792,7 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM branchID = targetBranchID; this.oldVersion = oldVersion; this.newVersion = newVersion; - lastIndex = originalRevision.getList(getFeature()).size() - 1; + lastIndex = originalRevision.size(getFeature()) - 1; lastRemovedIndex = -1; } @@ -844,11 +852,6 @@ public class BranchingListTableMappingWithRanges extends AbstractBasicListTableM public void visit(CDOUnsetFeatureDelta delta) { - if (delta.getFeature().isUnsettable()) - { - throw new ImplementationError("Should not be called"); //$NON-NLS-1$ - } - if (TRACER.isEnabled()) { TRACER.format("Delta Unsetting"); //$NON-NLS-1$ 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 873c9fe97a..8859f45065 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 @@ -487,8 +487,9 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping for (EStructuralFeature feature : listSizeFields.keySet()) { - CDOList list = revision.getList(feature); - stmt.setInt(column++, list.size()); + CDOList list = revision.getListOrNull(feature); + int size = list == null ? UNSET_LIST : list.size(); + stmt.setInt(column++, size); } } @@ -867,16 +868,19 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping IListMappingUnitSupport listMapping = listMappings[i]; EStructuralFeature feature = listMapping.getFeature(); - MoveableList<Object> list = revision.getList(feature); - int size = list.size(); - if (size != 0) + MoveableList<Object> list = revision.getListOrNull(feature); + if (list != null) { - if (resultSets[i] == null) + int size = list.size(); + if (size != 0) { - resultSets[i] = listMapping.queryUnitEntries(accessor, idHandler, timeStamp, rootID); - } + if (resultSets[i] == null) + { + resultSets[i] = listMapping.queryUnitEntries(accessor, idHandler, timeStamp, rootID); + } - listMapping.readUnitEntries(resultSets[i], idHandler, id, list); + listMapping.readUnitEntries(resultSets[i], idHandler, id, list); + } } } 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 f77135abcd..d4d1d36aef 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 @@ -463,8 +463,9 @@ public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapp for (EStructuralFeature feature : listSizeFields.keySet()) { - CDOList list = revision.getList(feature); - stmt.setInt(column++, list.size()); + CDOList list = revision.getListOrNull(feature); + int size = list == null ? UNSET_LIST : list.size(); + stmt.setInt(column++, size); } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java index 5bf405e926..be80e65c78 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java @@ -240,8 +240,9 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi for (EStructuralFeature feature : listSizeFields.keySet()) { - CDOList list = revision.getList(feature); - stmt.setInt(column++, list.size()); + CDOList list = revision.getListOrNull(feature); + int size = list == null ? UNSET_LIST : list.size(); + stmt.setInt(column++, size); } } diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java index f3e6f44fe4..378235bb0a 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java @@ -145,7 +145,7 @@ public class CDOAuditHandler extends AuditHandler { if (sourceEFeature.isMany()) { - for (Object value : (Collection<?>)source.getList(sourceEFeature)) + for (Object value : (Collection<?>)source.getOrCreateList(sourceEFeature)) { final String idAsString = entityToIdString(session, value); ((Collection<Object>)auditEntry.eGet(targetEFeature)).add(idAsString); @@ -167,7 +167,7 @@ public class CDOAuditHandler extends AuditHandler } else { - for (Object value : (Collection<?>)source.getList(sourceEFeature)) + for (Object value : (Collection<?>)source.getOrCreateList(sourceEFeature)) { ((Collection<Object>)auditEntry.eGet(targetEFeature)).add(convertValue(sourceEFeature, targetEFeature, value)); } @@ -204,7 +204,7 @@ public class CDOAuditHandler extends AuditHandler protected void convertFeatureMap(Session session, InternalCDORevision source, EStructuralFeature sourceEFeature, TeneoAuditEntry auditEntry, EStructuralFeature targetEFeature) { - super.convertFeatureMap(session, source.getList(sourceEFeature), sourceEFeature, auditEntry, targetEFeature); + super.convertFeatureMap(session, source.getOrCreateList(sourceEFeature), sourceEFeature, auditEntry, targetEFeature); } @Override diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java index ff0743560d..a603c084f9 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java @@ -155,7 +155,7 @@ public class HibernateAuditHandler { for (Object value : (Collection<?>)auditEntry.eGet(sourceEFeature)) { - cdoRevision.getList(targetEFeature).add(convertValue(targetEFeature, value)); + cdoRevision.getOrCreateList(targetEFeature).add(convertValue(targetEFeature, value)); } } else 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 39bb6fd669..d399003f75 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 @@ -737,7 +737,7 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS { // note this takes performance for sure as the list is read, // consider not supporting sourceIndex, or doing it differently - final WrappedHibernateList cdoList = (WrappedHibernateList)sourceRevision.getList(eref); + final WrappedHibernateList cdoList = (WrappedHibernateList)sourceRevision.getOrCreateList(eref); sourceIndex = cdoList.getDelegate().indexOf(revision); } diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyAttributeGetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyAttributeGetter.java index 9325e214d3..fd4f8bc191 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyAttributeGetter.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyAttributeGetter.java @@ -56,7 +56,7 @@ public class CDOManyAttributeGetter extends CDOPropertyGetter } InternalCDORevision revision = (InternalCDORevision)target; - CDOList list = revision.getList(getEStructuralFeature(), 10); + CDOList list = revision.getOrCreateList(getEStructuralFeature(), 10); if (list instanceof WrappedHibernateList) { diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceGetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceGetter.java index 922bb185c5..d215e476de 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceGetter.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceGetter.java @@ -56,7 +56,7 @@ public class CDOManyReferenceGetter extends CDOPropertyGetter } InternalCDORevision revision = (InternalCDORevision)target; - CDOList list = revision.getList(getEStructuralFeature(), 10); + CDOList list = revision.getOrCreateList(getEStructuralFeature(), 10); if (list instanceof WrappedHibernateList) { diff --git a/plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/Commits.java b/plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/Commits.java index 8b4228405d..9f9ec0bbc6 100644 --- a/plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/Commits.java +++ b/plugins/org.eclipse.emf.cdo.server.mongodb/src/org/eclipse/emf/cdo/server/internal/mongodb/Commits.java @@ -832,7 +832,7 @@ public class Commits extends Coll if (value != null) { List<?> list = (List<?>)value; - CDOList revisionList = revision.getList(feature, list.size()); + CDOList revisionList = revision.getOrCreateList(feature, list.size()); for (Object element : list) { element = valueHandler.fromMongo(element); diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LoadChunkIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LoadChunkIndication.java index b9a0f3f554..acf2caa2e6 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LoadChunkIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LoadChunkIndication.java @@ -99,11 +99,14 @@ public class LoadChunkIndication extends CDOServerReadIndication repository.ensureChunk(revision, feature, fromIndex, toIndex + 1); CDOType type = CDOModelUtil.getType(feature); - MoveableList<Object> list = revision.getList(feature); - for (int i = fromIndex; i <= toIndex; i++) + MoveableList<Object> list = revision.getListOrNull(feature); + if (list != null) { - Object value = list.get(i); - type.writeValue(out, value); + for (int i = fromIndex; i <= toIndex; i++) + { + Object value = list.get(i); + type.writeValue(out, value); + } } } } diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LoadRevisionsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LoadRevisionsIndication.java index 50002ab531..0763632639 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LoadRevisionsIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LoadRevisionsIndication.java @@ -238,24 +238,27 @@ public class LoadRevisionsIndication extends CDOServerReadIndication { if (feature.isMany()) { - MoveableList<Object> list = revision.getList(feature); - int toIndex = Math.min(loadRevisionCollectionChunkSize, list.size()) - 1; - for (int i = 0; i <= toIndex; i++) + MoveableList<Object> list = revision.getListOrNull(feature); + if (list != null) { - Object value = list.get(i); - if (value instanceof CDOID) + int toIndex = Math.min(loadRevisionCollectionChunkSize, list.size()) - 1; + for (int i = 0; i <= toIndex; i++) { - CDOID id = (CDOID)value; - if (!CDOIDUtil.isNull(id) && !revisions.contains(id)) + Object value = list.get(i); + if (value instanceof CDOID) { - RevisionInfo info = getRevisionInfo(id); - InternalCDORevision containedRevision = info.getResult(); - if (containedRevision != null) + CDOID id = (CDOID)value; + if (!CDOIDUtil.isNull(id) && !revisions.contains(id)) { - additionalRevisionInfos.add(info); - revisions.add(containedRevision.getID()); - additionalRevisions.add(containedRevision); - collectRevisions(containedRevision, revisions, additionalRevisionInfos, additionalRevisions, visitedFetchRules); + RevisionInfo info = getRevisionInfo(id); + InternalCDORevision containedRevision = info.getResult(); + if (containedRevision != null) + { + additionalRevisionInfos.add(info); + revisions.add(containedRevision.getID()); + additionalRevisions.add(containedRevision); + collectRevisions(containedRevision, revisions, additionalRevisionInfos, additionalRevisions, visitedFetchRules); + } } } } diff --git a/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/db/ObjyObject.java b/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/db/ObjyObject.java index e4a0ad03bb..7c894079d3 100644 --- a/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/db/ObjyObject.java +++ b/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/db/ObjyObject.java @@ -609,7 +609,7 @@ public class ObjyObject { // Object newValue = revision.getValue(feature); // --- TEMP solution to fix one of the tests... - CDOList list = revision.getList(feature); + CDOList list = revision.getOrCreateList(feature); Object[] values = new Object[list.size()]; // we need to pass a list of ooId objects. // TODO - This need some work!!!! @@ -849,7 +849,7 @@ public class ObjyObject // objects.length, 0); // TODO - use the following line instead of creating the cdoList // above. - MoveableList<Object> list = revision.getList(feature); + MoveableList<Object> list = revision.getOrCreateList(feature); // size = Math.min(size, 0); for (int i = 0; i < chunkSize; i++) diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java index 894e67028c..79b61a60e2 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java @@ -764,15 +764,7 @@ public class Repository extends Container<Object> implements InternalRepository, @Deprecated protected void ensureChunks(InternalCDORevision revision, int referenceChunk, IStoreAccessor accessor) { - for (EStructuralFeature feature : revision.getClassInfo().getAllPersistentFeatures()) - { - if (feature.isMany()) - { - MoveableList<Object> list = revision.getList(feature); - int chunkEnd = Math.min(referenceChunk, list.size()); - accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd); - } - } + throw new UnsupportedOperationException(); } public void ensureChunks(InternalCDORevision revision) @@ -793,27 +785,30 @@ public class Repository extends Container<Object> implements InternalRepository, { if (feature.isMany()) { - MoveableList<Object> list = revision.getList(feature); - int size = list.size(); - if (size != 0) + MoveableList<Object> list = revision.getListOrNull(feature); + if (list != null) { - int chunkSizeToUse = chunkSize; - if (chunkSizeToUse == UNCHUNKED) + int size = list.size(); + if (size != 0) { - chunkSizeToUse = size; - } + int chunkSizeToUse = chunkSize; + if (chunkSizeToUse == UNCHUNKED) + { + chunkSizeToUse = size; + } - int chunkEnd = Math.min(chunkSizeToUse, size); - accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd); + int chunkEnd = Math.min(chunkSizeToUse, size); + accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd); - if (unchunked) - { - for (int i = chunkEnd + 1; i < size; i++) + if (unchunked) { - if (list.get(i) == InternalCDOList.UNINITIALIZED) + for (int i = chunkEnd + 1; i < size; i++) { - unchunked = false; - break; + if (list.get(i) == InternalCDOList.UNINITIALIZED) + { + unchunked = false; + break; + } } } } @@ -831,7 +826,12 @@ public class Repository extends Container<Object> implements InternalRepository, { if (!revision.isUnchunked()) { - MoveableList<Object> list = revision.getList(feature); + MoveableList<Object> list = revision.getListOrNull(feature); + if (list == null) + { + return null; + } + chunkEnd = Math.min(chunkEnd, list.size()); IStoreAccessor accessor = StoreThreadLocal.getAccessor(); ensureChunk(revision, feature, accessor, list, chunkStart, chunkEnd); @@ -854,13 +854,16 @@ public class Repository extends Container<Object> implements InternalRepository, { if (feature.isMany()) { - MoveableList<Object> list = revision.getList(feature); - int size = list.size(); - for (int i = 0; i < size; i++) + MoveableList<Object> list = revision.getListOrNull(feature); + if (list != null) { - if (list.get(i) == InternalCDOList.UNINITIALIZED) + int size = list.size(); + for (int i = 0; i < size; i++) { - return false; + if (list.get(i) == InternalCDOList.UNINITIALIZED) + { + return false; + } } } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java index 395b895c55..257ae86235 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerImporter.java @@ -462,7 +462,7 @@ public abstract class CDOServerImporter if (feature.isMany()) { - CDOList list = revision.getList(feature); + CDOList list = revision.getOrCreateList(feature); list.add(value); } else diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java index 8fd5ec8e50..3605f601c4 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/H2Config.java @@ -46,7 +46,7 @@ public class H2Config extends DBConfig /** * @see #optimizeRepositoryRecreation(String, JdbcDataSource) */ - private final transient Map<String, Connection> leakyConnections = new HashMap<String, Connection>(); + private static final Map<String, Connection> leakyConnections = new HashMap<String, Connection>(); public H2Config() { diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.ecore b/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.ecore index 12dc6cd66d..4a62aee647 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.ecore +++ b/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.ecore @@ -5,6 +5,7 @@ <eClassifiers xsi:type="ecore:EClass" name="Class1"> <eStructuralFeatures xsi:type="ecore:EReference" name="class2" upperBound="-1" eType="#//subpackage/Class2" unsettable="true" eOpposite="#//subpackage/Class2/class1"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="additionalValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="MetaRef"> <eStructuralFeatures xsi:type="ecore:EReference" name="ePackageRef" eType="ecore:EClass platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EPackage"/> diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.genmodel b/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.genmodel index 12a92afb53..4f77bb46da 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.genmodel +++ b/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.genmodel @@ -14,6 +14,7 @@ <genDataTypes ecoreDataType="model3.ecore#//Point"/> <genClasses ecoreClass="model3.ecore#//Class1"> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model3.ecore#//Class1/class2"/> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model3.ecore#//Class1/additionalValue"/> </genClasses> <genClasses ecoreClass="model3.ecore#//MetaRef"> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model3.ecore#//MetaRef/ePackageRef"/> diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.legacy.genmodel b/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.legacy.genmodel index ae53d2d671..e81768cf17 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.legacy.genmodel +++ b/plugins/org.eclipse.emf.cdo.tests.model3/model/model3.legacy.genmodel @@ -13,6 +13,7 @@ <genDataTypes ecoreDataType="model3.ecore#//Point"/> <genClasses ecoreClass="model3.ecore#//Class1"> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model3.ecore#//Class1/class2"/> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute model3.ecore#//Class1/additionalValue"/> </genClasses> <genClasses ecoreClass="model3.ecore#//MetaRef"> <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference model3.ecore#//MetaRef/ePackageRef"/> diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/Class1.java b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/Class1.java index c78d017fd4..dde95fb2d7 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/Class1.java +++ b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/Class1.java @@ -23,6 +23,7 @@ import org.eclipse.emf.ecore.EObject; * </p> * <ul> * <li>{@link org.eclipse.emf.cdo.tests.model3.Class1#getClass2 <em>Class2</em>}</li> + * <li>{@link org.eclipse.emf.cdo.tests.model3.Class1#getAdditionalValue <em>Additional Value</em>}</li> * </ul> * * @see org.eclipse.emf.cdo.tests.model3.Model3Package#getClass1() @@ -70,4 +71,30 @@ public interface Class1 extends EObject */ boolean isSetClass2(); + /** + * Returns the value of the '<em><b>Additional Value</b></em>' attribute. + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Additional Value</em>' attribute isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Additional Value</em>' attribute. + * @see #setAdditionalValue(String) + * @see org.eclipse.emf.cdo.tests.model3.Model3Package#getClass1_AdditionalValue() + * @model + * @generated + */ + String getAdditionalValue(); + + /** + * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model3.Class1#getAdditionalValue <em>Additional Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Additional Value</em>' attribute. + * @see #getAdditionalValue() + * @generated + */ + void setAdditionalValue(String value); + } // Class1 diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/Model3Package.java b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/Model3Package.java index ea98a0e6d0..f6557fda1f 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/Model3Package.java +++ b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/Model3Package.java @@ -78,12 +78,21 @@ public interface Model3Package extends EPackage int CLASS1__CLASS2 = 0; /** + * The feature id for the '<em><b>Additional Value</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS1__ADDITIONAL_VALUE = 1; + + /** * The number of structural features of the '<em>Class1</em>' class. * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated * @ordered */ - int CLASS1_FEATURE_COUNT = 1; + int CLASS1_FEATURE_COUNT = 2; /** * The meta object id for the '{@link org.eclipse.emf.cdo.tests.model3.impl.MetaRefImpl <em>Meta Ref</em>}' class. @@ -829,6 +838,17 @@ public interface Model3Package extends EPackage EReference getClass1_Class2(); /** + * Returns the meta object for the attribute '{@link org.eclipse.emf.cdo.tests.model3.Class1#getAdditionalValue <em>Additional Value</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the attribute '<em>Additional Value</em>'. + * @see org.eclipse.emf.cdo.tests.model3.Class1#getAdditionalValue() + * @see #getClass1() + * @generated + */ + EAttribute getClass1_AdditionalValue(); + + /** * Returns the meta object for class '{@link org.eclipse.emf.cdo.tests.model3.MetaRef <em>Meta Ref</em>}'. <!-- * begin-user-doc --> <!-- end-user-doc --> * diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/impl/Class1Impl.java b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/impl/Class1Impl.java index 680acd526c..107bbe75a5 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/impl/Class1Impl.java +++ b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/impl/Class1Impl.java @@ -26,6 +26,7 @@ import org.eclipse.emf.ecore.EClass; * </p> * <ul> * <li>{@link org.eclipse.emf.cdo.tests.model3.impl.Class1Impl#getClass2 <em>Class2</em>}</li> + * <li>{@link org.eclipse.emf.cdo.tests.model3.impl.Class1Impl#getAdditionalValue <em>Additional Value</em>}</li> * </ul> * * @generated @@ -89,4 +90,24 @@ public class Class1Impl extends CDOObjectImpl implements Class1 return eIsSet(Model3Package.eINSTANCE.getClass1_Class2()); } + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String getAdditionalValue() + { + return (String)eGet(Model3Package.eINSTANCE.getClass1_AdditionalValue(), true); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setAdditionalValue(String newAdditionalValue) + { + eSet(Model3Package.eINSTANCE.getClass1_AdditionalValue(), newAdditionalValue); + } + } // Class1Impl diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/impl/Model3PackageImpl.java b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/impl/Model3PackageImpl.java index a2f6aaa205..8d61db0444 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/impl/Model3PackageImpl.java +++ b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/impl/Model3PackageImpl.java @@ -273,6 +273,16 @@ public class Model3PackageImpl extends EPackageImpl implements Model3Package } /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EAttribute getClass1_AdditionalValue() + { + return (EAttribute)class1EClass.getEStructuralFeatures().get(1); + } + + /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ @@ -886,6 +896,7 @@ public class Model3PackageImpl extends EPackageImpl implements Model3Package // Create classes and their features class1EClass = createEClass(CLASS1); createEReference(class1EClass, CLASS1__CLASS2); + createEAttribute(class1EClass, CLASS1__ADDITIONAL_VALUE); metaRefEClass = createEClass(META_REF); createEReference(metaRefEClass, META_REF__EPACKAGE_REF); @@ -1014,6 +1025,8 @@ public class Model3PackageImpl extends EPackageImpl implements Model3Package initEClass(class1EClass, Class1.class, "Class1", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEReference(getClass1_Class2(), theSubpackagePackage.getClass2(), theSubpackagePackage.getClass2_Class1(), "class2", null, 0, -1, Class1.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getClass1_AdditionalValue(), ecorePackage.getEString(), "additionalValue", null, 0, 1, Class1.class, !IS_TRANSIENT, !IS_VOLATILE, + IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEClass(metaRefEClass, MetaRef.class, "MetaRef", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEReference(getMetaRef_EPackageRef(), theEcorePackage.getEPackage(), null, "ePackageRef", null, 0, 1, MetaRef.class, !IS_TRANSIENT, !IS_VOLATILE, diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/Model3Package.java b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/Model3Package.java index 091ab63659..2b219c5de2 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/Model3Package.java +++ b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/Model3Package.java @@ -78,12 +78,21 @@ public interface Model3Package extends EPackage, org.eclipse.emf.cdo.tests.model int CLASS1__CLASS2 = 0; /** + * The feature id for the '<em><b>Additional Value</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS1__ADDITIONAL_VALUE = 1; + + /** * The number of structural features of the '<em>Class1</em>' class. * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated * @ordered */ - int CLASS1_FEATURE_COUNT = 1; + int CLASS1_FEATURE_COUNT = 2; /** * The meta object id for the '{@link org.eclipse.emf.cdo.tests.model3.legacy.impl.MetaRefImpl <em>Meta Ref</em>}' class. @@ -822,6 +831,17 @@ public interface Model3Package extends EPackage, org.eclipse.emf.cdo.tests.model EReference getClass1_Class2(); /** + * Returns the meta object for the attribute '{@link org.eclipse.emf.cdo.tests.model3.Class1#getAdditionalValue <em>Additional Value</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the attribute '<em>Additional Value</em>'. + * @see org.eclipse.emf.cdo.tests.model3.Class1#getAdditionalValue() + * @see #getClass1() + * @generated + */ + EAttribute getClass1_AdditionalValue(); + + /** * Returns the meta object for class '{@link org.eclipse.emf.cdo.tests.legacy.model3.MetaRef <em>Meta Ref</em>}'. <!-- * begin-user-doc --> <!-- end-user-doc --> * diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/impl/Class1Impl.java b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/impl/Class1Impl.java index 8bd89ad786..4f0046d721 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/impl/Class1Impl.java +++ b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/impl/Class1Impl.java @@ -15,10 +15,12 @@ import org.eclipse.emf.cdo.tests.model3.legacy.Model3Package; import org.eclipse.emf.cdo.tests.model3.subpackage.Class2; import org.eclipse.emf.cdo.tests.model3.subpackage.legacy.SubpackagePackage; +import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.emf.ecore.impl.EObjectImpl; import org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList; import org.eclipse.emf.ecore.util.InternalEList; @@ -32,6 +34,7 @@ import java.util.Collection; * </p> * <ul> * <li>{@link org.eclipse.emf.cdo.tests.model3.legacy.impl.Class1Impl#getClass2 <em>Class2</em>}</li> + * <li>{@link org.eclipse.emf.cdo.tests.model3.legacy.impl.Class1Impl#getAdditionalValue <em>Additional Value</em>}</li> * </ul> * * @generated @@ -49,6 +52,26 @@ public class Class1Impl extends EObjectImpl implements Class1 protected EList<Class2> class2; /** + * The default value of the '{@link #getAdditionalValue() <em>Additional Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getAdditionalValue() + * @generated + * @ordered + */ + protected static final String ADDITIONAL_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getAdditionalValue() <em>Additional Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getAdditionalValue() + * @generated + * @ordered + */ + protected String additionalValue = ADDITIONAL_VALUE_EDEFAULT; + + /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ @@ -103,6 +126,31 @@ public class Class1Impl extends EObjectImpl implements Class1 } /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String getAdditionalValue() + { + return additionalValue; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setAdditionalValue(String newAdditionalValue) + { + String oldAdditionalValue = additionalValue; + additionalValue = newAdditionalValue; + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.SET, Model3Package.CLASS1__ADDITIONAL_VALUE, oldAdditionalValue, additionalValue)); + } + } + + /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ @@ -144,6 +192,8 @@ public class Class1Impl extends EObjectImpl implements Class1 { case Model3Package.CLASS1__CLASS2: return getClass2(); + case Model3Package.CLASS1__ADDITIONAL_VALUE: + return getAdditionalValue(); } return super.eGet(featureID, resolve, coreType); } @@ -162,6 +212,9 @@ public class Class1Impl extends EObjectImpl implements Class1 getClass2().clear(); getClass2().addAll((Collection<? extends Class2>)newValue); return; + case Model3Package.CLASS1__ADDITIONAL_VALUE: + setAdditionalValue((String)newValue); + return; } super.eSet(featureID, newValue); } @@ -178,6 +231,9 @@ public class Class1Impl extends EObjectImpl implements Class1 case Model3Package.CLASS1__CLASS2: unsetClass2(); return; + case Model3Package.CLASS1__ADDITIONAL_VALUE: + setAdditionalValue(ADDITIONAL_VALUE_EDEFAULT); + return; } super.eUnset(featureID); } @@ -193,8 +249,30 @@ public class Class1Impl extends EObjectImpl implements Class1 { case Model3Package.CLASS1__CLASS2: return isSetClass2(); + case Model3Package.CLASS1__ADDITIONAL_VALUE: + return ADDITIONAL_VALUE_EDEFAULT == null ? additionalValue != null : !ADDITIONAL_VALUE_EDEFAULT.equals(additionalValue); } return super.eIsSet(featureID); } + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) + { + return super.toString(); + } + + StringBuilder result = new StringBuilder(super.toString()); + result.append(" (additionalValue: "); + result.append(additionalValue); + result.append(')'); + return result.toString(); + } + } // Class1Impl diff --git a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/impl/Model3PackageImpl.java b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/impl/Model3PackageImpl.java index 1504500101..71bf58e07a 100644 --- a/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/impl/Model3PackageImpl.java +++ b/plugins/org.eclipse.emf.cdo.tests.model3/src/org/eclipse/emf/cdo/tests/model3/legacy/impl/Model3PackageImpl.java @@ -273,6 +273,16 @@ public class Model3PackageImpl extends EPackageImpl implements Model3Package } /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EAttribute getClass1_AdditionalValue() + { + return (EAttribute)class1EClass.getEStructuralFeatures().get(1); + } + + /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ @@ -886,6 +896,7 @@ public class Model3PackageImpl extends EPackageImpl implements Model3Package // Create classes and their features class1EClass = createEClass(CLASS1); createEReference(class1EClass, CLASS1__CLASS2); + createEAttribute(class1EClass, CLASS1__ADDITIONAL_VALUE); metaRefEClass = createEClass(META_REF); createEReference(metaRefEClass, META_REF__EPACKAGE_REF); @@ -1014,6 +1025,8 @@ public class Model3PackageImpl extends EPackageImpl implements Model3Package initEClass(class1EClass, Class1.class, "Class1", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEReference(getClass1_Class2(), theSubpackagePackage.getClass2(), theSubpackagePackage.getClass2_Class1(), "class2", null, 0, -1, Class1.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getClass1_AdditionalValue(), ecorePackage.getEString(), "additionalValue", null, 0, 1, Class1.class, !IS_TRANSIENT, !IS_VOLATILE, + IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEClass(metaRefEClass, MetaRef.class, "MetaRef", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEReference(getMetaRef_EPackageRef(), theEcorePackage.getEPackage(), null, "ePackageRef", null, 0, 1, MetaRef.class, !IS_TRANSIENT, !IS_VOLATILE, diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SecurityTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SecurityTest.java index cc81b7a92f..ecd0d9c43d 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SecurityTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SecurityTest.java @@ -314,13 +314,13 @@ public class SecurityTest extends AbstractCDOTest { if (CDOIDUtil.isNull((CDOID)revision.getContainerID())) { - return revision.getList(EresourcePackage.Literals.CDO_RESOURCE__CONTENTS, 0); + return revision.getOrCreateList(EresourcePackage.Literals.CDO_RESOURCE__CONTENTS, 0); } return null; } - return revision.getList(EresourcePackage.Literals.CDO_RESOURCE_FOLDER__NODES, 0); + return revision.getOrCreateList(EresourcePackage.Literals.CDO_RESOURCE_FOLDER__NODES, 0); } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_318876_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_318876_Test.java index c8c610a7ae..19f2c91125 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_318876_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_318876_Test.java @@ -60,9 +60,6 @@ public class Bugzilla_318876_Test extends AbstractCDOTest CDOState state = CDOUtil.getCDOObject(purchaseOrder).cdoState(); assertEquals(CDOState.INVALID_CONFLICT, state); - - transaction.close(); - session.close(); } private void doSecondSession() throws CommitException @@ -76,6 +73,5 @@ public class Bugzilla_318876_Test extends AbstractCDOTest EcoreUtil.delete(purchaseOrder); transaction.commit(); - session.close(); } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405543_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405543_Test.java new file mode 100644 index 0000000000..e284536022 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405543_Test.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2004 - 2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Steve Monnier - initial API and implementation + * Eike Stepper - adapted for more correct test model definition + * Christian W. Damus (CEA) - adapted for new test model with unsettable attribute + */ +package org.eclipse.emf.cdo.tests.bugzilla; + +import static org.junit.Assert.assertNotEquals; + +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.model3.Class1; +import org.eclipse.emf.cdo.tests.model3.legacy.Model3Factory; +import org.eclipse.emf.cdo.tests.model3.subpackage.Class2; +import org.eclipse.emf.cdo.tests.model3.subpackage.legacy.SubpackageFactory; +import org.eclipse.emf.cdo.transaction.CDOTransaction; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.util.InternalEList; + +/** + * Bug 405543 - An unsettable many-valued reference that is set to an empty list is unset on new transaction. + * + * @author Steve Monnier + */ +public class Bugzilla_405543_Test extends AbstractCDOTest +{ + /** + * This test validates that an unset list isSet method is false. + */ + public void testIsUnsetOnUnsettableReference() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource(getResourcePath("/res")); + + Class1 element = getModel3Factory().createClass1(); + element.setAdditionalValue("Arbitrary value to cause eSettings to be non-null"); + assertFalse(element.isSetClass2()); + + resource.getContents().add(element); + assertFalse(element.isSetClass2()); + + transaction.commit(); + assertFalse(element.isSetClass2()); + + // Closing/Reopening Transaction and session. + session.close(); + session = openSession(); + transaction = session.openTransaction(); + resource = transaction.getOrCreateResource(getResourcePath("/res")); + + element = (Class1)resource.getContents().get(0); + assertFalse(element.isSetClass2()); + + Class2 element2 = getModel3SubpackageFactory().createClass2(); + element.getClass2().add(element2); + assertTrue(element.isSetClass2()); + + resource.getContents().add(element2); + assertTrue(element.isSetClass2()); + + transaction.commit(); + assertTrue(element.isSetClass2()); + + // Closing/Reopening Transaction and session. + session.close(); + session = openSession(); + transaction = session.openTransaction(); + resource = transaction.getOrCreateResource(getResourcePath("/res")); + + element = (Class1)resource.getContents().get(0); + assertTrue(element.isSetClass2()); + + element.unsetClass2(); + assertFalse(element.isSetClass2()); + + transaction.commit(); + assertFalse(element.isSetClass2()); + + // Closing/Reopening Transaction and session. + session.close(); + session = openSession(); + transaction = session.openTransaction(); + resource = transaction.getOrCreateResource(getResourcePath("/res")); + + element = (Class1)resource.getContents().get(0); + assertFalse(element.isSetClass2()); + } + + /** + * This test validates that an empty unsettable reference isSet method is true. + * In this test, the reference is set before the first commit. + */ + public void testIsSetOnUnsettableReference() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource(getResourcePath("/res")); + + Class1 element = getModel3Factory().createClass1(); + Class2 element2 = getModel3SubpackageFactory().createClass2(); + assertFalse(element.isSetClass2()); + + element.getClass2().add(element2); + assertTrue(element.isSetClass2()); + + element.getClass2().remove(element2); + assertTrue(element.isSetClass2()); + + resource.getContents().add(element); + assertTrue(element.isSetClass2()); + + resource.getContents().add(element2); + assertTrue(element.isSetClass2()); + + transaction.commit(); + assertTrue(element.isSetClass2()); + + // Closing/Reopening Transaction and session. + transaction.close(); + session.close(); + session = openSession(); + transaction = session.openTransaction(); + resource = transaction.getOrCreateResource(getResourcePath("/res")); + element = (Class1)resource.getContents().get(0); + + // Validate that class1 reference 'class2' is still set but empty. + assertTrue(element.isSetClass2()); + } + + /** + * This test validates that an empty unsettable reference isSet method is true. + * In this test, the reference is set after the first commit. + */ + public void testIsSetOnUnsettableReference2() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource(getResourcePath("/res")); + + // Create an object and set is a string attribute to the empty string. + Class1 element = getModel3Factory().createClass1(); + Class2 element2 = getModel3SubpackageFactory().createClass2(); + + resource.getContents().add(element); + assertFalse(element.isSetClass2()); + + resource.getContents().add(element2); + assertFalse(element.isSetClass2()); + + transaction.commit(); + assertFalse(element.isSetClass2()); + + element.getClass2().add(element2); + assertTrue(element.isSetClass2()); + + element.getClass2().remove(element2); + assertTrue(element.isSetClass2()); + + // Commit and reopen transaction on a new session. + transaction.commit(); + session.close(); + session = openSession(); + transaction = session.openTransaction(); + resource = transaction.getOrCreateResource(getResourcePath("/res")); + element = (Class1)resource.getContents().get(0); + + // Validate that class1 reference 'class2' is still set but empty. + assertTrue(element.isSetClass2()); + } + + public static void main(String[] args) + { + Class1 element = Model3Factory.eINSTANCE.createClass1(); + assertFalse(element.isSetClass2()); + + EList<Class2> list = element.getClass2(); + assertNotEquals(null, list); + assertEquals(0, list.size()); + assertTrue(list.isEmpty()); + assertFalse(((InternalEList.Unsettable<Class2>)list).isSet()); + + Object[] array1 = list.toArray(); + assertNotEquals(null, array1); + assertEquals(0, array1.length); + + Class2[] array2 = list.toArray(new Class2[list.size()]); + assertNotEquals(null, array2); + assertEquals(0, array2.length); + + assertEquals(-1, list.indexOf(SubpackageFactory.eINSTANCE.createClass2())); + assertEquals(-1, list.lastIndexOf(SubpackageFactory.eINSTANCE.createClass2())); + assertFalse(list.remove(SubpackageFactory.eINSTANCE.createClass2())); + assertFalse(list.contains(SubpackageFactory.eINSTANCE.createClass2())); + + try + { + list.get(0); + fail("IndexOutOfBoundsException expected"); + } + catch (IndexOutOfBoundsException expected) + { + // SUCCESS + } + + try + { + list.remove(0); + fail("IndexOutOfBoundsException expected"); + } + catch (IndexOutOfBoundsException expected) + { + // SUCCESS + } + + try + { + list.move(0, SubpackageFactory.eINSTANCE.createClass2()); + fail("IndexOutOfBoundsException expected"); + } + catch (IndexOutOfBoundsException expected) + { + // SUCCESS + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_429659_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_429659_Test.java index 62cca5a3bd..9cddf85ec0 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_429659_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_429659_Test.java @@ -204,10 +204,12 @@ public class Bugzilla_429659_Test extends AbstractCDOTest assertEquals("Incorrect number of expected notifications: ", unsettable ? 2 : 1, notifications.size()); } - private static class NotificationAsserter extends EContentAdapter + /** + * @author Eike Stepper + */ + private static final class NotificationAsserter extends EContentAdapter { - - private List<Notification> notifications = new ArrayList<Notification>(); + private final List<Notification> notifications = new ArrayList<Notification>(); @Override public void notifyChanged(Notification notification) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFolderImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFolderImpl.java index 75fb5ecd72..b0632f730f 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFolderImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFolderImpl.java @@ -91,7 +91,7 @@ public class CDOResourceFolderImpl extends CDOResourceNodeImpl implements CDORes try { - list = revision.getList(EresourcePackage.Literals.CDO_RESOURCE_FOLDER__NODES); + list = revision.getListOrNull(EresourcePackage.Literals.CDO_RESOURCE_FOLDER__NODES); } finally { 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 0a5244312e..173ea51218 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 @@ -20,6 +20,7 @@ import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.model.CDOModelUtil; import org.eclipse.emf.cdo.common.model.EMFUtil; +import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.security.CDOPermission; import org.eclipse.emf.cdo.eresource.CDOResource; @@ -1232,22 +1233,6 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC return new CDOStoreFeatureMap(eStructuralFeature); } - /** - * @since 4.1 - */ - protected final CDOStoreEcoreEMap createMap(EStructuralFeature eStructuralFeature) - { - return new CDOStoreEcoreEMap(eStructuralFeature); - } - - /** - * @since 4.1 - */ - protected final CDOStoreUnorderedEList<Object> createUnorderedList(EStructuralFeature eStructuralFeature) - { - return new CDOStoreUnorderedEList<Object>(eStructuralFeature); - } - @Override protected EList<?> createList(EStructuralFeature eStructuralFeature) { @@ -1264,10 +1249,25 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC return super.createList(eStructuralFeature); } + /** + * @since 4.1 + */ + protected final CDOStoreUnorderedEList<Object> createUnorderedList(EStructuralFeature eStructuralFeature) + { + return new CDOStoreUnorderedEList<Object>(eStructuralFeature); + } + + /** + * @since 4.1 + */ + protected final CDOStoreEcoreEMap createMap(EStructuralFeature eStructuralFeature) + { + return new CDOStoreEcoreEMap(eStructuralFeature); + } + private boolean isMap(EStructuralFeature eStructuralFeature) { - // Answer from Christian Damus: - // Java ensures that string constants are interned, so == is actually more efficient than equals() and it's correct + // Java ensures that string constants are interned, so == is actually more efficient than equals(). return eStructuralFeature.getEType().getInstanceClassName() == "java.util.Map$Entry"; //$NON-NLS-1$ } @@ -1360,13 +1360,34 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC { if (setting != null) { - int index = 0; @SuppressWarnings("unchecked") - EList<Object> list = (EList<Object>)setting; - for (Object value : list) + EList<Object> instanceList = (EList<Object>)setting; + int size = instanceList.size(); + + if (feature.isUnsettable()) + { + if (!object.eIsSet(feature)) + { + // Avoid list creation for unset lists. + return; + } + } + else + { + if (size == 0) + { + // Avoid list creation for empty lists that can't be unset. + return; + } + } + + // Get (and possibly create) the list here in order to support unsettable empty lists. + CDOList revisionList = revision.getOrCreateList(feature, size); + + for (Object value : instanceList) { Object cdoValue = cdoStore.convertToCDO(object, feature, value); - revision.add(feature, index++, cdoValue); + revisionList.add(cdoValue); } } } @@ -1399,8 +1420,8 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC int size = cdoStore.size(instance, eFeature); for (int index = 0; index < size; index++) { - // Do not trigger events - // Do not trigger inverse updates + // Do not trigger events. + // Do not trigger inverse updates. Object opposite = cdoStore.get(instance, eFeature, index); eStore.add(instance, eFeature, index, opposite); if (oppositeReference != null) @@ -1693,6 +1714,10 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC { private static final long serialVersionUID = 1L; + // { + // ensureEntryDataExists(); + // } + @Override public void unset() { @@ -1723,6 +1748,7 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC protected void didClear(int size, Object[] oldObjects) { CDOStoreEcoreEMap.this.doClear(); + // ensureEntryDataExists(); } @Override 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 8f0e4a3fa0..37e1c9e41f 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 @@ -591,11 +591,16 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper */ protected void revisionToInstanceFeature(EStructuralFeature feature) { - if (feature.isUnsettable() && !viewAndState.view.getStore().isSet(this, feature)) + boolean isSet = true; + if (feature.isUnsettable()) { - // Clarify if this is sufficient for bidirectional references - instance.eUnset(feature); - return; + isSet = viewAndState.view.getStore().isSet(this, feature); + if (!isSet) + { + // Clarify if this is sufficient for bidirectional references + instance.eUnset(feature); + return; + } } if (feature.isMany()) @@ -615,6 +620,14 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper InternalEList<Object> list = (InternalEList<Object>)instance.eGet(feature); clearEList(list); + + if (size == 0 && feature.isUnsettable() && isSet) + { + // In clearEList() no removes took place because the list is already empty. + // Now call clear() in order to set isSet=true. + list.clear(); + } + for (int i = 0; i < size; i++) { Object object = getValueFromRevision(feature, i); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java index 2969309459..6bff3d06f9 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOCollectionLoadingPolicyImpl.java @@ -84,7 +84,12 @@ public class CDOCollectionLoadingPolicyImpl implements CDOCollectionLoadingPolic InternalCDORevision revision = (InternalCDORevision)rev; int fetchIndex = serverIndex; - MoveableList<Object> list = revision.getList(feature); + MoveableList<Object> list = revision.getListOrNull(feature); + if (list == null) + { + return null; + } + int size = list.size(); int fromIndex = accessIndex; int toIndex = accessIndex; 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 553b9098a0..99d7bc3525 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 @@ -899,14 +899,17 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme { if (reference.isMany()) { - CDOList list = internalRevision.getList(reference); - for (Iterator<Object> it = list.iterator(); it.hasNext();) + CDOList list = internalRevision.getListOrNull(reference); + if (list != null) { - Object element = it.next(); - if (element instanceof CDOElementProxy) + for (Iterator<Object> it = list.iterator(); it.hasNext();) { - policy.resolveAllProxies(internalRevision, reference); - break; + Object element = it.next(); + if (element instanceof CDOElementProxy) + { + policy.resolveAllProxies(internalRevision, reference); + break; + } } } } 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 3181a8af9a..2440198e40 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 @@ -2295,8 +2295,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } } - CDOList list = cleanRevision.getList(feature); - final int originSize = list.size(); + CDOList list = cleanRevision.getListOrNull(feature); + final int originSize = list == null ? 0 : list.size(); return new CDOOriginSizeProvider() { @@ -2344,13 +2344,13 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (object.cdoState() == CDOState.NEW) { // Register Delta for new objects only if objectA doesn't belong to this savepoint - if (getLastSavepoint().getPreviousSavepoint() == null || featureDelta == null) + if (lastSavepoint.getPreviousSavepoint() == null || featureDelta == null) { needToSaveFeatureDelta = false; } else { - Map<CDOID, CDOObject> map = getLastSavepoint().getNewObjects(); + Map<CDOID, CDOObject> map = lastSavepoint.getNewObjects(); needToSaveFeatureDelta = !map.containsKey(id); } } @@ -2978,7 +2978,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa InternalCDORevision revision = (InternalCDORevision)rootResource.cdoRevision(); if (revision != null) { - list = revision.getList(EresourcePackage.Literals.CDO_RESOURCE__CONTENTS); + list = revision.getListOrNull(EresourcePackage.Literals.CDO_RESOURCE__CONTENTS); } } } @@ -2995,7 +2995,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa InternalCDORevision revision = (InternalCDORevision)folder.cdoRevision(); if (revision != null) { - list = revision.getList(EresourcePackage.Literals.CDO_RESOURCE_FOLDER__NODES); + list = revision.getListOrNull(EresourcePackage.Literals.CDO_RESOURCE_FOLDER__NODES); } } } @@ -3341,13 +3341,15 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa { if (reference.isMany()) { - CDOList list = revision.getList(reference); - int index = 0; - - for (Object value : list) + CDOList list = revision.getListOrNull(reference); + if (list != null) { - refs = addXRefLocal(refs, targetIDs, object, reference, index, value); - ++index; + int index = 0; + for (Object value : list) + { + refs = addXRefLocal(refs, targetIDs, object, reference, index, value); + ++index; + } } } else @@ -3682,7 +3684,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (reference.isMany()) { - CDOList list = cleanRevision.getList(reference); + CDOList list = cleanRevision.getListOrNull(reference); if (list != null) { for (Object value : list) 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 index dfe3ad28cd..f6ad3076fe 100644 --- 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 @@ -58,6 +58,19 @@ public class CDOUndoDetectorImpl implements CDOUndoDetector { if (feature.isMany()) { + if (feature.isUnsettable()) + { + if (cleanValue == null) + { + return currentValue == null; + } + + if (currentValue == null) + { + return false; + } + } + List<?> cleanList = (List<?>)cleanValue; List<?> currentList = (List<?>)currentValue; diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java index aad9c9fd5d..7db0000333 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CommitIntegrityCheck.java @@ -444,7 +444,7 @@ public class CommitIntegrityCheck { if (reference.isMany()) { - EList<?> list = cleanRev.getList(reference); + EList<?> list = cleanRev.getListOrNull(reference); if (list != null) { for (Object element : list) 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 5562d069da..712c7b1cd7 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 @@ -1213,7 +1213,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb try { - list = folderRevision.getList(nodesFeature); + list = folderRevision.getListOrNull(nodesFeature); } finally { @@ -1221,7 +1221,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb } CDOStore store = getStore(); - int size = list.size(); + int size = list == null ? 0 : list.size(); for (int i = 0; i < size; i++) { Object value = list.get(i); 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 69d1df257e..ac4abc8018 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 @@ -228,18 +228,19 @@ public final class CDOStoreImpl implements CDOStore } InternalCDORevision revision = readRevision(cdoObject); - if (feature.isMany()) + if (feature.isUnsettable()) { - CDOList list = revision.getList(feature); - return list != null && !list.isEmpty(); + Object value = revision.getValue(feature); + return value != null; } - Object value = revision.getValue(feature); - if (feature.isUnsettable()) + if (feature.isMany()) { - return value != null; + CDOList list = revision.getListOrNull(feature); + return list != null && !list.isEmpty(); } + Object value = revision.getValue(feature); if (value == null) { return false; @@ -603,12 +604,15 @@ public final class CDOStoreImpl implements CDOStore List<?> list = (List<?>)object; list.clear(); } + + if (!feature.isUnsettable()) + { + return; + } } - else - { - CDOFeatureDelta delta = new CDOUnsetFeatureDeltaImpl(feature); - writeRevision(cdoObject, delta); - } + + CDOFeatureDelta delta = new CDOUnsetFeatureDeltaImpl(feature); + writeRevision(cdoObject, delta); } finally { @@ -842,7 +846,7 @@ public final class CDOStoreImpl implements CDOStore if (value instanceof CDOID) { CDOID id = (CDOID)value; - CDOList list = revision.getList(feature); + CDOList list = revision.getOrCreateList(feature); CDORevisionPrefetchingPolicy policy = view.options().getRevisionPrefetchingPolicy(); InternalCDORevisionManager revisionManager = view.getSession().getRevisionManager(); List<CDOID> listOfIDs = policy.loadAhead(revisionManager, view, eObject, feature, list, index, id); @@ -939,8 +943,8 @@ public final class CDOStoreImpl implements CDOStore // Bug 293283 / Bug 314387 InternalCDORevision revision = readRevision(cdoObject); - CDOList list = revision.getList(feature); - int size = list.size(); + CDOList list = revision.getListOrNull(feature); + int size = list == null ? 0 : list.size(); if (index < 0 || size <= index) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); 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 ea16adbb14..7102a08c6c 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 @@ -317,10 +317,13 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv public void visit(CDOClearFeatureDelta delta) { // TODO Only for reference features? - CDOList list = newCleanRevision.getList(delta.getFeature()); - for (Object id : list) + CDOList list = newCleanRevision.getListOrNull(delta.getFeature()); + if (list != null) { - recurse(detachedObjectsUpdater, (CDOID)id); + for (Object id : list) + { + recurse(detachedObjectsUpdater, (CDOID)id); + } } } |