Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2011-12-09 13:14:38 +0000
committerEike Stepper2011-12-09 13:14:38 +0000
commit71a356fac26b2766f3702205b272655df98d0f99 (patch)
treeefc52e8bc428b84252e4834b7961a552e71e652c
parent7976f7a0abe1f0744699cc299725c58ce5e36c56 (diff)
downloadcdo-71a356fac26b2766f3702205b272655df98d0f99.tar.gz
cdo-71a356fac26b2766f3702205b272655df98d0f99.tar.xz
cdo-71a356fac26b2766f3702205b272655df98d0f99.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/AllConfigs.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_283985_3_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java174
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java5
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java55
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java4
7 files changed, 224 insertions, 19 deletions
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 a5b1dd0c78..f49f25a88b 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
@@ -243,6 +243,7 @@ public abstract class AllConfigs extends ConfigTestSuite
testClasses.add(Bugzilla_355915_Test.class);
testClasses.add(Bugzilla_359966_Test.class);
testClasses.add(Bugzilla_359992_Test.class);
+ testClasses.add(Bugzilla_362270_Test.class);
testClasses.add(Bugzilla_363287_Test.class);
testClasses.add(Bugzilla_365832_Test.class);
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_283985_3_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_283985_3_Test.java
index 97aecd4b3b..20fac57cd9 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_283985_3_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_283985_3_Test.java
@@ -149,7 +149,7 @@ public class Bugzilla_283985_3_Test extends AbstractCDOTest
}
/**
- * Bugzilla 312205 - After detach-reattach-rollback, object is not present in tx
+ * Bug 312205 - After detach-reattach-rollback, object is not present in tx
*/
public void test4()
{
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java
new file mode 100644
index 0000000000..605a6ce581
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_362270_Test.java
@@ -0,0 +1,174 @@
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.CDODeltaNotification;
+import org.eclipse.emf.cdo.CDOObject;
+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.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+
+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.EObject;
+import org.eclipse.emf.ecore.EReference;
+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.XMIResource;
+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.Status;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Test case for {@link CDODeltaNotification#getNewValue()} which must returns a local {@link EObject} contained in a
+ * {@link XMIResource} because a {@link CDOObject} stored in a {@link CDOResource} references the local {@link EObject}.
+ *
+ * @author Esteban Dugueperoux
+ */
+public class Bugzilla_362270_Test extends AbstractCDOTest
+{
+ private final EReference SUPPLIERS = getModel1Package().getCompany_Suppliers();
+
+ private final EReference PURCHASE_ORDERS = getModel1Package().getSupplier_PurchaseOrders();
+
+ public void testNotifierNotACDOLegacyAdapter() throws Exception
+ {
+ TransactionalEditingDomain domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain();
+ ResourceSet resourceSet = domain.getResourceSet();
+ registerXMIFactory(resourceSet);
+
+ // 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();
+ CDOUtil.setLegacyModeDefault(true);
+ final CDOTransaction cdoTransaction = session.openTransaction(resourceSet);
+
+ CDOResource cdoResource = cdoTransaction.createResource(getResourcePath("/test1"));
+ cdoResource.getContents().add(obeoCompany);
+ cdoTransaction.commit();
+
+ // 2. Create the local XMI resource
+ URI localResourceURI = createXMIResource();
+
+ // Reload the local resource through the CDOTransaction!!!
+ Resource localResource = resourceSet.getResource(localResourceURI, true);
+ Company martinCompany = (Company)localResource.getContents().get(0);
+ PurchaseOrder purchaseOrder = martinCompany.getPurchaseOrders().get(0);
+
+ Command addPurchaseOrderCmd = AddCommand.create(domain, martinSupplier, PURCHASE_ORDERS, purchaseOrder);
+ domain.getCommandStack().execute(addPurchaseOrderCmd);
+
+ // 4. Commit
+ cdoTransaction.commit();
+
+ domain.addResourceSetListener(new ResourceSetListenerImpl()
+ {
+ @Override
+ public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException
+ {
+ throw new RollbackException(Status.CANCEL_STATUS);
+ }
+ });
+
+ Command removeMartinSupplierCmd = RemoveCommand.create(domain, obeoCompany, SUPPLIERS, martinSupplier);
+ domain.getCommandStack().execute(removeMartinSupplierCmd);
+
+ AssertAdapter assertAdapter = new AssertAdapter(purchaseOrder);
+ martinSupplier.eAdapters().add(assertAdapter);
+
+ // 6. rollback the previous operation
+ domain.getCommandStack().execute(new RecordingCommand(domain)
+ {
+ @Override
+ protected void doExecute()
+ {
+ cdoTransaction.rollback();
+ }
+ });
+ }
+
+ private URI createXMIResource() throws IOException
+ {
+ ResourceSet localResourceSet = new ResourceSetImpl();
+ registerXMIFactory(localResourceSet);
+
+ File localResourceFile = createTempFile("localResource", ".model1").getAbsoluteFile();
+ URI localResourceURI = URI.createFileURI(localResourceFile.getAbsolutePath());
+ Resource localResource = localResourceSet.createResource(localResourceURI);
+
+ Company martinCompany = getModel1Factory().createCompany();
+ martinCompany.setName("Martin");
+ martinCompany.setCity("Berlin");
+
+ PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder();
+ martinCompany.getPurchaseOrders().add(purchaseOrder);
+
+ localResource.getContents().add(martinCompany);
+ localResource.save(Collections.emptyMap());
+
+ return localResourceURI;
+ }
+
+ private void registerXMIFactory(ResourceSet resourceSet)
+ {
+ Map<String, Object> map = resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
+ map.put("model1", new XMIResourceFactoryImpl());
+ }
+
+ private final class AssertAdapter extends AdapterImpl
+ {
+ private EObject eObject;
+
+ private int notifyCounter;
+
+ public AssertAdapter(EObject eObject)
+ {
+ this.eObject = eObject;
+ }
+
+ @Override
+ public void notifyChanged(Notification msg)
+ {
+ if (getModel1Package().getSupplier_PurchaseOrders().equals(msg.getFeature()))
+ {
+ switch (++notifyCounter)
+ {
+ case 1:
+ assertEquals(null, msg.getNewValue());
+ break;
+
+ case 2:
+ assertEquals(eObject, msg.getNewValue());
+ break;
+
+ default:
+ fail("Only 0 or 2 calls are expected");
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
index bc4eb13027..6db6dcd2b7 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
@@ -29,6 +29,7 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta;
import org.eclipse.net4j.util.collection.MultiMap;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.emf.spi.cdo.CDOTransactionStrategy;
import org.eclipse.emf.spi.cdo.InternalCDOSavepoint;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
@@ -390,7 +391,9 @@ public class CDOSavepointImpl extends CDOUserSavepointImpl implements InternalCD
{
InternalCDOTransaction transaction = getTransaction();
LifecycleUtil.checkActive(transaction);
- transaction.getTransactionStrategy().rollback(transaction, this);
+
+ CDOTransactionStrategy transactionStrategy = transaction.getTransactionStrategy();
+ transactionStrategy.rollback(transaction, this);
}
}
}
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 8c43f314ef..e5e0a954b7 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
@@ -1163,7 +1163,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
- // Rollback all persisted objects
+ // Rollback all detached objects
Map<CDOID, CDOObject> detachedObjectsMap = itrSavepoint.getDetachedObjects();
if (!detachedObjectsMap.isEmpty())
{
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 8c6841f184..d01995faeb 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
@@ -19,6 +19,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDExternal;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
@@ -679,26 +680,50 @@ public abstract class AbstractCDOView extends Lifecycle implements InternalCDOVi
return lastLookupObject;
}
- // Needed for recursive call to getObject. (from createObject/cleanObject/getResource/getObject)
- InternalCDOObject localLookupObject = objects.get(id);
- if (localLookupObject == null)
- {
- if (!loadOnDemand)
- {
- return null;
- }
+ lastLookupID = null;
+ lastLookupObject = null;
+ InternalCDOObject localLookupObject = null;
- excludeTempIDs(id);
- localLookupObject = createObject(id);
+ if (id.isExternal())
+ {
+ URI uri = URI.createURI(((CDOIDExternal)id).getURI());
+ ResourceSet resourceSet = getResourceSet();
- // CDOResource have a special way to register to the view.
- if (!CDOModelUtil.isResource(localLookupObject.eClass()))
+ localLookupObject = (InternalCDOObject)CDOUtil.getCDOObject(resourceSet.getEObject(uri, loadOnDemand));
+ if (localLookupObject == null)
{
- registerObject(localLookupObject);
+ if (!loadOnDemand)
+ {
+ return null;
+ }
+
+ throw new ObjectNotFoundException(id, this);
}
- else if (id.equals(getSession().getRepositoryInfo().getRootResourceID()))
+
+ }
+ else
+ {
+ // Needed for recursive call to getObject. (from createObject/cleanObject/getResource/getObject)
+ localLookupObject = objects.get(id);
+ if (localLookupObject == null)
{
- setRootResource((CDOResourceImpl)localLookupObject);
+ if (!loadOnDemand)
+ {
+ return null;
+ }
+
+ excludeTempIDs(id);
+ localLookupObject = createObject(id);
+
+ // CDOResource have a special way to register to the view.
+ if (!CDOModelUtil.isResource(localLookupObject.eClass()))
+ {
+ registerObject(localLookupObject);
+ }
+ else if (id.equals(getSession().getRepositoryInfo().getRootResourceID()))
+ {
+ setRootResource((CDOResourceImpl)localLookupObject);
+ }
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
index dc33de14c1..423f12d63e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
@@ -11,6 +11,7 @@
*/
package org.eclipse.emf.internal.cdo.view;
+import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
@@ -688,7 +689,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
// Add the object to the set of reattached objects
- transaction.getLastSavepoint().getReattachedObjects().put(id, object);
+ Map<CDOID, CDOObject> reattachedObjects = transaction.getLastSavepoint().getReattachedObjects();
+ reattachedObjects.put(id, object);
}
}

Back to the top