abstractversionmanager.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 527 行 · 第 1/2 页

JAVA
527
字号
/* * 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.version;import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;import org.apache.jackrabbit.core.NodeId;import org.apache.jackrabbit.core.NodeImpl;import org.apache.jackrabbit.core.SessionImpl;import org.apache.jackrabbit.core.state.ItemStateException;import org.apache.jackrabbit.core.state.LocalItemStateManager;import org.apache.jackrabbit.core.state.NodeState;import org.apache.jackrabbit.name.QName;import org.apache.jackrabbit.uuid.UUID;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.List;import javax.jcr.RepositoryException;import javax.jcr.Session;import javax.jcr.Value;import javax.jcr.version.VersionException;import javax.jcr.version.VersionHistory;/** * Base implementation of the {@link VersionManager} interface. * <p/> * All read operations must aquire the read lock before reading, all write * operations must aquire the write lock. */abstract class AbstractVersionManager implements VersionManager {    /**     * Logger instance.     */    private static Logger log = LoggerFactory.getLogger(AbstractVersionManager.class);    /**     * State manager for the version storage.     */    protected LocalItemStateManager stateMgr;    /**     * Persistent root node of the version histories.     */    protected NodeStateEx historyRoot;    /**     * the lock on this version manager     */    private final ReadWriteLock rwLock =            new ReentrantWriterPreferenceReadWriteLock() {                /**                 * Allow reader when there is no active writer, or current                 * thread owns the write lock (reentrant).                 */                protected boolean allowReader() {                    return activeWriter_ == null                        || activeWriter_ == Thread.currentThread();                }            };    //-------------------------------------------------------< VersionManager >    /**     * {@inheritDoc}     */    public InternalVersion getVersion(NodeId id) throws RepositoryException {        // lock handling via getItem()        InternalVersion v = (InternalVersion) getItem(id);        if (v == null) {            log.warn("Versioning item not found: " + id);        }        return v;    }    /**     * {@inheritDoc}     */    public InternalVersionHistory getVersionHistory(NodeId id)            throws RepositoryException {        // lock handling via getItem()        return (InternalVersionHistory) getItem(id);    }    /**     * {@inheritDoc}     */    public boolean hasVersionHistory(NodeId id) {        // lock handling via hasItem()        return hasItem(id);    }    /**     * {@inheritDoc}     */    public boolean hasVersion(NodeId id) {        // lock handling via hasItem()        return hasItem(id);    }    //-------------------------------------------------------< implementation >    /**     * aquires the write lock on this version manager.     */    protected void acquireWriteLock() {        while (true) {            try {                rwLock.writeLock().acquire();                return;            } catch (InterruptedException e) {                // ignore            }        }    }    /**     * releases the write lock on this version manager.     */    protected void releaseWriteLock() {        rwLock.writeLock().release();    }    /**     * aquires the read lock on this version manager.     */    protected void acquireReadLock() {        while (true) {            try {                rwLock.readLock().acquire();                return;            } catch (InterruptedException e) {                // ignore            }        }    }    /**     * releases the read lock on this version manager.     */    protected void releaseReadLock() {        rwLock.readLock().release();    }    /**     * Helper for managing write operations.     */    private class WriteOperation {        /**         * Flag for successful completion of the write operation.         */        private boolean success = false;        /**         * Saves the pending operations in the {@link LocalItemStateManager}.         *         * @throws ItemStateException if the pending state is invalid         * @throws RepositoryException if the pending state could not be persisted         */        public void save() throws ItemStateException, RepositoryException {            stateMgr.update();            success = true;        }        /**         * Closes the write operation. The pending operations are cancelled         * if they could not be properly saved. Finally the write lock is         * released.         */        public void close() {            try {                if (!success) {                    // update operation failed, cancel all modifications                    stateMgr.cancel();                }            } finally {                releaseWriteLock();            }        }    }    /**     * Starts a write operation by acquiring the write lock and setting the     * item state manager to the "edit" state. If something goes wrong, the     * write lock is released and an exception is thrown.     * <p>     * The pattern for using this method and the returned helper instance is:     * <pre>     *     WriteOperation operation = startWriteOperation();     *     try {     *         ...     *         operation.save(); // if everything is OK     *         ...     *     } catch (...) {     *         ...     *     } finally {     *         operation.close();     *     }     * </pre>     *     * @return write operation helper     * @throws RepositoryException if the write operation could not be started     */    private WriteOperation startWriteOperation() throws RepositoryException {        boolean success = false;        acquireWriteLock();        try {            stateMgr.edit();            success = true;            return new WriteOperation();        } catch (IllegalStateException e) {            throw new RepositoryException("Unable to start edit operation.", e);        } finally {            if (!success) {                releaseWriteLock();            }        }    }    /**     * {@inheritDoc}     */    public VersionHistory getVersionHistory(Session session, NodeState node)            throws RepositoryException {        acquireReadLock();        try {            NodeId vhId = getVersionHistoryId(node);            if (vhId == null) {                return null;            }            return (VersionHistory) ((SessionImpl) session).getNodeById(vhId);        } finally {            releaseReadLock();        }    }    /**     * Returns the item with the given persistent id. Subclass responsibility.     * <p/>     * Please note, that the overridden method must aquire the readlock before     * reading the state manager.     *     * @param id the id of the item     * @return version item     * @throws RepositoryException if an error occurs     */    protected abstract InternalVersionItem getItem(NodeId id)

⌨️ 快捷键说明

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