Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2011-08-10 12:45:38 -0400
committerEike Stepper2011-08-10 12:45:38 -0400
commitb4eeb8bcb32538d9766c01905dd898e01c4f27d1 (patch)
tree3f0ec3603b103af0f957630b8e6cda6c2016ec02
parent6b8f9ec45ac5f70dc0afe444be50ddf977c4b29b (diff)
downloadcdo-b4eeb8bcb32538d9766c01905dd898e01c4f27d1.tar.gz
cdo-b4eeb8bcb32538d9766c01905dd898e01c4f27d1.tar.xz
cdo-b4eeb8bcb32538d9766c01905dd898e01c4f27d1.zip
[354395] containsAll returns wrong result in case of detached objects
https://bugs.eclipse.org/bugs/show_bug.cgi?id=354395
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java40
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_354395_Test.java140
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStoreImpl.java18
4 files changed, 183 insertions, 16 deletions
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 791f304cb8..561155f184 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
@@ -437,7 +437,8 @@ public abstract class BaseCDORevision extends AbstractCDORevision
{
if (feature.isMany() && index != EStore.NO_INDEX)
{
- return getList(feature).get(index);
+ CDOList list = getList(feature);
+ return list.get(index);
}
return getValue(feature);
@@ -445,27 +446,32 @@ public abstract class BaseCDORevision extends AbstractCDORevision
public boolean contains(EStructuralFeature feature, Object value)
{
- return getList(feature).contains(value);
+ CDOList list = getList(feature);
+ return list.contains(value);
}
public int indexOf(EStructuralFeature feature, Object value)
{
- return getList(feature).indexOf(value);
+ CDOList list = getList(feature);
+ return list.indexOf(value);
}
- public boolean isEmpty(EStructuralFeature feature)
+ public int lastIndexOf(EStructuralFeature feature, Object value)
{
- return getList(feature).isEmpty();
+ CDOList list = getList(feature);
+ return list.lastIndexOf(value);
}
- public int lastIndexOf(EStructuralFeature feature, Object value)
+ public boolean isEmpty(EStructuralFeature feature)
{
- return getList(feature).lastIndexOf(value);
+ CDOList list = getList(feature);
+ return list.isEmpty();
}
public int size(EStructuralFeature feature)
{
- return getList(feature).size();
+ CDOList list = getList(feature);
+ return list.size();
}
public Object[] toArray(EStructuralFeature feature)
@@ -475,7 +481,8 @@ public abstract class BaseCDORevision extends AbstractCDORevision
throw new IllegalStateException("!feature.isMany()");
}
- return getList(feature).toArray();
+ CDOList list = getList(feature);
+ return list.toArray();
}
public <T> T[] toArray(EStructuralFeature feature, T[] array)
@@ -485,12 +492,14 @@ public abstract class BaseCDORevision extends AbstractCDORevision
throw new IllegalStateException("!feature.isMany()");
}
- return getList(feature).toArray(array);
+ CDOList list = getList(feature);
+ return list.toArray(array);
}
public void add(EStructuralFeature feature, int index, Object value)
{
- getList(feature).add(index, value);
+ CDOList list = getList(feature);
+ list.add(index, value);
}
public void clear(EStructuralFeature feature)
@@ -500,19 +509,22 @@ public abstract class BaseCDORevision extends AbstractCDORevision
public Object move(EStructuralFeature feature, int targetIndex, int sourceIndex)
{
- return getList(feature).move(targetIndex, sourceIndex);
+ CDOList list = getList(feature);
+ return list.move(targetIndex, sourceIndex);
}
public Object remove(EStructuralFeature feature, int index)
{
- return getList(feature).remove(index);
+ CDOList list = getList(feature);
+ return list.remove(index);
}
public Object set(EStructuralFeature feature, int index, Object value)
{
if (feature.isMany())
{
- return getList(feature).set(index, value);
+ CDOList list = getList(feature);
+ return list.set(index, value);
}
return setValue(feature, value);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
index 788c201888..7b49bbe8b8 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
@@ -237,5 +237,6 @@ public abstract class AllConfigs extends ConfigTestSuite
testClasses.add(Bugzilla_351393_Test.class);
testClasses.add(Bugzilla_351921_Test.class);
testClasses.add(Bugzilla_352303_Test.class);
+ testClasses.add(Bugzilla_354395_Test.class);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_354395_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_354395_Test.java
new file mode 100644
index 0000000000..74a39198a4
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_354395_Test.java
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.tests.model1.Customer;
+import org.eclipse.emf.cdo.tests.model1.SalesOrder;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
+import org.eclipse.emf.common.util.EList;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * ContainsAll with detached objects
+ * <p>
+ * See bug
+ *
+ * @author Stefan Schedl
+ */
+public class Bugzilla_354395_Test extends AbstractCDOTest
+{
+ public void testContains() throws Exception
+ {
+ {
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+ SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+
+ Company company = getModel1Factory().createCompany();
+ company.getSalesOrders().add(salesOrder);
+
+ Customer customer = getModel1Factory().createCustomer();
+ customer.setName("customer");
+ customer.getSalesOrders().add(salesOrder);
+
+ company.getCustomers().add(customer);
+ resource.getContents().add(company);
+
+ transaction.commit();
+ session.close();
+ }
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+ Company company = (Company)resource.getContents().get(0);
+ SalesOrder salesOrder = company.getSalesOrders().get(0);
+
+ // remove salesOrder from its containment list, salesOrder now detached
+ company.getSalesOrders().remove(salesOrder);
+ assertTransient(salesOrder);
+
+ Customer customer = company.getCustomers().get(0);
+ EList<SalesOrder> salesOrders = customer.getSalesOrders();
+
+ List<SalesOrder> javaList = new ArrayList<SalesOrder>();
+ for (SalesOrder order : salesOrders)
+ {
+ javaList.add(order);
+ }
+
+ Set<SalesOrder> lookFor = Collections.singleton(salesOrder);
+
+ // Test contains & containsAll with "normal" java list
+ assertEquals(true, javaList.contains(salesOrder));
+ assertEquals(true, javaList.containsAll(lookFor));
+
+ // Test contains & containsAll direct with the elist
+ assertEquals(true, salesOrders.contains(salesOrder));
+ assertEquals(true, salesOrders.containsAll(lookFor));
+ }
+
+ public void testIndexOf() throws Exception
+ {
+ {
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+ SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+
+ Company company = getModel1Factory().createCompany();
+ company.getSalesOrders().add(salesOrder);
+
+ Customer customer = getModel1Factory().createCustomer();
+ customer.setName("customer");
+ customer.getSalesOrders().add(salesOrder);
+
+ company.getCustomers().add(customer);
+ resource.getContents().add(company);
+
+ transaction.commit();
+ session.close();
+ }
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+ Company company = (Company)resource.getContents().get(0);
+ SalesOrder salesOrder = company.getSalesOrders().get(0);
+
+ // remove salesOrder from its containment list, salesOrder now detached
+ company.getSalesOrders().remove(salesOrder);
+ assertTransient(salesOrder);
+
+ Customer customer = company.getCustomers().get(0);
+ EList<SalesOrder> salesOrders = customer.getSalesOrders();
+
+ List<SalesOrder> javaList = new ArrayList<SalesOrder>();
+ for (SalesOrder order : salesOrders)
+ {
+ javaList.add(order);
+ }
+
+ // Test indexOf & lastIndexOf with "normal" java list
+ assertEquals(0, javaList.indexOf(salesOrder));
+ assertEquals(0, javaList.lastIndexOf(salesOrder));
+
+ // Test indexOf & lastIndexOf direct with the elist
+ assertEquals(0, salesOrders.indexOf(salesOrder));
+ assertEquals(0, salesOrders.lastIndexOf(salesOrder));
+ }
+}
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 09261dd848..8f20249b0a 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
@@ -14,6 +14,7 @@
*/
package org.eclipse.emf.internal.cdo.view;
+import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOType;
@@ -32,6 +33,7 @@ import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOUnsetFeatureDeltaImpl;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
@@ -261,10 +263,22 @@ public final class CDOStoreImpl implements CDOStore
TRACER.format("contains({0}, {1}, {2})", cdoObject, feature, value); //$NON-NLS-1$
}
- value = convertToCDO(cdoObject, feature, value);
+ Object convertedValue = convertToCDO(cdoObject, feature, value);
InternalCDORevision revision = getRevisionForReading(cdoObject);
- return revision.contains(feature, value);
+ boolean result = revision.contains(feature, convertedValue);
+
+ // Special handling of detached (TRANSIENT) objects, see bug 354395
+ if (!result && value instanceof EObject)
+ {
+ CDOObject cdoObjectValue = CDOUtil.getCDOObject((EObject)value);
+ if (FSMUtil.isTransient(cdoObjectValue))
+ {
+ result = revision.contains(feature, value);
+ }
+ }
+
+ return result;
}
}

Back to the top