Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaspar De Groot2011-09-01 07:52:03 +0000
committerCaspar De Groot2011-09-01 07:52:03 +0000
commitd91b8908f8f2cfb84cb9ac258cf57c440970e739 (patch)
tree7e28c7ac6bbc9e69a2eeb75169783fe43d45d20d
parent06652cd713e41e414f12e8254b9a3716d825371b (diff)
downloadcdo-d91b8908f8f2cfb84cb9ac258cf57c440970e739.tar.gz
cdo-d91b8908f8f2cfb84cb9ac258cf57c440970e739.tar.xz
cdo-d91b8908f8f2cfb84cb9ac258cf57c440970e739.zip
[351912] Lock coordination with SynchronizableRepositories
https://bugs.eclipse.org/bugs/show_bug.cgi?id=351912
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java35
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java49
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java (renamed from plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockingManagerContext.java)6
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockOwner.java22
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java71
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataInput.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataOutput.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java106
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockOwnerImpl.java21
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockStateImpl.java51
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java46
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java43
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationContext.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationInfo.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java17
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockDelegationRequest.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockNotificationIndication.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/OpenSessionRequest.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java25
-rw-r--r--plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/RepositoryStateNotificationIndication.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4ODurableLockingManager.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OLockArea.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/.settings/.api_filters8
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitDelegationIndication.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java37
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ReplicateRepositoryIndication.java56
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RepositoryStateNotificationRequest.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockArea.java15
-rw-r--r--plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockAreaManager.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server/.settings/.api_filters26
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java114
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java118
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java45
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java21
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java15
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java65
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java179
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISynchronizableRepository.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java23
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSynchronizableRepository.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalView.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/SyncingUtil.java60
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java185
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java79
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_312879_Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_319552_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_325097_Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_326047_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_328352_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_329014_Test.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayed2Test.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java247
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineRawTest.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestListener2.java54
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionConfiguration.java31
-rw-r--r--plugins/org.eclipse.emf.cdo/.settings/.api_filters49
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionConfiguration.java11
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java26
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java37
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOViewLocksChangedEvent.java (renamed from plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOLocksChangedEvent.java)9
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionConfigurationImpl.java20
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java43
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java3
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java77
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java5
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java143
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java31
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java33
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java48
-rw-r--r--plugins/org.gastro.server.web/src-gen/templates/MenuCardTemplate.java124
98 files changed, 2250 insertions, 661 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java
index 533044166a..4ef53d763a 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonSession.java
@@ -85,6 +85,16 @@ public interface CDOCommonSession extends IUserAware, IOptionsContainer, Closeab
public void setPassiveUpdateMode(PassiveUpdateMode mode);
/**
+ * @since 4.1
+ */
+ public LockNotificationMode getLockNotificationMode();
+
+ /**
+ * @since 4.1
+ */
+ public void setLockNotificationMode(LockNotificationMode mode);
+
+ /**
* Enumerates the possible {@link CDOCommonSession.Options#getPassiveUpdateMode() passive update modes} of a CDO
* session.
*
@@ -112,6 +122,31 @@ public interface CDOCommonSession extends IUserAware, IOptionsContainer, Closeab
}
/**
+ * Enumerates the possible {@link CDOCommonSession.Options#getLockNotificationMode() lock notification modes} of a
+ * CDO session.
+ *
+ * @since 4.1
+ */
+ public enum LockNotificationMode
+ {
+ /**
+ * This mode delivers no lock notifications
+ */
+ OFF,
+
+ /**
+ * This mode delivers lock notifications if one or more views have enabled them.
+ */
+ IF_REQUIRED_BY_VIEWS,
+
+ /**
+ * This mode always delivers lock notifications, even if no views have them enabled, and even if no views are
+ * open.
+ */
+ ALWAYS
+ }
+
+ /**
* An {@link IOptionsEvent options event} fired when the {@link PassiveUpdateMode passive update mode} of a CDO
* session has changed.
*
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
index f58ac44ccf..5834cb7e3f 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
@@ -11,9 +11,14 @@
package org.eclipse.emf.cdo.common;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.revision.CDORevisionProvider;
import org.eclipse.net4j.util.collection.Closeable;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.options.IOptions;
+import org.eclipse.net4j.util.options.IOptionsContainer;
+import org.eclipse.net4j.util.options.IOptionsEvent;
/**
* Abstracts the information about CDO views that is common to both client and server side.
@@ -23,7 +28,7 @@ import org.eclipse.net4j.util.collection.Closeable;
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface CDOCommonView extends CDOBranchPoint, CDORevisionProvider, Closeable
+public interface CDOCommonView extends CDOBranchPoint, CDORevisionProvider, IOptionsContainer, Closeable
{
public int getViewID();
@@ -38,4 +43,46 @@ public interface CDOCommonView extends CDOBranchPoint, CDORevisionProvider, Clos
* @since 4.0
*/
public String getDurableLockingID();
+
+ /**
+ * Returns the {@link Options options} of this view.
+ *
+ * @since 4.1
+ */
+ public Options options();
+
+ /**
+ * Encapsulates the configuration options of CDO views that are common to both client and server side.
+ *
+ * @author Eike Stepper
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 4.1
+ */
+ public interface Options extends IOptions
+ {
+ /**
+ * Returns <code>true</code> if this view will notify its {@link IListener listeners} about changes to the
+ * {@link CDOLockState lock states} of the objects in this view (due to lock operations in <i>other</i> views),
+ * <code>false</code> otherwise.
+ *
+ * @see CDOLockState
+ */
+ public boolean isLockNotificationEnabled();
+
+ /**
+ * Specifies whether this view will notify its {@link IListener listeners} about changes to the {@link CDOLockState
+ * lock states} of the objects in this view (due to lock operations in <i>other</i> views), or not.
+ *
+ * @see CDOLockState
+ */
+ public void setLockNotificationEnabled(boolean enabled);
+
+ /**
+ * @author Caspar De Groot
+ */
+ public interface LockNotificationEvent extends IOptionsEvent
+ {
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java
index 0307719d42..b3a55b4833 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java
@@ -13,6 +13,8 @@ package org.eclipse.emf.cdo.common.lock;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+
/**
* Represents a change in the lock state of a set of objects. Instances are meant to be sent from the server to the
* client for the purpose of notifying the latter.
@@ -51,6 +53,11 @@ public interface CDOLockChangeInfo extends CDOBranchPoint
public Operation getOperation();
/**
+ * @return the type of locks that were affected by the lock operation
+ */
+ public LockType getLockType();
+
+ /**
* Enumerates the possible locking operations.
*
* @author Caspar De Groot
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockingManagerContext.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java
index 00782c3f19..118f973516 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockingManagerContext.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java
@@ -8,13 +8,13 @@
* Contributors:
* Caspar De Groot - initial API and implementation
*/
-package org.eclipse.emf.cdo.spi.server;
+package org.eclipse.emf.cdo.common.lock;
/**
* @author Caspar De Groot
* @since 4.1
*/
-public interface InternalLockingManagerContext
+public interface CDOLockChangeInfoHandler
{
-
+ public void handleLockChangeInfo(CDOLockChangeInfo lockChangeInfo);
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockOwner.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockOwner.java
index 012fc15117..b5b42d29ff 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockOwner.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockOwner.java
@@ -31,25 +31,7 @@ public interface CDOLockOwner
*/
public int getViewID();
- /**
- * A constant to represent on the client-side that a lock's owner cannot be represented as a viewID-sessionID pair.
- */
- public static final CDOLockOwner UNKNOWN = new CDOLockOwner()
- {
- public int getViewID()
- {
- return 0;
- }
-
- public int getSessionID()
- {
- return 0;
- }
+ public String getDurableLockingID();
- @Override
- public String toString()
- {
- return CDOLockOwner.class.getSimpleName() + ".UNKNOWN";
- }
- };
+ public boolean isDurableView();
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java
index d36d9078b6..3250f5adfa 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java
@@ -13,15 +13,25 @@ package org.eclipse.emf.cdo.common.lock;
import org.eclipse.emf.cdo.common.CDOCommonSession;
import org.eclipse.emf.cdo.common.CDOCommonView;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockChangeInfoImpl;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockOwnerImpl;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockStateImpl;
+import org.eclipse.emf.cdo.internal.common.lock.CDOLockAreaImpl;
import org.eclipse.emf.cdo.spi.common.lock.InternalCDOLockState;
import org.eclipse.net4j.util.CheckUtil;
+import org.eclipse.net4j.util.HexUtil;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
+import java.util.Map;
+import java.util.Random;
+
/**
* Various static methods that may help with classes related to CDO locks.
*
@@ -47,9 +57,23 @@ public final class CDOLockUtil
for (CDOCommonView view : lockState.getReadLockOwners())
{
- int sessionID = view.getSession().getSessionID();
- int viewID = view.getViewID();
- CDOLockOwner owner = new CDOLockOwnerImpl(sessionID, viewID);
+ String durableLockingID = view.getDurableLockingID();
+ int sessionID, viewID;
+ CDOCommonSession session = view.getSession();
+ boolean isDurableView = session == null;
+ if (isDurableView)
+ {
+ // TODO (CD) Use some symbolic constants here?
+ sessionID = 0;
+ viewID = 0;
+ }
+ else
+ {
+ sessionID = session.getSessionID();
+ viewID = view.getViewID();
+ }
+
+ CDOLockOwner owner = new CDOLockOwnerImpl(sessionID, viewID, durableLockingID, isDurableView);
cdoLockState.addReadLockOwner(owner);
}
@@ -73,25 +97,54 @@ public final class CDOLockUtil
public static CDOLockOwner createLockOwner(CDOCommonView view)
{
CDOCommonSession session = view.getSession();
+ String durableLockingID = view.getDurableLockingID();
if (session != null)
{
int sessionID = session.getSessionID();
int viewID = view.getViewID();
- return new CDOLockOwnerImpl(sessionID, viewID);
+ return new CDOLockOwnerImpl(sessionID, viewID, durableLockingID, false);
}
- return CDOLockOwner.UNKNOWN;
+
+ CheckUtil.checkNull(durableLockingID, "durableLockingID");
+ return new CDOLockOwnerImpl(0, 0, durableLockingID, true); // TODO (CD) Symbolic constants?
}
public static CDOLockChangeInfo createLockChangeInfo(long timestamp, CDOLockOwner lockOwner, CDOBranch branch,
- Operation op, CDOLockState[] cdoLockStates)
+ Operation op, LockType lockType, CDOLockState[] cdoLockStates)
{
- return new CDOLockChangeInfoImpl(branch.getPoint(timestamp), lockOwner, cdoLockStates, op);
+ return new CDOLockChangeInfoImpl(branch.getPoint(timestamp), lockOwner, cdoLockStates, op, lockType);
}
public static CDOLockChangeInfo createLockChangeInfo(long timestamp, CDOCommonView view, CDOBranch viewedBranch,
- Operation op, CDOLockState[] cdoLockStates)
+ Operation op, LockType lockType, CDOLockState[] cdoLockStates)
{
CDOLockOwner lockOwner = createLockOwner(view);
- return createLockChangeInfo(timestamp, lockOwner, viewedBranch, op, cdoLockStates);
+ return createLockChangeInfo(timestamp, lockOwner, viewedBranch, op, lockType, cdoLockStates);
+ }
+
+ public static LockArea createLockArea(String durableLockingID, String userID, CDOBranchPoint branchPoint,
+ boolean readOnly, Map<CDOID, LockGrade> locks)
+ {
+ return new CDOLockAreaImpl(durableLockingID, userID, branchPoint, readOnly, locks);
+ }
+
+ public static LockArea createLockArea(String durableLockingID)
+ {
+ return new CDOLockAreaImpl(durableLockingID);
+ }
+
+ public static String createDurableLockingID()
+ {
+ return createDurableLockingID(LockArea.DEFAULT_DURABLE_LOCKING_ID_BYTES);
+ }
+
+ public static String createDurableLockingID(int bytes)
+ {
+ byte[] buffer = new byte[bytes];
+
+ Random random = new Random(System.currentTimeMillis());
+ random.nextBytes(buffer);
+
+ return HexUtil.bytesToHex(buffer);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java
index 5343f8f91a..6300d643d4 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/IDurableLockingManager.java
@@ -28,7 +28,7 @@ import java.util.Map;
public interface IDurableLockingManager
{
public LockArea createLockArea(String userID, CDOBranchPoint branchPoint, boolean readOnly,
- Map<CDOID, LockGrade> locks);
+ Map<CDOID, LockGrade> locks) throws LockAreaAlreadyExistsException;
/**
* Returns the {@link LockArea lock area} specified by the given durableLockingID, never <code>null</code>.
@@ -52,6 +52,11 @@ public interface IDurableLockingManager
*/
public interface LockArea extends CDOBranchPoint
{
+ /**
+ * @since 4.1
+ */
+ public static final int DEFAULT_DURABLE_LOCKING_ID_BYTES = 32;
+
public String getDurableLockingID();
public String getUserID();
@@ -61,6 +66,11 @@ public interface IDurableLockingManager
public Map<CDOID, LockGrade> getLocks();
/**
+ * @since 4.1
+ */
+ public boolean isDeleted();
+
+ /**
* A call-back interface for <em>handling</em> {@link LockArea lock area} objects.
*
* @author Eike Stepper
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataInput.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataInput.java
index acab6ac3ea..9b29f86a4c 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataInput.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataInput.java
@@ -22,6 +22,7 @@ import org.eclipse.emf.cdo.common.id.CDOIDReference;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
@@ -153,4 +154,9 @@ public interface CDODataInput extends ExtendedDataInput
* @since 4.1
*/
public CDOLockState readCDOLockState() throws IOException;
+
+ /**
+ * @since 4.1
+ */
+ public LockArea readCDOLockArea() throws IOException;
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataOutput.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataOutput.java
index 9c040d46fe..f0fcfcc251 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataOutput.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDODataOutput.java
@@ -23,6 +23,7 @@ import org.eclipse.emf.cdo.common.id.CDOIDReference;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
@@ -159,4 +160,9 @@ public interface CDODataOutput extends ExtendedDataOutput
* @since 4.1
*/
public void writeCDOLockOwner(CDOLockOwner lockOwner) throws IOException;
+
+ /**
+ * @since 4.1
+ */
+ public void writeCDOLockArea(LockArea lockArea) throws IOException;
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
index 722b158ca9..af623cafb9 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
@@ -324,4 +324,9 @@ public interface CDOProtocolConstants
* @since 3.0
*/
public static final byte REPLICATE_COMMIT = 2;
+
+ /**
+ * @since 4.1
+ */
+ public static final byte REPLICATE_LOCKAREA = 3;
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java
new file mode 100644
index 0000000000..4baa364851
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockAreaImpl.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2004 - 2011 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:
+ * Eike Stepper - initial API and implementation
+ * Caspar De Groot - maintenance
+ */
+package org.eclipse.emf.cdo.internal.common.lock;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
+
+import java.text.MessageFormat;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ * @since 4.1
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public class CDOLockAreaImpl implements LockArea
+{
+ public static final int DEFAULT_DURABLE_LOCKING_ID_BYTES = 32;
+
+ private final String durableLockingID;
+
+ private final String userID;
+
+ private final CDOBranchPoint branchPoint;
+
+ private final boolean readOnly;
+
+ private final Map<CDOID, LockGrade> locks;
+
+ private final boolean deleted;
+
+ public CDOLockAreaImpl(String durableLockingID, String userID, CDOBranchPoint branchPoint, boolean readOnly,
+ Map<CDOID, LockGrade> locks)
+ {
+ this.durableLockingID = durableLockingID;
+ this.userID = userID;
+ this.branchPoint = branchPoint;
+ this.readOnly = readOnly;
+ this.locks = locks;
+ deleted = false;
+ }
+
+ public CDOLockAreaImpl(String durableLockingID)
+ {
+ this.durableLockingID = durableLockingID;
+ userID = null;
+ branchPoint = null;
+ readOnly = false;
+ locks = null;
+ deleted = true;
+ }
+
+ public String getDurableLockingID()
+ {
+ return durableLockingID;
+ }
+
+ public String getUserID()
+ {
+ return userID;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return branchPoint.getBranch();
+ }
+
+ public long getTimeStamp()
+ {
+ return branchPoint.getTimeStamp();
+ }
+
+ public boolean isReadOnly()
+ {
+ return readOnly;
+ }
+
+ public Map<CDOID, LockGrade> getLocks()
+ {
+ return locks;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("DurableLockArea\nid={0}\nuser={1}\nbranchPoint={2}\nreadOnly={3}\nlocks={4}",
+ durableLockingID, userID, branchPoint, readOnly, locks);
+ }
+
+ public boolean isDeleted()
+ {
+ return deleted;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java
index 70c4c0a65f..e8a7a16b62 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java
@@ -16,6 +16,8 @@ import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+
/**
* @author Caspar De Groot
*/
@@ -29,13 +31,16 @@ public class CDOLockChangeInfoImpl implements CDOLockChangeInfo
private final Operation operation;
+ private final LockType lockType;
+
public CDOLockChangeInfoImpl(CDOBranchPoint branchPoint, CDOLockOwner lockOwner, CDOLockState[] lockStates,
- Operation operation)
+ Operation operation, LockType lockType)
{
this.branchPoint = branchPoint;
this.lockOwner = lockOwner;
this.lockStates = lockStates;
this.operation = operation;
+ this.lockType = lockType;
}
public CDOBranch getBranch()
@@ -62,4 +67,9 @@ public class CDOLockChangeInfoImpl implements CDOLockChangeInfo
{
return operation;
}
+
+ public LockType getLockType()
+ {
+ return lockType;
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockOwnerImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockOwnerImpl.java
index 3509e5fb46..29821d056b 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockOwnerImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockOwnerImpl.java
@@ -23,10 +23,16 @@ public class CDOLockOwnerImpl implements CDOLockOwner
private final int viewID;
- public CDOLockOwnerImpl(int sessionID, int viewID)
+ private final String durableLockingID;
+
+ private final boolean isDurableView;
+
+ public CDOLockOwnerImpl(int sessionID, int viewID, String durableLockingID, boolean isDurableView)
{
this.sessionID = sessionID;
this.viewID = viewID;
+ this.durableLockingID = durableLockingID;
+ this.isDurableView = isDurableView;
}
public int getSessionID()
@@ -39,6 +45,16 @@ public class CDOLockOwnerImpl implements CDOLockOwner
return viewID;
}
+ public String getDurableLockingID()
+ {
+ return durableLockingID;
+ }
+
+ public boolean isDurableView()
+ {
+ return isDurableView;
+ }
+
@Override
public int hashCode()
{
@@ -66,9 +82,8 @@ public class CDOLockOwnerImpl implements CDOLockOwner
public String toString()
{
StringBuilder builder = new StringBuilder("CDOLockOwner[");
- builder.append("session=");
builder.append(sessionID);
- builder.append(", view=");
+ builder.append(':');
builder.append(viewID);
builder.append(']');
return builder.toString();
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockStateImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockStateImpl.java
index 3520709d0a..e3d5e33661 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockStateImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockStateImpl.java
@@ -58,12 +58,18 @@ public class CDOLockStateImpl implements InternalCDOLockState
private boolean isReadLocked(CDOLockOwner by, boolean others)
{
- if (readLockOwners.size() == 0)
+ int n = readLockOwners.size();
+ if (n == 0)
{
return false;
}
- return readLockOwners.contains(by) ^ others;
+ if (!others)
+ {
+ return readLockOwners.contains(by);
+ }
+
+ return true;
}
private boolean isWriteLocked(CDOLockOwner by, boolean others)
@@ -91,6 +97,16 @@ public class CDOLockStateImpl implements InternalCDOLockState
return Collections.unmodifiableSet(readLockOwners);
}
+ public void addReadLockOwner(CDOLockOwner lockOwner)
+ {
+ readLockOwners.add(lockOwner);
+ }
+
+ public boolean removeReadLockOwner(CDOLockOwner lockOwner)
+ {
+ return readLockOwners.remove(lockOwner);
+ }
+
public CDOLockOwner getWriteLockOwner()
{
return writeLockOwner;
@@ -119,12 +135,12 @@ public class CDOLockStateImpl implements InternalCDOLockState
@Override
public String toString()
{
- StringBuilder builder = new StringBuilder("CDOLockState[lockedObject=");
+ StringBuilder builder = new StringBuilder("CDOLockState\nlockedObject=");
builder.append(lockedObject);
+ builder.append("\nreadLockOwners=");
if (readLockOwners.size() > 0)
{
- builder.append(", read=");
boolean first = true;
for (CDOLockOwner lockOwner : readLockOwners)
{
@@ -142,30 +158,17 @@ public class CDOLockStateImpl implements InternalCDOLockState
builder.deleteCharAt(builder.length() - 1);
}
-
- if (writeLockOwner != null)
+ else
{
- builder.append(", write=");
- builder.append(writeLockOwner);
+ builder.append("NONE");
}
- if (writeOptionOwner != null)
- {
- builder.append(", option=");
- builder.append(writeOptionOwner);
- }
+ builder.append("\nwriteLockOwner=");
+ builder.append(writeLockOwner != null ? writeLockOwner : "NONE");
- builder.append(']');
- return builder.toString();
- }
+ builder.append("\nwriteOptionOwner=");
+ builder.append(writeOptionOwner != null ? writeOptionOwner : "NONE");
- public void addReadLockOwner(CDOLockOwner lockOwner)
- {
- readLockOwners.add(lockOwner);
- }
-
- public boolean removeReadLockOwner(CDOLockOwner lockOwner)
- {
- return readLockOwners.remove(lockOwner);
+ return builder.toString();
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
index d64799ed3e..8928db8eb3 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
@@ -30,6 +30,8 @@ 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.common.lock.IDurableLockingManager.LockArea;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
@@ -56,6 +58,7 @@ import org.eclipse.emf.cdo.internal.common.id.CDOIDExternalImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDObjectLongImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDTempObjectExternalImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDTempObjectImpl;
+import org.eclipse.emf.cdo.internal.common.lock.CDOLockAreaImpl;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockChangeInfoImpl;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockOwnerImpl;
import org.eclipse.emf.cdo.internal.common.lock.CDOLockStateImpl;
@@ -95,7 +98,9 @@ import org.eclipse.emf.ecore.util.FeatureMapUtil;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* @author Eike Stepper
@@ -268,6 +273,7 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
CDOBranchPoint branchPoint = readCDOBranchPoint();
CDOLockOwner lockOwner = readCDOLockOwner();
Operation operation = readEnum(Operation.class);
+ LockType lockType = readCDOLockType();
int n = readInt();
CDOLockState[] lockStates = new CDOLockState[n];
@@ -276,19 +282,36 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
lockStates[i] = readCDOLockState();
}
- return new CDOLockChangeInfoImpl(branchPoint, lockOwner, lockStates, operation);
+ return new CDOLockChangeInfoImpl(branchPoint, lockOwner, lockStates, operation, lockType);
}
- public CDOLockOwner readCDOLockOwner() throws IOException
+ public LockArea readCDOLockArea() throws IOException
{
- boolean isUnknown = !readBoolean();
- if (isUnknown)
+ String durableLockingID = readString();
+ CDOBranch branch = readCDOBranch();
+ long timestamp = readLong();
+ String userID = readString();
+ boolean readOnly = readBoolean();
+
+ int nLockStates = readInt();
+ Map<CDOID, LockGrade> locks = new HashMap<CDOID, LockGrade>();
+ for (int i = 0; i < nLockStates; i++)
{
- return CDOLockOwner.UNKNOWN;
+ CDOID key = readCDOID();
+ LockGrade value = readEnum(LockGrade.class);
+ locks.put(key, value);
}
+
+ return new CDOLockAreaImpl(durableLockingID, userID, branch.getPoint(timestamp), readOnly, locks);
+ }
+
+ public CDOLockOwner readCDOLockOwner() throws IOException
+ {
int session = readInt();
int view = readInt();
- return new CDOLockOwnerImpl(session, view);
+ String lockAreaID = readString();
+ boolean isDurableView = readBoolean();
+ return new CDOLockOwnerImpl(session, view, lockAreaID, isDurableView);
}
public CDOLockState readCDOLockState() throws IOException
@@ -330,6 +353,11 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
return lockState;
}
+ public LockType readCDOLockType() throws IOException
+ {
+ return readEnum(LockType.class);
+ }
+
public CDOID readCDOID() throws IOException
{
byte ordinal = readByte();
@@ -587,12 +615,6 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
return readCDORevisionOrPrimitive();
}
- public LockType readCDOLockType() throws IOException
- {
- byte b = readByte();
- return b == 0 ? null : LockType.values()[b - 1];
- }
-
protected StringIO getPackageURICompressor()
{
return StringIO.DIRECT;
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java
index 9ceed91d70..ef3bcdaa6b 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataOutputImpl.java
@@ -22,6 +22,8 @@ import org.eclipse.emf.cdo.common.id.CDOIDReference;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
@@ -66,6 +68,7 @@ import org.eclipse.emf.ecore.util.FeatureMapUtil;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Collection;
+import java.util.Map;
import java.util.Set;
/**
@@ -227,6 +230,7 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im
writeCDOBranchPoint(lockChangeInfo);
writeCDOLockOwner(lockChangeInfo.getLockOwner());
writeEnum(lockChangeInfo.getOperation());
+ writeCDOLockType(lockChangeInfo.getLockType());
CDOLockState[] lockStates = lockChangeInfo.getLockStates();
writeInt(lockStates.length);
@@ -236,20 +240,30 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im
}
}
- public void writeCDOLockOwner(CDOLockOwner lockOwner) throws IOException
+ public void writeCDOLockArea(LockArea lockArea) throws IOException
{
- if (lockOwner != CDOLockOwner.UNKNOWN)
- {
- writeBoolean(true);
- writeInt(lockOwner.getSessionID());
- writeInt(lockOwner.getViewID());
- }
- else
+ writeString(lockArea.getDurableLockingID());
+ writeCDOBranch(lockArea.getBranch());
+ writeLong(lockArea.getTimeStamp());
+ writeString(lockArea.getUserID());
+ writeBoolean(lockArea.isReadOnly());
+
+ writeInt(lockArea.getLocks().size());
+ for (Map.Entry<CDOID, LockGrade> entry : lockArea.getLocks().entrySet())
{
- writeBoolean(false);
+ writeCDOID(entry.getKey());
+ writeEnum(entry.getValue());
}
}
+ public void writeCDOLockOwner(CDOLockOwner lockOwner) throws IOException
+ {
+ writeInt(lockOwner.getSessionID());
+ writeInt(lockOwner.getViewID());
+ writeString(lockOwner.getDurableLockingID());
+ writeBoolean(lockOwner.isDurableView());
+ }
+
public void writeCDOLockState(CDOLockState lockState) throws IOException
{
Object o = lockState.getLockedObject();
@@ -298,6 +312,11 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im
}
}
+ public void writeCDOLockType(LockType lockType) throws IOException
+ {
+ writeEnum(lockType);
+ }
+
public void writeCDOID(CDOID id) throws IOException
{
if (id == null)
@@ -516,12 +535,6 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im
}
}
- public void writeCDOLockType(LockType lockType) throws IOException
- {
- int b = lockType == null ? 0 : lockType.ordinal() + 1;
- writeByte(b);
- }
-
public CDOPackageRegistry getPackageRegistry()
{
return null;
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationContext.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationContext.java
index 8a8c330f67..5c16082075 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationContext.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationContext.java
@@ -12,11 +12,14 @@ package org.eclipse.emf.cdo.spi.common;
import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager;
/**
* @author Eike Stepper
- * @since 3.0
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
*/
-public interface CDOReplicationContext extends CDOReplicationInfo, CDOBranchHandler, CDOCommitInfoHandler
+public interface CDOReplicationContext extends CDOReplicationInfo, CDOBranchHandler, CDOCommitInfoHandler,
+ IDurableLockingManager.LockArea.Handler
{
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationInfo.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationInfo.java
index 0dde488948..0267e3c46c 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationInfo.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/CDOReplicationInfo.java
@@ -7,16 +7,23 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Caspar De Groot - maintenance
*/
package org.eclipse.emf.cdo.spi.common;
/**
* @author Eike Stepper
- * @since 3.0
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
*/
public interface CDOReplicationInfo
{
public int getLastReplicatedBranchID();
public long getLastReplicatedCommitTime();
+
+ /**
+ * @since 4.1
+ */
+ public String[] getLockAreaIDs();
}
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java
index ec77a73c52..253877a9b0 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionConfigurationImpl.java
@@ -250,6 +250,23 @@ public class CDONet4jSessionConfigurationImpl extends CDOSessionConfigurationImp
return rootResourceID;
}
+ public void setRootResourceID(CDOID rootResourceID)
+ {
+ // The rootResourceID may only be set if it is currently null
+ if (this.rootResourceID == null || this.rootResourceID.isNull())
+ {
+ this.rootResourceID = rootResourceID;
+ }
+ else if (this.rootResourceID != null && this.rootResourceID.equals(rootResourceID))
+ {
+ // Do nothing; it is the same.
+ }
+ else
+ {
+ throw new IllegalStateException("rootResourceID must not be changed unless it is null");
+ }
+ }
+
public boolean isSupportingAudits()
{
return supportingAudits;
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java
index 7cea690ca0..62ab03c6e2 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/CDONet4jSessionImpl.java
@@ -235,7 +235,8 @@ public class CDONet4jSessionImpl extends CDOSessionImpl implements org.eclipse.e
// TODO (CD) The next call is on the CDOClientProtocol; shouldn't it be on the DelegatingSessionProtocol instead?
OpenSessionResult result = protocol.openSession(repositoryName, options().isPassiveUpdateEnabled(), options()
- .getPassiveUpdateMode());
+ .getPassiveUpdateMode(), options().getLockNotificationMode());
+
setSessionID(result.getSessionID());
setUserID(result.getUserID());
setLastUpdateTime(result.getLastUpdateTime());
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
index 9ba6ae8b50..956ed5199e 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java
@@ -11,6 +11,7 @@
package org.eclipse.emf.cdo.internal.net4j.protocol;
import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
@@ -97,9 +98,10 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO
}
public OpenSessionResult openSession(String repositoryName, boolean passiveUpdateEnabled,
- PassiveUpdateMode passiveUpdateMode)
+ PassiveUpdateMode passiveUpdateMode, LockNotificationMode lockNotificationMode)
{
- return send(new OpenSessionRequest(this, repositoryName, passiveUpdateEnabled, passiveUpdateMode));
+ return send(new OpenSessionRequest(this, repositoryName, passiveUpdateEnabled, passiveUpdateMode,
+ lockNotificationMode));
}
public void disablePassiveUpdate()
@@ -229,7 +231,7 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO
{
revisionKeys.add(rev);
}
-
+
return lockObjects2(revisionKeys, viewID, viewedBranch, lockType, timeout);
}
@@ -241,7 +243,7 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO
try
{
- return new LockObjectsRequest(this, revisionKeys, viewID, viewedBranch, lockType, timeout).send();
+ return new LockObjectsRequest(this, revisionKeys, viewID, lockType, timeout).send();
}
catch (RemoteException ex)
{
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockDelegationRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockDelegationRequest.java
index 08be5b6615..dccc18ee02 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockDelegationRequest.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockDelegationRequest.java
@@ -27,17 +27,21 @@ public class LockDelegationRequest extends LockObjectsRequest
{
private String lockAreaID;
+ private CDOBranch viewedBranch;
+
public LockDelegationRequest(CDOClientProtocol protocol, String lockAreaID, List<CDORevisionKey> revisionKeys,
CDOBranch viewedBranch, LockType lockType, long timeout)
{
- super(protocol, CDOProtocolConstants.SIGNAL_LOCK_DELEGATION, revisionKeys, 0, viewedBranch, lockType, timeout);
+ super(protocol, CDOProtocolConstants.SIGNAL_LOCK_DELEGATION, revisionKeys, 0, lockType, timeout);
this.lockAreaID = lockAreaID;
+ this.viewedBranch = viewedBranch;
}
@Override
protected void requesting(CDODataOutput out) throws IOException
{
out.writeString(lockAreaID);
+ out.writeCDOBranch(viewedBranch);
super.requesting(out);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockNotificationIndication.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockNotificationIndication.java
index 2d4175c8ef..9ad8ae9754 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockNotificationIndication.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockNotificationIndication.java
@@ -33,6 +33,6 @@ public class LockNotificationIndication extends CDOClientIndication
{
CDOLockChangeInfo lockChangeInfo = in.readCDOLockChangeInfo();
InternalCDOSession session = getSession();
- session.handleLockNotification(lockChangeInfo);
+ session.handleLockNotification(lockChangeInfo, null);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java
index 2d8e9325d9..b01f0a0b0d 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/LockObjectsRequest.java
@@ -11,7 +11,6 @@
**************************************************************************/
package org.eclipse.emf.cdo.internal.net4j.protocol;
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
@@ -39,19 +38,14 @@ public class LockObjectsRequest extends CDOClientRequest<LockObjectsResult>
private List<CDORevisionKey> revisionKeys;
- /**
- * The branch being viewed
- */
- private CDOBranch viewedBranch;
-
public LockObjectsRequest(CDOClientProtocol protocol, List<CDORevisionKey> revisionKeys, int viewID,
- CDOBranch viewedBranch, LockType lockType, long timeout)
+ LockType lockType, long timeout)
{
- this(protocol, CDOProtocolConstants.SIGNAL_LOCK_OBJECTS, revisionKeys, viewID, viewedBranch, lockType, timeout);
+ this(protocol, CDOProtocolConstants.SIGNAL_LOCK_OBJECTS, revisionKeys, viewID, lockType, timeout);
}
protected LockObjectsRequest(CDOClientProtocol protocol, short signalID, List<CDORevisionKey> revisionKeys,
- int viewID, CDOBranch viewedBranch, LockType lockType, long timeout)
+ int viewID, LockType lockType, long timeout)
{
super(protocol, signalID);
@@ -59,7 +53,6 @@ public class LockObjectsRequest extends CDOClientRequest<LockObjectsResult>
this.lockType = lockType;
this.timeout = timeout;
this.revisionKeys = revisionKeys;
- this.viewedBranch = viewedBranch;
}
@Override
@@ -68,7 +61,6 @@ public class LockObjectsRequest extends CDOClientRequest<LockObjectsResult>
out.writeInt(viewID);
out.writeCDOLockType(lockType);
out.writeLong(timeout);
- out.writeCDOBranch(viewedBranch);
out.writeInt(revisionKeys.size());
for (CDORevisionKey revKey : revisionKeys)
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/OpenSessionRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/OpenSessionRequest.java
index 601496df3f..f7ba9581ba 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/OpenSessionRequest.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/OpenSessionRequest.java
@@ -13,6 +13,7 @@ package org.eclipse.emf.cdo.internal.net4j.protocol;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOID.ObjectType;
@@ -46,15 +47,18 @@ public class OpenSessionRequest extends CDOClientRequestWithMonitoring<OpenSessi
private PassiveUpdateMode passiveUpdateMode;
+ private LockNotificationMode lockNotificationMode;
+
private OpenSessionResult result;
public OpenSessionRequest(CDOClientProtocol protocol, String repositoryName, boolean passiveUpdateEnabled,
- PassiveUpdateMode passiveUpdateMode)
+ PassiveUpdateMode passiveUpdateMode, LockNotificationMode lockNotificationMode)
{
super(protocol, CDOProtocolConstants.SIGNAL_OPEN_SESSION);
this.repositoryName = repositoryName;
this.passiveUpdateEnabled = passiveUpdateEnabled;
this.passiveUpdateMode = passiveUpdateMode;
+ this.lockNotificationMode = lockNotificationMode;
}
@Override
@@ -80,6 +84,13 @@ public class OpenSessionRequest extends CDOClientRequestWithMonitoring<OpenSessi
}
out.writeEnum(passiveUpdateMode);
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing lockNotificationMode: {0}", lockNotificationMode); //$NON-NLS-1$
+ }
+
+ out.writeEnum(lockNotificationMode);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java
index 83f1082bcb..156fc10184 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/ReplicateRepositoryRequest.java
@@ -10,6 +10,8 @@
**************************************************************************/
package org.eclipse.emf.cdo.internal.net4j.protocol;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
@@ -37,6 +39,13 @@ public class ReplicateRepositoryRequest extends CDOClientRequest<Boolean>
{
out.writeInt(context.getLastReplicatedBranchID());
out.writeLong(context.getLastReplicatedCommitTime());
+
+ String[] lockAreaIDs = context.getLockAreaIDs();
+ out.writeInt(lockAreaIDs.length);
+ for (int i = 0; i < lockAreaIDs.length; i++)
+ {
+ out.writeString(lockAreaIDs[i]);
+ }
}
@Override
@@ -58,8 +67,22 @@ public class ReplicateRepositoryRequest extends CDOClientRequest<Boolean>
context.handleCommitInfo(in.readCDOCommitInfo());
break;
+ case CDOProtocolConstants.REPLICATE_LOCKAREA:
+ boolean deleted = !in.readBoolean();
+ if (deleted)
+ {
+ String deletedLockAreaID = in.readString();
+ LockArea area = CDOLockUtil.createLockArea(deletedLockAreaID);
+ context.handleLockArea(area);
+ }
+ else
+ {
+ context.handleLockArea(in.readCDOLockArea());
+ }
+ break;
+
default:
- throw new IOException("Invalid replicate opcode: " + opcode);
+ throw new IllegalStateException("Invalid replicate opcode: " + opcode);
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/RepositoryStateNotificationIndication.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/RepositoryStateNotificationIndication.java
index 1831d3c7af..557e043461 100644
--- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/RepositoryStateNotificationIndication.java
+++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/RepositoryStateNotificationIndication.java
@@ -12,6 +12,7 @@
package org.eclipse.emf.cdo.internal.net4j.protocol;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.internal.net4j.CDONet4jSessionConfigurationImpl.RepositoryInfo;
@@ -34,10 +35,13 @@ public class RepositoryStateNotificationIndication extends CDOClientIndication
{
CDOCommonRepository.State oldState = in.readEnum(CDOCommonRepository.State.class);
CDOCommonRepository.State newState = in.readEnum(CDOCommonRepository.State.class);
+ CDOID rootResourceID = in.readCDOID();
CDONet4jSessionImpl session = (CDONet4jSessionImpl)getSession();
RepositoryInfo repositoryInfo = (RepositoryInfo)session.getRepositoryInfo();
repositoryInfo.setState(newState);
+ repositoryInfo.setRootResourceID(rootResourceID);
+
session.handleRepositoryStateChanged(oldState, newState);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
index dfad801b99..bc1481a8bd 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
@@ -1301,6 +1301,11 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
return manager.createLockArea(this, durableLockingID, userID, branchPoint, readOnly, locks);
}
+ public void updateLockArea(LockArea lockArea)
+ {
+ throw new RuntimeException("TODO (CD)"); // TODO (CD)
+ }
+
public LockArea getLockArea(String durableLockingID) throws LockAreaNotFoundException
{
DurableLockingManager manager = getStore().getDurableLockingManager();
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
index 789e425a75..1e2183698d 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DurableLockingManager.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.server.internal.db;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea.Handler;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaAlreadyExistsException;
@@ -22,7 +23,6 @@ import org.eclipse.emf.cdo.server.db.IIDHandler;
import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.server.DurableLockArea;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.net4j.db.DBException;
@@ -179,7 +179,7 @@ public class DurableLockingManager extends Lifecycle
accessor.getConnection().commit();
- return new DurableLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
+ return CDOLockUtil.createLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
}
catch (SQLException ex)
{
@@ -531,7 +531,7 @@ public class DurableLockingManager extends Lifecycle
{
for (;;)
{
- String durableLockingID = DurableLockArea.createDurableLockingID();
+ String durableLockingID = CDOLockUtil.createDurableLockingID();
try
{
@@ -550,7 +550,7 @@ public class DurableLockingManager extends Lifecycle
{
CDOBranchPoint branchPoint = branchManager.getBranch(branchID).getPoint(timeStamp);
Map<CDOID, LockGrade> lockMap = getLockMap(accessor, durableLockingID);
- return new DurableLockArea(durableLockingID, userID, branchPoint, readOnly, lockMap);
+ return CDOLockUtil.createLockArea(durableLockingID, userID, branchPoint, readOnly, lockMap);
}
private Map<CDOID, LockGrade> getLockMap(DBStoreAccessor accessor, String durableLockingID)
diff --git a/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4ODurableLockingManager.java b/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4ODurableLockingManager.java
index 2efdf7e275..64b03cbd22 100644
--- a/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4ODurableLockingManager.java
+++ b/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4ODurableLockingManager.java
@@ -12,11 +12,11 @@ package org.eclipse.emf.cdo.server.internal.db4o;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea.Handler;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaNotFoundException;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
-import org.eclipse.emf.cdo.spi.server.DurableLockArea;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
@@ -42,7 +42,7 @@ public class DB4ODurableLockingManager extends Lifecycle
boolean readOnly, Map<CDOID, LockGrade> locks)
{
String durableLockingID = getNextDurableLockingID(accessor);
- LockArea lockArea = new DurableLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
+ LockArea lockArea = CDOLockUtil.createLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
storeLockArea(accessor, lockArea);
return lockArea;
}
@@ -183,7 +183,7 @@ public class DB4ODurableLockingManager extends Lifecycle
{
for (;;)
{
- String durableLockingID = DurableLockArea.createDurableLockingID();
+ String durableLockingID = CDOLockUtil.createDurableLockingID();
try
{
diff --git a/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OLockArea.java b/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OLockArea.java
index 35d248e751..92e5d02e13 100644
--- a/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OLockArea.java
+++ b/plugins/org.eclipse.emf.cdo.server.db4o/src/org/eclipse/emf/cdo/server/internal/db4o/DB4OLockArea.java
@@ -15,10 +15,10 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
import org.eclipse.emf.cdo.server.db4o.IDB4OStore;
-import org.eclipse.emf.cdo.spi.server.DurableLockArea;
import java.util.HashMap;
import java.util.LinkedList;
@@ -82,7 +82,8 @@ public class DB4OLockArea
lockMap.put(cdoid, lockGrade);
}
- LockArea lockArea = new DurableLockArea(primitive.id, primitive.userID, branchpoint, primitive.readOnly, lockMap);
+ LockArea lockArea = CDOLockUtil.createLockArea(primitive.id, primitive.userID, branchpoint, primitive.readOnly,
+ lockMap);
map.put(lockArea, primitive);
return lockArea;
}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/.settings/.api_filters b/plugins/org.eclipse.emf.cdo.server.net4j/.settings/.api_filters
index dcf823f69d..a491d67f25 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/.settings/.api_filters
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/.settings/.api_filters
@@ -8,4 +8,12 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ReplicateRepositoryIndication.java" type="org.eclipse.emf.cdo.server.internal.net4j.protocol.ReplicateRepositoryIndication">
+ <filter id="574619656">
+ <message_arguments>
+ <message_argument value="CDOReplicationContext"/>
+ <message_argument value="ReplicateRepositoryIndication"/>
+ </message_arguments>
+ </filter>
+ </resource>
</component>
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java
index a0fc0cbb82..c3c7d4f8db 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java
@@ -16,6 +16,7 @@ package org.eclipse.emf.cdo.server.internal.net4j.protocol;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.server.IRepositoryProvider;
@@ -94,12 +95,19 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement
}
}
+ @Deprecated
public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
throws Exception
{
+ sendRepositoryStateNotification(oldState, newState, null);
+ }
+
+ public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState,
+ CDOID rootResourceID) throws Exception
+ {
if (LifecycleUtil.isActive(getChannel()))
{
- new RepositoryStateNotificationRequest(this, oldState, newState).sendAsync();
+ new RepositoryStateNotificationRequest(this, oldState, newState, rootResourceID).sendAsync();
}
else
{
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitDelegationIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitDelegationIndication.java
index 1118f85a44..680d4e88f8 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitDelegationIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CommitDelegationIndication.java
@@ -36,6 +36,12 @@ public class CommitDelegationIndication extends CommitTransactionIndication
}
@Override
+ protected void indicating(CDODataInput in, OMMonitor monitor) throws Exception
+ {
+ super.indicating(in, monitor);
+ }
+
+ @Override
protected void initializeCommitContext(CDODataInput in) throws Exception
{
CDOBranch branch = in.readCDOBranch();
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java
index 34ca52a802..5c95ae8ee1 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/EnableLockNotificationIndication.java
@@ -34,7 +34,7 @@ public class EnableLockNotificationIndication extends CDOServerIndication
boolean enable = in.readBoolean();
InternalView view = getSession().getView(viewID);
- view.setLockNotificationEnabled(enable);
+ view.options().setLockNotificationEnabled(enable);
}
@Override
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java
index eaa67fd485..50322c5a03 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockDelegationIndication.java
@@ -11,8 +11,6 @@
package org.eclipse.emf.cdo.server.internal.net4j.protocol;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
-import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaNotFoundException;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
@@ -20,8 +18,7 @@ import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.InternalSession;
import org.eclipse.emf.cdo.spi.server.InternalView;
-
-import org.eclipse.net4j.util.CheckUtil;
+import org.eclipse.emf.cdo.spi.server.SyncingUtil;
import java.io.IOException;
@@ -34,6 +31,8 @@ public class LockDelegationIndication extends LockObjectsIndication
private String lockAreaID;
+ private CDOBranch viewedBranch;
+
public LockDelegationIndication(CDOServerProtocol protocol)
{
super(protocol, CDOProtocolConstants.SIGNAL_LOCK_DELEGATION);
@@ -43,6 +42,7 @@ public class LockDelegationIndication extends LockObjectsIndication
protected void indicating(CDODataInput in) throws IOException
{
lockAreaID = in.readString();
+ viewedBranch = in.readCDOBranch();
super.indicating(in);
}
@@ -60,35 +60,14 @@ public class LockDelegationIndication extends LockObjectsIndication
}
@Override
- protected IView getView(int viewID, CDOBranch viewedBranch)
+ protected IView getView(int viewID)
{
- // The view needs a lockArea...
- InternalLockManager lockManager = getRepository().getLockManager();
- InternalSession session = getSession();
- LockArea lockArea;
-
- try
- {
- lockArea = lockManager.getLockArea(lockAreaID);
-
- // If we get here, the lockArea already exists.
- view = (InternalView)lockManager.openView(session, InternalSession.TEMP_VIEW_ID, true, lockAreaID);
- }
- catch (LockAreaNotFoundException e)
- {
- // If we get here, the lockArea does not yet exist on the master, so we open
- // a view without a lockArea first, then create a lockArea with the given ID,
- // and associate it with the view.
- view = session.openView(InternalSession.TEMP_VIEW_ID, viewedBranch.getHead());
- lockArea = lockManager.createLockArea(view, lockAreaID);
- view.setDurableLockingID(lockAreaID);
- }
-
// The viewID received as an argument, is the ID of the client's view, which
// does not exist on the master. So we ignore this argument and open a new
// view instead.
- CheckUtil.checkState(lockAreaID.equals(lockArea.getDurableLockingID()), "lockAreaID has incorrect value");
-
+ InternalLockManager lockManager = getRepository().getLockManager();
+ InternalSession session = getSession();
+ view = SyncingUtil.openViewWithLockArea(session, lockManager, viewedBranch, lockAreaID);
return view;
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java
index b61cc1cf8b..4484526c62 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/LockObjectsIndication.java
@@ -12,7 +12,6 @@
*/
package org.eclipse.emf.cdo.server.internal.net4j.protocol;
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
@@ -53,7 +52,6 @@ public class LockObjectsIndication extends CDOServerWriteIndication
int viewID = in.readInt();
LockType lockType = in.readCDOLockType();
long timeout = in.readLong();
- CDOBranch viewedBranch = in.readCDOBranch();
int nRevisions = in.readInt();
List<CDORevisionKey> revisionKeys = new LinkedList<CDORevisionKey>();
@@ -63,11 +61,11 @@ public class LockObjectsIndication extends CDOServerWriteIndication
}
InternalRepository repository = getRepository();
- IView view = getView(viewID, viewedBranch);
- result = repository.lock((InternalView)view, lockType, revisionKeys, viewedBranch, timeout);
+ IView view = getView(viewID);
+ result = repository.lock((InternalView)view, lockType, revisionKeys, timeout);
}
- protected IView getView(int viewID, CDOBranch viewedBranch)
+ protected IView getView(int viewID)
{
return getSession().getView(viewID);
}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java
index 7d8a9962d4..fa7d727384 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/OpenSessionIndication.java
@@ -10,6 +10,7 @@
*/
package org.eclipse.emf.cdo.server.internal.net4j.protocol;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
@@ -42,6 +43,8 @@ public class OpenSessionIndication extends CDOServerIndicationWithMonitoring
private PassiveUpdateMode passiveUpdateMode;
+ private LockNotificationMode lockNotificationMode;
+
private InternalRepository repository;
private InternalSession session;
@@ -83,6 +86,12 @@ public class OpenSessionIndication extends CDOServerIndicationWithMonitoring
{
TRACER.format("Read passiveUpdateMode: {0}", passiveUpdateMode); //$NON-NLS-1$
}
+
+ lockNotificationMode = in.readEnum(LockNotificationMode.class);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read lockNotificationMode: {0}", lockNotificationMode); //$NON-NLS-1$
+ }
}
@Override
@@ -105,6 +114,7 @@ public class OpenSessionIndication extends CDOServerIndicationWithMonitoring
session = sessionManager.openSession(protocol);
session.setPassiveUpdateEnabled(passiveUpdateEnabled);
session.setPassiveUpdateMode(passiveUpdateMode);
+ session.setLockNotificationMode(lockNotificationMode);
protocol.setInfraStructure(session);
if (TRACER.isEnabled())
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ReplicateRepositoryIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ReplicateRepositoryIndication.java
index 1b0315f99a..d39b40a9ee 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ReplicateRepositoryIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/ReplicateRepositoryIndication.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.server.internal.net4j.protocol;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
@@ -20,6 +21,8 @@ import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
import org.eclipse.net4j.util.WrappedException;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
/**
* @author Eike Stepper
@@ -30,6 +33,8 @@ public class ReplicateRepositoryIndication extends CDOServerReadIndication
private long lastReplicatedCommitTime;
+ private String[] lockAreaIDs;
+
public ReplicateRepositoryIndication(CDOServerProtocol protocol)
{
super(protocol, CDOProtocolConstants.SIGNAL_REPLICATE_REPOSITORY);
@@ -40,11 +45,32 @@ public class ReplicateRepositoryIndication extends CDOServerReadIndication
{
lastReplicatedBranchID = in.readInt();
lastReplicatedCommitTime = in.readLong();
+ lockAreaIDs = new String[in.readInt()];
+ for (int i = 0; i < lockAreaIDs.length; i++)
+ {
+ lockAreaIDs[i] = in.readString();
+ }
+ }
+
+ private Set<String> createLockAreaIDSet()
+ {
+ Set<String> idSet = new HashSet<String>(lockAreaIDs.length);
+ for (String id : lockAreaIDs)
+ {
+ idSet.add(id);
+ }
+ return idSet;
}
@Override
protected void responding(final CDODataOutput out) throws IOException
{
+ // We will remove IDs from this set as we process lockAreas one by one;
+ // what remains in this set at the end are the lockAreas that the client
+ // has, but we don't have, which means that they were removed.
+ //
+ final Set<String> lockAreaIDSet = createLockAreaIDSet();
+
getRepository().replicate(new CDOReplicationContext()
{
public int getLastReplicatedBranchID()
@@ -57,6 +83,11 @@ public class ReplicateRepositoryIndication extends CDOServerReadIndication
return lastReplicatedCommitTime;
}
+ public String[] getLockAreaIDs()
+ {
+ return lockAreaIDs;
+ }
+
public void handleBranch(CDOBranch branch)
{
try
@@ -82,8 +113,33 @@ public class ReplicateRepositoryIndication extends CDOServerReadIndication
throw WrappedException.wrap(ex);
}
}
+
+ public boolean handleLockArea(LockArea lockArea)
+ {
+ try
+ {
+ out.writeByte(CDOProtocolConstants.REPLICATE_LOCKAREA);
+ out.writeBoolean(true);
+ out.writeCDOLockArea(lockArea);
+ lockAreaIDSet.remove(lockArea.getDurableLockingID());
+ return true;
+ }
+ catch (IOException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ }
});
+ // The IDs that are still in the lockAreaIDSet, must be the IDs of lockAreas that have
+ // been removed.
+ for (String deletedLockAreaID : lockAreaIDSet)
+ {
+ out.writeByte(CDOProtocolConstants.REPLICATE_LOCKAREA);
+ out.writeBoolean(false);
+ out.writeString(deletedLockAreaID);
+ }
+
out.writeByte(CDOProtocolConstants.REPLICATE_FINISHED);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RepositoryStateNotificationRequest.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RepositoryStateNotificationRequest.java
index a2835c2522..05d12fad25 100644
--- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RepositoryStateNotificationRequest.java
+++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RepositoryStateNotificationRequest.java
@@ -13,6 +13,7 @@
package org.eclipse.emf.cdo.server.internal.net4j.protocol;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
@@ -23,16 +24,19 @@ import java.io.IOException;
*/
public class RepositoryStateNotificationRequest extends CDOServerRequest
{
- private CDOCommonRepository.State oldState;
+ private final CDOCommonRepository.State oldState;
- private CDOCommonRepository.State newState;
+ private final CDOCommonRepository.State newState;
+
+ private final CDOID rootResourceID;
public RepositoryStateNotificationRequest(CDOServerProtocol serverProtocol, CDOCommonRepository.State oldState,
- CDOCommonRepository.State newState)
+ CDOCommonRepository.State newState, CDOID rootResourceID)
{
super(serverProtocol, CDOProtocolConstants.SIGNAL_REPOSITORY_STATE_NOTIFICATION);
this.oldState = oldState;
this.newState = newState;
+ this.rootResourceID = rootResourceID;
}
@Override
@@ -40,5 +44,6 @@ public class RepositoryStateNotificationRequest extends CDOServerRequest
{
out.writeEnum(oldState);
out.writeEnum(newState);
+ out.writeCDOID(rootResourceID);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockArea.java b/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockArea.java
index 9a2303cea3..c2eb781cae 100644
--- a/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockArea.java
+++ b/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockArea.java
@@ -164,19 +164,4 @@ public class ObjyLockArea extends ooObj
durableLockingID, userID, branchPoint, readOnly, readLockSet.size(), writeLockSet.size(),
readWriteLockSet.size());
}
-
- // public static String createDurableLockingID()
- // {
- // return createDurableLockingID(DEFAULT_DURABLE_LOCKING_ID_BYTES);
- // }
- //
- // public static String createDurableLockingID(int bytes)
- // {
- // byte[] buffer = new byte[bytes];
- //
- // Random random = new Random(System.currentTimeMillis());
- // random.nextBytes(buffer);
- //
- // return HexUtil.bytesToHex(buffer);
- // }
}
diff --git a/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockAreaManager.java b/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockAreaManager.java
index 959f7b8a5b..80943e5f4c 100644
--- a/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockAreaManager.java
+++ b/plugins/org.eclipse.emf.cdo.server.objectivity/src/org/eclipse/emf/cdo/server/internal/objectivity/schema/ObjyLockAreaManager.java
@@ -11,10 +11,10 @@
package org.eclipse.emf.cdo.server.internal.objectivity.schema;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea.Handler;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.server.DurableLockArea;
import com.objy.db.app.Iterator;
import com.objy.db.app.ooId;
@@ -73,7 +73,7 @@ public class ObjyLockAreaManager extends ooObj
ObjyBranch objyBranch = objyLockArea.getBranch();
CDOBranchPoint branchPoint = branchManager.getBranch(objyBranch.getBranchId())
.getPoint(objyLockArea.getTimeStamp());
- return new DurableLockArea(objyLockArea.getDurableLockingID(), objyLockArea.getUserID(), branchPoint,
+ return CDOLockUtil.createLockArea(objyLockArea.getDurableLockingID(), objyLockArea.getUserID(), branchPoint,
objyLockArea.isReadOnly(), objyLockArea.getLocks());
}
diff --git a/plugins/org.eclipse.emf.cdo.server/.settings/.api_filters b/plugins/org.eclipse.emf.cdo.server/.settings/.api_filters
index 9e39d0d361..833c77689b 100644
--- a/plugins/org.eclipse.emf.cdo.server/.settings/.api_filters
+++ b/plugins/org.eclipse.emf.cdo.server/.settings/.api_filters
@@ -10,6 +10,12 @@
</filter>
</resource>
<resource path="src/org/eclipse/emf/cdo/internal/server/LockManager.java" type="org.eclipse.emf.cdo.internal.server.LockManager$DurableView">
+ <filter id="574619656">
+ <message_arguments>
+ <message_argument value="Options"/>
+ <message_argument value="DurableView"/>
+ </message_arguments>
+ </filter>
<filter id="574660632">
<message_arguments>
<message_argument value="IView"/>
@@ -28,6 +34,12 @@
</filter>
</resource>
<resource path="src/org/eclipse/emf/cdo/internal/server/Repository.java" type="org.eclipse.emf.cdo.internal.server.Repository">
+ <filter id="574619656">
+ <message_arguments>
+ <message_argument value="CDOReplicationInfo"/>
+ <message_argument value="Repository"/>
+ </message_arguments>
+ </filter>
<filter id="574660632">
<message_arguments>
<message_argument value="InternalRepository"/>
@@ -100,6 +112,12 @@
</filter>
</resource>
<resource path="src/org/eclipse/emf/cdo/internal/server/View.java" type="org.eclipse.emf.cdo.internal.server.View">
+ <filter id="574619656">
+ <message_arguments>
+ <message_argument value="Options"/>
+ <message_argument value="View"/>
+ </message_arguments>
+ </filter>
<filter id="574660632">
<message_arguments>
<message_argument value="InternalView"/>
@@ -286,6 +304,14 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/cdo/spi/server/InternalSynchronizableRepository.java" type="org.eclipse.emf.cdo.spi.server.InternalSynchronizableRepository">
+ <filter id="571473929">
+ <message_arguments>
+ <message_argument value="CDOReplicationContext"/>
+ <message_argument value="InternalSynchronizableRepository"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/cdo/spi/server/Store.java" type="org.eclipse.emf.cdo.spi.server.Store">
<filter id="574660632">
<message_arguments>
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
index e6fe19fb5d..19d20940e8 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java
@@ -12,6 +12,7 @@
*/
package org.eclipse.emf.cdo.internal.server;
+import org.eclipse.emf.cdo.common.CDOCommonView;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
@@ -32,6 +33,7 @@ import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalStore;
import org.eclipse.emf.cdo.spi.server.InternalView;
+import org.eclipse.net4j.util.CheckUtil;
import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.WrappedException;
@@ -41,6 +43,7 @@ import org.eclipse.net4j.util.container.IContainer;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
+import org.eclipse.net4j.util.options.IOptionsContainer;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -60,6 +63,8 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
private Map<String, InternalView> openViews = new HashMap<String, InternalView>();
+ private Map<String, DurableView> durableViews = new HashMap<String, DurableView>();
+
@ExcludeFromDump
private transient IListener sessionListener = new ContainerEventAdapter<IView>()
{
@@ -112,7 +117,7 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
public synchronized Object getLockEntryObject(Object key)
{
LockState<Object, IView> lockState = getObjectToLocksMap().get(key);
- return lockState.getLockedObject();
+ return lockState == null ? null : lockState.getLockedObject();
}
public Object getLockKey(CDOID id, CDOBranch branch)
@@ -438,7 +443,7 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
/**
* @author Eike Stepper
*/
- private final class DurableView implements IView
+ private final class DurableView implements IView, CDOCommonView.Options
{
private String durableLockingID;
@@ -525,6 +530,43 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
{
return MessageFormat.format("DurableView[{0}]", durableLockingID);
}
+
+ public IOptionsContainer getContainer()
+ {
+ return null;
+ }
+
+ public void addListener(IListener listener)
+ {
+ }
+
+ public void removeListener(IListener listener)
+ {
+ }
+
+ public boolean hasListeners()
+ {
+ return false;
+ }
+
+ public IListener[] getListeners()
+ {
+ return null;
+ }
+
+ public Options options()
+ {
+ return this;
+ }
+
+ public boolean isLockNotificationEnabled()
+ {
+ return false;
+ }
+
+ public void setLockNotificationEnabled(boolean enabled)
+ {
+ }
}
/**
@@ -532,9 +574,34 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
*/
private final class DurableLockLoader implements LockArea.Handler
{
+ // Note (CD) This field is a sneaky way of avoiding more API changes.
+ // The view should properly be an argument on #handleLockArea(LockArea)
+ private IView view;
+
+ public DurableLockLoader()
+ {
+ }
+
+ public DurableLockLoader(IView view)
+ {
+ this.view = view;
+ }
+
+ private IView getView(LockArea area)
+ {
+ if (view != null)
+ {
+ return view;
+ }
+
+ DurableView view = new DurableView(area.getDurableLockingID());
+ durableViews.put(area.getDurableLockingID(), view);
+ return view;
+ }
+
public boolean handleLockArea(LockArea area)
{
- IView view = new DurableView(area.getDurableLockingID());
+ IView view = getView(area);
Collection<Object> readLocks = new ArrayList<Object>();
Collection<Object> writeLocks = new ArrayList<Object>();
@@ -590,4 +657,45 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern
}
return grade;
}
+
+ public void updateLockArea(LockArea lockArea)
+ {
+ DurableLocking2 accessor = getDurableLocking2();
+ if (lockArea.isDeleted())
+ {
+ accessor.deleteLockArea(lockArea.getDurableLockingID());
+ }
+ else
+ {
+ accessor.updateLockArea(lockArea);
+ }
+
+ IView view = openViews.get(lockArea.getDurableLockingID());
+ if (view == null)
+ {
+ view = durableViews.get(lockArea.getDurableLockingID());
+
+ // If we already have this durableView, we remove all the locks first...
+ if (view != null)
+ {
+ unlock2(view);
+ }
+
+ // ...then reload from the new lockArea
+ //
+ if (lockArea.isDeleted())
+ {
+ DurableView deletedView = durableViews.remove(lockArea.getDurableLockingID());
+ CheckUtil.checkNull(deletedView, "deletedView");
+ }
+ else
+ {
+ DurableLockLoader handler = new DurableLockLoader(view);
+ handler.handleLockArea(lockArea);
+ }
+
+ view = durableViews.get(lockArea.getDurableLockingID());
+ CheckUtil.checkNull(view, "view");
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
index d8c51bf38d..2b35f7b31a 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
@@ -285,7 +285,7 @@ public class Repository extends Container<Object> implements InternalRepository
if (sessionManager != null)
{
- sessionManager.sendRepositoryStateNotification(oldState, newState);
+ sessionManager.sendRepositoryStateNotification(oldState, newState, getRootResourceID());
}
}
@@ -1147,6 +1147,11 @@ public class Repository extends Container<Object> implements InternalRepository
{
return toCommitTime;
}
+
+ public String[] getLockAreaIDs()
+ {
+ return null; // TODO (CD)
+ }
};
}
@@ -1157,6 +1162,8 @@ public class Repository extends Container<Object> implements InternalRepository
long startTime = context.getLastReplicatedCommitTime();
commitInfoManager.getCommitInfos(null, startTime + 1L, CDOBranchPoint.UNSPECIFIED_DATE, context);
+
+ lockManager.getLockAreas(null, context);
}
public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
@@ -1340,30 +1347,38 @@ public class Repository extends Container<Object> implements InternalRepository
}
}
- public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revisionKeys,
- CDOBranch viewedBranch, long timeout)
+ public static List<Object> revisionKeysToObjects(List<CDORevisionKey> revisionKeys, CDOBranch viewedBranch,
+ boolean isSupportingBranches)
{
- List<Object> objectsToLock = new ArrayList<Object>();
- boolean isSupportingBranches = isSupportingBranches();
+ List<Object> lockables = new ArrayList<Object>();
for (CDORevisionKey revKey : revisionKeys)
{
CDOID id = revKey.getID();
if (isSupportingBranches)
{
- objectsToLock.add(CDOIDUtil.createIDAndBranch(id, viewedBranch));
+ lockables.add(CDOIDUtil.createIDAndBranch(id, viewedBranch));
}
else
{
- objectsToLock.add(id);
+ lockables.add(id);
}
}
+ return lockables;
+ }
- InternalLockManager lockManager = getLockManager();
- List<LockState<Object, IView>> newLockStates = null;
+ public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revKeys, long timeout)
+ {
+ List<Object> lockables = revisionKeysToObjects(revKeys, view.getBranch(), isSupportingBranches());
+ return lock(view, lockType, lockables, revKeys, timeout);
+ }
+ protected LockObjectsResult lock(InternalView view, LockType type, List<Object> lockables,
+ List<CDORevisionKey> loadedRevs, long timeout)
+ {
+ List<LockState<Object, IView>> newLockStates = null;
try
{
- newLockStates = lockManager.lock2(true, lockType, view, objectsToLock, timeout);
+ newLockStates = lockManager.lock2(true, type, view, lockables, timeout);
}
catch (TimeoutRuntimeException ex)
{
@@ -1374,13 +1389,35 @@ public class Repository extends Container<Object> implements InternalRepository
throw WrappedException.wrap(ex);
}
- List<CDORevisionKey> staleRevisions = new LinkedList<CDORevisionKey>();
- long requiredTimestamp = 0;
+ long[] requiredTimestamp = { 0L };
+ CDORevisionKey[] staleRevisionsArray = checkStaleRevisions(view, loadedRevs, lockables, type, requiredTimestamp);
- try
+ // If some of the clients' revisions are stale and it has passiveUpdates disabled,
+ // then the locks are useless so we release them and report the stale revisions
+ //
+ InternalSession session = view.getSession();
+ boolean staleNoUpdate = staleRevisionsArray.length > 0 && !session.isPassiveUpdateEnabled();
+ if (staleNoUpdate)
{
- InternalCDORevisionManager revManager = getRevisionManager();
+ lockManager.unlock2(true, type, view, lockables);
+ return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0]);
+ }
+ CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
+ sendLockNotifications(view, Operation.LOCK, type, cdoLockStates);
+
+ boolean waitForUpdate = staleRevisionsArray.length > 0;
+ return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates);
+ }
+
+ private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys,
+ List<Object> objectsToLock, LockType lockType, long[] requiredTimestamp)
+ {
+ List<CDORevisionKey> staleRevisions = new LinkedList<CDORevisionKey>();
+ if (revisionKeys != null)
+ {
+ InternalCDORevisionManager revManager = getRevisionManager();
+ CDOBranch viewedBranch = view.getBranch();
for (CDORevisionKey revKey : revisionKeys)
{
CDOID id = revKey.getID();
@@ -1389,6 +1426,7 @@ public class Repository extends Container<Object> implements InternalRepository
if (rev == null)
{
+ lockManager.unlock2(true, lockType, view, objectsToLock);
throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id,
viewedBranch));
}
@@ -1396,56 +1434,37 @@ public class Repository extends Container<Object> implements InternalRepository
if (!revKey.equals(rev))
{
staleRevisions.add(revKey);
- requiredTimestamp = Math.max(requiredTimestamp, rev.getTimeStamp());
+ requiredTimestamp[0] = Math.max(requiredTimestamp[0], rev.getTimeStamp());
}
}
}
- catch (IllegalArgumentException ex)
- {
- lockManager.unlock2(true, lockType, view, objectsToLock);
- throw ex;
- }
// Convert the list to an array, to satisfy the API later
//
CDORevisionKey[] staleRevisionsArray = new CDORevisionKey[staleRevisions.size()];
staleRevisions.toArray(staleRevisionsArray);
- // If some of the clients' revisions are stale and it has passiveUpdates disabled,
- // then the locks are useless so we release them and report the stale revisions
- InternalSession session = view.getSession();
- boolean staleNoUpdate = staleRevisionsArray.length > 0 && !session.isPassiveUpdateEnabled();
- if (staleNoUpdate)
- {
- lockManager.unlock2(true, lockType, view, objectsToLock);
- return new LockObjectsResult(false, false, false, requiredTimestamp, staleRevisionsArray, new CDOLockState[0]);
- }
-
- CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
- sendLockNotifications(view, viewedBranch, Operation.LOCK, cdoLockStates);
-
- boolean waitForUpdate = staleRevisionsArray.length > 0;
- return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp, staleRevisionsArray, cdoLockStates);
+ return staleRevisionsArray;
}
- private void sendLockNotifications(IView view, CDOBranch viewedBranch, Operation operation,
- CDOLockState[] cdoLockStates)
+ private void sendLockNotifications(IView view, Operation operation, LockType lockType, CDOLockState[] cdoLockStates)
{
long timestamp = getTimeStamp();
- CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(timestamp, view, viewedBranch, operation,
- cdoLockStates);
+ CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(timestamp, view, view.getBranch(), operation,
+ lockType, cdoLockStates);
getSessionManager().sendLockNotification((InternalSession)view.getSession(), lockChangeInfo);
}
// TODO (CD) This doesn't really belong here.. but getting it into CDOLockUtil isn't possible
- private CDOLockState[] toCDOLockStates(List<LockState<Object, IView>> lockStates)
+ public static CDOLockState[] toCDOLockStates(List<LockState<Object, IView>> lockStates)
{
CDOLockState[] cdoLockStates = new CDOLockState[lockStates.size()];
int i = 0;
for (LockState<Object, ? extends CDOCommonView> lockState : lockStates)
{
- cdoLockStates[i++] = CDOLockUtil.createLockState(lockState);
+ CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState);
+ cdoLockStates[i++] = cdoLockState;
}
return cdoLockStates;
@@ -1453,30 +1472,35 @@ public class Repository extends Container<Object> implements InternalRepository
public UnlockObjectsResult unlock(InternalView view, LockType lockType, List<CDOID> objectIDs)
{
- List<Object> revisionKeys = null;
+ List<Object> unlockables = null;
if (objectIDs != null)
{
- revisionKeys = new ArrayList<Object>(objectIDs.size());
+ unlockables = new ArrayList<Object>(objectIDs.size());
CDOBranch branch = view.getBranch();
for (CDOID id : objectIDs)
{
Object key = supportingBranches ? CDOIDUtil.createIDAndBranch(id, branch) : id;
- revisionKeys.add(key);
+ unlockables.add(key);
}
}
+ return doUnlock(view, lockType, unlockables);
+ }
+
+ protected UnlockObjectsResult doUnlock(InternalView view, LockType lockType, List<Object> unlockables)
+ {
List<LockState<Object, IView>> newLockStates = null;
- if (lockType == null && revisionKeys == null)
+ if (lockType == null) // Signals an unlock-all operation
{
newLockStates = lockManager.unlock2(true, view);
}
else
{
- newLockStates = lockManager.unlock2(true, lockType, view, revisionKeys);
+ newLockStates = lockManager.unlock2(true, lockType, view, unlockables);
}
CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
- sendLockNotifications(view, view.getBranch(), Operation.UNLOCK, cdoLockStates);
+ sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates);
return new UnlockObjectsResult(cdoLockStates);
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
index 3af601ddb4..f463f4a583 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
@@ -211,7 +211,7 @@ public class ServerCDOView extends AbstractCDOView implements org.eclipse.emf.cd
throw new UnsupportedOperationException();
}
- public void handleLockNotification(CDOLockChangeInfo lockChangeInfo)
+ public void handleLockNotification(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
{
// Do nothing
}
@@ -806,7 +806,7 @@ public class ServerCDOView extends AbstractCDOView implements org.eclipse.emf.cd
throw new UnsupportedOperationException();
}
- public void handleLockNotification(CDOLockChangeInfo lockChangeInfo)
+ public void handleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender)
{
throw new UnsupportedOperationException();
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
index cf32de47d4..ef6ee5482e 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
@@ -77,6 +77,9 @@ public class Session extends Container<IView> implements InternalSession
private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;
+ private LockNotificationMode lockNotificationMode = LockNotificationMode.ALWAYS; // TODO (CD) Default should be
+ // PER_VIEW
+
private long lastUpdateTime;
@ExcludeFromDump
@@ -203,6 +206,18 @@ public class Session extends Container<IView> implements InternalSession
this.passiveUpdateMode = passiveUpdateMode;
}
+ public LockNotificationMode getLockNotificationMode()
+ {
+ return lockNotificationMode;
+ }
+
+ public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
+ {
+ checkActive();
+ checkArg(lockNotificationMode, "lockNotificationMode");
+ this.lockNotificationMode = lockNotificationMode;
+ }
+
public long getLastUpdateTime()
{
synchronized (lastUpdateTimeLock)
@@ -346,12 +361,19 @@ public class Session extends Container<IView> implements InternalSession
}
}
+ @Deprecated
public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
throws Exception
{
+ sendRepositoryStateNotification(oldState, newState, null);
+ }
+
+ public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState,
+ CDOID rootResourceID) throws Exception
+ {
if (protocol != null)
{
- protocol.sendRepositoryStateNotification(oldState, newState);
+ protocol.sendRepositoryStateNotification(oldState, newState, rootResourceID);
}
}
@@ -458,14 +480,23 @@ public class Session extends Container<IView> implements InternalSession
{
if (protocol != null)
{
- // If this session has one (or more) views configured for this branch,
- // only then do we send the lockChangeInfo.
- for (InternalView view : getViews())
+ if (options().getLockNotificationMode() == LockNotificationMode.ALWAYS)
+ {
+ protocol.sendLockNotification(lockChangeInfo);
+ return;
+ }
+
+ if (options().getLockNotificationMode() == LockNotificationMode.IF_REQUIRED_BY_VIEWS)
{
- if (view.isLockNotificationEnabled() && view.getBranch().equals(lockChangeInfo.getBranch()))
+ // If this session has one (or more) views configured for this branch,
+ // only then do we send the lockChangeInfo.
+ for (InternalView view : getViews())
{
- protocol.sendLockNotification(lockChangeInfo);
- break;
+ if (view.options().isLockNotificationEnabled() && view.getBranch().equals(lockChangeInfo.getBranch()))
+ {
+ protocol.sendLockNotification(lockChangeInfo);
+ break;
+ }
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java
index 7869c798d1..22f71b80d7 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java
@@ -13,7 +13,9 @@
package org.eclipse.emf.cdo.internal.server;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
@@ -257,13 +259,20 @@ public class SessionManager extends Container<ISession> implements InternalSessi
}
}
+ @Deprecated
public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
{
+ sendRepositoryStateNotification(oldState, newState, null);
+ }
+
+ public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState,
+ CDOID rootResourceID)
+ {
for (InternalSession session : getSessions())
{
try
{
- session.sendRepositoryStateNotification(oldState, newState);
+ session.sendRepositoryStateNotification(oldState, newState, rootResourceID);
}
catch (Exception ex)
{
@@ -312,7 +321,10 @@ public class SessionManager extends Container<ISession> implements InternalSessi
{
for (InternalSession session : getSessions())
{
- // TODO Exclude the sender and notify locally there
+ if (session == sender || session.options().getLockNotificationMode() == LockNotificationMode.OFF)
+ {
+ continue;
+ }
try
{
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
index e2290cee19..e978f5c7e0 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
@@ -20,6 +20,10 @@ import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDObject;
import org.eclipse.emf.cdo.common.id.CDOIDReference;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch;
@@ -1056,6 +1060,10 @@ public class TransactionCommitContext implements InternalCommitContext
if (isAutoReleaseLocksEnabled())
{
postCommitLockStates = repository.getLockManager().unlock2(true, transaction);
+ if (!postCommitLockStates.isEmpty())
+ {
+ sendLockNotifications(postCommitLockStates);
+ }
}
monitor.worked();
@@ -1067,6 +1075,19 @@ public class TransactionCommitContext implements InternalCommitContext
}
}
+ private void sendLockNotifications(List<LockState<Object, IView>> newLockStates)
+ {
+ CDOLockState[] newStates = Repository.toCDOLockStates(newLockStates);
+
+ long timeStamp = getTimeStamp();
+ InternalTransaction tx = getTransaction();
+ CDOBranch branch = tx.getBranch();
+ Operation unlock = Operation.UNLOCK;
+
+ CDOLockChangeInfo info = CDOLockUtil.createLockChangeInfo(timeStamp, tx, branch, unlock, null, newStates);
+ repository.getSessionManager().sendLockNotification(tx.getSession(), info);
+ }
+
private void addNewPackageUnits(OMMonitor monitor)
{
InternalCDOPackageRegistry repositoryPackageRegistry = repository.getPackageRegistry(false);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
index a81cbb8d19..8e72f32596 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
@@ -11,6 +11,7 @@
*/
package org.eclipse.emf.cdo.internal.server;
+import org.eclipse.emf.cdo.common.CDOCommonView;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
@@ -24,6 +25,7 @@ import org.eclipse.emf.cdo.spi.server.InternalView;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.options.IOptionsContainer;
import java.text.MessageFormat;
import java.util.HashSet;
@@ -34,7 +36,7 @@ import java.util.Set;
/**
* @author Eike Stepper
*/
-public class View extends Lifecycle implements InternalView
+public class View extends Lifecycle implements InternalView, CDOCommonView.Options
{
private InternalSession session;
@@ -263,6 +265,16 @@ public class View extends Lifecycle implements InternalView
}
}
+ public IOptionsContainer getContainer()
+ {
+ return this;
+ }
+
+ public Options options()
+ {
+ return this;
+ }
+
public boolean isLockNotificationEnabled()
{
return lockNotificationsEnabled;
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java
index adfec3f101..3dd8efaa73 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.internal.server.embedded;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage;
import org.eclipse.emf.cdo.spi.common.CDOAuthenticationResult;
@@ -65,8 +66,15 @@ public class EmbeddedServerSessionProtocol extends Lifecycle implements ISession
clientSession.handleRepositoryTypeChanged(oldType, newType);
}
+ @Deprecated
public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
{
+ sendRepositoryStateNotification(oldState, newState, null);
+ }
+
+ public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState,
+ CDOID rootResourceID)
+ {
EmbeddedClientSession clientSession = clientSessionProtocol.getSession();
clientSession.handleRepositoryStateChanged(oldState, newState);
}
@@ -86,7 +94,7 @@ public class EmbeddedServerSessionProtocol extends Lifecycle implements ISession
public void sendLockNotification(CDOLockChangeInfo lockChangeInfo)
{
EmbeddedClientSession clientSession = clientSessionProtocol.getSession();
- clientSession.handleLockNotification(lockChangeInfo);
+ clientSession.handleLockNotification(lockChangeInfo, null);
}
public void sendRemoteSessionNotification(InternalSession sender, byte opcode)
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
index 1f3b13f3b4..dfdb97e09c 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStore.java
@@ -23,6 +23,7 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea.Handler;
import org.eclipse.emf.cdo.common.model.CDOModelConstants;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
@@ -46,7 +47,6 @@ import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.SyntheticCDORevision;
-import org.eclipse.emf.cdo.spi.server.DurableLockArea;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.LongIDStore;
import org.eclipse.emf.cdo.spi.server.StoreAccessorPool;
@@ -758,15 +758,21 @@ public class MEMStore extends LongIDStore implements IMEMStore, BranchLoader, Du
{
do
{
- durableLockingID = DurableLockArea.createDurableLockingID();
+ durableLockingID = CDOLockUtil.createDurableLockingID();
} while (lockAreas.containsKey(durableLockingID));
}
- LockArea area = new DurableLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
+ LockArea area = CDOLockUtil.createLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
lockAreas.put(durableLockingID, area);
return area;
}
+ public synchronized void updateLockArea(LockArea lockArea)
+ {
+ String durableLockingID = lockArea.getDurableLockingID();
+ lockAreas.put(durableLockingID, lockArea);
+ }
+
public synchronized LockArea getLockArea(String durableLockingID) throws LockAreaNotFoundException
{
LockArea area = lockAreas.get(durableLockingID);
@@ -783,7 +789,8 @@ public class MEMStore extends LongIDStore implements IMEMStore, BranchLoader, Du
for (LockArea area : lockAreas.values())
{
String userID = area.getUserID();
- if (userID != null && userID.startsWith(userIDPrefix))
+ if (userID == null || userID.startsWith(userIDPrefix))
+ // if (userID != null && userID.startsWith(userIDPrefix)) // TODO (CD) Used to be this. Any breakage?
{
if (!handler.handleLockArea(area))
{
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java
index 90974d1a21..55da263437 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/mem/MEMStoreAccessor.java
@@ -414,6 +414,11 @@ public class MEMStoreAccessor extends LongIDStoreAccessor implements Raw, Durabl
return getStore().createLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
}
+ public void updateLockArea(LockArea lockArea)
+ {
+ getStore().updateLockArea(lockArea);
+ }
+
public LockArea getLockArea(String durableLockingID) throws LockAreaNotFoundException
{
return getStore().getLockArea(durableLockingID);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java
index 33bdeb1f3b..a2fe4df2de 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java
@@ -11,16 +11,20 @@
package org.eclipse.emf.cdo.internal.server.syncing;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchCreatedEvent;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.internal.common.revision.NOOPRevisionCache;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
+import org.eclipse.emf.cdo.server.StoreThreadLocal;
import org.eclipse.emf.cdo.session.CDOSessionConfiguration;
import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
+import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
import org.eclipse.emf.cdo.spi.server.InternalRepositorySynchronizer;
import org.eclipse.emf.cdo.spi.server.InternalSynchronizableRepository;
@@ -66,12 +70,18 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
private static final Integer COMMIT_PRIORITY = 3;
+ private static final Integer LOCKS_PRIORITY = COMMIT_PRIORITY;
+
private int retryInterval = DEFAULT_RETRY_INTERVAL;
private Object connectLock = new Object();
private InternalSynchronizableRepository localRepository;
+ /**
+ * The session that connects to the master; used passively to receive notifications, and actively to request
+ * replications.
+ */
private InternalCDOSession remoteSession;
private RemoteSessionListener remoteSessionListener = new RemoteSessionListener();
@@ -117,10 +127,10 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
return remoteSessionConfigurationFactory;
}
- public void setRemoteSessionConfigurationFactory(CDOSessionConfigurationFactory remoteSessionConfigurationFactory)
+ public void setRemoteSessionConfigurationFactory(CDOSessionConfigurationFactory masterSessionConfigurationFactory)
{
- checkArg(remoteSessionConfigurationFactory, "remoteSessionConfigurationFactory"); //$NON-NLS-1$
- this.remoteSessionConfigurationFactory = remoteSessionConfigurationFactory;
+ checkArg(masterSessionConfigurationFactory, "remoteSessionConfigurationFactory"); //$NON-NLS-1$
+ remoteSessionConfigurationFactory = masterSessionConfigurationFactory;
}
public InternalCDOSession getRemoteSession()
@@ -206,7 +216,7 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
super.doDeactivate();
}
- private void disconnect()
+ private void handleDisconnect()
{
OM.LOG.info("Disconnected from master.");
if (localRepository.getRootResourceID() == null)
@@ -299,12 +309,17 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
addWork(new CommitRunnable(e));
}
}
+ else if (event instanceof CDOSessionLocksChangedEvent)
+ {
+ CDOSessionLocksChangedEvent e = (CDOSessionLocksChangedEvent)event;
+ addWork(new LocksRunnable(e));
+ }
else if (event instanceof ILifecycleEvent)
{
ILifecycleEvent e = (ILifecycleEvent)event;
if (e.getKind() == ILifecycleEvent.Kind.DEACTIVATED && e.getSource() == remoteSession)
{
- disconnect();
+ handleDisconnect();
}
}
}
@@ -346,6 +361,7 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
{
CDOSessionConfiguration masterConfiguration = remoteSessionConfigurationFactory.createSessionConfiguration();
masterConfiguration.setPassiveUpdateMode(PassiveUpdateMode.ADDITIONS);
+ masterConfiguration.setLockNotificationMode(LockNotificationMode.ALWAYS);
remoteSession = (InternalCDOSession)masterConfiguration.openSession();
@@ -442,7 +458,7 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
{
OM.LOG.warn("Replication attempt failed. Retrying in " + retryInterval + " seconds...", ex);
sleepRetryInterval();
- disconnect();
+ handleDisconnect();
}
}
}
@@ -573,4 +589,41 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos
return COMMIT_PRIORITY;
}
}
+
+ /**
+ * @author Caspar De Groot
+ */
+ private final class LocksRunnable extends QueueRunnable
+ {
+ private CDOLockChangeInfo lockChangeInfo;
+
+ public LocksRunnable(CDOLockChangeInfo lockChangeInfo)
+ {
+ this.lockChangeInfo = lockChangeInfo;
+ }
+
+ public void run()
+ {
+ try
+ {
+ StoreThreadLocal.setSession(localRepository.getReplicatorSession());
+ localRepository.handleLockChangeInfo(lockChangeInfo);
+ }
+ catch (Exception ex)
+ {
+ // TODO (CD) Retry as for commit?
+ ex.printStackTrace();
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
+ @Override
+ protected Integer getPriority()
+ {
+ return LOCKS_PRIORITY;
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
index 9f424cbd0b..06e640bc58 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/SynchronizableRepository.java
@@ -11,6 +11,7 @@
package org.eclipse.emf.cdo.internal.server.syncing;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
@@ -19,6 +20,11 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lob.CDOLob;
+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.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
@@ -37,6 +43,7 @@ import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalRepositorySynchronizer;
import org.eclipse.emf.cdo.spi.server.InternalSession;
@@ -45,10 +52,11 @@ import org.eclipse.emf.cdo.spi.server.InternalStore;
import org.eclipse.emf.cdo.spi.server.InternalSynchronizableRepository;
import org.eclipse.emf.cdo.spi.server.InternalTransaction;
import org.eclipse.emf.cdo.spi.server.InternalView;
+import org.eclipse.emf.cdo.spi.server.SyncingUtil;
-import org.eclipse.net4j.util.CheckUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.Monitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.transaction.TransactionException;
@@ -65,6 +73,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -181,6 +190,11 @@ public abstract class SynchronizableRepository extends Repository.Default implem
}
}
+ public String[] getLockAreaIDs()
+ {
+ return new String[0]; // TODO (CD)
+ }
+
public void handleBranch(CDOBranch branch)
{
if (branch.isLocal())
@@ -235,6 +249,62 @@ public abstract class SynchronizableRepository extends Repository.Default implem
}
}
+ public void handleLockChangeInfo(CDOLockChangeInfo lockChangeInfo)
+ {
+ CDOLockOwner owner = lockChangeInfo.getLockOwner();
+ String durableLockingID = owner.getDurableLockingID();
+ CDOBranch viewedBranch = lockChangeInfo.getBranch();
+ InternalLockManager lockManager = getLockManager();
+ LockType lockType = lockChangeInfo.getLockType();
+
+ InternalView view = null;
+
+ try
+ {
+ view = SyncingUtil.openViewWithLockArea(replicatorSession, lockManager, viewedBranch, durableLockingID);
+ List<Object> lockables = new LinkedList<Object>();
+
+ for (CDOLockState lockState : lockChangeInfo.getLockStates())
+ {
+ lockables.add(lockState.getLockedObject());
+ }
+
+ if (lockChangeInfo.getOperation() == Operation.LOCK)
+ {
+ long timeout = 10000; // TODO (CD)
+ super.lock(view, lockType, lockables, null, timeout);
+ }
+ else if (lockChangeInfo.getOperation() == Operation.UNLOCK)
+ {
+ super.doUnlock(view, lockType, lockables);
+ }
+ else
+ {
+ throw new IllegalStateException("Unexpected: " + lockChangeInfo.getOperation());
+ }
+ }
+ finally
+ {
+ LifecycleUtil.deactivate(view);
+ }
+ }
+
+ public boolean handleLockArea(LockArea area)
+ {
+ try
+ {
+ StoreThreadLocal.setSession(replicatorSession);
+ getLockManager().updateLockArea(area);
+
+ // TODO (CD) getSessionManager().sendLockNotification(sender, lockChangeInfo);
+ return true;
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
public void replicateRaw(CDODataInput in, OMMonitor monitor) throws IOException
{
try
@@ -261,6 +331,25 @@ public abstract class SynchronizableRepository extends Repository.Default implem
}
}
+ public void goOnline()
+ {
+ if (getState() == OFFLINE)
+ {
+ LifecycleUtil.activate(synchronizer);
+ // Do not set the state to ONLINE yet; the synchronizer will set it to SYNCING first,
+ // and then to ONLINE after a succesful replication.
+ }
+ }
+
+ public void goOffline()
+ {
+ if (getState() != OFFLINE)
+ {
+ LifecycleUtil.deactivate(synchronizer);
+ setState(OFFLINE);
+ }
+ }
+
private void replicateRawReviseRevisions()
{
InternalCDORevisionCache cache = getRevisionManager().getCache();
@@ -398,6 +487,7 @@ public abstract class SynchronizableRepository extends Repository.Default implem
{
replicatorSession = getSessionManager().openSession(null);
replicatorSession.options().setPassiveUpdateEnabled(false);
+ replicatorSession.options().setLockNotificationMode(LockNotificationMode.OFF);
synchronizer.setLocalRepository(this);
synchronizer.activate();
@@ -429,59 +519,64 @@ public abstract class SynchronizableRepository extends Repository.Default implem
}
@Override
- public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revisionKeys,
- CDOBranch viewedBranch, long timeout)
+ public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revisionKeys, long timeout)
{
- CheckUtil.checkState(view.getBranch().equals(viewedBranch),
- "Client view's branch and server view's branch are different.");
-
if (view.getBranch().isLocal())
{
- return super.lock(view, lockType, revisionKeys, viewedBranch, timeout);
+ return super.lock(view, lockType, revisionKeys, timeout);
}
-
+
if (getState() != ONLINE)
{
throw new CDOException("Cannot lock in a non-local branch when clone is not connected to master");
}
-
- return lockThrough(true, view, lockType, revisionKeys, viewedBranch, timeout);
+
+ return lockThrough(view, lockType, revisionKeys, timeout);
}
- private LockObjectsResult lockThrough(boolean explicit, InternalView view, LockType lockType,
- List<CDORevisionKey> revisionKeys, CDOBranch viewedBranch, long timeout)
+ private LockObjectsResult lockOnMaster(InternalView view, LockType type, List<CDORevisionKey> revKeys, long timeout)
+ throws InterruptedException
{
// Delegate locking to the master
InternalCDOSession remoteSession = getSynchronizer().getRemoteSession();
CDOSessionProtocol sessionProtocol = remoteSession.getSessionProtocol();
- try
+
+ String areaID = view.getDurableLockingID();
+ if (areaID == null)
+ {
+ throw new IllegalStateException("Durable locking is not enabled.");
+ }
+
+ LockObjectsResult masterLockingResult = sessionProtocol.delegateLockObjects(areaID, revKeys, view.getBranch(),
+ type, timeout);
+
+ if (masterLockingResult.isSuccessful() && masterLockingResult.isWaitForUpdate())
{
- String lockAreaID = view.getDurableLockingID();
- if (lockAreaID == null)
+ if (!getSynchronizer().getRemoteSession().options().isPassiveUpdateEnabled())
{
- throw new IllegalStateException("Durable locking is not enabled.");
+ throw new AssertionError(
+ "Master lock result requires clone to wait, but clone does not have passiveUpdates enabled.");
}
-
- LockObjectsResult masterLockingResult = sessionProtocol.delegateLockObjects(lockAreaID, revisionKeys,
- viewedBranch, lockType, timeout);
+
+ long requiredTimestamp = masterLockingResult.getRequiredTimestamp();
+ remoteSession.waitForUpdate(requiredTimestamp);
+ }
+
+ return masterLockingResult;
+ }
+
+ private LockObjectsResult lockThrough(InternalView view, LockType type, List<CDORevisionKey> keys, long timeout)
+ {
+ try
+ {
+ LockObjectsResult masterLockingResult = lockOnMaster(view, type, keys, timeout);
if (!masterLockingResult.isSuccessful())
{
return masterLockingResult;
}
-
- if (masterLockingResult.isWaitForUpdate())
- {
- if (!getSynchronizer().getRemoteSession().options().isPassiveUpdateEnabled())
- {
- throw new AssertionError(
- "Master lock result requires clone to wait, but clone does not have passiveUpdates enabled.");
- }
-
- long requiredTimestamp = masterLockingResult.getRequiredTimestamp();
- remoteSession.waitForUpdate(requiredTimestamp);
- }
-
- return super.lock(view, lockType, revisionKeys, viewedBranch, timeout);
+
+ LockObjectsResult localLockingResult = super.lock(view, type, keys, timeout);
+ return localLockingResult;
}
catch (InterruptedException ex)
{
@@ -494,30 +589,34 @@ public abstract class SynchronizableRepository extends Repository.Default implem
{
if (view.getBranch().isLocal())
{
- return super.unlock(view, lockType, objectIDs);
+ super.unlock(view, lockType, objectIDs);
}
-
+
if (getState() != ONLINE)
{
throw new CDOException("Cannot unlock in a non-local branch when clone is not connected to master");
}
-
+
return unlockThrough(view, lockType, objectIDs);
}
- private UnlockObjectsResult unlockThrough(InternalView view, LockType lockType, List<CDOID> objectIDs)
+ private void unlockOnMaster(InternalView view, LockType lockType, List<CDOID> objectIDs)
{
- // Delegate unlocking to the master
InternalCDOSession remoteSession = getSynchronizer().getRemoteSession();
CDOSessionProtocol sessionProtocol = remoteSession.getSessionProtocol();
-
+
String lockAreaID = view.getDurableLockingID();
if (lockAreaID == null)
{
throw new IllegalStateException("Durable locking is not enabled.");
}
-
+
sessionProtocol.delegateUnlockObjects(lockAreaID, objectIDs, lockType);
+ }
+
+ private UnlockObjectsResult unlockThrough(InternalView view, LockType lockType, List<CDOID> objectIDs)
+ {
+ unlockOnMaster(view, lockType, objectIDs);
return super.unlock(view, lockType, objectIDs);
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java
index d9da5d9cc5..26d6524f43 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreAccessor.java
@@ -708,12 +708,14 @@ public interface IStoreAccessor extends IQueryHandlerProvider, BranchLoader, Com
}
/**
- * @author Eike Stepper
+ * @author Caspar De Groot
* @since 4.1
*/
public interface DurableLocking2 extends DurableLocking
{
LockArea createLockArea(String durableLockingID, String userID, CDOBranchPoint branchPoint, boolean readOnly,
Map<CDOID, LockGrade> locks);
+
+ public void updateLockArea(LockArea lockArea);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISynchronizableRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISynchronizableRepository.java
index 4a64a170a4..334f8bf77c 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISynchronizableRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISynchronizableRepository.java
@@ -27,4 +27,14 @@ public interface ISynchronizableRepository extends IRepository
public int getLastReplicatedBranchID();
public long getLastReplicatedCommitTime();
+
+ /**
+ * @since 4.1
+ */
+ public void goOnline();
+
+ /**
+ * @since 4.1
+ */
+ public void goOffline();
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java
index e31811842e..1db5bfc221 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/DurableLockArea.java
@@ -13,20 +13,20 @@ package org.eclipse.emf.cdo.spi.server;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
-import org.eclipse.net4j.util.HexUtil;
-
import java.text.MessageFormat;
import java.util.Map;
-import java.util.Random;
/**
* @author Eike Stepper
* @since 4.0
* @noextend This interface is not intended to be extended by clients.
+ * @deprecated Use {@link CDOLockUtil#createLockArea(String, String, CDOBranchPoint, boolean, Map)} instead
*/
+@Deprecated
public class DurableLockArea implements LockArea
{
public static final int DEFAULT_DURABLE_LOCKING_ID_BYTES = 32;
@@ -84,22 +84,25 @@ public class DurableLockArea implements LockArea
@Override
public String toString()
{
- return MessageFormat.format("DurableLockArea[id={0}, user={1}, branchPoint={2}, readOnly={3}, locks={4}]",
+ return MessageFormat.format("DurableLockArea\nid={0}\nuser={1}\nbranchPoint={2}\nreadOnly={3}\nlocks={4}",
durableLockingID, userID, branchPoint, readOnly, locks);
}
public static String createDurableLockingID()
{
- return createDurableLockingID(DEFAULT_DURABLE_LOCKING_ID_BYTES);
+ return CDOLockUtil.createDurableLockingID();
}
public static String createDurableLockingID(int bytes)
{
- byte[] buffer = new byte[bytes];
-
- Random random = new Random(System.currentTimeMillis());
- random.nextBytes(buffer);
+ return CDOLockUtil.createDurableLockingID(bytes);
+ }
- return HexUtil.bytesToHex(buffer);
+ /**
+ * @since 4.1
+ */
+ public boolean isDeleted()
+ {
+ return false;
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java
index d8e378f566..1562ae0689 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.spi.server;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.protocol.CDOProtocol;
import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage;
@@ -34,9 +35,19 @@ public interface ISessionProtocol extends CDOProtocol
public void sendRepositoryTypeNotification(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType)
throws Exception;
+ /**
+ * @deprecated
+ */
+ @Deprecated
public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
throws Exception;
+ /**
+ * @since 4.1
+ */
+ public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState,
+ CDOID rootResourceID) throws Exception;
+
public void sendBranchNotification(InternalCDOBranch branch) throws Exception;
public void sendCommitNotification(CDOCommitInfo commitInfo) throws Exception;
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java
index d96cc595bf..ab8d9a2c37 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalLockManager.java
@@ -112,6 +112,12 @@ public interface InternalLockManager extends IRWOLockManager<Object, IView>, IDu
public LockArea createLockArea(InternalView view, String lockAreaID);
/**
+ * @since 4.1
+ */
+ // TODO (CD) I've also added this to DurableLocking2 Refactoring opportunity?
+ public void updateLockArea(LockArea lockArea);
+
+ /**
* @since 4.0
*/
public IView openView(ISession session, int viewID, boolean readOnly, String durableLockingID);
@@ -125,4 +131,9 @@ public interface InternalLockManager extends IRWOLockManager<Object, IView>, IDu
* @since 4.1
*/
public LockState<Object, IView> getLockState(Object key);
+
+ /**
+ * @since 4.1
+ */
+ public void setLockState(Object key, LockState<Object, IView> lockState);
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
index 732f716931..eb8c0b50ce 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
@@ -221,8 +221,7 @@ public interface InternalRepository extends IRepository, PackageProcessor, Packa
/**
* @since 4.1
*/
- public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revisionKeys,
- CDOBranch viewedBranch, long timeout);
+ public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revisionKeys, long timeout);
/**
* @since 4.1
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java
index e06734b554..9195c68c5c 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSession.java
@@ -56,9 +56,21 @@ public interface InternalSession extends ISession, CDOIDProvider, CDOCommonSessi
public void sendRepositoryTypeNotification(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType)
throws Exception;
+ /**
+ * @deprecated use
+ * {@link #sendRepositoryStateNotification(org.eclipse.emf.cdo.common.CDOCommonRepository.State, org.eclipse.emf.cdo.common.CDOCommonRepository.State, CDOID)}
+ * instead
+ */
+ @Deprecated
public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
throws Exception;
+ /**
+ * @since 4.1
+ */
+ public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState,
+ CDOID rootResourceID) throws Exception;
+
public void sendBranchNotification(InternalCDOBranch branch) throws Exception;
public void sendCommitNotification(CDOCommitInfo commitInfo) throws Exception;
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java
index f82d68a887..435b78e680 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSessionManager.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.spi.server;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.server.ISessionManager;
import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage;
@@ -48,8 +49,20 @@ public interface InternalSessionManager extends ISessionManager
public void sendRepositoryTypeNotification(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType);
+ /**
+ * @deprecated use
+ * {@link #sendRepositoryStateNotification(org.eclipse.emf.cdo.common.CDOCommonRepository.State, org.eclipse.emf.cdo.common.CDOCommonRepository.State, CDOID)}
+ * instead
+ */
+ @Deprecated
public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState);
+ /**
+ * @since 4.1
+ */
+ public void sendRepositoryStateNotification(CDOCommonRepository.State oldState, CDOCommonRepository.State newState,
+ CDOID rootResourceID);
+
public void sendBranchNotification(InternalSession sender, InternalCDOBranch branch);
public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSynchronizableRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSynchronizableRepository.java
index d764fbdb67..f4c3298dc0 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSynchronizableRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalSynchronizableRepository.java
@@ -10,6 +10,7 @@
*/
package org.eclipse.emf.cdo.spi.server;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfoHandler;
import org.eclipse.emf.cdo.server.ISynchronizableRepository;
import org.eclipse.emf.cdo.spi.common.CDORawReplicationContext;
import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
@@ -21,7 +22,7 @@ import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface InternalSynchronizableRepository extends ISynchronizableRepository, InternalRepository,
- CDOReplicationContext, CDORawReplicationContext
+ CDOReplicationContext, CDORawReplicationContext, CDOLockChangeInfoHandler
{
public InternalRepositorySynchronizer getSynchronizer();
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalView.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalView.java
index 7440be841f..8adca8fe50 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalView.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalView.java
@@ -53,14 +53,4 @@ public interface InternalView extends IView, ILifecycle
public void clearChangeSubscription();
public void doClose();
-
- /**
- * @since 4.1
- */
- public boolean isLockNotificationEnabled();
-
- /**
- * @since 4.1
- */
- public void setLockNotificationEnabled(boolean enable);
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/SyncingUtil.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/SyncingUtil.java
new file mode 100644
index 0000000000..a6eef7052e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/SyncingUtil.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2004 - 2011 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.server;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
+import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaNotFoundException;
+
+import org.eclipse.net4j.util.CheckUtil;
+
+/**
+ * Static methods that may help with classes related to repository synchronization.
+ *
+ * @author Eike Stepper
+ * @since 4.1
+ */
+public final class SyncingUtil
+{
+ private SyncingUtil()
+ {
+ }
+
+ public static InternalView openViewWithLockArea(InternalSession session, InternalLockManager lockManager,
+ CDOBranch viewedBranch, String lockAreaID)
+ {
+ LockArea lockArea;
+ InternalView view;
+
+ try
+ {
+ lockArea = lockManager.getLockArea(lockAreaID);
+
+ // If we get here, the lockArea already exists.
+ view = (InternalView)lockManager.openView(session, InternalSession.TEMP_VIEW_ID, true, lockAreaID);
+ }
+ catch (LockAreaNotFoundException e)
+ {
+ // If we get here, the lockArea does not yet exist, so we open
+ // a view without a lockArea first, then create a lockArea with the given ID,
+ // and associate it with the view.
+ view = session.openView(InternalSession.TEMP_VIEW_ID, viewedBranch.getHead());
+ lockArea = lockManager.createLockArea(view, lockAreaID);
+ view.setDurableLockingID(lockAreaID);
+ }
+
+ CheckUtil.checkNull(lockAreaID, "lockAreaID");
+ CheckUtil.checkNull(lockArea, "lockArea");
+ CheckUtil.checkState(lockAreaID.equals(lockArea.getDurableLockingID()), "lockAreaID has incorrect value");
+
+ return view;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java
index 424762bb4d..b43e368938 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/LockingNotificationsTest.java
@@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+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.common.lock.CDOLockUtil;
@@ -26,8 +27,10 @@ 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.util.CommitException;
-import org.eclipse.emf.cdo.view.CDOLocksChangedEvent;
import org.eclipse.emf.cdo.view.CDOView;
+import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent;
+
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
/**
* @author Caspar De Groot
@@ -41,32 +44,87 @@ public class LockingNotificationsTest extends AbstractLockingTest
return view;
}
- public void testSameBranchDifferentSession() throws CommitException
+ public void testSameBranchDifferentSession_explicitRelease() throws CommitException
+ {
+ sameBranchDifferentSession(LockReleaseMode.EXPLICIT);
+ }
+
+ public void testSameBranchDifferentSession_autoRelease() throws CommitException
+ {
+ sameBranchDifferentSession(LockReleaseMode.AUTO);
+ }
+
+ private void sameBranchDifferentSession(LockReleaseMode mode) throws CommitException
{
CDOSession session1 = openSession();
CDOSession session2 = openSession();
CDOView controlView = openViewWithLockNotifications(session2, null);
- test(session1, controlView, true);
+ if (mode == LockReleaseMode.EXPLICIT)
+ {
+ withExplicitRelease(session1, controlView, true);
+ }
+ else if (mode == LockReleaseMode.AUTO)
+ {
+ withAutoRelease(session1, controlView, true);
+ }
+
session1.close();
session2.close();
}
- public void testSameBranchSameSession() throws CommitException
+ public void testSameBranchSameSession_explicitRelease() throws CommitException
+ {
+ sameBranchSameSession(LockReleaseMode.EXPLICIT);
+ }
+
+ public void testSameBranchSameSession_autoRelease() throws CommitException
+ {
+ sameBranchSameSession(LockReleaseMode.AUTO);
+ }
+
+ private void sameBranchSameSession(LockReleaseMode mode) throws CommitException
{
CDOSession session1 = openSession();
CDOView controlView = openViewWithLockNotifications(session1, null);
- test(session1, controlView, true);
+ if (mode == LockReleaseMode.EXPLICIT)
+ {
+ withExplicitRelease(session1, controlView, true);
+ }
+ else if (mode == LockReleaseMode.AUTO)
+ {
+ withAutoRelease(session1, controlView, true);
+ }
+
session1.close();
}
@Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
public void testDifferentBranchDifferentSession() throws CommitException
{
+ differentBranchDifferentSession(LockReleaseMode.EXPLICIT);
+ }
+
+ @Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
+ public void testDifferentBranchDifferentSession_autoRelease() throws CommitException
+ {
+ differentBranchDifferentSession(LockReleaseMode.AUTO);
+ }
+
+ private void differentBranchDifferentSession(LockReleaseMode mode) throws CommitException
+ {
CDOSession session1 = openSession();
CDOBranch subBranch = session1.getBranchManager().getMainBranch().createBranch("sub1");
CDOSession session2 = openSession();
CDOView controlView = openViewWithLockNotifications(session2, subBranch);
- test(session1, controlView, false);
+ if (mode == LockReleaseMode.EXPLICIT)
+ {
+ withExplicitRelease(session1, controlView, false);
+ }
+ else if (mode == LockReleaseMode.AUTO)
+ {
+ withAutoRelease(session1, controlView, false);
+ }
+
session1.close();
session2.close();
}
@@ -74,27 +132,47 @@ public class LockingNotificationsTest extends AbstractLockingTest
@Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
public void testDifferentBranchSameSession() throws CommitException
{
+ differentBranchSameSession(LockReleaseMode.EXPLICIT);
+ }
+
+ @Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
+ public void testDifferentBranchSameSession_autoRelease() throws CommitException
+ {
+ differentBranchSameSession(LockReleaseMode.AUTO);
+ }
+
+ private void differentBranchSameSession(LockReleaseMode mode) throws CommitException
+ {
CDOSession session1 = openSession();
CDOBranch subBranch = session1.getBranchManager().getMainBranch().createBranch("sub2");
CDOView controlView = openViewWithLockNotifications(session1, subBranch);
- test(session1, controlView, false);
+ if (mode == LockReleaseMode.EXPLICIT)
+ {
+ withExplicitRelease(session1, controlView, false);
+ }
+ else if (mode == LockReleaseMode.AUTO)
+ {
+ withAutoRelease(session1, controlView, false);
+ }
+
session1.close();
}
- private void test(CDOSession session1, CDOView controlView, boolean mustReceiveNotifications) throws CommitException
+ private void withExplicitRelease(CDOSession session1, CDOView controlView, boolean mustReceiveNotifications)
+ throws CommitException
{
+ TestListener2 controlViewListener = new TestListener2(CDOViewLocksChangedEvent.class);
+ controlView.addListener(controlViewListener);
+
CDOTransaction tx1 = session1.openTransaction();
CDOResource res1 = tx1.getOrCreateResource(getResourcePath("r1"));
- TestListener2 transactionListener = new TestListener2(CDOLocksChangedEvent.class);
+ TestListener2 transactionListener = new TestListener2(CDOViewLocksChangedEvent.class);
tx1.addListener(transactionListener);
res1.getContents().clear();
Company company = getModel1Factory().createCompany();
res1.getContents().add(company);
tx1.commit();
- TestListener2 controlViewListener = new TestListener2(CDOLocksChangedEvent.class);
- controlView.addListener(controlViewListener);
-
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
CDOObject cdoCompanyInControlView = null;
@@ -111,7 +189,7 @@ public class LockingNotificationsTest extends AbstractLockingTest
controlViewListener.waitFor(1);
assertEquals(1, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(0);
+ CDOViewLocksChangedEvent event = (CDOViewLocksChangedEvent)controlViewListener.getEvents().get(0);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
@@ -128,7 +206,7 @@ public class LockingNotificationsTest extends AbstractLockingTest
assertEquals(2, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(1);
+ CDOViewLocksChangedEvent event = (CDOViewLocksChangedEvent)controlViewListener.getEvents().get(1);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
@@ -146,7 +224,7 @@ public class LockingNotificationsTest extends AbstractLockingTest
controlViewListener.waitFor(3);
assertEquals(3, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(2);
+ CDOViewLocksChangedEvent event = (CDOViewLocksChangedEvent)controlViewListener.getEvents().get(2);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
@@ -165,7 +243,7 @@ public class LockingNotificationsTest extends AbstractLockingTest
assertEquals(4, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(3);
+ CDOViewLocksChangedEvent event = (CDOViewLocksChangedEvent)controlViewListener.getEvents().get(3);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
@@ -182,7 +260,7 @@ public class LockingNotificationsTest extends AbstractLockingTest
controlViewListener.waitFor(5);
assertEquals(5, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(4);
+ CDOViewLocksChangedEvent event = (CDOViewLocksChangedEvent)controlViewListener.getEvents().get(4);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
@@ -199,7 +277,7 @@ public class LockingNotificationsTest extends AbstractLockingTest
assertEquals(6, controlViewListener.getEvents().size());
- CDOLocksChangedEvent event = (CDOLocksChangedEvent)controlViewListener.getEvents().get(5);
+ CDOViewLocksChangedEvent event = (CDOViewLocksChangedEvent)controlViewListener.getEvents().get(5);
assertLockOwner(tx1, event.getLockOwner());
CDOLockState[] lockStates = event.getLockStates();
@@ -217,6 +295,58 @@ public class LockingNotificationsTest extends AbstractLockingTest
}
}
+ private void withAutoRelease(CDOSession session1, CDOView controlView, boolean mustReceiveNotifications)
+ throws CommitException
+ {
+ TestListener2 controlViewListener = new TestListener2(CDOViewLocksChangedEvent.class);
+ controlView.addListener(controlViewListener);
+
+ CDOTransaction tx1 = session1.openTransaction();
+ tx1.options().setAutoReleaseLocksEnabled(true);
+ CDOResource res1 = tx1.getOrCreateResource(getResourcePath("r1"));
+ res1.getContents().clear();
+ Company company = getModel1Factory().createCompany();
+ res1.getContents().add(company);
+ tx1.commit();
+
+ implicitRelease(company, LockType.WRITE, tx1, controlViewListener, mustReceiveNotifications);
+ implicitRelease(company, LockType.READ, tx1, controlViewListener, mustReceiveNotifications);
+ implicitRelease(company, LockType.OPTION, tx1, controlViewListener, mustReceiveNotifications);
+ }
+
+ private void implicitRelease(Company company, LockType type, CDOTransaction tx, TestListener2 controlViewListener,
+ boolean mustReceiveNotifications) throws CommitException
+ {
+ CDOViewLocksChangedEvent e;
+ CDOObject cdoCompany = CDOUtil.getCDOObject(company);
+
+ company.setName(company.getName() + "x"); // Make name field dirty
+ cdoCompany.cdoWriteLock().lock();
+
+ if (mustReceiveNotifications)
+ {
+ controlViewListener.waitFor(1);
+ e = (CDOViewLocksChangedEvent)controlViewListener.getEvents().get(0);
+ assertSame(Operation.LOCK, e.getOperation());
+ assertSame(LockType.WRITE, e.getLockType());
+ }
+
+ tx.commit();
+
+ if (mustReceiveNotifications)
+ {
+ controlViewListener.waitFor(2);
+ e = (CDOViewLocksChangedEvent)controlViewListener.getEvents().get(1);
+ assertSame(Operation.UNLOCK, e.getOperation());
+ assertNull(e.getLockType());
+ }
+
+ if (!mustReceiveNotifications)
+ {
+ assertEquals(0, controlViewListener.getEvents().size());
+ }
+ }
+
private void assertLockedObject(CDOObject obj, Object lockedObject)
{
if (lockedObject instanceof CDOIDAndBranch)
@@ -241,13 +371,13 @@ public class LockingNotificationsTest extends AbstractLockingTest
CDOSession session1 = openSession();
CDOSession session2 = openSession();
CDOView controlView = session2.openView();
- test(session1, controlView, false);
+ withExplicitRelease(session1, controlView, false);
controlView.options().setLockNotificationEnabled(true);
- test(session1, controlView, true);
+ withExplicitRelease(session1, controlView, true);
controlView.options().setLockNotificationEnabled(false);
- test(session1, controlView, false);
+ withExplicitRelease(session1, controlView, false);
session1.close();
session2.close();
@@ -275,7 +405,7 @@ public class LockingNotificationsTest extends AbstractLockingTest
Company company1 = (Company)resource.getContents().get(0);
CDOObject cdoObj = CDOUtil.getCDOObject(company1);
assertEquals(true, cdoObj.cdoWriteLock().isLockedByOthers());
- assertSame(CDOLockOwner.UNKNOWN, cdoObj.cdoLockState().getWriteLockOwner());
+ assertEquals(true, cdoObj.cdoLockState().getWriteLockOwner().isDurableView());
session2.close();
}
@@ -297,7 +427,14 @@ public class LockingNotificationsTest extends AbstractLockingTest
assertClean(cdoObj, tx1);
assertNotNull(cdoObj.cdoLockState());
- res1.getContents().add(company1);
- tx1.commit();
+ session1.close();
+ }
+
+ /**
+ * @author Caspar De Groot
+ */
+ private static enum LockReleaseMode
+ {
+ EXPLICIT, AUTO
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
index 409492315a..4186b96b2c 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
@@ -637,35 +637,40 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
stopMasterTransport();
}
- @Override
- protected InternalRepository createRepository(String name)
+ protected InternalRepository createMasterRepository(String masterName, String name, Map<String, String> props,
+ boolean failover)
{
- boolean failover = getTestFailover();
- Map<String, String> props = getRepositoryProperties();
-
- final String masterName = name + "_master";
IStore masterStore = createStore(masterName);
-
- InternalRepository master;
if (failover)
{
InternalRepositorySynchronizer synchronizer = createSynchronizer("backup", name);
- master = (InternalRepository)CDOServerUtil.createFailoverParticipant(masterName, masterStore, props,
+ return (InternalRepository)CDOServerUtil.createFailoverParticipant(masterName, masterStore, props,
synchronizer, true);
}
- else
- {
- master = (InternalRepository)CDOServerUtil.createRepository(masterName, masterStore, props);
- }
+ return (InternalRepository)CDOServerUtil.createRepository(masterName, masterStore, props);
+ }
+
+ @Override
+ protected InternalRepository createRepository(String name)
+ {
+ boolean failover = getTestFailover();
+ Map<String, String> props = getRepositoryProperties();
+
+ final String masterName = "master";
+ InternalRepository master;
synchronized (repositories)
{
- repositories.put(masterName, master);
+ master = repositories.get(masterName);
+ if (master == null)
+ {
+ master = createMasterRepository(masterName, name, props, failover);
+ repositories.put(masterName, master);
+ LifecycleUtil.activate(master);
+ startMasterTransport();
+ }
}
- LifecycleUtil.activate(master);
- startMasterTransport();
-
InternalRepositorySynchronizer synchronizer = createSynchronizer("master", masterName);
IStore store = createStore(name);
@@ -673,33 +678,31 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
{
return (InternalRepository)CDOServerUtil.createFailoverParticipant(name, store, props, synchronizer, false);
}
- else
+
+ OfflineClone repository = new OfflineClone()
{
- OfflineClone repository = new OfflineClone()
+ @Override
+ public void handleCommitInfo(CDOCommitInfo commitInfo)
{
- @Override
- public void handleCommitInfo(CDOCommitInfo commitInfo)
- {
- waitIfLockAvailable();
- super.handleCommitInfo(commitInfo);
- }
+ waitIfLockAvailable();
+ super.handleCommitInfo(commitInfo);
+ }
- private void waitIfLockAvailable()
+ private void waitIfLockAvailable()
+ {
+ long millis = getTestDelayedCommitHandling();
+ if (millis != 0L)
{
- long millis = getTestDelayedCommitHandling();
- if (millis != 0L)
- {
- ConcurrencyUtil.sleep(millis);
- }
+ ConcurrencyUtil.sleep(millis);
}
- };
+ }
+ };
- repository.setName(name);
- repository.setStore((InternalStore)store);
- repository.setProperties(props);
- repository.setSynchronizer(synchronizer);
- return repository;
- }
+ repository.setName(name);
+ repository.setStore((InternalStore)store);
+ repository.setProperties(props);
+ repository.setSynchronizer(synchronizer);
+ return repository;
}
protected InternalRepositorySynchronizer createSynchronizer(final String acceptorName, final String repositoryName)
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_312879_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_312879_Test.java
index 445bb9c939..2d208c952e 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_312879_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_312879_Test.java
@@ -71,8 +71,7 @@ public class Bugzilla_312879_Test extends AbstractSyncingTest
public void testSwitchMasterAndCommit() throws Exception
{
- InternalSynchronizableRepository repo1_master = (InternalSynchronizableRepository)getRepository(getRepository()
- .getName() + "_master");
+ InternalSynchronizableRepository repo1_master = (InternalSynchronizableRepository)getRepository("master");
InternalSynchronizableRepository repo1 = getRepository();
InternalSynchronizableRepository master = repo1_master;
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_319552_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_319552_Test.java
index 479ff23821..0e532d5455 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_319552_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_319552_Test.java
@@ -42,7 +42,7 @@ public class Bugzilla_319552_Test extends AbstractSyncingTest
InternalRepository clone = getRepository();
waitForOnline(clone);
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOSession session = openSession();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_325097_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_325097_Test.java
index fa8e2f8596..2fab297d66 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_325097_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_325097_Test.java
@@ -77,8 +77,7 @@ public class Bugzilla_325097_Test extends AbstractSyncingTest
public void testNewObjectAfterSwitch() throws Exception
{
- InternalSynchronizableRepository repo1_master = (InternalSynchronizableRepository)getRepository(getRepository()
- .getName() + "_master");
+ InternalSynchronizableRepository repo1_master = (InternalSynchronizableRepository)getRepository("master");
InternalSynchronizableRepository repo1 = getRepository();
InternalSynchronizableRepository master = repo1_master;
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_326047_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_326047_Test.java
index 3961f0e596..d12a932c2d 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_326047_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_326047_Test.java
@@ -48,7 +48,7 @@ public class Bugzilla_326047_Test extends AbstractSyncingTest
InternalRepository clone = getRepository();
waitForOnline(clone);
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOSession session = openSession();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_328352_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_328352_Test.java
index 3011c2df92..37caf351af 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_328352_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_328352_Test.java
@@ -54,7 +54,7 @@ public class Bugzilla_328352_Test extends AbstractSyncingTest
waitForOnline(clone);
// create master session & transaction.
- InternalRepository master = getRepository(clone.getName() + "_master");
+ InternalRepository master = getRepository("master");
CDOSession masterSession = openSession(master.getName());
CDOTransaction masterTransaction = masterSession.openTransaction();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_329014_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_329014_Test.java
index fe48027911..144648c21b 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_329014_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/Bugzilla_329014_Test.java
@@ -61,7 +61,7 @@ public class Bugzilla_329014_Test extends AbstractSyncingTest
cloneSession.options().setPassiveUpdateMode(PassiveUpdateMode.CHANGES);
waitForOnline(clone);
- master = getRepository(clone.getName() + "_master");
+ master = getRepository("master");
masterSession = openSession(master.getName());
masterSession.options().setPassiveUpdateMode(PassiveUpdateMode.CHANGES);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java
index 88c50875c3..69d2d7f10b 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/FailoverTest.java
@@ -69,7 +69,7 @@ public class FailoverTest extends AbstractSyncingTest
public void testMasterCommits_ArrivalInBackup() throws Exception
{
- CDOSession session = openSession(getRepository().getName() + "_master");
+ CDOSession session = openSession("master");
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/my/resource"));
@@ -112,7 +112,7 @@ public class FailoverTest extends AbstractSyncingTest
public void testMasterCommits_NotificationsFromBackup() throws Exception
{
- CDOSession masterSession = openSession(getRepository().getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction transaction = masterSession.openTransaction();
CDOResource resource = transaction.createResource("/my/resource");
@@ -158,8 +158,10 @@ public class FailoverTest extends AbstractSyncingTest
public void testClientCommitsToBackupForbidden() throws Exception
{
- InternalRepository backup = getRepository();
- InternalRepository master = getRepository(backup.getName() + "_master");
+ /* InternalRepository backup = */
+ getRepository();
+
+ InternalRepository master = getRepository("master");
TestListener listener = new TestListener();
CDOSession masterSession = openSession(master.getName());
@@ -189,7 +191,7 @@ public class FailoverTest extends AbstractSyncingTest
public void testPauseMasterTransport() throws Exception
{
- CDOSession session = openSession(getRepository().getName() + "_master");
+ CDOSession session = openSession("master");
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/my/resource"));
@@ -229,7 +231,7 @@ public class FailoverTest extends AbstractSyncingTest
public void testSwitchMaster() throws Exception
{
- CDOSession session = openSession(getRepository().getName() + "_master");
+ CDOSession session = openSession("master");
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/my/resource"));
@@ -262,7 +264,7 @@ public class FailoverTest extends AbstractSyncingTest
try
{
getRepository().setType(CDOCommonRepository.Type.MASTER);
- getRepository(getRepository().getName() + "_master").setType(CDOCommonRepository.Type.BACKUP);
+ getRepository("master").setType(CDOCommonRepository.Type.BACKUP);
company.setName("Commit should fail");
try
@@ -292,7 +294,7 @@ public class FailoverTest extends AbstractSyncingTest
public void testSwitchMasterAndCommit() throws Exception
{
- CDOSession session = openSession(getRepository().getName() + "_master");
+ CDOSession session = openSession("master");
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/my/resource"));
@@ -315,7 +317,7 @@ public class FailoverTest extends AbstractSyncingTest
try
{
getRepository().setType(CDOCommonRepository.Type.MASTER);
- getRepository(getRepository().getName() + "_master").setType(CDOCommonRepository.Type.BACKUP);
+ getRepository("master").setType(CDOCommonRepository.Type.BACKUP);
session.close();
session = openSession();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayed2Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayed2Test.java
index 1bada7bcda..e6b100f9bc 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayed2Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayed2Test.java
@@ -34,8 +34,7 @@ public class OfflineDelayed2Test extends AbstractSyncingTest
{
int nbrOfCommits = 5;
- InternalRepository clone = getRepository();
- InternalRepository master = getRepository(clone.getName() + "_master");
+ InternalRepository master = getRepository("master");
CDOSession masterSession = openSession(master.getName());
CDOTransaction masterTransaction = masterSession.openTransaction();
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java
index ae4dd9193d..a2055ca6e6 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineDelayedTest.java
@@ -43,7 +43,7 @@ public class OfflineDelayedTest extends AbstractSyncingTest
getOfflineConfig().stopMasterTransport();
waitForOffline(clone);
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.createResource("/master/resource");
for (int i = 0; i < 10; i++)
@@ -81,7 +81,7 @@ public class OfflineDelayedTest extends AbstractSyncingTest
waitForOnline(clone);
{
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.createResource("/master/resource");
@@ -131,7 +131,7 @@ public class OfflineDelayedTest extends AbstractSyncingTest
getOfflineConfig().stopMasterTransport();
waitForOffline(clone);
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.createResource("/master/resource");
for (int i = 0; i < 20; i++)
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
index 7983d3919b..6c741957b1 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineLockingTest.java
@@ -11,15 +11,26 @@
package org.eclipse.emf.cdo.tests.offline;
import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.internal.server.syncing.OfflineClone;
import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
+import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.tests.AbstractSyncingTest;
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.CDOLocksChangedEvent;
+import org.eclipse.emf.cdo.util.CommitException;
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.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
/**
* @author Caspar De Groot
@@ -28,9 +39,10 @@ public class OfflineLockingTest extends AbstractSyncingTest
{
public void testLockAndUnlockThrough() throws Exception
{
- CDOSession masterSession = openSession(getRepository().getName() + "_master");
+ assertEquals(true, getRepository("repo1") instanceof OfflineClone);
- CDOSession cloneSession = openSession();
+ CDOSession masterSession = openSession("master");
+ CDOSession cloneSession = openSession("repo1");
waitForOnline(cloneSession.getRepositoryInfo());
CDOTransaction cloneTx = cloneSession.openTransaction();
@@ -44,7 +56,7 @@ public class OfflineLockingTest extends AbstractSyncingTest
CDOView masterView = masterSession.openView();
masterView.options().setLockNotificationEnabled(true);
- TestListener2 masterViewListener = new TestListener2(CDOLocksChangedEvent.class);
+ TestListener2 masterViewListener = new TestListener2(CDOViewLocksChangedEvent.class);
masterView.addListener(masterViewListener);
CDOObject cdoCompanyOnMaster = masterView.getObject(cdoCompany.cdoID());
@@ -60,7 +72,232 @@ public class OfflineLockingTest extends AbstractSyncingTest
masterSession.close();
}
- public void testMasterLocks_ArrivalInClone() throws Exception
+ public void testCloneLocks_arrivalInOtherClone() throws Exception
+ {
+ // Create a 2nd clone repository
+ assertEquals(true, getRepository("repo1") instanceof OfflineClone);
+ assertEquals(true, getRepository("repo2") instanceof OfflineClone);
+
+ CDOSession clone1Session = openSession("repo1");
+ TestListener2 session1lockListener = new TestListener2(CDOSessionLocksChangedEvent.class, "session1lockListener");
+ clone1Session.addListener(session1lockListener);
+ waitForOnline(clone1Session.getRepositoryInfo());
+
+ CDOSession clone2Session = openSession("repo2");
+ TestListener2 session2invalidationListener = new TestListener2(CDOSessionInvalidationEvent.class,
+ "session2invalidationListener");
+ clone2Session.addListener(session2invalidationListener);
+ TestListener2 session2lockListener = new TestListener2(CDOSessionLocksChangedEvent.class, "session2lockListener");
+ clone2Session.addListener(session2lockListener);
+ waitForOnline(clone2Session.getRepositoryInfo());
+
+ CDOTransaction clone1Tx = openTransaction(clone1Session);
+
+ CDOResource resourceInSession1 = clone1Tx.createResource(getResourcePath("test"));
+ Company companyA = getModel1Factory().createCompany();
+ Company companyB = getModel1Factory().createCompany();
+ Company companyC = getModel1Factory().createCompany();
+ resourceInSession1.getContents().add(companyA);
+ resourceInSession1.getContents().add(companyB);
+ resourceInSession1.getContents().add(companyC);
+ clone1Tx.commit();
+
+ CDOObject companyA_session1 = CDOUtil.getCDOObject(companyA);
+ CDOObject companyB_session1 = CDOUtil.getCDOObject(companyB);
+ CDOObject companyC_session1 = CDOUtil.getCDOObject(companyC);
+
+ session2invalidationListener.setTimeout(Integer.MAX_VALUE);
+ session2invalidationListener.waitFor(1); // Wait for the commit notification
+
+ CDOTransaction clone2Tx = openTransaction(clone2Session);
+
+ CDOResource resourceInSession2 = clone2Tx.getResource(getResourcePath("test"));
+ CDOObject companyA_session2 = CDOUtil.getCDOObject(resourceInSession2.getContents().get(0));
+ CDOObject companyB_session2 = CDOUtil.getCDOObject(resourceInSession2.getContents().get(1));
+ CDOObject companyC_session2 = CDOUtil.getCDOObject(resourceInSession2.getContents().get(2));
+
+ CDOSessionLocksChangedEvent e;
+
+ // Verify that thusfar we haven't received any locking events in session 1
+ assertEquals(0, session1lockListener.getEvents().size());
+
+ // Perform the lock in session 2, connected to clone 2
+ companyA_session2.cdoWriteLock().lock();
+
+ // Wait for the lock notification in session 1, which is connected to clone 1
+ session1lockListener.waitFor(1);
+
+ e = (CDOSessionLocksChangedEvent)session1lockListener.getEvents().get(0);
+ assertSame(LockType.WRITE, e.getLockType());
+ assertSame(Operation.LOCK, e.getOperation());
+ assertEquals(true, companyA_session1.cdoWriteLock().isLockedByOthers());
+
+ // Perform the unlock in session 2, connected to clone 2
+ companyA_session2.cdoWriteLock().unlock();
+
+ // Wait for the lock notification in session 1, which is connected to clone 1
+ session1lockListener.waitFor(2);
+
+ e = (CDOSessionLocksChangedEvent)session1lockListener.getEvents().get(1);
+ assertSame(LockType.WRITE, e.getLockType());
+ assertSame(Operation.UNLOCK, e.getOperation());
+ assertEquals(false, companyA_session1.cdoWriteLock().isLockedByOthers());
+
+ // Now vice versa . . .
+
+ session2lockListener.getEvents().clear();
+
+ // Perform the lock in session 1, connected to clone 1
+ companyA_session1.cdoWriteLock().lock();
+
+ // Wait for the lock notification in session 2, which is connected to clone 2
+ session2lockListener.waitFor(1);
+
+ e = (CDOSessionLocksChangedEvent)session2lockListener.getEvents().get(0);
+ assertSame(LockType.WRITE, e.getLockType());
+ assertSame(Operation.LOCK, e.getOperation());
+ assertEquals(true, companyA_session2.cdoWriteLock().isLockedByOthers());
+
+ // Perform the unlock in session 1, connected to clone 1
+ companyA_session1.cdoWriteLock().unlock();
+
+ // Wait for the lock notification in session 1, which is connected to clone 1
+ session2lockListener.waitFor(2);
+
+ e = (CDOSessionLocksChangedEvent)session2lockListener.getEvents().get(1);
+ assertSame(LockType.WRITE, e.getLockType());
+ assertSame(Operation.UNLOCK, e.getOperation());
+ assertEquals(false, companyA_session2.cdoWriteLock().isLockedByOthers());
+
+ // Now try an unlock-all . . .
+
+ session1lockListener.getEvents().clear();
+
+ companyA_session2.cdoReadLock().lock();
+ companyB_session2.cdoWriteLock().lock();
+ companyC_session2.cdoWriteOption().lock();
+
+ session1lockListener.waitFor(3);
+
+ assertEquals(true, companyA_session1.cdoReadLock().isLockedByOthers());
+ assertEquals(true, companyB_session1.cdoWriteLock().isLockedByOthers());
+ assertEquals(true, companyC_session1.cdoWriteOption().isLockedByOthers());
+
+ clone2Tx.unlockObjects();
+
+ session1lockListener.waitFor(4);
+
+ assertEquals(false, companyA_session1.cdoReadLock().isLockedByOthers());
+ assertEquals(false, companyA_session1.cdoWriteLock().isLockedByOthers());
+ assertEquals(false, companyA_session1.cdoWriteOption().isLockedByOthers());
+
+ clone1Session.close();
+ clone2Session.close();
+ }
+
+ public void testCloneLocks_replicationToOtherClone() throws CommitException
+ {
+ InternalRepository repo1 = getRepository("repo1");
+ assertEquals(true, repo1 instanceof OfflineClone);
+ InternalRepository repo2 = getRepository("repo2");
+ assertEquals(true, repo2 instanceof OfflineClone);
+
+ OfflineClone clone2 = (OfflineClone)repo2;
+
+ waitForOnline(getRepository("repo1"));
+ waitForOnline(getRepository("repo2"));
+
+ CDOSession clone1session = openSession("repo1");
+
+ // Store 3 objects in repo1
+ CDOTransaction tx1_sess1 = openTransaction(clone1session);
+ CDOResource resource_tx1_sess1 = tx1_sess1.createResource(getResourcePath("test"));
+ Company companyA = getModel1Factory().createCompany();
+ Company companyB = getModel1Factory().createCompany();
+ Company companyC = getModel1Factory().createCompany();
+ resource_tx1_sess1.getContents().add(companyA);
+ resource_tx1_sess1.getContents().add(companyB);
+ resource_tx1_sess1.getContents().add(companyC);
+ tx1_sess1.commit();
+
+ {
+ // Verify that they're visible in repo2
+ CDOSession clone2session = openSession("repo2");
+ CDOTransaction tx1_sess2 = openTransaction(clone2session);
+ CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
+ assertEquals(3, resource_tx1_sess2.getContents().size());
+ tx1_sess2.close();
+ clone2session.close();
+ }
+
+ clone2.goOffline();
+ waitForOffline(clone2);
+
+ // Lock the objects in repo1. Since repo1 is ONLINE, this will also lock them
+ // in the master.
+ CDOUtil.getCDOObject(companyA).cdoReadLock().lock();
+ CDOUtil.getCDOObject(companyB).cdoWriteLock().lock();
+ CDOUtil.getCDOObject(companyC).cdoWriteOption().lock();
+
+ clone2.goOnline();
+ waitForOnline(clone2);
+
+ {
+ // Verify that the locks are visible in repo2
+ CDOSession clone2session = openSession("repo2");
+ CDOTransaction tx1_sess2 = openTransaction(clone2session);
+ CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
+ EList<EObject> contents = resource_tx1_sess2.getContents();
+ CDOObject companyA_in_sess2 = CDOUtil.getCDOObject(contents.get(0));
+ CDOObject companyB_in_sess2 = CDOUtil.getCDOObject(contents.get(1));
+ CDOObject companyC_in_sess2 = CDOUtil.getCDOObject(contents.get(2));
+
+ assertEquals(true, companyA_in_sess2.cdoReadLock().isLockedByOthers());
+ assertEquals(true, companyB_in_sess2.cdoWriteLock().isLockedByOthers());
+ assertEquals(true, companyC_in_sess2.cdoWriteOption().isLockedByOthers());
+
+ tx1_sess2.close();
+ clone2session.close();
+ }
+
+ clone2.goOffline();
+ waitForOffline(clone2);
+
+ // Unlock the objects in repo1. Since repo1 is ONLINE, this will also lock them
+ // in the master.
+ CDOUtil.getCDOObject(companyA).cdoReadLock().unlock();
+ CDOUtil.getCDOObject(companyB).cdoWriteLock().unlock();
+ CDOUtil.getCDOObject(companyC).cdoWriteOption().unlock();
+
+ clone2.goOnline();
+ waitForOnline(clone2);
+
+ {
+ // Verify in repo2
+ CDOSession clone2session = openSession("repo2");
+ CDOTransaction tx1_sess2 = openTransaction(clone2session);
+ CDOResource resource_tx1_sess2 = tx1_sess2.getResource(getResourcePath("test"));
+ EList<EObject> contents = resource_tx1_sess2.getContents();
+ CDOObject companyA_in_sess2 = CDOUtil.getCDOObject(contents.get(0));
+ CDOObject companyB_in_sess2 = CDOUtil.getCDOObject(contents.get(1));
+ CDOObject companyC_in_sess2 = CDOUtil.getCDOObject(contents.get(2));
+
+ assertEquals(false, companyA_in_sess2.cdoReadLock().isLockedByOthers());
+ assertEquals(false, companyB_in_sess2.cdoWriteLock().isLockedByOthers());
+ assertEquals(false, companyC_in_sess2.cdoWriteOption().isLockedByOthers());
+
+ tx1_sess2.close();
+ clone2session.close();
+ }
+
+ clone1session.close();
+ }
+
+ private static CDOTransaction openTransaction(CDOSession session)
{
+ CDOTransaction tx = session.openTransaction();
+ tx.options().setLockNotificationEnabled(true);
+ tx.enableDurableLocking(true);
+ return tx;
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineRawTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineRawTest.java
index a23a1aa775..e9f3d02e8b 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineRawTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineRawTest.java
@@ -69,7 +69,7 @@ public class OfflineRawTest extends OfflineTest
transaction.addListener(transactionListener);
{
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.getResource("/my/resource");
@@ -136,7 +136,7 @@ public class OfflineRawTest extends OfflineTest
transaction.addListener(transactionListener);
{
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.getResource("/my/resource");
@@ -198,7 +198,7 @@ public class OfflineRawTest extends OfflineTest
waitForOffline(clone);
{
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.getResource("/my/resource");
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java
index 5c848502cc..8787e1a332 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/offline/OfflineTest.java
@@ -40,7 +40,7 @@ public class OfflineTest extends AbstractSyncingTest
{
public void testMasterCommits_ArrivalInClone() throws Exception
{
- CDOSession session = openSession(getRepository().getName() + "_master");
+ CDOSession session = openSession("master");
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource("/my/resource");
@@ -83,7 +83,7 @@ public class OfflineTest extends AbstractSyncingTest
protected void masterCommits_NotificationsFromClone() throws Exception
{
- CDOSession masterSession = openSession(getRepository().getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction transaction = masterSession.openTransaction();
CDOResource resource = transaction.createResource("/my/resource");
@@ -130,7 +130,7 @@ public class OfflineTest extends AbstractSyncingTest
public void testClientCommits() throws Exception
{
InternalRepository clone = getRepository();
- InternalRepository master = getRepository(clone.getName() + "_master");
+ InternalRepository master = getRepository("master");
TestListener listener = new TestListener();
CDOSession masterSession = openSession(master.getName());
@@ -165,7 +165,7 @@ public class OfflineTest extends AbstractSyncingTest
getOfflineConfig().stopMasterTransport();
waitForOffline(clone);
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.createResource("/master/resource");
@@ -205,7 +205,7 @@ public class OfflineTest extends AbstractSyncingTest
getOfflineConfig().stopMasterTransport();
waitForOffline(clone);
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.createResource("/master/resource");
@@ -238,7 +238,7 @@ public class OfflineTest extends AbstractSyncingTest
getOfflineConfig().stopMasterTransport();
waitForOffline(clone);
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction masterTransaction = masterSession.openTransaction();
CDOResource masterResource = masterTransaction.createResource("/master/resource");
@@ -356,7 +356,7 @@ public class OfflineTest extends AbstractSyncingTest
getOfflineConfig().stopMasterTransport();
waitForOffline(clone);
- CDOSession masterSession = openSession(clone.getName() + "_master");
+ CDOSession masterSession = openSession("master");
CDOTransaction transaction = masterSession.openTransaction();
CDOResource resource = transaction.createResource("/my/resource");
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 b05050dac8..3e77c7ca93 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
@@ -24,18 +24,31 @@ import junit.framework.Assert;
*/
public class TestListener2 implements IListener
{
+ private final static long DEFAULT_TIMEOUT = 3000; // 3 seconds
+
private List<IEvent> events = new LinkedList<IEvent>();
private Class<? extends IEvent> eventClass;
+ private long timeout;
+
+ private String name;
+
public TestListener2(Class<? extends IEvent> eventClass)
{
+ this(eventClass, null);
+ }
+
+ public TestListener2(Class<? extends IEvent> eventClass, String name)
+ {
this.eventClass = eventClass;
+ this.name = name;
+ timeout = DEFAULT_TIMEOUT;
}
public synchronized void notifyEvent(IEvent event)
{
- if (eventClass.isAssignableFrom(event.getClass()))
+ if (eventClass == null || eventClass.isAssignableFrom(event.getClass()))
{
events.add(event);
notify();
@@ -47,9 +60,13 @@ public class TestListener2 implements IListener
return events;
}
- public synchronized void waitFor(int n)
+ public void setTimeout(long timeout)
+ {
+ this.timeout = timeout;
+ }
+
+ public synchronized void waitFor(int n, long timeout)
{
- long timeout = 2000;
long t = 0;
while (events.size() < n)
@@ -72,4 +89,35 @@ public class TestListener2 implements IListener
timeout -= System.currentTimeMillis() - t;
}
}
+
+ public void waitFor(int i)
+ {
+ waitFor(i, timeout);
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder(TestListener2.class.getSimpleName());
+ builder.append('[');
+ if (name != null)
+ {
+ builder.append("name=\"");
+ builder.append(name);
+ builder.append('\"');
+ }
+
+ if (eventClass != null)
+ {
+ if (builder.charAt(builder.length() - 1) != '[')
+ {
+ builder.append(';');
+ }
+ builder.append("eventClass=");
+ builder.append(eventClass.getSimpleName());
+ }
+
+ builder.append(']');
+ return builder.toString();
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionConfiguration.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionConfiguration.java
index 81c2408d9e..f9b3b7a379 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionConfiguration.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/util/TestSessionConfiguration.java
@@ -10,6 +10,7 @@
*/
package org.eclipse.emf.cdo.tests.util;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
import org.eclipse.emf.cdo.common.protocol.CDOAuthenticator;
@@ -23,47 +24,52 @@ import org.eclipse.net4j.util.event.Notifier;
*/
public abstract class TestSessionConfiguration extends Notifier implements CDOSessionConfiguration
{
- public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode)
+ public boolean isSessionOpen()
{
throw new UnsupportedOperationException();
}
- public void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
+ public boolean isActivateOnOpen()
{
throw new UnsupportedOperationException();
}
- public void setExceptionHandler(CDOSession.ExceptionHandler exceptionHandler)
+ public void setActivateOnOpen(boolean activateOnOpen)
{
throw new UnsupportedOperationException();
}
- public void setIDGenerator(CDOIDGenerator idGenerator)
+ public CDOAuthenticator getAuthenticator()
{
throw new UnsupportedOperationException();
}
- public void setActivateOnOpen(boolean activateOnOpen)
+ public boolean isPassiveUpdateEnabled()
{
throw new UnsupportedOperationException();
}
- public boolean isSessionOpen()
+ public void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
{
throw new UnsupportedOperationException();
}
- public boolean isPassiveUpdateEnabled()
+ public PassiveUpdateMode getPassiveUpdateMode()
{
throw new UnsupportedOperationException();
}
- public boolean isActivateOnOpen()
+ public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode)
{
throw new UnsupportedOperationException();
}
- public PassiveUpdateMode getPassiveUpdateMode()
+ public LockNotificationMode getLockNotificationMode()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setLockNotificationMode(LockNotificationMode mode)
{
throw new UnsupportedOperationException();
}
@@ -73,12 +79,17 @@ public abstract class TestSessionConfiguration extends Notifier implements CDOSe
throw new UnsupportedOperationException();
}
+ public void setExceptionHandler(CDOSession.ExceptionHandler exceptionHandler)
+ {
+ throw new UnsupportedOperationException();
+ }
+
public CDOIDGenerator getIDGenerator()
{
throw new UnsupportedOperationException();
}
- public CDOAuthenticator getAuthenticator()
+ public void setIDGenerator(CDOIDGenerator idGenerator)
{
throw new UnsupportedOperationException();
}
diff --git a/plugins/org.eclipse.emf.cdo/.settings/.api_filters b/plugins/org.eclipse.emf.cdo/.settings/.api_filters
index c9ee6895d7..19ffeb033c 100644
--- a/plugins/org.eclipse.emf.cdo/.settings/.api_filters
+++ b/plugins/org.eclipse.emf.cdo/.settings/.api_filters
@@ -60,6 +60,14 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java" type="org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent">
+ <filter id="571473929">
+ <message_arguments>
+ <message_argument value="CDOLockChangeInfo"/>
+ <message_argument value="CDOSessionLocksChangedEvent"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java" type="org.eclipse.emf.cdo.transaction.CDOPushTransaction">
<filter id="574660632">
<message_arguments>
@@ -91,33 +99,35 @@
</message_arguments>
</filter>
</resource>
- <resource path="src/org/eclipse/emf/cdo/view/CDOLocksChangedEvent.java" type="org.eclipse.emf.cdo.view.CDOLocksChangedEvent">
+ <resource path="src/org/eclipse/emf/cdo/view/CDOQuery.java" type="org.eclipse.emf.cdo.view.CDOQuery">
<filter id="571473929">
<message_arguments>
- <message_argument value="CDOBranchPoint"/>
- <message_argument value="CDOLocksChangedEvent"/>
+ <message_argument value="CDOQueryInfo"/>
+ <message_argument value="CDOQuery"/>
</message_arguments>
</filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/view/CDOView.java" type="org.eclipse.emf.cdo.view.CDOView">
<filter id="571473929">
<message_arguments>
- <message_argument value="CDOLockChangeInfo"/>
- <message_argument value="CDOLocksChangedEvent"/>
+ <message_argument value="CDOCommonView"/>
+ <message_argument value="CDOView"/>
</message_arguments>
</filter>
</resource>
- <resource path="src/org/eclipse/emf/cdo/view/CDOQuery.java" type="org.eclipse.emf.cdo.view.CDOQuery">
+ <resource path="src/org/eclipse/emf/cdo/view/CDOView.java" type="org.eclipse.emf.cdo.view.CDOView$Options">
<filter id="571473929">
<message_arguments>
- <message_argument value="CDOQueryInfo"/>
- <message_argument value="CDOQuery"/>
+ <message_argument value="Options"/>
+ <message_argument value="Options"/>
</message_arguments>
</filter>
</resource>
- <resource path="src/org/eclipse/emf/cdo/view/CDOView.java" type="org.eclipse.emf.cdo.view.CDOView">
+ <resource path="src/org/eclipse/emf/cdo/view/CDOViewLocksChangedEvent.java" type="org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent">
<filter id="571473929">
<message_arguments>
- <message_argument value="CDOCommonView"/>
- <message_argument value="CDOView"/>
+ <message_argument value="CDOLockChangeInfo"/>
+ <message_argument value="CDOViewLocksChangedEvent"/>
</message_arguments>
</filter>
</resource>
@@ -157,6 +167,14 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java" type="org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent">
+ <filter id="574619656">
+ <message_arguments>
+ <message_argument value="CDOLockChangeInfo"/>
+ <message_argument value="DefaultLocksChangedEvent"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java" type="org.eclipse.emf.internal.cdo.view.AbstractCDOView">
<filter id="574660632">
<message_arguments>
@@ -166,6 +184,15 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java" type="org.eclipse.emf.internal.cdo.view.CDOViewImpl$OptionsImpl">
+ <filter id="574660632">
+ <message_arguments>
+ <message_argument value="Options"/>
+ <message_argument value="Options"/>
+ <message_argument value="OptionsImpl"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java" type="org.eclipse.emf.spi.cdo.CDOSessionProtocol">
<filter id="571473929">
<message_arguments>
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionConfiguration.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionConfiguration.java
index 02912bb8ff..c219833a51 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionConfiguration.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionConfiguration.java
@@ -10,6 +10,7 @@
*/
package org.eclipse.emf.cdo.session;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
import org.eclipse.emf.cdo.common.protocol.CDOAuthenticator;
@@ -52,6 +53,16 @@ public interface CDOSessionConfiguration extends INotifier
public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode);
/**
+ * @since 4.1
+ */
+ public LockNotificationMode getLockNotificationMode();
+
+ /**
+ * @since 4.1
+ */
+ public void setLockNotificationMode(LockNotificationMode mode);
+
+ /**
* @see CDOSession#getExceptionHandler()
*/
public CDOSession.ExceptionHandler getExceptionHandler();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java
new file mode 100644
index 0000000000..90faae741d
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSessionLocksChangedEvent.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2004 - 2011 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:
+ * Caspar De Groot - initial API and implementation
+ */
+package org.eclipse.emf.cdo.session;
+
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.view.CDOView;
+
+/**
+ * @author Caspar De Groot
+ * @since 4.1
+ */
+public interface CDOSessionLocksChangedEvent extends CDOSessionEvent, CDOLockChangeInfo
+{
+ /**
+ * Returns the view that caused the lock changes if this view is local, or <code>null</code> if the view was remote.
+ */
+ public CDOView getSender();
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
index 4d74a8f3c2..100d1a4f65 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
@@ -21,7 +21,6 @@ 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.lock.CDOLockState;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.eresource.CDOResource;
@@ -35,10 +34,7 @@ import org.eclipse.emf.cdo.util.ReadOnlyException;
import org.eclipse.net4j.util.collection.CloseableIterator;
import org.eclipse.net4j.util.concurrent.IRWLockManager;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.event.INotifier;
-import org.eclipse.net4j.util.options.IOptions;
-import org.eclipse.net4j.util.options.IOptionsContainer;
import org.eclipse.net4j.util.options.IOptionsEvent;
import org.eclipse.net4j.util.ref.ReferenceType;
@@ -76,7 +72,7 @@ import java.util.Set;
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface CDOView extends CDOCommonView, CDOUpdatable, INotifier, IOptionsContainer
+public interface CDOView extends CDOCommonView, CDOUpdatable, INotifier
{
/**
* Returns the {@link CDOSession session} this view was opened by.
@@ -406,7 +402,7 @@ public interface CDOView extends CDOCommonView, CDOUpdatable, INotifier, IOption
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
- public interface Options extends IOptions
+ public interface Options extends org.eclipse.emf.cdo.common.CDOCommonView.Options
{
/**
* Returns the {@link CDOView view} of this options object.
@@ -468,27 +464,6 @@ public interface CDOView extends CDOCommonView, CDOUpdatable, INotifier, IOption
public void setInvalidationNotificationEnabled(boolean enabled);
/**
- * Returns <code>true</code> if this view will notify its {@link IListener listeners} about changes to the
- * {@link CDOLockState lock states} of the objects in this view (due to lock operations in <i>other</i> views),
- * <code>false</code> otherwise.
- *
- * @see CDOLocksChangedEvent
- * @see CDOLockState
- * @since 4.1
- */
- public boolean isLockNotificationEnabled();
-
- /**
- * Specifies whether this view will notify its {@link IListener listeners} about changes to the {@link CDOLockState
- * lock states} of the objects in this view (due to lock operations in <i>other</i> views), or not.
- *
- * @see CDOLocksChangedEvent
- * @see CDOLockState
- * @since 4.1
- */
- public void setLockNotificationEnabled(boolean enabled);
-
- /**
* Returns the current set of {@link CDOAdapterPolicy change subscription policies}.
*
* @return The current set of change subscription policies, never <code>null</code>.
@@ -669,14 +644,6 @@ public interface CDOView extends CDOCommonView, CDOUpdatable, INotifier, IOption
}
/**
- * @author Caspar De Groot
- * @since 4.1
- */
- public interface LockNotificationEvent extends IOptionsEvent
- {
- }
-
- /**
* An {@link IOptionsEvent options event} fired from view {@link CDOView#options() options} when the
* {@link Options#setRevisionPrefetchingPolicy(CDORevisionPrefetchingPolicy) revision prefetching policy} option has
* changed.
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOLocksChangedEvent.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOViewLocksChangedEvent.java
index 904dabbaaf..8bdb7d8005 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOLocksChangedEvent.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOViewLocksChangedEvent.java
@@ -13,12 +13,13 @@ package org.eclipse.emf.cdo.view;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
/**
- * A {@link CDOViewEvent view event} fired when lock notifications are being received from a repository.
- * {@link CDOView.Options#setLockNotificationEnabled(boolean)} must be enabled for this event to be fired.
- *
* @author Caspar De Groot
* @since 4.1
*/
-public interface CDOLocksChangedEvent extends CDOViewEvent, CDOLockChangeInfo
+public interface CDOViewLocksChangedEvent extends CDOViewEvent, CDOLockChangeInfo
{
+ /**
+ * Returns the view that caused the lock changes if this view is local, or <code>null</code> if the view was remote.
+ */
+ public CDOView getSender();
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionConfigurationImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionConfigurationImpl.java
index 607d3855fe..3bb1caf936 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionConfigurationImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionConfigurationImpl.java
@@ -10,6 +10,7 @@
*/
package org.eclipse.emf.internal.cdo.session;
+import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfoManager;
@@ -43,6 +44,8 @@ public abstract class CDOSessionConfigurationImpl extends Notifier implements In
private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;
+ private LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS;
+
private CDOAuthenticator authenticator = new CDOAuthenticatorImpl();
private CDOSession.ExceptionHandler exceptionHandler;
@@ -120,6 +123,22 @@ public abstract class CDOSessionConfigurationImpl extends Notifier implements In
this.passiveUpdateMode = passiveUpdateMode;
}
+ public LockNotificationMode getLockNotificationMode()
+ {
+ return lockNotificationMode;
+ }
+
+ public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
+ {
+ checkNotOpen();
+ uncheckedSetLockNotificationMode(lockNotificationMode);
+ }
+
+ protected void uncheckedSetLockNotificationMode(LockNotificationMode lockNotificationMode)
+ {
+ this.lockNotificationMode = lockNotificationMode;
+ }
+
public CDOAuthenticator getAuthenticator()
{
return authenticator;
@@ -272,6 +291,7 @@ public abstract class CDOSessionConfigurationImpl extends Notifier implements In
{
session.options().setPassiveUpdateEnabled(passiveUpdateEnabled);
session.options().setPassiveUpdateMode(passiveUpdateMode);
+ session.options().setLockNotificationMode(lockNotificationMode);
session.setMainBranchLocal(mainBranchLocal);
session.setExceptionHandler(exceptionHandler);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
index 0c3f04c28c..4e5b154dff 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
@@ -57,6 +57,7 @@ import org.eclipse.emf.cdo.session.CDOCollectionLoadingPolicy;
import org.eclipse.emf.cdo.session.CDORepositoryInfo;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
+import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
import org.eclipse.emf.cdo.session.remote.CDORemoteSessionManager;
import org.eclipse.emf.cdo.spi.common.CDOLobStoreImpl;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
@@ -83,6 +84,7 @@ import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.messages.Messages;
import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
import org.eclipse.emf.internal.cdo.session.remote.CDORemoteSessionManagerImpl;
+import org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
@@ -836,12 +838,17 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
}
}
- public void handleLockNotification(CDOLockChangeInfo lockChangeInfo)
+ public void handleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender)
{
for (InternalCDOView view : getViews())
{
- view.handleLockNotification(lockChangeInfo);
+ if (view != sender)
+ {
+ view.handleLockNotification(sender, lockChangeInfo);
+ }
}
+
+ fireEvent(new LocksChangedEvent(sender, lockChangeInfo));
}
private void registerPackageUnits(List<CDOPackageUnit> packageUnits)
@@ -1334,6 +1341,8 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;
+ private LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS;
+
private CDOCollectionLoadingPolicy collectionLoadingPolicy;
private CDOLobStore lobCache = CDOLobStoreImpl.INSTANCE;
@@ -1429,6 +1438,16 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
}
}
+ public LockNotificationMode getLockNotificationMode()
+ {
+ return lockNotificationMode;
+ }
+
+ public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
+ {
+ this.lockNotificationMode = lockNotificationMode;
+ }
+
public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
{
synchronized (this)
@@ -1717,4 +1736,24 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme
return "CDOSessionInvalidationEvent[" + commitInfo + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
+
+ /**
+ * @author Caspar De Groot
+ * @since 4.1
+ */
+ private final class LocksChangedEvent extends DefaultLocksChangedEvent implements CDOSessionLocksChangedEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ public LocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
+ {
+ super(CDOSessionImpl.this, sender, lockChangeInfo);
+ }
+
+ @Override
+ public CDOSession getSource()
+ {
+ return (CDOSession)super.getSource();
+ }
+ }
}
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 0d1a9d2329..73d8546d3a 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
@@ -34,6 +34,7 @@ import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lob.CDOLob;
import org.eclipse.emf.cdo.common.lob.CDOLobStore;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
@@ -2652,7 +2653,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
CDOLockState[] newLockStates = result.getNewLockStates();
if (newLockStates != null)
{
- updateLockStates(newLockStates);
+ updateAndNotifyLockStates(Operation.UNLOCK, null, newLockStates);
}
}
catch (RuntimeException ex)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java
new file mode 100644
index 0000000000..3a3577d454
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/DefaultLocksChangedEvent.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2004 - 2011 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.internal.cdo.util;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.event.Event;
+import org.eclipse.net4j.util.event.INotifier;
+
+import org.eclipse.emf.spi.cdo.InternalCDOView;
+
+/**
+ * @author Caspar De Groot
+ * @since 4.1
+ */
+public class DefaultLocksChangedEvent extends Event implements CDOLockChangeInfo
+{
+ private static final long serialVersionUID = 1L;
+
+ private final InternalCDOView sender;
+
+ private final CDOLockChangeInfo lockChangeInfo;
+
+ public DefaultLocksChangedEvent(INotifier notifier, InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
+ {
+ super(notifier);
+ this.sender = sender;
+ this.lockChangeInfo = lockChangeInfo;
+ }
+
+ public InternalCDOView getSender()
+ {
+ return sender;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return lockChangeInfo.getBranch();
+ }
+
+ public long getTimeStamp()
+ {
+ return lockChangeInfo.getTimeStamp();
+ }
+
+ public CDOLockOwner getLockOwner()
+ {
+ return lockChangeInfo.getLockOwner();
+ }
+
+ public CDOLockState[] getLockStates()
+ {
+ return lockChangeInfo.getLockStates();
+ }
+
+ public Operation getOperation()
+ {
+ return lockChangeInfo.getOperation();
+ }
+
+ public LockType getLockType()
+ {
+ return lockChangeInfo.getLockType();
+ }
+}
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 2c481cdf2d..8137cbc8a4 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
@@ -208,6 +208,11 @@ public abstract class AbstractCDOView extends Lifecycle implements InternalCDOVi
if (rootResource == null)
{
CDOID rootResourceID = getSession().getRepositoryInfo().getRootResourceID();
+ if (rootResourceID == null || rootResourceID.isNull())
+ {
+ throw new IllegalStateException("RootResourceID is null; is the repository not yet initialized?");
+ }
+
CDOResourceImpl resource = (CDOResourceImpl)getObject(rootResourceID);
setRootResource(resource);
}
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 ccf4144098..5f6be8a610 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
@@ -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.id.CDOID;
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.common.lock.CDOLockUtil;
@@ -41,18 +42,19 @@ import org.eclipse.emf.cdo.util.StaleRevisionLockException;
import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
import org.eclipse.emf.cdo.view.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.view.CDOInvalidationPolicy;
-import org.eclipse.emf.cdo.view.CDOLocksChangedEvent;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewDurabilityChangedEvent;
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
+import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.messages.Messages;
import org.eclipse.emf.internal.cdo.object.CDODeltaNotificationImpl;
import org.eclipse.emf.internal.cdo.object.CDOInvalidationNotificationImpl;
import org.eclipse.emf.internal.cdo.object.CDONotificationBuilder;
+import org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
@@ -86,6 +88,7 @@ import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
+import org.eclipse.emf.spi.cdo.InternalCDOView;
import org.eclipse.core.runtime.NullProgressMonitor;
@@ -293,7 +296,8 @@ public class CDOViewImpl extends AbstractCDOView
throw new AssertionError("Unexpected lock result state");
}
- updateLockStates(result.getNewLockStates());
+ // Update the lock states in this view
+ updateAndNotifyLockStates(Operation.LOCK, lockType, result.getNewLockStates());
if (result.isWaitForUpdate())
{
@@ -308,6 +312,15 @@ public class CDOViewImpl extends AbstractCDOView
}
}
+ protected void updateAndNotifyLockStates(Operation op, LockType type, CDOLockState[] newLockStates)
+ {
+ updateLockStates(newLockStates);
+ notifyOtherViewsAboutLockChanges(op, type, newLockStates);
+ }
+
+ /**
+ * Updates the lock states of objects held in this view
+ */
protected void updateLockStates(CDOLockState[] newLockStates)
{
for (CDOLockState lockState : newLockStates)
@@ -331,6 +344,60 @@ public class CDOViewImpl extends AbstractCDOView
}
}
+ /**
+ * Notifies other views of lock changes performed in this view
+ */
+ private void notifyOtherViewsAboutLockChanges(Operation op, LockType type, CDOLockState[] lockStates)
+ {
+ if (lockStates.length > 0)
+ {
+ CDOLockChangeInfo lockChangeInfo = makeLockChangeInfo(op, type, lockStates);
+ getSession().handleLockNotification(lockChangeInfo, this);
+ }
+ }
+
+ private CDOLockChangeInfo makeLockChangeInfo(Operation op, LockType type, CDOLockState[] newLockStates)
+ {
+ long timestamp = 0L; // TODO (CD) Get rid of timestamps; replace with sequential number
+ return CDOLockUtil.createLockChangeInfo(timestamp, this, getBranch(), op, type, newLockStates);
+ }
+
+ public void handleLockNotification(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
+ {
+ if (!options().isLockNotificationEnabled())
+ {
+ return;
+ }
+
+ // If lockChangeInfo pertains to a different view, do nothing.
+ if (!lockChangeInfo.getBranch().equals(getBranch()))
+ {
+ return;
+ }
+
+ // If lockChangeInfo represents lock changes authored by this view itself, do nothing.
+ CDOLockOwner thisView = CDOLockUtil.createLockOwner(this);
+ if (lockChangeInfo.getLockOwner().equals(thisView))
+ {
+ return;
+ }
+
+ // TODO (CD) I know it is Eike's desideratum that this be done asynchronously.. but beware,
+ // this will require the tests to be fixed to listen for the view events instead of the
+ // session events.
+ updateLockStates(lockChangeInfo.getLockStates());
+ fireLocksChangedEvent(sender, lockChangeInfo);
+ }
+
+ private void fireLocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
+ {
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ fireEvent(new LocksChangedEvent(sender, lockChangeInfo), listeners);
+ }
+ }
+
protected InternalCDORevision getRevision(CDOObject object)
{
if (object.cdoState() == CDOState.NEW)
@@ -367,7 +434,7 @@ public class CDOViewImpl extends AbstractCDOView
CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
UnlockObjectsResult result = sessionProtocol.unlockObjects2(this, objectIDs, lockType);
- updateLockStates(result.getNewLockStates());
+ updateAndNotifyLockStates(Operation.UNLOCK, lockType, result.getNewLockStates());
}
/**
@@ -928,39 +995,6 @@ public class CDOViewImpl extends AbstractCDOView
}
}
- public void handleLockNotification(CDOLockChangeInfo lockChangeInfo)
- {
- if (!options().isLockNotificationEnabled())
- {
- return;
- }
-
- // If lockChangeInfo pertains to a different view, do nothing.
- if (!lockChangeInfo.getBranch().equals(getBranch()))
- {
- return;
- }
-
- // If lockChangeInfo represents lock changes authored by this view itself, do nothing.
- CDOLockOwner thisView = CDOLockUtil.createLockOwner(this);
- if (lockChangeInfo.getLockOwner().equals(thisView))
- {
- return;
- }
-
- updateLockStates(lockChangeInfo.getLockStates());
- fireLocksChangedEvent(lockChangeInfo);
- }
-
- private void fireLocksChangedEvent(CDOLockChangeInfo lockChangeInfo)
- {
- IListener[] listeners = getListeners();
- if (listeners != null)
- {
- fireEvent(new LocksChangedEvent(lockChangeInfo), listeners);
- }
- }
-
/**
* @author Simon McDuff
* @since 2.0
@@ -1392,40 +1426,19 @@ public class CDOViewImpl extends AbstractCDOView
* @author Caspar De Groot
* @since 4.1
*/
- private final class LocksChangedEvent extends Event implements CDOLocksChangedEvent
+ private final class LocksChangedEvent extends DefaultLocksChangedEvent implements CDOViewLocksChangedEvent
{
private static final long serialVersionUID = 1L;
- private CDOLockChangeInfo lockChangeInfo;
-
- public LocksChangedEvent(CDOLockChangeInfo lockChangeInfo)
- {
- this.lockChangeInfo = lockChangeInfo;
- }
-
- public CDOBranch getBranch()
- {
- return lockChangeInfo.getBranch();
- }
-
- public long getTimeStamp()
- {
- return lockChangeInfo.getTimeStamp();
- }
-
- public CDOLockOwner getLockOwner()
+ public LocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
{
- return lockChangeInfo.getLockOwner();
+ super(CDOViewImpl.this, sender, lockChangeInfo);
}
- public CDOLockState[] getLockStates()
- {
- return lockChangeInfo.getLockStates();
- }
-
- public Operation getOperation()
+ @Override
+ public InternalCDOView getSource()
{
- return lockChangeInfo.getOperation();
+ return (InternalCDOView)super.getSource();
}
}
@@ -1524,7 +1537,7 @@ public class CDOViewImpl extends AbstractCDOView
event = new LockNotificationEventImpl();
}
}
-
+
fireEvent(event);
}
@@ -1817,7 +1830,7 @@ public class CDOViewImpl extends AbstractCDOView
private final class LockNotificationEventImpl extends OptionsEvent implements LockNotificationEvent
{
private static final long serialVersionUID = 1L;
-
+
public LockNotificationEventImpl()
{
super(OptionsImpl.this);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java
index 2f0459575c..e7dac87441 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java
@@ -183,7 +183,7 @@ public interface InternalCDOSession extends CDOSession, PackageProcessor, Packag
/**
* @since 4.1
*/
- public void handleLockNotification(CDOLockChangeInfo lockChangeInfo);
+ public void handleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender);
/**
* @since 3.0
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
index 27ba5cc0b0..f2e163ceb1 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
@@ -139,39 +139,10 @@ public interface InternalCDOView extends CDOView, CDOIDProvider, ILifecycle
/**
* @since 4.1
*/
- public void handleLockNotification(CDOLockChangeInfo lockChangeInfo);
+ public void handleLockNotification(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo);
/**
* @since 4.1
*/
public CDOLockState[] getLockStates(Collection<CDOID> ids);
-
- // /**
- // * Each time CDORevision or CDOState of an CDOObject is modified, ensure that no concurrent access is modifying it
- // at
- // * the same time. Uses {@link InternalCDOView#getStateLock()} to be thread safe.
- // * <p>
- // * In the case where {@link CDOObject#cdoRevision()} or {@link CDOObject#cdoState()} is called without using this
- // * lock, it is not guarantee that the state didn't change immediately after.
- // * <p>
- // * <code>
- // * if (cdoObject.cdoState() != CDOState.PROXY)
- // * {
- // * // At this point could be a proxy!
- // * cdoObject.cdoRevision();
- // * }
- // * </code>
- // * <p>
- // * The reason were we didn't use {@link CDOView#getLock()} is to not allow the access of that lock to the users
- // since
- // * it is very critical. Instead of giving this API to the end-users, a better API should be given in the CDOObject
- // to
- // * give them want they need.
- // */
- // public ReentrantLock getStateLock();
- //
- // /**
- // * @since 4.0
- // */
- // public Object getObjectsLock();
}
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java
index 846e9f3e35..89e6844b5c 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWOLockManager.java
@@ -40,6 +40,13 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo
private final Map<OBJECT, LockState<OBJECT, CONTEXT>> objectToLockStateMap = createObjectToLocksMap();
+ /**
+ * A mapping of contexts (owners of locks) to the lock states that they are involved in. Here, an 'involvement' means
+ * that the context owns at least one lock on the object that the lock state is for. To determine exactly what kind of
+ * lock, the lock state object obtained from this map must be queried.
+ * <p>
+ * This map is a performance optimization to avoid having to scan all lock states.
+ */
private final Map<CONTEXT, Set<LockState<OBJECT, CONTEXT>>> contextToLockStates = createContextToLocksMap();
public void lock(LockType type, CONTEXT context, Collection<? extends OBJECT> objectsToLock, long timeout)
@@ -73,7 +80,7 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo
{
LockState<OBJECT, CONTEXT> lockState = lockStates.get(i);
lockState.lock(type, context);
- addLockToContext(context, lockState);
+ addContextToLockStateMapping(context, lockState);
}
return lockStates;
@@ -256,11 +263,31 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo
return contextToLockStates;
}
- public LockState<OBJECT, CONTEXT> getLockState(Object key)
+ public LockState<OBJECT, CONTEXT> getLockState(OBJECT key)
{
return objectToLockStateMap.get(key);
}
+ public synchronized void setLockState(OBJECT key, LockState<OBJECT, CONTEXT> lockState)
+ {
+ objectToLockStateMap.put(key, lockState);
+
+ for (CONTEXT readLockOwner : lockState.getReadLockOwners())
+ {
+ addContextToLockStateMapping(readLockOwner, lockState);
+ }
+ CONTEXT writeLockOwner = lockState.getWriteLockOwner();
+ if (writeLockOwner != null)
+ {
+ addContextToLockStateMapping(writeLockOwner, lockState);
+ }
+ CONTEXT writeOptionOwner = lockState.getWriteOptionOwner();
+ if (writeOptionOwner != null)
+ {
+ addContextToLockStateMapping(writeOptionOwner, lockState);
+ }
+ }
+
private LockState<OBJECT, CONTEXT> getOrCreateLockState(OBJECT o)
{
LockState<OBJECT, CONTEXT> lockState = objectToLockStateMap.get(o);
@@ -292,7 +319,7 @@ public class RWOLockManager<OBJECT, CONTEXT> extends Lifecycle implements IRWOLo
return true;
}
- private void addLockToContext(CONTEXT context, LockState<OBJECT, CONTEXT> lockState)
+ private void addContextToLockStateMapping(CONTEXT context, LockState<OBJECT, CONTEXT> lockState)
{
Set<LockState<OBJECT, CONTEXT>> lockStates = contextToLockStates.get(context);
if (lockStates == null)
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java
index d069d31e98..59a99a3b02 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java
@@ -40,6 +40,10 @@ public final class ExtendedIOUtil
private static final int MAX_UTF_CHARS = MAX_UTF_LENGTH / 3;
+ private static final int MAX_ENUM_LITERALS = Byte.MAX_VALUE - Byte.MIN_VALUE;
+
+ private static final byte NO_ENUM_LITERAL = Byte.MIN_VALUE;
+
private ExtendedIOUtil()
{
}
@@ -207,19 +211,16 @@ public final class ExtendedIOUtil
*/
public static void writeEnum(DataOutput out, Enum<?> literal) throws IOException
{
- int ordinal = literal.ordinal();
- int size = literal.getDeclaringClass().getEnumConstants().length;
- if (size <= Byte.MAX_VALUE)
+ if (literal == null)
{
- out.writeByte(ordinal);
- }
- else if (size <= Short.MAX_VALUE)
- {
- out.writeShort(ordinal);
+ out.writeByte(NO_ENUM_LITERAL);
}
else
{
- out.writeInt(ordinal);
+ getEnumLiterals(literal.getDeclaringClass()); // Check valid size
+
+ int ordinal = literal.ordinal();
+ out.writeByte(ordinal + Byte.MIN_VALUE + 1);
}
}
@@ -228,23 +229,28 @@ public final class ExtendedIOUtil
*/
public static <T extends Enum<?>> T readEnum(DataInput in, Class<T> type) throws IOException
{
- T[] literals = type.getEnumConstants();
- int size = literals.length;
- int ordinal;
- if (size <= Byte.MAX_VALUE)
- {
- ordinal = in.readByte();
- }
- else if (size <= Short.MAX_VALUE)
+ T[] literals = getEnumLiterals(type);
+
+ int ordinal = in.readByte();
+ if (ordinal == NO_ENUM_LITERAL)
{
- ordinal = in.readShort();
+ return null;
}
- else
+
+ return literals[ordinal - Byte.MIN_VALUE - 1];
+ }
+
+ private static <T> T[] getEnumLiterals(Class<T> type)
+ {
+ T[] literals = type.getEnumConstants();
+
+ int size = literals.length;
+ if (size > MAX_ENUM_LITERALS)
{
- ordinal = in.readInt();
+ throw new AssertionError("Enum too large: " + size + " literals");
}
- return literals[ordinal];
+ return literals;
}
/**
diff --git a/plugins/org.gastro.server.web/src-gen/templates/MenuCardTemplate.java b/plugins/org.gastro.server.web/src-gen/templates/MenuCardTemplate.java
index bab6834d67..1ddb695ad9 100644
--- a/plugins/org.gastro.server.web/src-gen/templates/MenuCardTemplate.java
+++ b/plugins/org.gastro.server.web/src-gen/templates/MenuCardTemplate.java
@@ -1,62 +1,62 @@
-package templates;
-
-import org.gastro.inventory.*;
-import org.gastro.server.internal.web.*;
-
-public class MenuCardTemplate
-{
- protected static String nl;
- public static synchronized MenuCardTemplate create(String lineSeparator)
- {
- nl = lineSeparator;
- MenuCardTemplate result = new MenuCardTemplate();
- nl = null;
- return result;
- }
-
- public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;
- protected final String TEXT_1 = "";
- protected final String TEXT_2 = NL + NL + "<html>" + NL + " <header>" + NL + "\t <title>" + NL + "\t\t\t";
- protected final String TEXT_3 = NL + "\t </title>" + NL + "\t\t<link media=\"screen\" href=\"gastro.css\" type=\"text/css\" rel=\"stylesheet\">" + NL + "\t<header>" + NL + "<body>" + NL + "" + NL + "<h1>";
- protected final String TEXT_4 = "</h1>" + NL + "<table border=\"0\" width=\"400\">";
- protected final String TEXT_5 = NL + "\t<tr><td colspan=\"3\"><h2>";
- protected final String TEXT_6 = "</h2></td></tr>" + NL + "\t<tr><td colspan=\"3\"><h4>";
- protected final String TEXT_7 = "</h4></td></tr>" + NL + "\t";
- protected final String TEXT_8 = NL + "\t\t<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td colspan=\"2\"><h3>";
- protected final String TEXT_9 = "</h3></td></tr>" + NL + "\t\t<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td>";
- protected final String TEXT_10 = "</td>" + NL + "\t\t\t\t\t<td align=\"right\" valign=\"bottom\" width=\"80\">";
- protected final String TEXT_11 = " </td></tr>" + NL + "\t";
- protected final String TEXT_12 = NL + "</table>" + NL + "" + NL + "</body>" + NL + "</html>";
- protected final String TEXT_13 = NL;
-
- public String generate(Object argument)
- {
- final StringBuffer stringBuffer = new StringBuffer();
- stringBuffer.append(TEXT_1);
- MenuCard menuCard = (MenuCard)argument;
- stringBuffer.append(TEXT_2);
- stringBuffer.append(GastroServlet.html(menuCard.getTitle()));
- stringBuffer.append(TEXT_3);
- stringBuffer.append(GastroServlet.html(menuCard.getTitle()));
- stringBuffer.append(TEXT_4);
- for (Section section : menuCard.getSections()) {
- stringBuffer.append(TEXT_5);
- stringBuffer.append(GastroServlet.html(section.getTitle()));
- stringBuffer.append(TEXT_6);
- stringBuffer.append(GastroServlet.html(section.getText()));
- stringBuffer.append(TEXT_7);
- for (Offering offering : section.getOfferings()) {
- stringBuffer.append(TEXT_8);
- stringBuffer.append(GastroServlet.html(offering.getName()));
- stringBuffer.append(TEXT_9);
- stringBuffer.append(GastroServlet.html(offering.getDescription()));
- stringBuffer.append(TEXT_10);
- stringBuffer.append(GastroServlet.html(offering.getPrice()));
- stringBuffer.append(TEXT_11);
- }
- }
- stringBuffer.append(TEXT_12);
- stringBuffer.append(TEXT_13);
- return stringBuffer.toString();
- }
-}
+package templates;
+
+import org.gastro.inventory.*;
+import org.gastro.server.internal.web.*;
+
+public class MenuCardTemplate
+{
+ protected static String nl;
+ public static synchronized MenuCardTemplate create(String lineSeparator)
+ {
+ nl = lineSeparator;
+ MenuCardTemplate result = new MenuCardTemplate();
+ nl = null;
+ return result;
+ }
+
+ public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;
+ protected final String TEXT_1 = "";
+ protected final String TEXT_2 = NL + NL + "<html>" + NL + " <header>" + NL + "\t <title>" + NL + "\t\t\t";
+ protected final String TEXT_3 = NL + "\t </title>" + NL + "\t\t<link media=\"screen\" href=\"gastro.css\" type=\"text/css\" rel=\"stylesheet\">" + NL + "\t<header>" + NL + "<body>" + NL + "" + NL + "<h1>";
+ protected final String TEXT_4 = "</h1>" + NL + "<table border=\"0\" width=\"400\">";
+ protected final String TEXT_5 = NL + "\t<tr><td colspan=\"3\"><h2>";
+ protected final String TEXT_6 = "</h2></td></tr>" + NL + "\t<tr><td colspan=\"3\"><h4>";
+ protected final String TEXT_7 = "</h4></td></tr>" + NL + "\t";
+ protected final String TEXT_8 = NL + "\t\t<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td colspan=\"2\"><h3>";
+ protected final String TEXT_9 = "</h3></td></tr>" + NL + "\t\t<tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td>";
+ protected final String TEXT_10 = "</td>" + NL + "\t\t\t\t\t<td align=\"right\" valign=\"bottom\" width=\"80\">";
+ protected final String TEXT_11 = " </td></tr>" + NL + "\t";
+ protected final String TEXT_12 = NL + "</table>" + NL + "" + NL + "</body>" + NL + "</html>";
+ protected final String TEXT_13 = NL;
+
+ public String generate(Object argument)
+ {
+ final StringBuffer stringBuffer = new StringBuffer();
+ stringBuffer.append(TEXT_1);
+ MenuCard menuCard = (MenuCard)argument;
+ stringBuffer.append(TEXT_2);
+ stringBuffer.append(GastroServlet.html(menuCard.getTitle()));
+ stringBuffer.append(TEXT_3);
+ stringBuffer.append(GastroServlet.html(menuCard.getTitle()));
+ stringBuffer.append(TEXT_4);
+ for (Section section : menuCard.getSections()) {
+ stringBuffer.append(TEXT_5);
+ stringBuffer.append(GastroServlet.html(section.getTitle()));
+ stringBuffer.append(TEXT_6);
+ stringBuffer.append(GastroServlet.html(section.getText()));
+ stringBuffer.append(TEXT_7);
+ for (Offering offering : section.getOfferings()) {
+ stringBuffer.append(TEXT_8);
+ stringBuffer.append(GastroServlet.html(offering.getName()));
+ stringBuffer.append(TEXT_9);
+ stringBuffer.append(GastroServlet.html(offering.getDescription()));
+ stringBuffer.append(TEXT_10);
+ stringBuffer.append(GastroServlet.html(offering.getPrice()));
+ stringBuffer.append(TEXT_11);
+ }
+ }
+ stringBuffer.append(TEXT_12);
+ stringBuffer.append(TEXT_13);
+ return stringBuffer.toString();
+ }
+}

Back to the top