diff options
6 files changed, 133 insertions, 51 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 3d12c0d20c..096e85b70e 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 @@ -49,7 +49,6 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.InternalEObject.EStore; import org.eclipse.emf.ecore.util.FeatureMap; import org.eclipse.emf.ecore.util.FeatureMap.Entry; import org.eclipse.emf.ecore.util.FeatureMapUtil; @@ -495,7 +494,7 @@ public abstract class BaseCDORevision extends AbstractCDORevision public Object get(EStructuralFeature feature, int index) { - if (feature.isMany() && index != EStore.NO_INDEX) + if (feature.isMany()) { CDOList list = getList(feature); return list.get(index); 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 eb5759751a..8b35188e44 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 @@ -25,8 +25,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import java.util.Date; /** - * Bug 318876 - Mechanism for avoiding dangling refs can introduce spurious conflicts</p> - * http://bugs.eclipse.org/318876</p> + * Bug 318876 - Mechanism for avoiding dangling refs can introduce spurious conflicts. * * @author Caspar De Groot */ @@ -34,50 +33,49 @@ public class Bugzilla_318876_Test extends AbstractCDOTest { public void test() throws CommitException { - final CDOSession session = openSession(); + CDOSession session = openSession(); session.options().setPassiveUpdateEnabled(false); - CDOTransaction tx = session.openTransaction(); - CDOResource r1 = tx.createResource(getResourcePath("/r1")); //$NON-NLS-1$ - PurchaseOrder po1 = getModel1Factory().createPurchaseOrder(); - po1.setDate(new Date()); - r1.getContents().add(po1); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource(getResourcePath("/res")); + + PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder(); + purchaseOrder.setDate(new Date()); + resource.getContents().add(purchaseOrder); Supplier supplier = getModel1Factory().createSupplier(); - supplier.getPurchaseOrders().add(po1); - r1.getContents().add(supplier); + supplier.getPurchaseOrders().add(purchaseOrder); + resource.getContents().add(supplier); - tx.commit(); + transaction.commit(); - // Remove po2 in another session + // Remove purchaseOrder in another session doSecondSession(); // Make the supplier dirty so that it will be scanned for dangling refs - // during processing of the refresh results + // in supplier.getPurchaseOrders() during processing of the refresh results supplier.setName("Supplier"); session.refresh(); - CDOState state = CDOUtil.getCDOObject(po1).cdoState(); - System.out.println("--> purchaseOrder state (should be INVALID) = " + state); - assertEquals(CDOState.INVALID, state); + CDOState state = CDOUtil.getCDOObject(purchaseOrder).cdoState(); + assertEquals(CDOState.INVALID_CONFLICT, state); - tx.close(); + transaction.close(); session.close(); } private void doSecondSession() throws CommitException { CDOSession session = openSession(); - CDOTransaction tx = session.openTransaction(); - CDOResource r1 = tx.getResource(getResourcePath("/r1")); //$NON-NLS-1$ + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.getResource(getResourcePath("/res")); - // Detach the po - PurchaseOrder po = (PurchaseOrder)r1.getContents().get(0); - EcoreUtil.delete(po); + // Detach the purchaseOrder + PurchaseOrder purchaseOrder = (PurchaseOrder)resource.getContents().get(0); + EcoreUtil.delete(purchaseOrder); - tx.commit(); - tx.close(); + transaction.commit(); session.close(); } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405850_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405850_Test.java new file mode 100644 index 0000000000..40795a90a2 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_405850_Test.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + */ +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.PurchaseOrder; +import org.eclipse.emf.cdo.tests.model1.Supplier; +import org.eclipse.emf.cdo.transaction.CDOTransaction; + +import org.eclipse.emf.common.util.EList; + +/** + * Bug 405850 - CDORevision.get(feature, -1) should throw an IndexOutOfBoundsException for many-valued features + * + * @author Eike Stepper + */ +public class Bugzilla_405850_Test extends AbstractCDOTest +{ + public void testIndexOutOfBounds() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource(getResourcePath("/res")); + + PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder(); + resource.getContents().add(purchaseOrder); + + Supplier supplier = getModel1Factory().createSupplier(); + EList<PurchaseOrder> purchaseOrders = supplier.getPurchaseOrders(); + purchaseOrders.add(purchaseOrder); + resource.getContents().add(supplier); + + transaction.commit(); + + try + { + purchaseOrders.get(-1); + fail("IndexOutOfBoundsException expected"); + } + catch (IndexOutOfBoundsException expected) + { + // SUCCEED + } + + try + { + purchaseOrders.get(1); + fail("IndexOutOfBoundsException expected"); + } + catch (IndexOutOfBoundsException expected) + { + // SUCCEED + } + } +} 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 9f5a71a99f..91f85438d8 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 @@ -137,7 +137,6 @@ import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EStructuralFeature.Setting; -import org.eclipse.emf.ecore.InternalEObject.EStore; import org.eclipse.emf.ecore.impl.EClassImpl.FeatureSubsetSupplier; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.Resource.Internal; @@ -2379,12 +2378,27 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa { InternalCDORevision cleanRevision = cleanRevisions.get(referencer); - Object value = cleanRevision.get(reference, EStore.NO_INDEX); - if (value instanceof CDOObject && value == referencedObject || // - value instanceof CDOID && value.equals(referencedOID) || // - value instanceof CDOList && ((CDOList)value).contains(referencedOID)) + if (reference.isMany()) { - continue; + CDOList list = cleanRevision.getList(reference); + if (list != null) + { + for (Object value : list) + { + if (value == referencedOID || value == referencedObject) + { + continue; + } + } + } + } + else + { + Object value = cleanRevision.getValue(reference); + if (value == referencedOID || value == referencedObject) + { + continue; + } } } 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 3ecce96036..ce8c6c1d56 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 @@ -36,7 +36,6 @@ import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.InternalEObject.EStore; import org.eclipse.emf.spi.cdo.InternalCDOObject; import org.eclipse.emf.spi.cdo.InternalCDOTransaction; import org.eclipse.emf.spi.cdo.InternalCDOTransaction.InternalCDOCommitContext; @@ -445,18 +444,21 @@ public class CommitIntegrityCheck { if (referencerClassInfo.hasPersistentOpposite(reference)) { - Object value = cleanRev.get(reference, EStore.NO_INDEX); - if (value != null) + if (reference.isMany()) { - if (reference.isMany()) + EList<?> list = cleanRev.getList(reference); + if (list != null) { - EList<?> list = (EList<?>)value; for (Object element : list) { checkBidiRefTargetIncluded(element, referencer, reference.getName(), msgFrag); } } - else + } + else + { + Object value = cleanRev.getValue(reference); + if (value != null) { checkBidiRefTargetIncluded(value, referencer, reference.getName(), msgFrag); } 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 a40952ea04..504832ed0f 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 @@ -205,23 +205,27 @@ public final class CDOStoreImpl implements CDOStore TRACER.format("isSet({0}, {1})", cdoObject, feature); //$NON-NLS-1$ } - if (!feature.isUnsettable()) + InternalCDORevision revision = getRevisionForReading(cdoObject); + if (feature.isMany()) { - if (feature.isMany()) - { - InternalCDORevision revision = getRevisionForReading(cdoObject); - CDOList list = revision.getList(feature); - return list != null && !list.isEmpty(); - } + CDOList list = revision.getList(feature); + return list != null && !list.isEmpty(); + } - Object value = eObject.eGet(feature); - Object defaultValue = feature.getDefaultValue(); - return !ObjectUtil.equals(value, defaultValue); + Object value = revision.getValue(feature); + if (feature.isUnsettable()) + { + return value != null; + } + + if (value == null) + { + return false; } - // TODO This get() may not work for lists, see above - Object value = get(eObject, feature, NO_INDEX); - return value != null; + value = convertToEMF(eObject, revision, feature, NO_INDEX, value); + Object defaultValue = feature.getDefaultValue(); + return !ObjectUtil.equals(value, defaultValue); } } |