org.opencms.lock.CmsLock Maven / Gradle / Ivy
Show all versions of opencms-core Show documentation
/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software GmbH & Co. KG, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.lock;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsUser;
import org.opencms.util.CmsUUID;
/**
* Represents the lock state of a VFS resource.
*
* The lock state is combination of how, by whom and in which project
* a resource is currently locked.
*
* @since 6.0.0
*
* @see org.opencms.file.CmsObject#getLock(org.opencms.file.CmsResource)
* @see org.opencms.lock.CmsLockManager
*/
public class CmsLock implements Comparable {
/** The shared null lock object. */
private static final CmsLock NULL_LOCK = new CmsLock(
"",
CmsUUID.getNullUUID(),
new CmsProject(),
CmsLockType.UNLOCKED);
/** The project where the resource is locked. */
private CmsProject m_project;
/** The related lock. */
private CmsLock m_relatedLock;
/** The name of the locked resource. */
private String m_resourceName;
/** Indicates how the resource is locked. */
private CmsLockType m_type;
/** The ID of the user who locked the resource. */
private CmsUUID m_userId;
/**
* Constructor for a new Cms lock.
*
* @param resourceName the full resource name including the site root
* @param userId the ID of the user who locked the resource
* @param project the project where the resource is locked
* @param type flag indicating how the resource is locked
*/
public CmsLock(String resourceName, CmsUUID userId, CmsProject project, CmsLockType type) {
m_resourceName = resourceName;
m_userId = userId;
m_project = project;
m_type = type;
}
/**
* Returns the shared Null CmsLock.
*
* @return the shared Null CmsLock
*/
public static CmsLock getNullLock() {
return CmsLock.NULL_LOCK;
}
/**
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(CmsLock other) {
return m_resourceName.compareTo(other.m_resourceName);
}
/**
* Compares this lock to the specified object.
*
* @param obj the object to compare to
* @return true if and only if member values of this CmsLock are the same with the compared CmsLock
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof CmsLock) {
CmsLock other = (CmsLock)obj;
return other.m_resourceName.equals(m_resourceName)
&& other.m_userId.equals(m_userId)
&& other.m_project.equals(m_project)
&& other.m_type.equals(m_type);
}
return false;
}
/**
* Returns the edition lock.
*
* @return the edition lock
*/
public CmsLock getEditionLock() {
if (isSystemLock()) {
return getRelatedLock();
}
return this;
}
/**
* Returns the project where the resource is currently locked.
*
* @return the project where the resource is currently locked
*/
public CmsProject getProject() {
return m_project;
}
/**
* Returns the ID of the project where the resource is currently locked.
*
* @return the ID of the project
*/
public CmsUUID getProjectId() {
return m_project.getUuid();
}
/**
* Returns the name of the locked resource.
*
* @return the name of the locked resource
*/
public String getResourceName() {
return m_resourceName;
}
/**
* Returns the system lock.
*
* @return the system lock
*/
public CmsLock getSystemLock() {
if (!isSystemLock()) {
return getRelatedLock();
}
return this;
}
/**
* Returns the type about how the resource is locked.
*
* @return the type of the lock
*/
public CmsLockType getType() {
return m_type;
}
/**
* Returns the ID of the user who currently locked the resource.
*
* @return the ID of the user
*/
public CmsUUID getUserId() {
return m_userId;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return m_project.hashCode() + m_resourceName.hashCode() + m_userId.hashCode() + m_type.hashCode();
}
/**
* Returns true
if this is an directly inherited lock.
*
* @return true
if this is an directly inherited lock
*/
public boolean isDirectlyInherited() {
return m_type.isDirectlyInherited();
}
/**
* Returns true
if this is an exclusive, temporary exclusive, or
* directly inherited lock, and the given user is the owner of this lock.
*
* @param user the user to compare to the owner of this lock
*
* @return true
if this is an exclusive, temporary exclusive, or
* directly inherited lock, and the given user is the owner of this lock
*/
public boolean isDirectlyOwnedBy(CmsUser user) {
return (isExclusive() || isDirectlyInherited()) && isOwnedBy(user);
}
/**
* Returns true
if this is an exclusive, temporary exclusive, or
* directly inherited lock, and the current user is the owner of this lock,
* checking also the project of the lock.
*
* @param cms the CMS context to check
*
* @return true
if this is an exclusive, temporary exclusive, or
* directly inherited lock, and the current user is the owner of this lock
*/
public boolean isDirectlyOwnedInProjectBy(CmsObject cms) {
return (isExclusive() || isDirectlyInherited())
&& isOwnedInProjectBy(
cms.getRequestContext().getCurrentUser(),
cms.getRequestContext().getCurrentProject());
}
/**
* Returns true
if this is an exclusive, temporary exclusive, or
* directly inherited lock, and the given user is the owner of this lock,
* checking also the project of the lock.
*
* @param user the user to compare to the owner of this lock
* @param project the project to compare to the project of this lock
*
* @return true
if this is an exclusive, temporary exclusive, or
* directly inherited lock, and the given user is the owner of this lock
*/
public boolean isDirectlyOwnedInProjectBy(CmsUser user, CmsProject project) {
return (isExclusive() || isDirectlyInherited()) && isOwnedInProjectBy(user, project);
}
/**
* Returns true
if this is an exclusive (or temporary exclusive) lock.
*
* @return true
if this is an exclusive (or temporary exclusive) lock
*/
public boolean isExclusive() {
return m_type.isExclusive();
}
/**
* Returns true
if this is an exclusive (or temporary exclusive) lock,
* and the given user is the owner of this lock.
*
* @param user the user to compare to the owner of this lock
*
* @return true
if this is an exclusive (or temporary exclusive) lock,
* and the given user is the owner of this lock
*/
public boolean isExclusiveOwnedBy(CmsUser user) {
return isExclusive() && isOwnedBy(user);
}
/**
* Returns true
if this is an exclusive (or temporary exclusive) lock,
* and the given user is the owner and the given project is the project of this lock.
*
* @param user the user to compare to the owner of this lock
* @param project the project to compare to the project of this lock
*
* @return true
if this is an exclusive (or temporary exclusive) lock,
* and the given user is the owner and the given project is the project of this lock
*/
public boolean isExclusiveOwnedInProjectBy(CmsUser user, CmsProject project) {
return isExclusive() && isOwnedInProjectBy(user, project);
}
/**
* Returns true
if this is an inherited lock, which may either be directly or shared inherited.
*
* @return true
if this is an inherited lock, which may either be directly or shared inherited
*/
public boolean isInherited() {
return m_type.isInherited();
}
/**
* Returns true
if the given project is the project of this lock.
*
* @param project the project to compare to the project of this lock
*
* @return true
if the given project is the project of this lock
*/
public boolean isInProject(CmsProject project) {
return m_project.equals(project);
}
/**
* Checks if a resource can be locked by a user.
*
* The resource is not lockable if it already has a lock of type {@link CmsLockType#PUBLISH}.
*
* The resource is lockable either
* - if it is currently unlocked
* - if it has a lock of another type set and the user is the lock owner
*
* @param user the user to test lockeability for
*
* @return true
if this lock blocks any operation on the locked resource until it is unlocked
*/
public boolean isLockableBy(CmsUser user) {
if (getSystemLock().isPublish()) {
return false;
}
if (getEditionLock().isUnlocked() && getSystemLock().isUnlocked()) {
return true;
}
return getEditionLock().isOwnedBy(user);
}
/**
* Returns true
if this lock is the NULL
lock which can
* be obtained by {@link #getNullLock()}.
*
* Only for the NULL
lock, {@link #isUnlocked()} is true
.
*
* @return true
if this lock is the NULL
lock
*/
public boolean isNullLock() {
return isUnlocked();
}
/**
* Returns true
if the given user is the owner of this lock.
*
* @param user the user to compare to the owner of this lock
*
* @return true
if the given user is the owner of this lock
*/
public boolean isOwnedBy(CmsUser user) {
return m_userId.equals(user.getId());
}
/**
* Returns true
if the given user is the owner of this lock,
* and this lock belongs to the given project.
*
* @param user the user to compare to the owner of this lock
* @param project the project to compare to the project of this lock
*
* @return true
if the given user is the owner of this lock,
* and this lock belongs to the given project
*/
public boolean isOwnedInProjectBy(CmsUser user, CmsProject project) {
return isOwnedBy(user) && isInProject(project);
}
/**
* Returns true
if this is a persistent lock that should be saved when the systems shuts down.
*
* @return true
if this is a persistent lock that should be saved when the systems shuts down
*/
public boolean isPersistent() {
return m_type.isPersistent();
}
/**
* Returns true
if this is a publish lock.
*
* @return true
if this is a publish lock
*/
public boolean isPublish() {
return m_type.isPublish();
}
/**
* Returns true
if this is a shared lock.
*
* @return true
if this is a shared lock
*/
public boolean isShared() {
return m_type.isShared();
}
/**
* Returns true
if this is a system (2nd level) lock.
*
* @return true
if this is a system (2nd level) lock
*/
public boolean isSystemLock() {
return m_type.isSystem();
}
/**
* Returns true
if this is a temporary lock.
*
* @return true
if this is a temporary lock
*/
public boolean isTemporary() {
return m_type.isTemporary();
}
/**
* Returns true
if this lock is in fact unlocked.
*
* Only if this is true
, the result lock is equal to the NULL
lock,
* which can be obtained by {@link #getNullLock()}.
*
* @return true
if this lock is in fact unlocked
*/
public boolean isUnlocked() {
return m_type.isUnlocked();
}
/**
* Builds a string representation of the current state.
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[CmsLock: resource: ");
buf.append(getResourceName());
buf.append(", type: ");
buf.append(getType());
buf.append(", project: ");
buf.append(getProjectId());
buf.append(", user: ");
buf.append(getUserId());
if (getRelatedLock() != null) {
buf.append(", related lock: ");
buf.append(getRelatedLock().getType());
}
buf.append("]");
return buf.toString();
}
/**
* @see java.lang.Object#clone()
*/
@Override
protected Object clone() {
CmsLock lock = new CmsLock(m_resourceName, m_userId, m_project, m_type);
if ((m_relatedLock != null) && !m_relatedLock.isNullLock()) {
lock.setRelatedLock(
new CmsLock(
m_relatedLock.m_resourceName,
m_relatedLock.m_userId,
m_relatedLock.m_project,
m_relatedLock.m_type));
}
return lock;
}
/**
* Returns the related Lock.
*
* @return the related Lock
*/
protected CmsLock getRelatedLock() {
if (m_relatedLock == null) {
CmsLockType type;
if (isSystemLock()) {
type = CmsLockType.UNLOCKED;
} else {
type = CmsLockType.SYSTEM_UNLOCKED;
}
CmsLock lock = new CmsLock(getResourceName(), getUserId(), getProject(), type);
lock.setRelatedLock(this);
if (isUnlocked()) {
// prevent the null lock gets modified
return lock;
}
m_relatedLock = lock;
}
return m_relatedLock;
}
/**
* Sets the related Lock.
*
* @param relatedLock the related Lock to set
*/
protected void setRelatedLock(CmsLock relatedLock) {
if (this == NULL_LOCK) {
throw new RuntimeException("null lock");
}
if ((relatedLock == null) || relatedLock.isUnlocked()) {
m_relatedLock = null;
} else {
m_relatedLock = relatedLock;
m_relatedLock.m_relatedLock = this;
}
}
}