diff options
32 files changed, 442 insertions, 150 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 8bea47f3e5..09cee9b7a3 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 @@ -169,5 +169,19 @@ public interface CDOCommonSession extends IUserAware, IOptionsContainer, Closeab public PassiveUpdateMode getNewMode(); } + + /** + * An {@link IOptionsEvent options event} fired when the {@link LockNotificationMode lock notification mode} of a + * CDO session has changed. + * + * @author Caspar De Groot + * @since 4.1 + */ + public interface LockNotificationModeEvent extends IOptionsEvent + { + public LockNotificationMode getOldMode(); + + public LockNotificationMode getNewMode(); + } } } 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 d24ec88fc2..fc6f689211 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 @@ -86,6 +86,7 @@ public interface CDOCommonView extends CDOBranchPoint, CDORevisionProvider, IOpt */ public interface LockNotificationEvent extends IOptionsEvent { + boolean getEnabled(); } } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java index 118f973516..91b3cc3329 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfoHandler.java @@ -11,6 +11,9 @@ package org.eclipse.emf.cdo.common.lock; /** + * A call-back interface that indicates the ability to <i>handle</i> {@link CDOLockChangeInfo lock-change infos} that + * are passed from other entities. + * * @author Caspar De Groot * @since 4.1 */ 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 430e020670..919cd41f58 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 @@ -68,9 +68,12 @@ public interface IDurableLockingManager public Map<CDOID, LockGrade> getLocks();
/**
+ * Returns <code>true</code> if this instance represents a lock area that is known to be missing (not present) on a
+ * master server. (Relevant only in a replicating configuration.)
+ *
* @since 4.1
*/
- public boolean isDeleted();
+ public boolean isMissing();
/**
* A call-back interface for <em>handling</em> {@link LockArea lock area} objects.
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 af623cafb9..1c2644d659 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 @@ -242,6 +242,11 @@ public interface CDOProtocolConstants */ public static final short SIGNAL_ENABLE_LOCK_NOTIFICATION = 53; + /** + * @since 4.1 + */ + public static final short SIGNAL_SET_LOCK_NOTIFICATION_MODE = 54; + // ////////////////////////////////////////////////////////////////////// // Session Refresh 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 index 4baa364851..3bbb9e5e46 100644 --- 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 @@ -39,7 +39,7 @@ public class CDOLockAreaImpl implements LockArea private final Map<CDOID, LockGrade> locks; - private final boolean deleted; + private final boolean missing; public CDOLockAreaImpl(String durableLockingID, String userID, CDOBranchPoint branchPoint, boolean readOnly, Map<CDOID, LockGrade> locks) @@ -49,7 +49,7 @@ public class CDOLockAreaImpl implements LockArea this.branchPoint = branchPoint; this.readOnly = readOnly; this.locks = locks; - deleted = false; + missing = false; } public CDOLockAreaImpl(String durableLockingID) @@ -59,7 +59,7 @@ public class CDOLockAreaImpl implements LockArea branchPoint = null; readOnly = false; locks = null; - deleted = true; + missing = true; } public String getDurableLockingID() @@ -99,8 +99,8 @@ public class CDOLockAreaImpl implements LockArea durableLockingID, userID, branchPoint, readOnly, locks); } - public boolean isDeleted() + public boolean isMissing() { - return deleted; + return missing; } } 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 956ed5199e..20491c89b5 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 @@ -525,4 +525,9 @@ public class CDOClientProtocol extends SignalProtocol<CDOSession> implements CDO { send(new EnableLockNotificationRequest(this, viewID, on)); } + + public void setLockNotificationMode(LockNotificationMode mode) + { + send(new SetLockNotificationModeRequest(this, mode)); + } } 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 b01f0a0b0d..1b6b9b53e2 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 @@ -84,6 +84,8 @@ public class LockObjectsRequest extends CDOClientRequest<LockObjectsResult> staleRevisions[i] = in.readCDORevisionKey(); } + long timestamp = in.readLong(); + int n = in.readInt(); CDOLockState[] newLockStates = new CDOLockState[n]; for (int i = 0; i < n; i++) @@ -91,6 +93,7 @@ public class LockObjectsRequest extends CDOClientRequest<LockObjectsResult> newLockStates[i] = in.readCDOLockState(); } - return new LockObjectsResult(succesful, timeout, waitForUpdate, requiredTimestamp, staleRevisions, newLockStates); + return new LockObjectsResult(succesful, timeout, waitForUpdate, requiredTimestamp, staleRevisions, newLockStates, + timestamp); } } 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 156fc10184..d919a00a7f 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 @@ -68,11 +68,11 @@ public class ReplicateRepositoryRequest extends CDOClientRequest<Boolean> break; case CDOProtocolConstants.REPLICATE_LOCKAREA: - boolean deleted = !in.readBoolean(); - if (deleted) + boolean missing = !in.readBoolean(); + if (missing) { - String deletedLockAreaID = in.readString(); - LockArea area = CDOLockUtil.createLockArea(deletedLockAreaID); + String missingLockAreaID = in.readString(); + LockArea area = CDOLockUtil.createLockArea(missingLockAreaID); context.handleLockArea(area); } else diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/SetLockNotificationModeRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/SetLockNotificationModeRequest.java new file mode 100644 index 0000000000..688cdb250d --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/SetLockNotificationModeRequest.java @@ -0,0 +1,44 @@ +/** + * 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.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; + +import java.io.IOException; + +/** + * @author Caspar De Groot + */ +public class SetLockNotificationModeRequest extends CDOClientRequest<Boolean> +{ + private LockNotificationMode mode; + + public SetLockNotificationModeRequest(CDOClientProtocol protocol, LockNotificationMode mode) + { + super(protocol, CDOProtocolConstants.SIGNAL_SET_LOCK_NOTIFICATION_MODE); + this.mode = mode; + } + + @Override + protected void requesting(CDODataOutput out) throws IOException + { + out.writeEnum(mode); + } + + @Override + protected Boolean confirming(CDODataInput in) throws IOException + { + return in.readBoolean(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java index 0eefb367a3..1dcc86cf82 100644 --- a/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java +++ b/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/UnlockObjectsRequest.java @@ -90,12 +90,13 @@ public class UnlockObjectsRequest extends CDOClientRequest<UnlockObjectsResult> @Override protected UnlockObjectsResult confirming(CDODataInput in) throws IOException { + long timestamp = in.readLong(); int n = in.readInt(); CDOLockState[] newLockStates = new CDOLockState[n]; for (int i = 0; i < n; i++) { newLockStates[i] = in.readCDOLockState(); } - return new UnlockObjectsResult(newLockStates); + return new UnlockObjectsResult(newLockStates, timestamp); } } 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 bc1481a8bd..42aca92d88 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,9 +1301,10 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, return manager.createLockArea(this, durableLockingID, userID, branchPoint, readOnly, locks); } - public void updateLockArea(LockArea lockArea) + public void updateLockArea(LockArea area) { - throw new RuntimeException("TODO (CD)"); // TODO (CD) + DurableLockingManager manager = getStore().getDurableLockingManager(); + manager.updateLockArea(this, area); } public LockArea getLockArea(String durableLockingID) throws LockAreaNotFoundException 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 1e2183698d..7fbd726665 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 @@ -151,30 +151,7 @@ public class DurableLockingManager extends Lifecycle if (!locks.isEmpty())
{
- try
- {
- stmt = statementCache.getPreparedStatement(sqlInsertLock, ReuseProbability.MEDIUM);
- stmt.setString(1, durableLockingID);
-
- for (Entry<CDOID, LockGrade> entry : locks.entrySet())
- {
- CDOID id = entry.getKey();
- int grade = entry.getValue().getValue();
-
- idHandler.setCDOID(stmt, 2, id);
- stmt.setInt(3, grade);
-
- DBUtil.update(stmt, true);
- }
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
+ insertLocks(accessor, durableLockingID, locks);
}
accessor.getConnection().commit();
@@ -187,6 +164,37 @@ public class DurableLockingManager extends Lifecycle }
}
+ private void insertLocks(DBStoreAccessor accessor, String durableLockingID, Map<CDOID, LockGrade> locks)
+ {
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = statementCache.getPreparedStatement(sqlInsertLock, ReuseProbability.MEDIUM);
+ stmt.setString(1, durableLockingID);
+
+ for (Entry<CDOID, LockGrade> entry : locks.entrySet())
+ {
+ CDOID id = entry.getKey();
+ int grade = entry.getValue().getValue();
+
+ idHandler.setCDOID(stmt, 2, id);
+ stmt.setInt(3, grade);
+
+ DBUtil.update(stmt, true);
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
public LockArea getLockArea(DBStoreAccessor accessor, String durableLockingID) throws LockAreaNotFoundException
{
IPreparedStatementCache statementCache = accessor.getStatementCache();
@@ -300,6 +308,22 @@ public class DurableLockingManager extends Lifecycle }
}
+ public void updateLockArea(DBStoreAccessor accessor, LockArea area)
+ {
+ try
+ {
+ String areaID = area.getDurableLockingID();
+ unlockWithoutCommit(accessor, areaID);
+ insertLocks(accessor, areaID, area.getLocks());
+
+ accessor.getConnection().commit();
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ }
+
public void lock(DBStoreAccessor accessor, String durableLockingID, LockType type,
Collection<? extends Object> objectsToLock)
{
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 c3c7d4f8db..30281c9dc2 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 @@ -320,6 +320,9 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement case CDOProtocolConstants.SIGNAL_ENABLE_LOCK_NOTIFICATION: return new EnableLockNotificationIndication(this); + case CDOProtocolConstants.SIGNAL_SET_LOCK_NOTIFICATION_MODE: + return new SetLockNotificationModeIndication(this); + default: return super.createSignalReactor(signalID); } 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 4484526c62..3773c05cb0 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 @@ -85,6 +85,8 @@ public class LockObjectsIndication extends CDOServerWriteIndication out.writeCDORevisionKey(revKey); } + out.writeLong(result.getTimestamp()); + CDOLockState[] newLockStates = result.getNewLockStates(); out.writeInt(newLockStates.length); for (CDOLockState lockState : newLockStates) diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/SetLockNotificationModeIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/SetLockNotificationModeIndication.java new file mode 100644 index 0000000000..24092247af --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/SetLockNotificationModeIndication.java @@ -0,0 +1,42 @@ +/** + * 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.server.internal.net4j.protocol; + +import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; + +import java.io.IOException; + +/** + * @author Caspar De Groot + */ +public class SetLockNotificationModeIndication extends CDOServerReadIndication +{ + public SetLockNotificationModeIndication(CDOServerProtocol protocol) + { + super(protocol, CDOProtocolConstants.SIGNAL_SET_LOCK_NOTIFICATION_MODE); + } + + @Override + protected void indicating(CDODataInput in) throws IOException + { + LockNotificationMode mode = in.readEnum(LockNotificationMode.class); + getSession().setLockNotificationMode(mode); + } + + @Override + protected void responding(CDODataOutput out) throws IOException + { + out.writeBoolean(true); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java index a945056014..e4cc3a133d 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnlockObjectsIndication.java @@ -74,6 +74,7 @@ public class UnlockObjectsIndication extends CDOServerWriteIndication @Override protected void responding(CDODataOutput out) throws IOException { + out.writeLong(result.getTimestamp()); CDOLockState[] newLockStates = result.getNewLockStates(); out.writeInt(newLockStates.length); for (CDOLockState state : newLockStates) 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 19d20940e8..26ba1ad922 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 @@ -574,34 +574,14 @@ 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 = getView(area); + IView view = durableViews.get(area.getDurableLockingID()); + CheckUtil.checkNull(view, "view"); Collection<Object> readLocks = new ArrayList<Object>(); Collection<Object> writeLocks = new ArrayList<Object>(); @@ -658,44 +638,54 @@ public class LockManager extends RWOLockManager<Object, IView> implements Intern return grade; } - public void updateLockArea(LockArea lockArea) + private IView getOrCreateView(String lockAreaID) { - DurableLocking2 accessor = getDurableLocking2(); - if (lockArea.isDeleted()) + IView view = openViews.get(lockAreaID); + if (view == null) { - accessor.deleteLockArea(lockArea.getDurableLockingID()); + view = durableViews.get(lockAreaID); } - else + if (view == null) { - accessor.updateLockArea(lockArea); + view = new DurableView(lockAreaID); + durableViews.put(lockAreaID, (DurableView)view); } + return view; + } - IView view = openViews.get(lockArea.getDurableLockingID()); - if (view == null) + private LockArea getLockAreaNoEx(String durableLockingID) + { + try + { + return getLockArea(durableLockingID); + } + catch (LockAreaNotFoundException e) { - view = durableViews.get(lockArea.getDurableLockingID()); + return null; + } + } - // If we already have this durableView, we remove all the locks first... - if (view != null) - { - unlock2(view); - } + public void updateLockArea(LockArea lockArea) + { + String durableLockingID = lockArea.getDurableLockingID(); + DurableLocking2 accessor = getDurableLocking2(); - // ...then reload from the new lockArea - // - if (lockArea.isDeleted()) + if (lockArea.isMissing()) + { + LockArea localLockArea = getLockAreaNoEx(durableLockingID); + if (localLockArea != null && localLockArea.getLocks().size() > 0) { - DurableView deletedView = durableViews.remove(lockArea.getDurableLockingID()); + accessor.deleteLockArea(durableLockingID); + DurableView deletedView = durableViews.remove(durableLockingID); CheckUtil.checkNull(deletedView, "deletedView"); } - else - { - DurableLockLoader handler = new DurableLockLoader(view); - handler.handleLockArea(lockArea); - } - - view = durableViews.get(lockArea.getDurableLockingID()); - CheckUtil.checkNull(view, "view"); + } + else + { + accessor.updateLockArea(lockArea); + IView view = getOrCreateView(durableLockingID); + unlock2(view); + new DurableLockLoader().handleLockArea(lockArea); } } } 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 2b35f7b31a..70dacf074b 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 @@ -1150,7 +1150,7 @@ public class Repository extends Container<Object> implements InternalRepository public String[] getLockAreaIDs() { - return null; // TODO (CD) + return null; // TODO (CD) Raw replication of lockAreas } }; } @@ -1382,7 +1382,7 @@ public class Repository extends Container<Object> implements InternalRepository } catch (TimeoutRuntimeException ex) { - return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0]); + return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0], getTimeStamp()); } catch (InterruptedException ex) { @@ -1400,14 +1400,16 @@ public class Repository extends Container<Object> implements InternalRepository if (staleNoUpdate) { lockManager.unlock2(true, type, view, lockables); - return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0]); + return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0], + getTimeStamp()); } 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); + return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates, + getTimeStamp()); } private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys, @@ -1499,10 +1501,11 @@ public class Repository extends Container<Object> implements InternalRepository newLockStates = lockManager.unlock2(true, lockType, view, unlockables); } + long timestamp = getTimeStamp(); CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates); sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates); - return new UnlockObjectsResult(cdoLockStates); + return new UnlockObjectsResult(cdoLockStates, timestamp); } @Override 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 ef6ee5482e..bb0205d2ba 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,8 +77,7 @@ 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 LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS; private long lastUpdateTime; diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java index dd7471a941..531f5a9494 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java @@ -11,6 +11,7 @@ package org.eclipse.emf.cdo.internal.server.embedded; 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; @@ -165,6 +166,11 @@ public class EmbeddedClientSessionProtocol extends Lifecycle implements CDOSessi throw new UnsupportedOperationException(); } + public void setLockNotificationMode(LockNotificationMode mode) + { + throw new UnsupportedOperationException(); + } + public Object loadChunk(InternalCDORevision revision, EStructuralFeature feature, int accessIndex, int fetchIndex, int fromIndex, int toIndex) { 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 dfdb97e09c..96f26ac283 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 @@ -790,7 +790,6 @@ public class MEMStore extends LongIDStore implements IMEMStore, BranchLoader, Du { String userID = area.getUserID(); 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/syncing/RepositorySynchronizer.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/syncing/RepositorySynchronizer.java index a2fe4df2de..dfb44b894a 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 @@ -506,25 +506,64 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos } } - /** - * @author Eike Stepper - */ - private final class CommitRunnable extends QueueRunnable + private final class CommitRunnable extends RetryingRunnable { private CDOCommitInfo commitInfo; - private List<Exception> failedRuns; - public CommitRunnable(CDOCommitInfo commitInfo) { this.commitInfo = commitInfo; } + @Override + protected void doRun() + { + localRepository.handleCommitInfo(commitInfo); + } + + @Override + public int compareTo(QueueRunnable o) + { + int result = super.compareTo(o); + if (result == 0) + { + Long timeStamp = commitInfo.getTimeStamp(); + Long timeStamp2 = ((CommitRunnable)o).commitInfo.getTimeStamp(); + result = timeStamp < timeStamp2 ? -1 : timeStamp == timeStamp2 ? 0 : 1; + } + + return result; + } + + @Override + protected Integer getPriority() + { + return COMMIT_PRIORITY; + } + + @Override + protected String getErrorMessage() + { + return "Replication of master commit failed:" + commitInfo; + } + } + + /** + * @author Eike Stepper + */ + private abstract class RetryingRunnable extends QueueRunnable + { + private List<Exception> failedRuns; + + protected abstract void doRun(); + + protected abstract String getErrorMessage(); + public void run() { try { - localRepository.handleCommitInfo(commitInfo); + doRun(); } catch (Exception ex) { @@ -553,7 +592,7 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos { try { - addWork(CommitRunnable.this); + addWork(this); } catch (Exception ex) { @@ -564,36 +603,16 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos } else { - OM.LOG.error("Replication of master commit failed:" + commitInfo, ex); + OM.LOG.error(getErrorMessage(), ex); } } } - - @Override - public int compareTo(QueueRunnable o) - { - int result = super.compareTo(o); - if (result == 0) - { - Long timeStamp = commitInfo.getTimeStamp(); - Long timeStamp2 = ((CommitRunnable)o).commitInfo.getTimeStamp(); - result = timeStamp < timeStamp2 ? -1 : timeStamp == timeStamp2 ? 0 : 1; - } - - return result; - } - - @Override - protected Integer getPriority() - { - return COMMIT_PRIORITY; - } } /** * @author Caspar De Groot */ - private final class LocksRunnable extends QueueRunnable + private final class LocksRunnable extends RetryingRunnable { private CDOLockChangeInfo lockChangeInfo; @@ -602,18 +621,20 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos this.lockChangeInfo = lockChangeInfo; } - public void run() + @Override + protected Integer getPriority() + { + return LOCKS_PRIORITY; + } + + @Override + protected void doRun() { try { StoreThreadLocal.setSession(localRepository.getReplicatorSession()); localRepository.handleLockChangeInfo(lockChangeInfo); } - catch (Exception ex) - { - // TODO (CD) Retry as for commit? - ex.printStackTrace(); - } finally { StoreThreadLocal.release(); @@ -621,9 +642,9 @@ public class RepositorySynchronizer extends QueueRunner implements InternalRepos } @Override - protected Integer getPriority() + protected String getErrorMessage() { - return LOCKS_PRIORITY; + return "Replication of master lock changes failed:" + lockChangeInfo; } } } 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 06e640bc58..2276dc9b99 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 @@ -192,7 +192,24 @@ public abstract class SynchronizableRepository extends Repository.Default implem public String[] getLockAreaIDs() { - return new String[0]; // TODO (CD) + try + { + StoreThreadLocal.setSession(replicatorSession); + final List<String> areaIDs = new LinkedList<String>(); + getLockManager().getLockAreas(null, new LockArea.Handler() + { + public boolean handleLockArea(LockArea area) + { + areaIDs.add(area.getDurableLockingID()); + return true; + } + }); + return areaIDs.toArray(new String[areaIDs.size()]); + } + finally + { + StoreThreadLocal.release(); + } } public void handleBranch(CDOBranch branch) @@ -271,7 +288,11 @@ public abstract class SynchronizableRepository extends Repository.Default implem if (lockChangeInfo.getOperation() == Operation.LOCK) { - long timeout = 10000; // TODO (CD) + // If we can't lock immediately, there's a conflict, which means we're in big + // trouble: somehow locks were obtained on the clone but not on the master. What to do? + // TODO (CD) Consider this problem further + // + long timeout = 0; super.lock(view, lockType, lockables, null, timeout); } else if (lockChangeInfo.getOperation() == Operation.UNLOCK) 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 1db5bfc221..40c3826844 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 @@ -101,7 +101,7 @@ public class DurableLockArea implements LockArea /**
* @since 4.1
*/
- public boolean isDeleted()
+ public boolean isMissing()
{
return false;
}
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 69d2d7f10b..d57d24e87c 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 @@ -71,7 +71,7 @@ public class FailoverTest extends AbstractSyncingTest { CDOSession session = openSession("master"); CDOTransaction transaction = session.openTransaction(); - CDOResource resource = transaction.createResource(getResourcePath("/my/resource")); + CDOResource resource = transaction.createResource(getResourcePath("test")); Company company = getModel1Factory().createCompany(); company.setName("Test"); 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 index 90faae741d..7698905e44 100644 --- 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 @@ -14,6 +14,14 @@ import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; import org.eclipse.emf.cdo.view.CDOView; /** + * A {@link CDOSessionEvent session event} fired when lock-change notifications are received from a remote repository. + * For this event to be fired, + * {@link CDOSession.Options#setLockNotificationMode(org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode) + * the lock notification mode} must either be set to ALWAYS, or it must be set to IF_REQUIRED_BY_VIEWS <i>and</i> at + * least one of this sessions' views must have + * {@link org.eclipse.emf.cdo.common.CDOCommonView.Options#setLockNotificationEnabled(boolean) its lock-notification + * enablement} set to <code>true</code>. + * * @author Caspar De Groot * @since 4.1 */ 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 4e5b154dff..6153b50d6e 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 @@ -1445,6 +1445,23 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme public void setLockNotificationMode(LockNotificationMode lockNotificationMode) { + checkArg(lockNotificationMode, "lockNotificationMode"); //$NON-NLS-1$ + if (this.lockNotificationMode != lockNotificationMode) + { + LockNotificationMode oldMode = this.lockNotificationMode; + this.lockNotificationMode = lockNotificationMode; + CDOSessionProtocol protocol = getSessionProtocol(); + if (protocol != null) + { + protocol.setLockNotificationMode(lockNotificationMode); + + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new LockNotificationModeEventImpl(oldMode, lockNotificationMode), listeners); + } + } + } this.lockNotificationMode = lockNotificationMode; } @@ -1589,6 +1606,33 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme } /** + * @author Caspar De Groot + */ + private final class LockNotificationModeEventImpl extends OptionsEvent implements LockNotificationModeEvent + { + private static final long serialVersionUID = 1L; + + private LockNotificationMode oldMode, newMode; + + public LockNotificationModeEventImpl(LockNotificationMode oldMode, LockNotificationMode newMode) + { + super(OptionsImpl.this); + this.oldMode = oldMode; + this.newMode = newMode; + } + + public LockNotificationMode getOldMode() + { + return oldMode; + } + + public LockNotificationMode getNewMode() + { + return newMode; + } + } + + /** * @author Eike Stepper */ private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java index c88715ae53..83cb15a21e 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/DelegatingSessionProtocol.java @@ -11,6 +11,7 @@ package org.eclipse.emf.internal.cdo.session; 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; @@ -735,6 +736,23 @@ public class DelegatingSessionProtocol extends Lifecycle implements CDOSessionPr } } + public void setLockNotificationMode(LockNotificationMode mode) + { + int attempt = 0; + for (;;) + { + try + { + delegate.setLockNotificationMode(mode); + return; + } + catch (Exception ex) + { + handleException(++attempt, ex); + } + } + } + public RefreshSessionResult refresh(long lastUpdateTime, Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions, int initialChunkSize, boolean enablePassiveUpdates) 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 73d8546d3a..b6e535b9a0 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 @@ -2653,7 +2653,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa CDOLockState[] newLockStates = result.getNewLockStates(); if (newLockStates != null) { - updateAndNotifyLockStates(Operation.UNLOCK, null, newLockStates); + updateAndNotifyLockStates(Operation.UNLOCK, null, result.getTimeStamp(), newLockStates); } } catch (RuntimeException ex) 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 5f6be8a610..b1dc5c1069 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 @@ -297,7 +297,7 @@ public class CDOViewImpl extends AbstractCDOView } // Update the lock states in this view - updateAndNotifyLockStates(Operation.LOCK, lockType, result.getNewLockStates()); + updateAndNotifyLockStates(Operation.LOCK, lockType, result.getTimestamp(), result.getNewLockStates()); if (result.isWaitForUpdate()) { @@ -312,10 +312,10 @@ public class CDOViewImpl extends AbstractCDOView } } - protected void updateAndNotifyLockStates(Operation op, LockType type, CDOLockState[] newLockStates) + protected void updateAndNotifyLockStates(Operation op, LockType type, long timestamp, CDOLockState[] newLockStates) { updateLockStates(newLockStates); - notifyOtherViewsAboutLockChanges(op, type, newLockStates); + notifyOtherViewsAboutLockChanges(op, type, timestamp, newLockStates); } /** @@ -347,18 +347,17 @@ public class CDOViewImpl extends AbstractCDOView /** * Notifies other views of lock changes performed in this view */ - private void notifyOtherViewsAboutLockChanges(Operation op, LockType type, CDOLockState[] lockStates) + private void notifyOtherViewsAboutLockChanges(Operation op, LockType type, long timestamp, CDOLockState[] lockStates) { if (lockStates.length > 0) { - CDOLockChangeInfo lockChangeInfo = makeLockChangeInfo(op, type, lockStates); + CDOLockChangeInfo lockChangeInfo = makeLockChangeInfo(op, type, timestamp, lockStates); getSession().handleLockNotification(lockChangeInfo, this); } } - private CDOLockChangeInfo makeLockChangeInfo(Operation op, LockType type, CDOLockState[] newLockStates) + private CDOLockChangeInfo makeLockChangeInfo(Operation op, LockType type, long timestamp, CDOLockState[] newLockStates) { - long timestamp = 0L; // TODO (CD) Get rid of timestamps; replace with sequential number return CDOLockUtil.createLockChangeInfo(timestamp, this, getBranch(), op, type, newLockStates); } @@ -434,7 +433,7 @@ public class CDOViewImpl extends AbstractCDOView CDOSessionProtocol sessionProtocol = session.getSessionProtocol(); UnlockObjectsResult result = sessionProtocol.unlockObjects2(this, objectIDs, lockType); - updateAndNotifyLockStates(Operation.UNLOCK, lockType, result.getNewLockStates()); + updateAndNotifyLockStates(Operation.UNLOCK, lockType, result.getTimestamp(), result.getNewLockStates()); } /** @@ -1534,7 +1533,7 @@ public class CDOViewImpl extends AbstractCDOView CDOSessionProtocol protocol = getSession().getSessionProtocol(); protocol.enableLockNotifications(viewID, enabled); lockNotificationsEnabled = enabled; - event = new LockNotificationEventImpl(); + event = new LockNotificationEventImpl(enabled); } } @@ -1831,9 +1830,17 @@ public class CDOViewImpl extends AbstractCDOView { private static final long serialVersionUID = 1L; - public LockNotificationEventImpl() + private boolean enabled; + + public LockNotificationEventImpl(boolean enabled) { super(OptionsImpl.this); + this.enabled = enabled; + } + + public boolean getEnabled() + { + return enabled; } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java index fdfc9111ed..0dd3e0d929 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java @@ -14,6 +14,7 @@ import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.CDOObjectReference; 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.branch.CDOBranch; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; @@ -86,6 +87,11 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo public void setPassiveUpdateMode(PassiveUpdateMode mode); /** + * @since 4.1 + */ + public void setLockNotificationMode(LockNotificationMode mode); + + /** * @since 3.0 */ public RefreshSessionResult refresh(long lastUpdateTime, @@ -807,6 +813,8 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo private long requiredTimestamp; + private long timestamp; + private CDORevisionKey[] staleRevisions; private CDOLockState[] newLockStates; @@ -815,14 +823,14 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo public LockObjectsResult(boolean successful, boolean timedOut, boolean waitForUpdate, long requiredTimestamp, CDORevisionKey[] staleRevisions) { - throw new AssertionError("Deprecated"); // TODO (CD) What to do about this?? + throw new AssertionError("Deprecated"); } /** * @since 4.1 */ public LockObjectsResult(boolean successful, boolean timedOut, boolean waitForUpdate, long requiredTimestamp, - CDORevisionKey[] staleRevisions, CDOLockState[] newLockStates) + CDORevisionKey[] staleRevisions, CDOLockState[] newLockStates, long timestamp) { this.successful = successful; this.timedOut = timedOut; @@ -830,6 +838,7 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo this.requiredTimestamp = requiredTimestamp; this.staleRevisions = staleRevisions; this.newLockStates = newLockStates; + this.timestamp = timestamp; } public boolean isSuccessful() @@ -864,6 +873,14 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo { return newLockStates; } + + /** + * @since 4.1 + */ + public long getTimestamp() + { + return timestamp; + } } /** @@ -873,7 +890,9 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo { private CDOLockState[] newLockStates; - public UnlockObjectsResult(CDOLockState[] newLockStates) + private long timestamp; + + public UnlockObjectsResult(CDOLockState[] newLockStates, long timestamp) { this.newLockStates = newLockStates; } @@ -882,5 +901,10 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, BranchLo { return newLockStates; } + + public long getTimestamp() + { + return timestamp; + } } } |