diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src')
14 files changed, 874 insertions, 5 deletions
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 new file mode 100644 index 0000000000..0307719d42 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockChangeInfo.java @@ -0,0 +1,62 @@ +/** + * 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.common.lock; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; + +/** + * 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. + * + * @author Caspar De Groot + * @since 4.1 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface CDOLockChangeInfo extends CDOBranchPoint +{ + /** + * @return The branch at which the lock changes took place, same as <code>getView().getBranch()</code>. + */ + public CDOBranch getBranch(); + + /** + * @return The repository time at which the lock changes took place. This is only an informal indication; no formal + * relation (e.g. an ordering) with commit timestamps is guaranteed. + */ + public long getTimeStamp(); + + /** + * @return The view, represented as a {@link CDOLockOwner}, that authored the lock changes. + */ + public CDOLockOwner getLockOwner(); + + /** + * @return The new lock states of the objects that were affected by the change + */ + public CDOLockState[] getLockStates(); + + /** + * @return the type of lock operation that caused the lock changes + */ + public Operation getOperation(); + + /** + * Enumerates the possible locking operations. + * + * @author Caspar De Groot + */ + public enum Operation + { + LOCK, UNLOCK + } +} 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 new file mode 100644 index 0000000000..012fc15117 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockOwner.java @@ -0,0 +1,55 @@ +/** + * 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.common.lock; + +/** + * A client-side representation of a view owning locks. + * <p> + * + * @author Caspar De Groot + * @since 4.1 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface CDOLockOwner +{ + /** + * @return the ID identifying the session that owns the view + */ + public int getSessionID(); + + /** + * @return the ID identifying the view within the session + */ + 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; + } + + @Override + public String toString() + { + return CDOLockOwner.class.getSimpleName() + ".UNKNOWN"; + } + }; +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockState.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockState.java new file mode 100644 index 0000000000..0e470b28c3 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockState.java @@ -0,0 +1,56 @@ +/** + * 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.common.lock; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch; + +import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; + +import java.util.Set; + +/** + * A client-side representation of <i>all</i> the locks on a single CDOObject. + * <p> + * As an individual lock is always owned by view, which in turn is owned by a session, the methods on this interface + * return instances of {@link CDOLockOwner} which carry that information. + * <p> + * + * @author Caspar De Groot + * @since 4.1 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface CDOLockState +{ + /** + * Gets a unique identifier for the object that is locked; typically a {@link CDOID} or a {@link CDOIDAndBranch}, + * depending on whether branching support is enabled or not + * + * @return the identifier + */ + public Object getLockedObject(); + + /** + * If the 'others' argument is <code>false</code>, this method returns <code>true</code> if this lock is currently + * held by the <i>requesting</i> CDOView, <code>false</code> otherwise. + * <p> + * If the 'others' argument is <code>true</code>, this method returns <code>true</code> if this lock is currently held + * by <i>another</i> view (i.e. any view different from the requesting one), <code>false</code> otherwise. + */ + public boolean isLocked(LockType lockType, CDOLockOwner lockOwner, boolean others); + + public Set<CDOLockOwner> getReadLockOwners(); + + public CDOLockOwner getWriteLockOwner(); + + public CDOLockOwner getWriteOptionOwner(); +} 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 new file mode 100644 index 0000000000..d36d9078b6 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/lock/CDOLockUtil.java @@ -0,0 +1,97 @@ +/** + * 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.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.lock.CDOLockChangeInfo.Operation; +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.spi.common.lock.InternalCDOLockState; + +import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState; + +/** + * Various static methods that may help with classes related to CDO locks. + * + * @author Caspar De Groot + * @since 4.1 + */ +public final class CDOLockUtil +{ + private CDOLockUtil() + { + } + + public static CDOLockState createLockState(Object target) + { + return new CDOLockStateImpl(target); + } + + public static CDOLockState createLockState(LockState<Object, ? extends CDOCommonView> lockState) + { + CheckUtil.checkArg(lockState, "lockState"); + + InternalCDOLockState cdoLockState = new CDOLockStateImpl(lockState.getLockedObject()); + + for (CDOCommonView view : lockState.getReadLockOwners()) + { + int sessionID = view.getSession().getSessionID(); + int viewID = view.getViewID(); + CDOLockOwner owner = new CDOLockOwnerImpl(sessionID, viewID); + cdoLockState.addReadLockOwner(owner); + } + + CDOCommonView writeLockOwner = lockState.getWriteLockOwner(); + if (writeLockOwner != null) + { + CDOLockOwner owner = createLockOwner(writeLockOwner); + cdoLockState.setWriteLockOwner(owner); + } + + CDOCommonView writeOptionOwner = lockState.getWriteOptionOwner(); + if (writeOptionOwner != null) + { + CDOLockOwner owner = createLockOwner(writeOptionOwner); + cdoLockState.setWriteOptionOwner(owner); + } + + return cdoLockState; + } + + public static CDOLockOwner createLockOwner(CDOCommonView view) + { + CDOCommonSession session = view.getSession(); + if (session != null) + { + int sessionID = session.getSessionID(); + int viewID = view.getViewID(); + return new CDOLockOwnerImpl(sessionID, viewID); + } + return CDOLockOwner.UNKNOWN; + } + + public static CDOLockChangeInfo createLockChangeInfo(long timestamp, CDOLockOwner lockOwner, CDOBranch branch, + Operation op, CDOLockState[] cdoLockStates) + { + return new CDOLockChangeInfoImpl(branch.getPoint(timestamp), lockOwner, cdoLockStates, op); + } + + public static CDOLockChangeInfo createLockChangeInfo(long timestamp, CDOCommonView view, CDOBranch viewedBranch, + Operation op, CDOLockState[] cdoLockStates) + { + CDOLockOwner lockOwner = createLockOwner(view); + return createLockChangeInfo(timestamp, lockOwner, viewedBranch, op, cdoLockStates); + } +} 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 7d042af590..5343f8f91a 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 @@ -24,8 +24,6 @@ import java.util.Map; *
* @author Eike Stepper
* @since 4.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 IDurableLockingManager
{
@@ -104,6 +102,28 @@ public interface IDurableLockingManager }
/**
+ * @author Caspar De Groot
+ * @since 4.1
+ */
+ public static class LockAreaAlreadyExistsException extends IllegalStateException
+ {
+ private static final long serialVersionUID = 1L;
+
+ private String durableLockingID;
+
+ public LockAreaAlreadyExistsException(String durableLockingID)
+ {
+ super("A lock area with ID=" + durableLockingID + " already exists");
+ this.durableLockingID = durableLockingID;
+ }
+
+ public String getDurableLockingID()
+ {
+ return durableLockingID;
+ }
+ }
+
+ /**
* Enumerates the possible combinations of read and write locks on a single CDO object.
*
* @author Eike Stepper
@@ -165,7 +185,8 @@ public interface IDurableLockingManager public LockGrade getUpdated(LockType type, boolean on)
{
- int mask = type == LockType.READ ? 1 : 2;
+ int mask = getMask(type);
+
if (on)
{
return get(value | mask);
@@ -174,6 +195,23 @@ public interface IDurableLockingManager return get(value & ~mask);
}
+ private int getMask(LockType type)
+ {
+ switch (type)
+ {
+ case READ:
+ return 1;
+
+ case WRITE:
+ return 2;
+
+ case OPTION:
+ return 4;
+ }
+
+ return 0;
+ }
+
public static LockGrade get(LockType type)
{
if (type == LockType.READ)
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 2cbbde9d83..acab6ac3ea 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 @@ -19,6 +19,9 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitData; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; 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.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.model.CDOPackageInfo; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; @@ -135,4 +138,19 @@ public interface CDODataInput extends ExtendedDataInput // ///////////////////////////////////////////////////////////////////////////////////////////////// public LockType readCDOLockType() throws IOException; + + /** + * @since 4.1 + */ + public CDOLockChangeInfo readCDOLockChangeInfo() throws IOException; + + /** + * @since 4.1 + */ + public CDOLockOwner readCDOLockOwner() throws IOException; + + /** + * @since 4.1 + */ + public CDOLockState readCDOLockState() 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 db036d7926..9c040d46fe 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 @@ -20,6 +20,9 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDProvider; 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.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.model.CDOPackageInfo; import org.eclipse.emf.cdo.common.model.CDOPackageRegistry; @@ -141,4 +144,19 @@ public interface CDODataOutput extends ExtendedDataOutput // ///////////////////////////////////////////////////////////////////////////////////////////////// public void writeCDOLockType(LockType lockType) throws IOException; + + /** + * @since 4.1 + */ + public void writeCDOLockChangeInfo(CDOLockChangeInfo lockChangeInfo) throws IOException; + + /** + * @since 4.1 + */ + public void writeCDOLockState(CDOLockState lockState) throws IOException; + + /** + * @since 4.1 + */ + public void writeCDOLockOwner(CDOLockOwner lockOwner) 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 ef2fbfee26..722b158ca9 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 @@ -217,6 +217,31 @@ public interface CDOProtocolConstants */ public static final short SIGNAL_HANDLE_REVISIONS = 48; + /** + * @since 4.1 + */ + public static final short SIGNAL_LOCK_DELEGATION = 49; + + /** + * @since 4.1 + */ + public static final short SIGNAL_UNLOCK_DELEGATION = 50; + + /** + * @since 4.1 + */ + public static final short SIGNAL_LOCK_NOTIFICATION = 51; + + /** + * @since 4.1 + */ + public static final short SIGNAL_LOCK_STATE = 52; + + /** + * @since 4.1 + */ + public static final short SIGNAL_ENABLE_LOCK_NOTIFICATION = 53; + // ////////////////////////////////////////////////////////////////////// // Session Refresh 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 new file mode 100644 index 0000000000..70c4c0a65f --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockChangeInfoImpl.java @@ -0,0 +1,65 @@ +/** + * 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.common.lock; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; +import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo; +import org.eclipse.emf.cdo.common.lock.CDOLockOwner; +import org.eclipse.emf.cdo.common.lock.CDOLockState; + +/** + * @author Caspar De Groot + */ +public class CDOLockChangeInfoImpl implements CDOLockChangeInfo +{ + private final CDOBranchPoint branchPoint; + + private final CDOLockOwner lockOwner; + + private final CDOLockState[] lockStates; + + private final Operation operation; + + public CDOLockChangeInfoImpl(CDOBranchPoint branchPoint, CDOLockOwner lockOwner, CDOLockState[] lockStates, + Operation operation) + { + this.branchPoint = branchPoint; + this.lockOwner = lockOwner; + this.lockStates = lockStates; + this.operation = operation; + } + + public CDOBranch getBranch() + { + return branchPoint.getBranch(); + } + + public long getTimeStamp() + { + return branchPoint.getTimeStamp(); + } + + public CDOLockOwner getLockOwner() + { + return lockOwner; + } + + public CDOLockState[] getLockStates() + { + return lockStates; + } + + public Operation getOperation() + { + return operation; + } +} 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 new file mode 100644 index 0000000000..3509e5fb46 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockOwnerImpl.java @@ -0,0 +1,76 @@ +/** + * 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.common.lock; + +import org.eclipse.emf.cdo.common.lock.CDOLockOwner; + +import org.eclipse.net4j.util.ObjectUtil; + +/** + * @author Caspar De Groot + */ +public class CDOLockOwnerImpl implements CDOLockOwner +{ + private final int sessionID; + + private final int viewID; + + public CDOLockOwnerImpl(int sessionID, int viewID) + { + this.sessionID = sessionID; + this.viewID = viewID; + } + + public int getSessionID() + { + return sessionID; + } + + public int getViewID() + { + return viewID; + } + + @Override + public int hashCode() + { + return ObjectUtil.hashCode(sessionID, viewID); + } + + @Override + public boolean equals(Object obj) + { + if (obj == this) + { + return true; + } + + if (obj instanceof CDOLockOwner) + { + CDOLockOwner that = (CDOLockOwner)obj; + return sessionID == that.getSessionID() && viewID == that.getViewID(); + } + + return false; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("CDOLockOwner["); + builder.append("session="); + builder.append(sessionID); + builder.append(", view="); + 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 new file mode 100644 index 0000000000..3520709d0a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/lock/CDOLockStateImpl.java @@ -0,0 +1,171 @@ +/** + * 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.common.lock; + +import org.eclipse.emf.cdo.common.lock.CDOLockOwner; +import org.eclipse.emf.cdo.spi.common.lock.InternalCDOLockState; + +import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Caspar De Groot + */ +public class CDOLockStateImpl implements InternalCDOLockState +{ + private final Object lockedObject; + + private final Set<CDOLockOwner> readLockOwners = new HashSet<CDOLockOwner>(); + + private CDOLockOwner writeLockOwner; + + private CDOLockOwner writeOptionOwner; + + public CDOLockStateImpl(Object lockedObject) + { + CheckUtil.checkArg(lockedObject, "lockedObject"); + this.lockedObject = lockedObject; + } + + public boolean isLocked(LockType lockType, CDOLockOwner lockOwner, boolean others) + { + switch (lockType) + { + case READ: + return isReadLocked(lockOwner, others); + + case WRITE: + return isWriteLocked(lockOwner, others); + + case OPTION: + return isOptionLocked(lockOwner, others); + } + + return false; + } + + private boolean isReadLocked(CDOLockOwner by, boolean others) + { + if (readLockOwners.size() == 0) + { + return false; + } + + return readLockOwners.contains(by) ^ others; + } + + private boolean isWriteLocked(CDOLockOwner by, boolean others) + { + if (writeLockOwner == null) + { + return false; + } + + return writeLockOwner.equals(by) ^ others; + } + + private boolean isOptionLocked(CDOLockOwner by, boolean others) + { + if (writeOptionOwner == null) + { + return false; + } + + return writeOptionOwner.equals(by) ^ others; + } + + public Set<CDOLockOwner> getReadLockOwners() + { + return Collections.unmodifiableSet(readLockOwners); + } + + public CDOLockOwner getWriteLockOwner() + { + return writeLockOwner; + } + + public void setWriteLockOwner(CDOLockOwner lockOwner) + { + writeLockOwner = lockOwner; + } + + public CDOLockOwner getWriteOptionOwner() + { + return writeOptionOwner; + } + + public void setWriteOptionOwner(CDOLockOwner lockOwner) + { + writeOptionOwner = lockOwner; + } + + public Object getLockedObject() + { + return lockedObject; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("CDOLockState[lockedObject="); + builder.append(lockedObject); + + if (readLockOwners.size() > 0) + { + builder.append(", read="); + boolean first = true; + for (CDOLockOwner lockOwner : readLockOwners) + { + if (first) + { + first = false; + } + else + { + builder.append(", "); + } + + builder.append(lockOwner); + } + + builder.deleteCharAt(builder.length() - 1); + } + + if (writeLockOwner != null) + { + builder.append(", write="); + builder.append(writeLockOwner); + } + + if (writeOptionOwner != null) + { + builder.append(", option="); + builder.append(writeOptionOwner); + } + + builder.append(']'); + return builder.toString(); + } + + public void addReadLockOwner(CDOLockOwner lockOwner) + { + readLockOwners.add(lockOwner); + } + + public boolean removeReadLockOwner(CDOLockOwner lockOwner) + { + return readLockOwners.remove(lockOwner); + } +} 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 6da3c339f2..d64799ed3e 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 @@ -26,6 +26,10 @@ 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.lob.CDOLobUtil; +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.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.model.CDOModelUtil; import org.eclipse.emf.cdo.common.model.CDOPackageInfo; @@ -52,6 +56,9 @@ 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.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.messages.Messages; import org.eclipse.emf.cdo.internal.common.revision.CDOIDAndBranchImpl; import org.eclipse.emf.cdo.internal.common.revision.CDOIDAndVersionImpl; @@ -66,6 +73,7 @@ import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl import org.eclipse.emf.cdo.internal.common.revision.delta.CDOUnsetFeatureDeltaImpl; import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager; import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; +import org.eclipse.emf.cdo.spi.common.lock.InternalCDOLockState; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; @@ -255,6 +263,73 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl return new FailureCommitInfo(timeStamp, previousTimeStamp); } + public CDOLockChangeInfo readCDOLockChangeInfo() throws IOException + { + CDOBranchPoint branchPoint = readCDOBranchPoint(); + CDOLockOwner lockOwner = readCDOLockOwner(); + Operation operation = readEnum(Operation.class); + + int n = readInt(); + CDOLockState[] lockStates = new CDOLockState[n]; + for (int i = 0; i < n; i++) + { + lockStates[i] = readCDOLockState(); + } + + return new CDOLockChangeInfoImpl(branchPoint, lockOwner, lockStates, operation); + } + + public CDOLockOwner readCDOLockOwner() throws IOException + { + boolean isUnknown = !readBoolean(); + if (isUnknown) + { + return CDOLockOwner.UNKNOWN; + } + int session = readInt(); + int view = readInt(); + return new CDOLockOwnerImpl(session, view); + } + + public CDOLockState readCDOLockState() throws IOException + { + Object target; + boolean sendingBranchWithID = readBoolean(); + if (!sendingBranchWithID) + { + target = readCDOID(); + } + else + { + target = readCDOIDAndBranch(); + } + + InternalCDOLockState lockState = new CDOLockStateImpl(target); + + int nReadLockOwners = readInt(); + for (int i = 0; i < nReadLockOwners; i++) + { + CDOLockOwner lockOwner = readCDOLockOwner(); + lockState.addReadLockOwner(lockOwner); + } + + boolean hasWriteLock = readBoolean(); + if (hasWriteLock) + { + CDOLockOwner lockOwner = readCDOLockOwner(); + lockState.setWriteLockOwner(lockOwner); + } + + boolean hasWriteOption = readBoolean(); + if (hasWriteOption) + { + CDOLockOwner lockOwner = readCDOLockOwner(); + lockState.setWriteOptionOwner(lockOwner); + } + + return lockState; + } + public CDOID readCDOID() throws IOException { byte ordinal = readByte(); @@ -514,7 +589,8 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl public LockType readCDOLockType() throws IOException { - return readBoolean() ? LockType.WRITE : LockType.READ; + byte b = readByte(); + return b == 0 ? null : LockType.values()[b - 1]; } protected StringIO getPackageURICompressor() 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 394aad8048..9ceed91d70 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 @@ -19,6 +19,9 @@ import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDProvider; 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.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.model.CDOModelUtil; import org.eclipse.emf.cdo.common.model.CDOPackageInfo; @@ -63,6 +66,7 @@ import org.eclipse.emf.ecore.util.FeatureMapUtil; import java.io.IOException; import java.text.MessageFormat; import java.util.Collection; +import java.util.Set; /** * @author Eike Stepper @@ -218,6 +222,82 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im } } + public void writeCDOLockChangeInfo(CDOLockChangeInfo lockChangeInfo) throws IOException + { + writeCDOBranchPoint(lockChangeInfo); + writeCDOLockOwner(lockChangeInfo.getLockOwner()); + writeEnum(lockChangeInfo.getOperation()); + + CDOLockState[] lockStates = lockChangeInfo.getLockStates(); + writeInt(lockStates.length); + for (CDOLockState lockState : lockStates) + { + writeCDOLockState(lockState); + } + } + + public void writeCDOLockOwner(CDOLockOwner lockOwner) throws IOException + { + if (lockOwner != CDOLockOwner.UNKNOWN) + { + writeBoolean(true); + writeInt(lockOwner.getSessionID()); + writeInt(lockOwner.getViewID()); + } + else + { + writeBoolean(false); + } + } + + public void writeCDOLockState(CDOLockState lockState) throws IOException + { + Object o = lockState.getLockedObject(); + if (o instanceof CDOID) + { + writeBoolean(false); + writeCDOID((CDOID)o); + } + else if (o instanceof CDOIDAndBranch) + { + writeBoolean(true); + writeCDOIDAndBranch((CDOIDAndBranch)o); + } + else + { + throw new AssertionError("Unexpected type: " + o.getClass().getSimpleName()); + } + + Set<CDOLockOwner> readLockOwners = lockState.getReadLockOwners(); + writeInt(readLockOwners.size()); + for (CDOLockOwner readLockOwner : readLockOwners) + { + writeCDOLockOwner(readLockOwner); + } + + CDOLockOwner writeLockOwner = lockState.getWriteLockOwner(); + if (writeLockOwner != null) + { + writeBoolean(true); + writeCDOLockOwner(writeLockOwner); + } + else + { + writeBoolean(false); + } + + CDOLockOwner writeOptionOwner = lockState.getWriteOptionOwner(); + if (writeOptionOwner != null) + { + writeBoolean(true); + writeCDOLockOwner(writeOptionOwner); + } + else + { + writeBoolean(false); + } + } + public void writeCDOID(CDOID id) throws IOException { if (id == null) @@ -438,7 +518,8 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im public void writeCDOLockType(LockType lockType) throws IOException { - writeBoolean(lockType == LockType.WRITE ? true : false); + int b = lockType == null ? 0 : lockType.ordinal() + 1; + writeByte(b); } public CDOPackageRegistry getPackageRegistry() diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/lock/InternalCDOLockState.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/lock/InternalCDOLockState.java new file mode 100644 index 0000000000..dddd9f7713 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/lock/InternalCDOLockState.java @@ -0,0 +1,31 @@ +/** + * 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.spi.common.lock; + +import org.eclipse.emf.cdo.common.lock.CDOLockOwner; +import org.eclipse.emf.cdo.common.lock.CDOLockState; + +/** + * @author Caspar De Groot + * @since 4.1 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface InternalCDOLockState extends CDOLockState +{ + public void addReadLockOwner(CDOLockOwner lockOwner); + + public boolean removeReadLockOwner(CDOLockOwner lockOwner); + + public void setWriteLockOwner(CDOLockOwner lockOwner); + + public void setWriteOptionOwner(CDOLockOwner lockOwner); +} |