cmslockmanager.java
来自「找了很久才找到到源代码」· Java 代码 · 共 900 行 · 第 1/3 页
JAVA
900 行
/*
* File : $Source: /usr/local/cvs/opencms/src/org/opencms/lock/CmsLockManager.java,v $
* Date : $Date: 2007-09-07 12:02:16 $
* Version: $Revision: 1.45 $
*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) 2002 - 2007 Alkacon Software GmbH (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, 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.db.CmsDbContext;
import org.opencms.db.CmsDriverManager;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.CmsUser;
import org.opencms.file.CmsVfsResourceNotFoundException;
import org.opencms.i18n.CmsMessageContainer;
import org.opencms.main.CmsException;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsUUID;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* The CmsLockManager is used by the Cms application to detect
* the lock state of a resource.<p>
*
* The lock state depends on the path of the resource, and probably
* locked parent folders. The result of a query to the lock manager
* are instances of CmsLock objects.<p>
*
* @author Michael Emmerich
* @author Thomas Weckert
* @author Andreas Zahner
* @author Michael Moossen
*
* @version $Revision: 1.45 $
*
* @since 6.0.0
*
* @see org.opencms.file.CmsObject#getLock(CmsResource)
* @see org.opencms.lock.CmsLock
*/
public final class CmsLockManager {
/** The driver manager instance. */
private CmsDriverManager m_driverManager;
/** The flag to indicate if the locks should be written to the db. */
private boolean m_isDirty = false;
/** The flag to indicate if the lock manager has been started in run level 4. */
private boolean m_runningInServlet = false;
/**
* Default constructor, creates a new lock manager.<p>
*
* @param driverManager the driver manager instance
*/
public CmsLockManager(CmsDriverManager driverManager) {
m_driverManager = driverManager;
}
/**
* Adds a resource to the lock manager.<p>
*
* @param dbc the current database context
* @param resource the resource
* @param user the user who locked the resource
* @param project the project where the resource is locked
* @param type the lock type
*
* @throws CmsLockException if the resource is locked
* @throws CmsException if something goes wrong
*/
public void addResource(CmsDbContext dbc, CmsResource resource, CmsUser user, CmsProject project, CmsLockType type)
throws CmsLockException, CmsException {
// check the type
if (!type.isSystem() && !type.isExclusive()) {
// invalid type
throw new CmsLockException(Messages.get().container(Messages.ERR_INVALID_LOCK_TYPE_1, type.toString()));
}
// get the current lock
CmsLock currentLock = getLock(dbc, resource);
// check lockability
checkLockable(dbc, resource, user, project, type, currentLock);
boolean needNewLock = true;
// prevent shared locks get compromised
if ((type.isExclusive()) && !(type.isTemporary() && currentLock.isInherited())) {
if (!currentLock.getEditionLock().isUnlocked()) {
needNewLock = false;
}
}
CmsLock newLock = CmsLock.getNullLock();
if (needNewLock) {
// lock the resource
newLock = new CmsLock(resource.getRootPath(), user.getId(), project, type);
lockResource(newLock);
}
// handle collisions with exclusive locked sub-resources in case of a folder
if (resource.isFolder() && newLock.getSystemLock().isUnlocked()) {
String resourceName = resource.getRootPath();
Iterator itLocks = OpenCms.getMemoryMonitor().getAllCachedLocks().iterator();
while (itLocks.hasNext()) {
CmsLock lock = (CmsLock)itLocks.next();
String lockedPath = lock.getResourceName();
if (lockedPath.startsWith(resourceName) && !lockedPath.equals(resourceName)) {
unlockResource(lockedPath, false);
}
}
}
}
/**
* Counts the exclusive locked resources in a project.<p>
*
* @param project the project
*
* @return the number of exclusive locked resources in the specified project
*/
public int countExclusiveLocksInProject(CmsProject project) {
int count = 0;
Iterator itLocks = OpenCms.getMemoryMonitor().getAllCachedLocks().iterator();
while (itLocks.hasNext()) {
CmsLock lock = (CmsLock)itLocks.next();
if (lock.getEditionLock().isInProject(project)) {
count++;
}
}
return count;
}
/**
* Returns the lock state of the given resource.<p>
*
* In case no lock is set, the <code>null lock</code> which can be obtained
* by {@link CmsLock#getNullLock()} is returned.<p>
*
* @param dbc the current database context
* @param resource the resource
*
* @return the lock state of the given resource
* @throws CmsException if something goes wrong
*/
public CmsLock getLock(CmsDbContext dbc, CmsResource resource) throws CmsException {
return getLock(dbc, resource, true);
}
/**
* Returns the lock state of the given resource.<p>
*
* In case no lock is set, the <code>null lock</code> which can be obtained
* by {@link CmsLock#getNullLock()} is returned.<p>
*
* @param dbc the current database context
* @param resource the resource
* @param includeSiblings if siblings (shared locks) should be included in the search
*
* @return the lock state of the given resource
* @throws CmsException if something goes wrong
*/
public CmsLock getLock(CmsDbContext dbc, CmsResource resource, boolean includeSiblings) throws CmsException {
// resources are never locked in the online project
// and non-existent resources are never locked
if ((resource == null) || (dbc.currentProject().isOnlineProject())) {
return CmsLock.getNullLock();
}
// check exclusive direct locks first
CmsLock lock = getDirectLock(resource.getRootPath());
if ((lock == null) && includeSiblings) {
// check if siblings are exclusively locked
List siblings = internalReadSiblings(dbc, resource);
lock = getSiblingsLock(siblings, resource.getRootPath());
}
if (lock == null) {
// if there is no parent lock, this will be the null lock as well
lock = getParentLock(resource.getRootPath());
}
if (!lock.getSystemLock().isUnlocked()) {
lock = lock.getSystemLock();
} else {
lock = lock.getEditionLock();
}
return lock;
}
/**
* Returns all exclusive locked resources matching the given resource name and filter.<p>
*
* @param dbc the database context
* @param resourceName the resource name
* @param filter the lock filter
*
* @return a list of root paths
*
* @throws CmsException if something goes wrong
*/
public List getLocks(CmsDbContext dbc, String resourceName, CmsLockFilter filter) throws CmsException {
List locks = new ArrayList();
Iterator itLocks = OpenCms.getMemoryMonitor().getAllCachedLocks().iterator();
while (itLocks.hasNext()) {
CmsLock lock = (CmsLock)itLocks.next();
if (filter.isSharedExclusive()) {
CmsResource resource;
try {
resource = m_driverManager.readResource(dbc, lock.getResourceName(), CmsResourceFilter.ALL);
} catch (CmsVfsResourceNotFoundException e) {
OpenCms.getMemoryMonitor().uncacheLock(lock.getResourceName());
continue;
}
if (resource.getSiblingCount() > 1) {
Iterator itSiblings = internalReadSiblings(dbc, resource).iterator();
while (itSiblings.hasNext()) {
CmsResource sibling = (CmsResource)itSiblings.next();
CmsLock siblingLock = internalSiblingLock(lock, sibling.getRootPath());
if (filter.match(resourceName, siblingLock)) {
locks.add(siblingLock);
}
}
}
}
if (filter.match(resourceName, lock)) {
locks.add(lock);
}
}
return locks;
}
/**
* Returns <code>true</code> if the given resource contains a resource that has a system lock.<p>
*
* This check is required for certain operations on folders.<p>
*
* @param dbc the database context
* @param resource the resource to check the system locks for
*
* @return <code>true</code> if the given resource contains a resource that has a system lock
*
* @throws CmsException if something goes wrong
*/
public boolean hasSystemLocks(CmsDbContext dbc, CmsResource resource) throws CmsException {
if (resource == null) {
return false;
}
Iterator itLocks = OpenCms.getMemoryMonitor().getAllCachedLocks().iterator();
while (itLocks.hasNext()) {
CmsLock lock = (CmsLock)itLocks.next();
if (lock.getSystemLock().isUnlocked()) {
// only system locks matter here
continue;
}
if (lock.getResourceName().startsWith(resource.getRootPath())) {
if (lock.getResourceName().startsWith(resource.getRootPath())) {
return true;
}
try {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?