Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2013-01-22 03:29:34 -0500
committerEike Stepper2013-01-22 03:30:18 -0500
commit00275a1321c9da35e59ec5fd4b81a215f4c2c1fe (patch)
tree7849ad21584761580aa3eac5c561a1446ef05e1f
parentcc30ef6f6fbcd02de8fea7d1e3efb6dd27cfbbac (diff)
downloadcdo-00275a1321c9da35e59ec5fd4b81a215f4c2c1fe.tar.gz
cdo-00275a1321c9da35e59ec5fd4b81a215f4c2c1fe.tar.xz
cdo-00275a1321c9da35e59ec5fd4b81a215f4c2c1fe.zip
[362270] CDODeltaNotification.getNewValue() returns a CDOIDExternal
instead of the EObject from the containing XMIResource https://bugs.eclipse.org/bugs/show_bug.cgi?id=362270
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270b_Test.java146
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java157
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDODeltaNotificationImpl.java27
-rw-r--r--plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java5
4 files changed, 330 insertions, 5 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270b_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270b_Test.java
new file mode 100644
index 0000000000..5e773280a9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270b_Test.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2004 - 2013 Esteban Dugueperoux 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:
+ * Esteban Dugueperoux - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.eresource.CDOResourceFactory;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.model4.ContainedElementNoOpposite;
+import org.eclipse.emf.cdo.tests.model4.GenRefMultiContained;
+import org.eclipse.emf.cdo.tests.model4.RefSingleNonContainedNPL;
+import org.eclipse.emf.cdo.transaction.CDOSavepoint;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
+import org.eclipse.emf.internal.cdo.object.CDOLegacyAdapter;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
+
+import java.util.Collections;
+
+/**
+ * @author Esteban Dugueperoux
+ */
+public class Bugzilla_362270b_Test extends AbstractCDOTest
+{
+ private static final String REMOTE_RESOURCE_PATH = "sharedResource.model1";
+
+ private CDOTransaction cdoTransaction;
+
+ private ContainedElementNoOpposite containedElementNoOpposite1;
+
+ private ContainedElementNoOpposite containedElementNoOpposite2;
+
+ private RefSingleNonContainedNPL refSingleNonContainedNPL1;
+
+ private RefSingleNonContainedNPL refSingleNonContainedNPL2;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ Resource.Factory.Registry registry = Resource.Factory.Registry.INSTANCE;
+ registry.getProtocolToFactoryMap().put("cdo.net4j.tcp", CDOResourceFactory.INSTANCE);
+ registry.getExtensionToFactoryMap().put("model1", new XMIResourceFactoryImpl());
+
+ CDOSession session = openSession();
+ cdoTransaction = session.openTransaction();
+ init(cdoTransaction);
+ }
+
+ private void init(CDOTransaction cdoTransaction) throws Exception
+ {
+ URI localResourceURI = URI.createFileURI(createTempFile("resource", ".model1").getCanonicalPath());
+ Resource remoteResource = cdoTransaction.createResource(getResourcePath(REMOTE_RESOURCE_PATH));
+ Resource localResource = cdoTransaction.getResourceSet().createResource(localResourceURI);
+
+ GenRefMultiContained localGenRefMultiContained = getModel4Factory().createGenRefMultiContained();
+ containedElementNoOpposite1 = getModel4Factory().createContainedElementNoOpposite();
+ containedElementNoOpposite2 = getModel4Factory().createContainedElementNoOpposite();
+ localGenRefMultiContained.getElements().add(containedElementNoOpposite1);
+ localGenRefMultiContained.getElements().add(containedElementNoOpposite2);
+
+ localResource.getContents().add(localGenRefMultiContained);
+ localResource.save(Collections.emptyMap());
+
+ GenRefMultiContained genRefMultiContained = getModel4Factory().createGenRefMultiContained();
+ refSingleNonContainedNPL1 = getModel4Factory().createRefSingleNonContainedNPL();
+ refSingleNonContainedNPL2 = getModel4Factory().createRefSingleNonContainedNPL();
+ refSingleNonContainedNPL1.setElement(containedElementNoOpposite1);
+ refSingleNonContainedNPL2.setElement(containedElementNoOpposite1);
+ genRefMultiContained.getElements().add(refSingleNonContainedNPL1);
+ genRefMultiContained.getElements().add(refSingleNonContainedNPL2);
+ remoteResource.getContents().add(genRefMultiContained);
+ remoteResource.save(Collections.emptyMap());
+
+ genRefMultiContained.eAdapters().add(new ECrossReferenceAdapter());
+ }
+
+ public void testRollback() throws Exception
+ {
+ RemoteUser remoteUser = new RemoteUser();
+ remoteUser.accessContents();
+
+ CDOSavepoint savepoint = cdoTransaction.setSavepoint();
+ refSingleNonContainedNPL1.setElement(containedElementNoOpposite2);
+ refSingleNonContainedNPL1.setElement(containedElementNoOpposite1);
+ savepoint.rollback();
+ refSingleNonContainedNPL2.setElement(containedElementNoOpposite2);
+ refSingleNonContainedNPL2.setElement(containedElementNoOpposite1);
+
+ cdoTransaction.commit();
+
+ Adapter adapter = EcoreUtil.getAdapter(containedElementNoOpposite1.eAdapters(), CDOLegacyAdapter.class);
+ assertNull("A legacy adapter should NOT be attached to an external object", adapter);
+ }
+
+ /**
+ * @author Esteban Dugueperoux
+ */
+ private final class RemoteUser
+ {
+ private CDOTransaction transaction;
+
+ private CDOResource sharedResource;
+
+ private GenRefMultiContained genRefMultiContained;
+
+ public RemoteUser()
+ {
+ CDOSession session = openSession();
+ transaction = session.openTransaction();
+ sharedResource = transaction.getResource(getResourcePath(REMOTE_RESOURCE_PATH));
+ }
+
+ public void accessContents()
+ {
+ genRefMultiContained = (GenRefMultiContained)sharedResource.getContents().get(0);
+ genRefMultiContained.eAdapters().add(new ECrossReferenceAdapter());
+ }
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ cdoTransaction = null;
+ containedElementNoOpposite1 = null;
+ containedElementNoOpposite2 = null;
+ refSingleNonContainedNPL1 = null;
+ refSingleNonContainedNPL2 = null;
+ super.tearDown();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java
new file mode 100644
index 0000000000..4721a53933
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270c_Test.java
@@ -0,0 +1,157 @@
+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.PurchaseOrder;
+import org.eclipse.emf.cdo.tests.model1.Supplier;
+import org.eclipse.emf.cdo.transaction.CDOSavepoint;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
+import org.eclipse.emf.internal.cdo.object.CDOLegacyWrapper;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.RemoveCommand;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.emf.transaction.ResourceSetListenerImpl;
+import org.eclipse.emf.transaction.RollbackException;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Esteban Dugueperoux
+ */
+public class Bugzilla_362270c_Test extends AbstractCDOTest
+{
+ private static final String RESOURCE_PATH = "/test1";
+
+ public void testNotifierNotACDOLegacyAdapter() throws Exception
+ {
+ TransactionalEditingDomain domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain();
+ ResourceSet resourceSet = domain.getResourceSet();
+
+ // 1. Create the CDOResource
+ Company obeoCompany = getModel1Factory().createCompany();
+ obeoCompany.setName("OBEO");
+ obeoCompany.setCity("Nantes");
+
+ Supplier martinSupplier = getModel1Factory().createSupplier();
+ obeoCompany.getSuppliers().add(martinSupplier);
+
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction(resourceSet);
+ CDOResource resource = transaction.createResource(getResourcePath(RESOURCE_PATH));
+
+ resource.getContents().add(obeoCompany);
+ resource.save(Collections.emptyMap());
+
+ // 2. Create the local XMI resource
+ Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
+ Map<String, Object> m = reg.getExtensionToFactoryMap();
+ m.put("model1", new XMIResourceFactoryImpl());
+
+ Company martinCompany = getModel1Factory().createCompany();
+ martinCompany.setName("Martin");
+ martinCompany.setCity("Berlin");
+
+ PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder();
+ martinCompany.getPurchaseOrders().add(purchaseOrder);
+
+ File localResourceFile = createTempFile("localResource", ".model1");
+ URI localResourceURI = URI.createFileURI(localResourceFile.getAbsolutePath());
+ Resource localResource = new ResourceSetImpl().createResource(localResourceURI);
+
+ localResource.getContents().add(martinCompany);
+ localResource.save(Collections.emptyMap());
+ localResource = resourceSet.getResource(localResourceURI, true);
+
+ // 3. Add a reference from the CDOResource to the local resource
+ Command addPurchaseOrderCmd = AddCommand.create(domain, martinSupplier, getModel1Package()
+ .getSupplier_PurchaseOrders(), purchaseOrder);
+ domain.getCommandStack().execute(addPurchaseOrderCmd);
+
+ resource.save(Collections.emptyMap());
+
+ // 4. Create the first CDOSavepoint
+ final CDOSavepoint firstSavepoint = transaction.setSavepoint();
+
+ Rollbacker rollbacker = new Rollbacker();
+ domain.addResourceSetListener(rollbacker);
+
+ // 5. Detach a CDOObject
+ Command removeMartinSupplierCmd = RemoveCommand.create(domain, obeoCompany, getModel1Package()
+ .getCompany_Suppliers(), martinSupplier);
+ domain.getCommandStack().execute(removeMartinSupplierCmd);
+
+ // 6. Rollback the previous operation
+ Command rollbackSavepointCmd = new RecordingCommand(domain)
+ {
+ @Override
+ protected void doExecute()
+ {
+ firstSavepoint.rollback();
+ }
+ };
+
+ NotifierCollector collector = new NotifierCollector();
+ martinSupplier.eAdapters().add(collector);
+
+ domain.getCommandStack().execute(rollbackSavepointCmd);
+ domain.removeResourceSetListener(rollbacker);
+
+ for (Object notifier : collector.getNotifiers())
+ {
+ assertNotInstanceOf(CDOLegacyWrapper.class, notifier);
+ }
+ }
+
+ /**
+ * @author Esteban Dugueperoux
+ */
+ private class Rollbacker extends ResourceSetListenerImpl
+ {
+ @Override
+ public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException
+ {
+ IStatus status = Status.CANCEL_STATUS;
+ throw new RollbackException(status);
+ }
+ }
+
+ /**
+ * @author Esteban Dugueperoux
+ */
+ private class NotifierCollector extends AdapterImpl
+ {
+ private Set<Object> notifiers = new HashSet<Object>();
+
+ @Override
+ public void notifyChanged(Notification msg)
+ {
+ notifiers.add(msg.getNotifier());
+ }
+
+ public Set<Object> getNotifiers()
+ {
+ return notifiers;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDODeltaNotificationImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDODeltaNotificationImpl.java
index b79c7f446a..737fddac4c 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDODeltaNotificationImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDODeltaNotificationImpl.java
@@ -14,16 +14,19 @@ package org.eclipse.emf.internal.cdo.object;
import org.eclipse.emf.cdo.CDODeltaNotification;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDExternal;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOView;
@@ -136,14 +139,28 @@ public class CDODeltaNotificationImpl extends ENotificationImpl implements CDODe
{
CDOID id = (CDOID)object;
- try
+ if (id instanceof CDOIDExternal)
{
- InternalCDOView view = getCDOObject().cdoView();
- object = view.getObject(id, true);
+ CDOIDExternal idExternal = (CDOIDExternal)id;
+ Resource resource = notifier.eResource();
+ if (resource != null)
+ {
+ String uriString = idExternal.getURI();
+ URI uri = URI.createURI(uriString);
+ object = resource.getResourceSet().getEObject(uri, false);
+ }
}
- catch (ObjectNotFoundException ex)
+ else
{
- object = null;
+ try
+ {
+ InternalCDOView view = getCDOObject().cdoView();
+ object = view.getObject(id, true);
+ }
+ catch (ObjectNotFoundException ex)
+ {
+ object = null;
+ }
}
}
diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java
index 90cbd802ee..291eae1865 100644
--- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java
+++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java
@@ -524,6 +524,11 @@ public abstract class AbstractOMTest extends TestCase
expected.isInstance(object));
}
+ public static void assertNotInstanceOf(Class<?> expected, Object object)
+ {
+ assertEquals("An instance of " + expected + ": " + object.getClass().getName(), false, expected.isInstance(object));
+ }
+
public static void assertActive(Object object) throws InterruptedException
{
final LatchTimeOuter timeOuter = new LatchTimeOuter();

Back to the top