nodeimpl.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,586 行 · 第 1/5 页
JAVA
1,586 行
/* * 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.jackrabbit.core.nodetype.EffectiveNodeType;import org.apache.jackrabbit.core.nodetype.NodeDef;import org.apache.jackrabbit.core.nodetype.NodeDefId;import org.apache.jackrabbit.core.nodetype.NodeDefinitionImpl;import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;import org.apache.jackrabbit.core.nodetype.PropDef;import org.apache.jackrabbit.core.nodetype.PropertyDefinitionImpl;import org.apache.jackrabbit.core.state.ItemState;import org.apache.jackrabbit.core.state.ItemStateException;import org.apache.jackrabbit.core.state.NodeReferences;import org.apache.jackrabbit.core.state.NodeReferencesId;import org.apache.jackrabbit.core.state.NodeState;import org.apache.jackrabbit.core.state.PropertyState;import org.apache.jackrabbit.core.value.InternalValue;import org.apache.jackrabbit.core.version.LabelVersionSelector;import org.apache.jackrabbit.core.version.InternalFreeze;import org.apache.jackrabbit.core.version.InternalFrozenNode;import org.apache.jackrabbit.core.version.InternalFrozenVersionHistory;import org.apache.jackrabbit.core.version.VersionSelector;import org.apache.jackrabbit.core.version.DateVersionSelector;import org.apache.jackrabbit.core.version.VersionImpl;import org.apache.jackrabbit.core.lock.LockManager;import org.apache.jackrabbit.name.MalformedPathException;import org.apache.jackrabbit.name.NameException;import org.apache.jackrabbit.name.NoPrefixDeclaredException;import org.apache.jackrabbit.name.Path;import org.apache.jackrabbit.name.QName;import org.apache.jackrabbit.name.PathFormat;import org.apache.jackrabbit.name.NameFormat;import org.apache.jackrabbit.util.ChildrenCollectorFilter;import org.apache.jackrabbit.util.IteratorHelper;import org.apache.jackrabbit.uuid.UUID;import org.apache.jackrabbit.value.ValueHelper;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.jcr.AccessDeniedException;import javax.jcr.InvalidItemStateException;import javax.jcr.Item;import javax.jcr.ItemExistsException;import javax.jcr.ItemNotFoundException;import javax.jcr.ItemVisitor;import javax.jcr.MergeException;import javax.jcr.NamespaceException;import javax.jcr.NoSuchWorkspaceException;import javax.jcr.Node;import javax.jcr.NodeIterator;import javax.jcr.PathNotFoundException;import javax.jcr.Property;import javax.jcr.PropertyIterator;import javax.jcr.PropertyType;import javax.jcr.RepositoryException;import javax.jcr.UnsupportedRepositoryOperationException;import javax.jcr.Value;import javax.jcr.ValueFormatException;import javax.jcr.lock.Lock;import javax.jcr.lock.LockException;import javax.jcr.nodetype.ConstraintViolationException;import javax.jcr.nodetype.NoSuchNodeTypeException;import javax.jcr.nodetype.NodeDefinition;import javax.jcr.nodetype.NodeType;import javax.jcr.nodetype.PropertyDefinition;import javax.jcr.version.OnParentVersionAction;import javax.jcr.version.Version;import javax.jcr.version.VersionException;import javax.jcr.version.VersionHistory;import javax.jcr.version.VersionIterator;import java.io.InputStream;import java.util.ArrayList;import java.util.Arrays;import java.util.BitSet;import java.util.Calendar;import java.util.Collections;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;/** * <code>NodeImpl</code> implements the <code>Node</code> interface. */public class NodeImpl extends ItemImpl implements Node { private static Logger log = LoggerFactory.getLogger(NodeImpl.class); /** same as ((NodeState) state).getNodeTypeName(); cached to avoid type casts */ protected final QName primaryTypeName; /** the definition of this node */ protected NodeDefinition definition; // flag set in status passed to getOrCreateProperty if property was created protected static final short CREATED = 0; /** * Protected constructor. * * @param itemMgr the <code>ItemManager</code> that created this <code>Node</code> instance * @param session the <code>Session</code> through which this <code>Node</code> is acquired * @param id id of this <code>Node</code> * @param state state associated with this <code>Node</code> * @param definition definition of <i>this</i> <code>Node</code> * @param listeners listeners on life cylce changes of this <code>NodeImpl</code> */ protected NodeImpl(ItemManager itemMgr, SessionImpl session, NodeId id, NodeState state, NodeDefinition definition, ItemLifeCycleListener[] listeners) { super(itemMgr, session, id, state, listeners); this.definition = definition; // paranoid sanity check NodeTypeRegistry ntReg = session.getNodeTypeManager().getNodeTypeRegistry(); if (ntReg.isRegistered(state.getNodeTypeName())) { primaryTypeName = state.getNodeTypeName(); } else { /** * todo need proper way of handling inconsistent/corrupt node type references * e.g. 'flag' nodes that refer to non-registered node types */ log.warn("Fallback to nt:unstructured due to unknown node type '" + state.getNodeTypeName() + "' of node " + safeGetJCRPath()); primaryTypeName = QName.NT_UNSTRUCTURED; } } /** * Returns the id of the property at <code>relPath</code> or <code>null</code> * if no property exists at <code>relPath</code>. * <p/> * Note that access rights are not checked. * * @param relPath relative path of a (possible) property * @return the id of the property at <code>relPath</code> or * <code>null</code> if no property exists at <code>relPath</code> * @throws RepositoryException if <code>relPath</code> is not a valid * relative path */ protected PropertyId resolveRelativePropertyPath(String relPath) throws RepositoryException { try { /** * first check if relPath is just a name (in which case we don't * have to build & resolve absolute path) */ if (relPath.indexOf('/') == -1) { QName propName = session.getQName(relPath); // check if property entry exists NodeState thisState = (NodeState) state; if (thisState.hasPropertyName(propName)) { return new PropertyId(thisState.getNodeId(), propName); } else { // there's no property with that name return null; } } /** * build and resolve absolute path */ Path p = Path.create(getPrimaryPath(), session.getQPath(relPath), false) .getCanonicalPath(); ItemId id = session.getHierarchyManager().resolvePath(p); if (id == null) { // path not found return null; } if (!id.denotesNode()) { return (PropertyId) id; } else { // not a property return null; } } catch (NameException e) { String msg = "failed to resolve path " + relPath + " relative to " + safeGetJCRPath(); log.debug(msg); throw new RepositoryException(msg, e); } } /** * Returns the id of the node at <code>relPath</code> or <code>null</code> * if no node exists at <code>relPath</code>. * <p/> * Note that access rights are not checked. * * @param relPath relative path of a (possible) node * @return the id of the node at <code>relPath</code> or * <code>null</code> if no node exists at <code>relPath</code> * @throws RepositoryException if <code>relPath</code> is not a valid * relative path */ protected NodeId resolveRelativeNodePath(String relPath) throws RepositoryException { try { /** * first check if relPath is just a name (in which case we don't * have to build & resolve absolute path) */ Path p = session.getQPath(relPath); if (p.getLength() == 1) { Path.PathElement pe = p.getNameElement(); if (pe.denotesName()) { // check if node entry exists NodeState thisState = (NodeState) state; int index = pe.getIndex(); if (index == 0) { index = 1; } NodeState.ChildNodeEntry cne = thisState.getChildNodeEntry(pe.getName(), index); if (cne != null) { return cne.getId(); } else { // there's no child node with that name return null; } } } /** * build and resolve absolute path */ p = Path.create(getPrimaryPath(), p, true); ItemId id = session.getHierarchyManager().resolvePath(p); if (id == null) { // path not found return null; } if (id.denotesNode()) { return (NodeId) id; } else { // not a node return null; } } catch (NameException e) { String msg = "failed to resolve path " + relPath + " relative to " + safeGetJCRPath(); log.debug(msg); throw new RepositoryException(msg, e); } } /** * Determines if there are pending unsaved changes either on <i>this</i> * node or on any node or property in the subtree below it. * * @return <code>true</code> if there are pending unsaved changes, * <code>false</code> otherwise. * @throws RepositoryException if an error occured */ protected boolean hasPendingChanges() throws RepositoryException { if (isTransient()) { return true; } Iterator iter = stateMgr.getDescendantTransientItemStates((NodeId) id); return iter.hasNext(); } protected synchronized ItemState getOrCreateTransientItemState() throws RepositoryException { if (!isTransient()) { try { // make transient (copy-on-write) NodeState transientState = stateMgr.createTransientNodeState((NodeState) state, ItemState.STATUS_EXISTING_MODIFIED); // replace persistent with transient state state = transientState; } catch (ItemStateException ise) { String msg = "failed to create transient state"; log.debug(msg); throw new RepositoryException(msg, ise); } } return state; } /** * Computes the values of well-known system (i.e. protected) properties. * todo: duplicate code in BatchedItemOperations: consolidate and delegate to NodeTypeInstanceHandler * * @param name * @param def * @return * @throws RepositoryException */ protected InternalValue[] computeSystemGeneratedPropertyValues(QName name, PropertyDefinitionImpl def) throws RepositoryException { InternalValue[] genValues = null; /** * todo: need to come up with some callback mechanism for applying system generated values * (e.g. using a NodeTypeInstanceHandler interface) */ NodeState thisState = (NodeState) state; // compute system generated values NodeTypeImpl nt = (NodeTypeImpl) def.getDeclaringNodeType(); if (nt.getQName().equals(QName.MIX_REFERENCEABLE)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?