⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lockmanagerimpl.java

📁 jsr170接口的java实现。是个apache的开源项目。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.lock;import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;import org.apache.commons.collections.map.LinkedMap;import org.apache.jackrabbit.core.ItemId;import org.apache.jackrabbit.core.NodeId;import org.apache.jackrabbit.core.NodeImpl;import org.apache.jackrabbit.util.PathMap;import org.apache.jackrabbit.core.SessionImpl;import org.apache.jackrabbit.core.SessionListener;import org.apache.jackrabbit.core.util.Dumpable;import org.apache.jackrabbit.core.cluster.LockEventChannel;import org.apache.jackrabbit.core.cluster.LockEventListener;import org.apache.jackrabbit.core.cluster.ClusterOperation;import org.apache.jackrabbit.core.fs.FileSystem;import org.apache.jackrabbit.core.fs.FileSystemException;import org.apache.jackrabbit.core.fs.FileSystemResource;import org.apache.jackrabbit.core.observation.EventImpl;import org.apache.jackrabbit.core.observation.SynchronousEventListener;import org.apache.jackrabbit.name.MalformedPathException;import org.apache.jackrabbit.name.NamespaceResolver;import org.apache.jackrabbit.name.Path;import org.apache.jackrabbit.name.QName;import org.apache.jackrabbit.name.PathFormat;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.jcr.ItemNotFoundException;import javax.jcr.Node;import javax.jcr.PathNotFoundException;import javax.jcr.RepositoryException;import javax.jcr.Session;import javax.jcr.lock.Lock;import javax.jcr.lock.LockException;import javax.jcr.observation.Event;import javax.jcr.observation.EventIterator;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintStream;import java.util.ArrayList;import java.util.Iterator;/** * Provides the functionality needed for locking and unlocking nodes. */public class LockManagerImpl implements LockManager, SynchronousEventListener,        LockEventListener, Dumpable {    /**     * Logger     */    private static final Logger log = LoggerFactory.getLogger(LockManagerImpl.class);    /**     * Name of the lock file     */    private static final String LOCKS_FILE = "locks";    /**     * Path map containing all locks at the leaves.     */    private final PathMap lockMap = new PathMap();    /**     * Lock to path map.     */    private final ReentrantLock lockMapLock = new ReentrantLock();    /**     * System session     */    private final SessionImpl session;    /**     * Locks file     */    private final FileSystemResource locksFile;    /**     * Flag indicating whether automatic saving is disabled.     */    private boolean savingDisabled;    /**     * Namespace resolver     */    private final NamespaceResolver nsResolver;    /**     * Lock event channel.     */    private LockEventChannel eventChannel;    /**     * Create a new instance of this class.     *     * @param session system session     * @param fs      file system for persisting locks     * @throws RepositoryException if an error occurs     */    public LockManagerImpl(SessionImpl session, FileSystem fs)            throws RepositoryException {        this.session = session;        this.nsResolver = session.getNamespaceResolver();        this.locksFile = new FileSystemResource(fs, FileSystem.SEPARATOR + LOCKS_FILE);        session.getWorkspace().getObservationManager().                addEventListener(this, Event.NODE_ADDED | Event.NODE_REMOVED,                        "/", true, null, null, true);        try {            if (locksFile.exists()) {                load();            }        } catch (FileSystemException e) {            throw new RepositoryException("I/O error while reading locks from '"                    + locksFile.getPath() + "'", e);        }    }    /**     * Close this lock manager. Writes back all changes.     */    public void close() {        save();    }    /**     * Read locks from locks file and populate path map     */    private void load() throws FileSystemException {        BufferedReader reader = null;        try {            reader = new BufferedReader(                    new InputStreamReader(locksFile.getInputStream()));            while (true) {                String s = reader.readLine();                if (s == null || s.equals("")) {                    break;                }                reapplyLock(LockToken.parse(s));            }        } catch (IOException e) {            throw new FileSystemException("error while reading locks file", e);        } finally {            if (reader != null) {                try {                    reader.close();                } catch (IOException e2) {                    /* ignore */                }            }        }    }    /**     * Reapply a lock given a lock token that was read from the locks file     *     * @param lockToken lock token to apply     */    private void reapplyLock(LockToken lockToken) {        try {            NodeImpl node = (NodeImpl) session.getItemManager().getItem(lockToken.id);            Path path = getPath(lockToken.id);            LockInfo info = new LockInfo(lockToken, false,                    node.getProperty(QName.JCR_LOCKISDEEP).getBoolean(),                    node.getProperty(QName.JCR_LOCKOWNER).getString());            info.setLive(true);            lockMap.put(path, info);        } catch (RepositoryException e) {            log.warn("Unable to recreate lock '" + lockToken                    + "': " + e.getMessage());            log.debug("Root cause: ", e);        }    }    /**     * Write locks to locks file     */    private void save() {        if (savingDisabled) {            return;        }        final ArrayList list = new ArrayList();        lockMap.traverse(new PathMap.ElementVisitor() {            public void elementVisited(PathMap.Element element) {                LockInfo info = (LockInfo) element.get();                if (!info.sessionScoped) {                    list.add(info);                }            }        }, false);        BufferedWriter writer = null;        try {            writer = new BufferedWriter(                    new OutputStreamWriter(locksFile.getOutputStream()));            for (int i = 0; i < list.size(); i++) {                AbstractLockInfo info = (AbstractLockInfo) list.get(i);                writer.write(info.lockToken.toString());                writer.newLine();            }        } catch (FileSystemException fse) {            log.warn("I/O error while saving locks to '"                    + locksFile.getPath() + "': " + fse.getMessage());            log.debug("Root cause: ", fse);        } catch (IOException ioe) {            log.warn("I/O error while saving locks to '"                    + locksFile.getPath() + "': " + ioe.getMessage());            log.debug("Root cause: ", ioe);        } finally {            if (writer != null) {                try {                    writer.close();                } catch (IOException e) {                    // ignore                }            }        }    }    /**     * Internal <code>lock</code> implementation that takes the same parameters     * as the public method but will not modify content.     * @param node node to lock     * @param isDeep whether the lock applies to this node only     * @param isSessionScoped whether the lock is session scoped     * @return lock     * @throws LockException       if the node is already locked     * @throws RepositoryException if another error occurs     */    AbstractLockInfo internalLock(NodeImpl node, boolean isDeep, boolean isSessionScoped)            throws LockException, RepositoryException {        SessionImpl session = (SessionImpl) node.getSession();        LockInfo info = new LockInfo(new LockToken(node.getNodeId()),                isSessionScoped, isDeep, session.getUserID());        ClusterOperation operation = null;        boolean successful = false;        // Cluster is only informed about open-scoped locks        if (eventChannel != null && !isSessionScoped) {            operation = eventChannel.create(node.getNodeId(), isDeep, session.getUserID());        }        acquire();        try {            // check whether node is already locked            Path path = getPath(node.getId());            PathMap.Element element = lockMap.map(path, false);            LockInfo other = (LockInfo) element.get();            if (other != null) {                if (element.hasPath(path)) {                    throw new LockException("Node already locked: " + node.safeGetJCRPath());                } else if (other.deep) {                    throw new LockException("Parent node has deep lock.");                }            }            if (info.deep && element.hasPath(path)                    && element.getChildrenCount() > 0) {                throw new LockException("Some child node is locked.");            }            // create lock token            info.setLockHolder(session);            info.setLive(true);            session.addListener(info);            session.addLockToken(info.lockToken.toString(), false);            lockMap.put(path, info);            if (!info.sessionScoped) {                save();                successful = true;            }            return info;        } finally {            release();            if (operation != null) {                operation.ended(successful);            }        }    }    /**     * Unlock a node (internal implementation)     * @param node node to unlock     * @throws LockException       if the node can not be unlocked     * @throws RepositoryException if another error occurs     */    void internalUnlock(NodeImpl node)            throws LockException, RepositoryException {        ClusterOperation operation = null;        boolean successful = false;        if (eventChannel != null) {            operation = eventChannel.create(node.getNodeId());        }                acquire();        try {            SessionImpl session = (SessionImpl) node.getSession();            // check whether node is locked by this session            PathMap.Element element = lockMap.map(                    getPath(node.getId()), true);            if (element == null) {                throw new LockException("Node not locked: " + node.safeGetJCRPath());            }            AbstractLockInfo info = (AbstractLockInfo) element.get();            if (info == null) {                throw new LockException("Node not locked: " + node.safeGetJCRPath());            }            if (session != info.getLockHolder()) {                throw new LockException("Node not locked by session: " + node.safeGetJCRPath());            }            session.removeLockToken(info.getLockToken(session), false);            element.set(null);            info.setLive(false);            if (!info.sessionScoped) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -