summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon McDuff2008-05-23 13:20:50 (EDT)
committerSimon McDuff2008-05-23 13:20:50 (EDT)
commitbf1c533eb3b25c5014f41e197e74fd402e7d9a35 (patch)
tree1722a56ddcba3ffc3e69fbb514e3538d6b26f162
parent9b9bcfaac140cd53b70c433e6b87823aa7794bde (diff)
downloadcdo-bf1c533eb3b25c5014f41e197e74fd402e7d9a35.zip
cdo-bf1c533eb3b25c5014f41e197e74fd402e7d9a35.tar.gz
cdo-bf1c533eb3b25c5014f41e197e74fd402e7d9a35.tar.bz2
[233277] Automatic link persistence objects together
https://bugs.eclipse.org/bugs/show_bug.cgi?id=233277
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java103
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java6
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java5
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java9
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java41
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOAutoAttacher.java176
6 files changed, 322 insertions, 18 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java
new file mode 100644
index 0000000..8633fb4
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Simon McDuff, Canada.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.tests;
+
+import org.eclipse.emf.cdo.CDOSession;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.tests.model1.Model1Factory;
+import org.eclipse.emf.cdo.tests.model1.Order;
+import org.eclipse.emf.cdo.tests.model1.OrderDetail;
+import org.eclipse.emf.cdo.tests.model1.Product;
+import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
+import org.eclipse.emf.cdo.tests.model1.Supplier;
+
+import org.eclipse.emf.internal.cdo.CDOTransactionImpl;
+import org.eclipse.emf.internal.cdo.util.CDOAutoAttacher;
+
+
+/**
+ * @author Simon McDuff
+ */
+public class AutoAttacherTest extends AbstractCDOTest
+{
+
+
+ public void testBasic() throws Exception
+ {
+ CDOSession session = openModel1Session();
+
+ CDOTransactionImpl transaction = (CDOTransactionImpl)session.openTransaction();
+
+ new CDOAutoAttacher(transaction);
+
+ CDOResource resource1 = transaction.getOrCreateResource("/test1");
+
+ Product product = Model1Factory.eINSTANCE.createProduct();
+ {
+ assertTransient(product);
+
+ resource1.getContents().add(product);
+ assertEquals(resource1, product.eResource());
+ //assertEquals(resource1, ((EObjectImpl)product).eDirectResource());
+
+ assertNew(product, transaction);
+
+ }
+
+ OrderDetail orderDetail = Model1Factory.eINSTANCE.createOrderDetail();
+ {
+ assertTransient(orderDetail);
+ product.getOrderDetails().add(orderDetail);
+ assertNew(orderDetail, transaction);
+ }
+
+ Order order = Model1Factory.eINSTANCE.createOrder();
+ {
+ // Bidirectionnel/containment relationship
+ assertTransient(order);
+ // Fail for now. Need to be able to handle that case!
+ //order.getOrderDetails().add(orderDetail);
+
+ //assertTransient(order);
+ }
+
+ transaction.close();
+ session.close();
+ }
+
+ public void testBasic2() throws Exception
+ {
+ CDOSession session = openModel1Session();
+
+ CDOTransactionImpl transaction = (CDOTransactionImpl)session.openTransaction();
+
+ new CDOAutoAttacher(transaction);
+
+ CDOResource resource1 = transaction.getOrCreateResource("/test1");
+
+ Supplier supplier = Model1Factory.eINSTANCE.createSupplier();
+ PurchaseOrder purchaseOrder = Model1Factory.eINSTANCE.createPurchaseOrder();
+
+ supplier.getPurchaseOrders().add(purchaseOrder);
+
+ assertTransient(supplier);
+
+ resource1.getContents().add(supplier);
+
+ assertNew(supplier, transaction);
+ assertNew(purchaseOrder, transaction);
+
+
+ transaction.close();
+ session.close();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
index aef3dd4..7544edb 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
@@ -434,7 +434,7 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
*/
public void attached(EObject object)
{
- InternalCDOObject legacy = getLegacyWrapper(object);
+ /*InternalCDOObject legacy = getLegacyWrapper(object);
if (legacy.cdoState() != CDOState.CLEAN)
{
CDOStateMachine.INSTANCE.attach(legacy, this, view);
@@ -443,7 +443,7 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
// legacy.eBasicSetContainer(null, 0, null);
// legacy.eSetResource(this, null);
// }
- }
+ }*/
}
/**
@@ -451,8 +451,10 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
*/
public void detached(EObject object)
{
+ /*
InternalCDOObject legacy = getLegacyWrapper(object);
CDOStateMachine.INSTANCE.detach(legacy);
+ */
}
/**
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 6bda90a..a1d06f9 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
@@ -569,6 +569,11 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
{
// Delegate to CDOStore
getStore().setContainer(this, newContainer, newContainerFeatureID);
+
+ if (newContainer instanceof Resource.Internal)
+ {
+ eSetDirectResource((Resource.Internal)newContainer);
+ }
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
index c7e6acd..de9aa60 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
@@ -504,14 +504,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
{
CDOViewImpl view = (CDOViewImpl)object.cdoView();
CDOTransactionImpl transaction = view.toTransaction();
-
- // Register Delta for new objects only if objectA doesn't belong to this savepoint
- if (transaction.getLastSavePoint().getPreviousSavePoint() == null || featureDelta == null) return;
-
- Map<CDOID, ? extends CDOObject> map = object instanceof CDOResource ? transaction.getLastSavePoint()
- .getNewResources() : transaction.getLastSavePoint().getNewObjects();
-
- if (!map.containsKey(object.cdoID())) transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta);
+ transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta);
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
index f8e4502..7e0652a 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
@@ -495,21 +495,46 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
public void registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta)
{
- CDORevisionDelta revisionDelta = (CDORevisionDelta)lastSavePoint.getRevisionDeltas().get(object.cdoID());
-
- if (revisionDelta == null)
+ boolean needToSaveFeatureDelta = true;
+
+ if (object.cdoState() == CDOState.NEW)
{
- revisionDelta = (CDORevisionDelta)CDORevisionDeltaUtil.create(object.cdoRevision());
- lastSavePoint.getRevisionDeltas().put(object.cdoID(), revisionDelta);
+ // Register Delta for new objects only if objectA doesn't belong to this savepoint
+ if (this.getLastSavePoint().getPreviousSavePoint() == null || featureDelta == null)
+ {
+ needToSaveFeatureDelta = false;
+ }
+ else
+ {
+ Map<CDOID, ? extends CDOObject> map = object instanceof CDOResource ? this.getLastSavePoint()
+ .getNewResources() : this.getLastSavePoint().getNewObjects();
+
+ needToSaveFeatureDelta = !map.containsKey(object.cdoID());
+ }
}
-
- ((InternalCDORevisionDelta)revisionDelta).addFeatureDelta(featureDelta);
+
+ if (needToSaveFeatureDelta)
+ {
+ CDORevisionDelta revisionDelta = (CDORevisionDelta)lastSavePoint.getRevisionDeltas().get(object.cdoID());
+
+ if (revisionDelta == null)
+ {
+ revisionDelta = (CDORevisionDelta)CDORevisionDeltaUtil.create(object.cdoRevision());
+ lastSavePoint.getRevisionDeltas().put(object.cdoID(), revisionDelta);
+ }
+
+ ((InternalCDORevisionDelta)revisionDelta).addFeatureDelta(featureDelta);
+ }
+
for (CDOTransactionHandler handler : getHandlers())
{
handler.modifyingObject(this, object, featureDelta);
}
}
-
+
+ protected void fireEventRegisterDelta(InternalCDOObject object, CDOFeatureDelta featureDelta)
+ {
+ }
public void registerRevisionDelta(CDORevisionDelta revisionDelta)
{
lastSavePoint.getRevisionDeltas().putIfAbsent(revisionDelta.getID(), revisionDelta);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOAutoAttacher.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOAutoAttacher.java
new file mode 100644
index 0000000..20175c2
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOAutoAttacher.java
@@ -0,0 +1,176 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Simon McDuff, Canada.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/package org.eclipse.emf.internal.cdo.util;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.CDOTransactionHandler;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOContainerFeatureDelta;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.protocol.revision.delta.CDOUnsetFeatureDelta;
+
+import org.eclipse.emf.internal.cdo.InternalCDOObject;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+
+import java.util.List;
+/**
+ * @author Simon McDuff
+ */
+public class CDOAutoAttacher implements CDOTransactionHandler
+{
+ CDOTransaction cdoTransaction;
+
+
+
+ class CDOFeatureDeltaVisitorAutoAttach implements CDOFeatureDeltaVisitor
+ {
+
+ Resource resource;
+ CDOFeatureDeltaVisitorAutoAttach(Resource resource)
+ {
+ this.resource = resource;
+ }
+ public void visit(CDOAddFeatureDelta featureChange)
+ {
+ persist(resource, featureChange.getValue());
+ }
+
+ public void visit(CDOClearFeatureDelta featureChange)
+ {
+
+ }
+
+ public void visit(CDOListFeatureDelta featureChange)
+ {
+
+ }
+
+ public void visit(CDOMoveFeatureDelta featureChange)
+ {
+
+ }
+
+ public void visit(CDORemoveFeatureDelta featureChange)
+ {
+ }
+
+ public void visit(CDOSetFeatureDelta featureChange)
+ {
+ persist(resource, featureChange.getValue());
+ }
+
+ public void visit(CDOUnsetFeatureDelta featureChange)
+ {
+ }
+
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ }
+
+ };
+
+ public CDOAutoAttacher(CDOTransaction transaction)
+ {
+ this.cdoTransaction = transaction;
+ transaction.addHandler(this);
+ }
+
+ protected void persist(Resource res, Object object)
+ {
+ if (object instanceof CDOResource)
+ return;
+
+ if (!(object instanceof InternalCDOObject))
+ return;
+
+ res.getContents().add((InternalCDOObject)object);
+ }
+
+ /**
+ * @param eObject
+ */
+ private void handle(Resource resource, EObject eObject)
+ {
+ for (EReference reference : eObject.eClass().getEAllReferences())
+ {
+ if (reference.isMany())
+ {
+ List<EObject> list = (List<EObject>)eObject.eGet(reference);
+ for (EObject element : list)
+ {
+ if (element.eResource() == null)
+ {
+ if (reference.isContainment())
+ handle(resource, element);
+ else
+ persist(resource, element);
+ }
+ }
+ }
+ else
+ {
+ EObject element = (EObject)eObject.eGet(reference);
+
+ if (element != null && element.eResource() == null)
+ {
+ // objectsAdded.add(element);
+ if (reference.isContainment())
+ handle(resource, element);
+ else
+ persist(resource, element);
+ }
+ }
+ }
+
+ }
+
+ public void addingObject(CDOTransaction transaction, CDOObject object)
+ {
+ if (object instanceof CDOResource)
+ return;
+
+ // Persist the graph as well.
+ handle(object.eResource(), object);
+ }
+
+ public void committingTransaction(CDOTransaction transaction)
+ {
+
+ }
+
+ public void modifyingObject(CDOTransaction transaction, CDOObject object, CDOFeatureDelta featureChange)
+ {
+ if (object instanceof CDOResource)
+ return;
+
+ if (featureChange != null)
+ {
+ CDOFeatureDeltaVisitorAutoAttach featureChangeVisitor = new CDOFeatureDeltaVisitorAutoAttach( object.cdoResource());
+ featureChange.accept(featureChangeVisitor);
+ }
+
+ }
+
+ public void rollingbackTransaction(CDOTransaction transaction)
+ {
+ }
+
+}