diff options
author | Eike Stepper | 2016-09-10 08:29:47 +0000 |
---|---|---|
committer | Eike Stepper | 2016-09-10 08:29:47 +0000 |
commit | 52636ecc9b96f02a3a8338871a70643d78653951 (patch) | |
tree | ba748cd21fa972315e6255998504f609d41c8e98 | |
parent | 1949a7c63791ce27888aac4c46cbe93147905227 (diff) | |
download | cdo-52636ecc9b96f02a3a8338871a70643d78653951.tar.gz cdo-52636ecc9b96f02a3a8338871a70643d78653951.tar.xz cdo-52636ecc9b96f02a3a8338871a70643d78653951.zip |
[469301] Have abillity to lock a set of locally detached objects atomically
https://bugs.eclipse.org/bugs/show_bug.cgi?id=469301
4 files changed, 97 insertions, 7 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java index e000f22f42..1918e6dd97 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_469301_Test.java @@ -11,18 +11,27 @@ package org.eclipse.emf.cdo.tests.bugzilla; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; +import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation; +import org.eclipse.emf.cdo.common.lock.CDOLockOwner; import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.server.IView; 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.util.TestListener2; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CDOUtil; +import org.eclipse.emf.cdo.view.CDOView; +import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent; import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState; +import org.eclipse.emf.spi.cdo.InternalCDOObject; +import org.eclipse.emf.spi.cdo.InternalCDOTransaction; + import java.util.List; /** @@ -42,10 +51,14 @@ public class Bugzilla_469301_Test extends AbstractCDOTest resource.getContents().add(company1); transaction.commit(); - resource.getContents().remove(company0); - resource.getContents().remove(company1); + TestListener2 controlListener1 = openControlView(transaction, session, "LOCAL"); + TestListener2 controlListener2 = openControlView(transaction, openSession(), "REMOTE"); + // Detach List<? extends CDOObject> companies = CDOUtil.getCDOObjects(company0, company1); + resource.getContents().removeAll(companies); + + // Lock transaction.lockObjects(companies, LockType.WRITE, DEFAULT_TIMEOUT); CDOLockState[] lockStates = transaction.getLockStatesOfObjects(companies); @@ -58,5 +71,59 @@ public class Bugzilla_469301_Test extends AbstractCDOTest LockState<Object, IView> serverLockState = serverLockState(session, lockState); assertEquals(serverTransaction(transaction), serverLockState.getWriteLockOwner()); } + + assertEvent(controlListener1, transaction, CDOLockChangeInfo.Operation.LOCK); + assertEvent(controlListener2, transaction, CDOLockChangeInfo.Operation.LOCK); + + // Unlock + transaction.unlockObjects(companies, LockType.WRITE); + + lockStates = transaction.getLockStatesOfObjects(companies); + assertEquals(2, lockStates.length); + + for (CDOLockState lockState : lockStates) + { + assertNull(lockState.getWriteLockOwner()); + assertNull(serverLockState(session, lockState)); + } + + assertEvent(controlListener1, transaction, CDOLockChangeInfo.Operation.UNLOCK); + assertEvent(controlListener2, transaction, CDOLockChangeInfo.Operation.UNLOCK); + } + + private TestListener2 openControlView(CDOTransaction transaction, CDOSession session, String name) + { + CDOView controlView = session.openView(); + controlView.options().setLockNotificationEnabled(true); + + int counter = 1; + for (InternalCDOObject object : ((InternalCDOTransaction)transaction).getObjectsList()) + { + // Load control object and make sure that it is not garbage collected. + InternalCDOObject controlObject = controlView.getObject(object); + controlView.properties().put(name + counter++, controlObject); + } + + TestListener2 controlListener = new TestListener2(CDOViewLocksChangedEvent.class, name); + controlView.addListener(controlListener); + return controlListener; + } + + private void assertEvent(TestListener2 controlListener, CDOLockOwner lockOwner, CDOLockChangeInfo.Operation operation) + { + controlListener.waitFor(1, DEFAULT_TIMEOUT); + + CDOViewLocksChangedEvent event = (CDOViewLocksChangedEvent)controlListener.getEvents().get(0); + assertEquals(operation, event.getOperation()); + assertEquals(LockType.WRITE, event.getLockType()); + assertEquals(lockOwner, event.getLockOwner()); + assertEquals(2, event.getLockStates().length); + + for (CDOLockState lockState : event.getLockStates()) + { + assertEquals(event.getOperation() == Operation.LOCK ? lockOwner : null, lockState.getWriteLockOwner()); + } + + controlListener.clearEvents(); } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java index a871b5058a..69c6416889 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java @@ -16,6 +16,7 @@ import org.eclipse.net4j.util.event.IListener; import org.junit.Assert; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -166,10 +167,18 @@ public class TestListener2 implements IListener waitFor(i, timeout); } + public void clearEvents() + { + synchronized (this) + { + events.clear(); + } + } + public String formatEvents(String prefix, String suffix) { StringBuilder builder = new StringBuilder(); - + synchronized (this) { for (Entry<IEvent, Long> entry : events.entrySet()) @@ -177,10 +186,16 @@ public class TestListener2 implements IListener builder.append(prefix + entry.getValue() + ": " + entry.getKey() + suffix); } } - + return builder.toString(); } + public void dump(PrintStream out) + { + out.println(this); + out.print(formatEvents(" ", "\n")); + } + @Override public String toString() { 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 11a8184b85..ee091e349e 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 @@ -1271,10 +1271,10 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb List<CDOID> ids = new ArrayList<CDOID>(); for (CDOObject object : objects) { - InternalCDORevision revision = getRevision(object); - if (revision != null) + CDOID id = getID((InternalCDOObject)object, true); + if (id != null) { - ids.add(revision.getID()); + ids.add(id); } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java index 3e76bdc971..6322ba8f9e 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java @@ -657,6 +657,14 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv } } } + else if (FSMUtil.isTransient(object)) + { + CDOID id = getID((InternalCDOObject)object, true); + if (id != null) + { + objectIDs.add(id); + } + } else { objectIDs.add(object.cdoID()); |