diff options
3 files changed, 115 insertions, 2 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_373096_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_373096_Test.java new file mode 100644 index 0000000000..abc4c1eace --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_373096_Test.java @@ -0,0 +1,73 @@ +/* + * 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: + * Esteban Dugueperoux - initial API and implementation + */ +package org.eclipse.emf.cdo.tests.bugzilla; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOState; +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.Category; +import org.eclipse.emf.cdo.tests.model1.Company; +import org.eclipse.emf.cdo.tests.model1.Product1; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; + +import java.util.Collections; + +/** + * @author Esteban Dugueperoux + */ +public class Bugzilla_373096_Test extends AbstractCDOTest +{ + public void testDragAndDrop() throws Throwable + { + CDOSession session = openSession(); + + CDOTransaction transaction = session.openTransaction(); + CDOResource cdoResource = transaction.createResource(getResourcePath("/test1")); + transaction.commit(); + + Company company = getModel1Factory().createCompany(); + Category category1 = getModel1Factory().createCategory(); + Category category2 = getModel1Factory().createCategory(); + Product1 productToDragAndDrop = getModel1Factory().createProduct1(); + + company.getCategories().add(category1); + company.getCategories().add(category2); + category1.getProducts().add(productToDragAndDrop); + + cdoResource.getContents().add(company); + cdoResource.save(Collections.emptyMap()); + CDOObject cdoObject = CDOUtil.getCDOObject(productToDragAndDrop); + + // dragAndDrop to category1 + category1.getProducts().remove(productToDragAndDrop); + category2.getProducts().add(productToDragAndDrop); + + // Set a first save point + transaction.setSavepoint(); + + // undo the dragAndDrop + category2.getProducts().remove(productToDragAndDrop); + category1.getProducts().add(productToDragAndDrop); + + // Set a second save point + transaction.setSavepoint(); + + assertEquals(true, transaction.getDirtyObjects().values().contains(cdoObject)); + + CDOState cdoState = cdoObject.cdoState(); + assertNotSame(CDOState.CLEAN, cdoState); + + cdoResource.save(Collections.emptyMap()); + } +} 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 e5e0a954b7..709d2e632b 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 @@ -927,6 +927,14 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } /** + * @since 4.0 + */ + public synchronized InternalCDOSavepoint getFirstSavepoint() + { + return firstSavepoint; + } + + /** * @since 2.0 */ public synchronized InternalCDOSavepoint getLastSavepoint() 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 d2015260c3..05e333c7ba 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 @@ -33,6 +33,7 @@ import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.internal.cdo.CDOObjectImpl; import org.eclipse.emf.internal.cdo.bundle.OM; +import org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl; import org.eclipse.net4j.util.collection.Pair; import org.eclipse.net4j.util.fsm.FiniteStateMachine; @@ -49,6 +50,7 @@ import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult; import org.eclipse.emf.spi.cdo.FSMUtil; import org.eclipse.emf.spi.cdo.InternalCDOObject; +import org.eclipse.emf.spi.cdo.InternalCDOSavepoint; import org.eclipse.emf.spi.cdo.InternalCDOSession; import org.eclipse.emf.spi.cdo.InternalCDOTransaction; import org.eclipse.emf.spi.cdo.InternalCDOView; @@ -660,9 +662,22 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent public void execute(InternalCDOObject object, CDOState state, CDOEvent event, InternalCDOTransaction transaction) { InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager(); - CDORevision cleanRevision = transaction.getCleanRevisions().get(object); - + InternalCDORevision cleanRevision = transaction.getCleanRevisions().get(object).copy(); CDOID id = cleanRevision.getID(); + + // Bug 373096: Determine clean revision of the CURRENT/LAST savepoint + InternalCDOSavepoint savepoint = getFirstSavePoint(transaction); + while (savepoint.getNextSavepoint() != null) + { + CDORevisionDelta delta = savepoint.getRevisionDeltas().get(id); + if (delta != null) + { + delta.apply(cleanRevision); + } + + savepoint = savepoint.getNextSavepoint(); + } + object.cdoInternalSetID(id); object.cdoInternalSetView(transaction); @@ -694,6 +709,23 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent Map<CDOID, CDOObject> reattachedObjects = transaction.getLastSavepoint().getReattachedObjects(); reattachedObjects.put(id, object); } + + private InternalCDOSavepoint getFirstSavePoint(InternalCDOTransaction transaction) + { + if (transaction instanceof CDOTransactionImpl) + { + CDOTransactionImpl impl = (CDOTransactionImpl)transaction; + return impl.getFirstSavepoint(); + } + + InternalCDOSavepoint savepoint = transaction.getLastSavepoint(); + while (savepoint.getPreviousSavepoint() != null) + { + savepoint = savepoint.getPreviousSavepoint(); + } + + return savepoint; + } } /** |