itemmanager.java

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

JAVA
781
字号
/* * 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;import org.apache.commons.collections.map.ReferenceMap;import org.apache.jackrabbit.core.nodetype.NodeDefId;import org.apache.jackrabbit.core.nodetype.NodeDefinitionImpl;import org.apache.jackrabbit.core.nodetype.PropDefId;import org.apache.jackrabbit.core.nodetype.PropertyDefinitionImpl;import org.apache.jackrabbit.core.security.AccessManager;import org.apache.jackrabbit.core.state.ItemState;import org.apache.jackrabbit.core.state.ItemStateException;import org.apache.jackrabbit.core.state.ItemStateManager;import org.apache.jackrabbit.core.state.NoSuchItemStateException;import org.apache.jackrabbit.core.state.NodeState;import org.apache.jackrabbit.core.state.PropertyState;import org.apache.jackrabbit.core.state.SessionItemStateManager;import org.apache.jackrabbit.core.state.ItemStateListener;import org.apache.jackrabbit.core.util.Dumpable;import org.apache.jackrabbit.core.version.VersionHistoryImpl;import org.apache.jackrabbit.core.version.VersionImpl;import org.apache.jackrabbit.name.Path;import org.apache.jackrabbit.name.QName;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.jcr.AccessDeniedException;import javax.jcr.ItemNotFoundException;import javax.jcr.NamespaceException;import javax.jcr.NodeIterator;import javax.jcr.PathNotFoundException;import javax.jcr.PropertyIterator;import javax.jcr.RepositoryException;import javax.jcr.nodetype.NodeDefinition;import javax.jcr.nodetype.PropertyDefinition;import java.io.PrintStream;import java.util.ArrayList;import java.util.Iterator;import java.util.Map;/** * There's one <code>ItemManager</code> instance per <code>Session</code> * instance. It is the factory for <code>Node</code> and <code>Property</code> * instances. * <p/> * The <code>ItemManager</code>'s responsabilities are: * <ul> * <li>providing access to <code>Item</code> instances by <code>ItemId</code> * whereas <code>Node</code> and <code>Item</code> are only providing relative access. * <li>returning the instance of an existing <code>Node</code> or <code>Property</code>, * given its absolute path. * <li>creating the per-session instance of a <code>Node</code> * or <code>Property</code> that doesn't exist yet and needs to be created first. * <li>guaranteeing that there aren't multiple instances representing the same * <code>Node</code> or <code>Property</code> associated with the same * <code>Session</code> instance. * <li>maintaining a cache of the item instances it created. * <li>respecting access rights of associated <code>Session</code> in all methods. * </ul> * <p/> * If the parent <code>Session</code> is an <code>XASession</code>, there is * one <code>ItemManager</code> instance per started global transaction. */public class ItemManager implements ItemLifeCycleListener, Dumpable, ItemStateListener {    private static Logger log = LoggerFactory.getLogger(ItemManager.class);    private final NodeDefinition rootNodeDef;    private final NodeId rootNodeId;    protected final SessionImpl session;    private final ItemStateManager itemStateProvider;    private final HierarchyManager hierMgr;    /**     * A cache for item instances created by this <code>ItemManager</code>     */    private final Map itemCache;    /**     * Creates a new per-session instance <code>ItemManager</code> instance.     *     * @param itemStateProvider the item state provider associated with     *                          the new instance     * @param hierMgr           the hierarchy manager     * @param session           the session associated with the new instance     * @param rootNodeDef       the definition of the root node     * @param rootNodeId        the id of the root node     */    protected ItemManager(SessionItemStateManager itemStateProvider, HierarchyManager hierMgr,                          SessionImpl session, NodeDefinition rootNodeDef,                          NodeId rootNodeId) {        this.itemStateProvider = itemStateProvider;        this.hierMgr = hierMgr;        this.session = session;        this.rootNodeDef = rootNodeDef;        this.rootNodeId = rootNodeId;        // setup item cache with weak references to items        itemCache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK);        itemStateProvider.addListener(this);    }    /**     * Disposes this <code>ItemManager</code> and frees resources.     */    void dispose() {        synchronized (itemCache) {            itemCache.clear();        }    }    private NodeDefinition getDefinition(NodeState state)            throws RepositoryException {        NodeDefId defId = state.getDefinitionId();        NodeDefinitionImpl def = session.getNodeTypeManager().getNodeDefinition(defId);        if (def == null) {            /**             * todo need proper way of handling inconsistent/corrupt definition             * e.g. 'flag' items that refer to non-existent definitions             */            log.warn("node at " + safeGetJCRPath(state.getNodeId())                    + " has invalid definitionId (" + defId + ")");            // fallback: try finding applicable definition            NodeImpl parent = (NodeImpl) getItem(state.getParentId());            NodeState parentState = (NodeState) parent.getItemState();            NodeState.ChildNodeEntry cne = parentState.getChildNodeEntry(state.getNodeId());            def = parent.getApplicableChildNodeDefinition(cne.getName(), state.getNodeTypeName());            state.setDefinitionId(def.unwrap().getId());        }        return def;    }    private PropertyDefinition getDefinition(PropertyState state)            throws RepositoryException {        PropDefId defId = state.getDefinitionId();        PropertyDefinitionImpl def = session.getNodeTypeManager().getPropertyDefinition(defId);        if (def == null) {            /**             * todo need proper way of handling inconsistent/corrupt definition             * e.g. 'flag' items that refer to non-existent definitions             */            log.warn("property at " + safeGetJCRPath(state.getPropertyId())                    + " has invalid definitionId (" + defId + ")");            // fallback: try finding applicable definition            NodeImpl parent = (NodeImpl) getItem(state.getParentId());            def = parent.getApplicablePropertyDefinition(                    state.getName(), state.getType(), state.isMultiValued(), true);            state.setDefinitionId(def.unwrap().getId());        }        return def;    }    /**     * Retrieves state of item with given <code>id</code>. If the specified item     * doesn't exist an <code>ItemNotFoundException</code> will be thrown.     * If the item exists but the current session is not granted read access an     * <code>AccessDeniedException</code> will be thrown.     *     * @param id id of item to be retrieved     * @return state state of said item     * @throws ItemNotFoundException if no item with given <code>id</code> exists     * @throws AccessDeniedException if the current session is not allowed to     *                               read the said item     * @throws RepositoryException   if another error occurs     */    private ItemState getItemState(ItemId id)            throws ItemNotFoundException, AccessDeniedException,            RepositoryException {        // check privileges        if (!session.getAccessManager().isGranted(id, AccessManager.READ)) {            // clear cache            ItemImpl item = retrieveItem(id);            if (item != null) {                evictItem(id);            }            throw new AccessDeniedException("cannot read item " + id);        }        try {            return itemStateProvider.getItemState(id);        } catch (NoSuchItemStateException nsise) {            String msg = "no such item: " + id;            log.debug(msg);            throw new ItemNotFoundException(msg);        } catch (ItemStateException ise) {            String msg = "failed to retrieve item state of " + id;            log.error(msg);            throw new RepositoryException(msg, ise);        }    }    //--------------------------------------------------< item access methods >    /**     * Checks if the item with the given path exists.     *     * @param path path to the item to be checked     * @return true if the specified item exists     */    public boolean itemExists(Path path) {        try {            // check sanity of session            session.sanityCheck();            ItemId id = hierMgr.resolvePath(path);            if (id == null) {                return false;            }            // check if state exists for the given item            if (!itemStateProvider.hasItemState(id)) {                return false;            }            // check privileges            if (!session.getAccessManager().isGranted(id, AccessManager.READ)) {                // clear cache                evictItem(id);                // item exists but the session has not been granted read access                return false;            }            return true;        } catch (ItemNotFoundException infe) {            return false;        } catch (RepositoryException re) {            return false;        }    }    /**     * Checks if the item with the given id exists.     *     * @param id id of the item to be checked     * @return true if the specified item exists     */    public boolean itemExists(ItemId id) {        try {            // check sanity of session            session.sanityCheck();            // check if state exists for the given item            if (!itemStateProvider.hasItemState(id)) {                return false;            }            // check privileges            if (!session.getAccessManager().isGranted(id, AccessManager.READ)) {                // clear cache                evictItem(id);                // item exists but the session has not been granted read access                return false;            }            return true;        } catch (ItemNotFoundException infe) {            return false;        } catch (RepositoryException re) {            return false;        }    }    /**     * @return     * @throws RepositoryException     */    NodeImpl getRootNode() throws RepositoryException {        return (NodeImpl) getItem(rootNodeId);    }    /**     * @param path     * @return     * @throws PathNotFoundException     * @throws AccessDeniedException     * @throws RepositoryException     */    public ItemImpl getItem(Path path)            throws PathNotFoundException, AccessDeniedException, RepositoryException {        ItemId id = hierMgr.resolvePath(path);        if (id == null) {            throw new PathNotFoundException(safeGetJCRPath(path));        }        try {            return getItem(id);        } catch (ItemNotFoundException infe) {            throw new PathNotFoundException(safeGetJCRPath(path));        }    }    /**     * @param id     * @return     * @throws RepositoryException     */    public synchronized ItemImpl getItem(ItemId id)            throws ItemNotFoundException, AccessDeniedException, RepositoryException {        // check sanity of session        session.sanityCheck();        // check cache        ItemImpl item = retrieveItem(id);        if (item == null) {            // not yet in cache, need to create instance:            // check privileges            if (!session.getAccessManager().isGranted(id, AccessManager.READ)) {                throw new AccessDeniedException("cannot read item " + id);            }            // create instance of item            item = createItemInstance(id);        }        return item;    }    /**     * Returns the item instance for the given item state.     * @param state the item state     * @return the item instance for the given item <code>state</code>.     * @throws RepositoryException     */    public synchronized ItemImpl getItem(ItemState state)            throws ItemNotFoundException, AccessDeniedException, RepositoryException {        // check sanity of session        session.sanityCheck();        ItemId id = state.getId();        // check cache        ItemImpl item = retrieveItem(id);        if (item == null) {            // not yet in cache, need to create instance:            // only check privileges if state is not new            if (state.getStatus() != ItemState.STATUS_NEW                    && !session.getAccessManager().isGranted(id, AccessManager.READ)) {                throw new AccessDeniedException("cannot read item " + id);            }            // create instance of item            item = createItemInstance(id);        }        return item;    }    /**     * @param parentId     * @return     * @throws ItemNotFoundException     * @throws AccessDeniedException     * @throws RepositoryException     */    synchronized boolean hasChildNodes(NodeId parentId)            throws ItemNotFoundException, AccessDeniedException, RepositoryException {        // check sanity of session        session.sanityCheck();        ItemState state = getItemState(parentId);        if (!state.isNode()) {            String msg = "can't list child nodes of property " + parentId;            log.debug(msg);            throw new RepositoryException(msg);        }        NodeState nodeState = (NodeState) state;        Iterator iter = nodeState.getChildNodeEntries().iterator();        while (iter.hasNext()) {            NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next();            // check read access            if (session.getAccessManager().isGranted(entry.getId(), AccessManager.READ)) {                return true;            }        }        return false;    }    /**     * @param parentId     * @return     * @throws ItemNotFoundException

⌨️ 快捷键说明

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