batcheditemoperations.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,596 行 · 第 1/5 页
JAVA
1,596 行
* checked-out, or is non-versionable but its nearest versionable ancestor * is checked-out, or is non-versionable and there are no versionable * ancestors. * * @param nodePath * @throws PathNotFoundException * @throws VersionException * @throws RepositoryException */ protected void verifyCheckedOut(Path nodePath) throws PathNotFoundException, VersionException, RepositoryException { // search nearest ancestor that is versionable, start with node at nodePath /** * FIXME should not only rely on existence of jcr:isCheckedOut property * but also verify that node.isNodeType("mix:versionable")==true; * this would have a negative impact on performance though... */ NodeState nodeState = getNodeState(nodePath); while (!nodeState.hasPropertyName(QName.JCR_ISCHECKEDOUT)) { if (nodePath.denotesRoot()) { return; } nodePath = nodePath.getAncestor(1); nodeState = getNodeState(nodePath); } PropertyId propId = new PropertyId(nodeState.getNodeId(), QName.JCR_ISCHECKEDOUT); PropertyState propState; try { propState = (PropertyState) stateMgr.getItemState(propId); } catch (ItemStateException ise) { String msg = "internal error: failed to retrieve state of " + safeGetJCRPath(propId); log.debug(msg); throw new RepositoryException(msg, ise); } boolean checkedOut = ((Boolean) propState.getValues()[0].internalValue()).booleanValue(); if (!checkedOut) { throw new VersionException(safeGetJCRPath(nodePath) + " is checked-in"); } } /** * Verifies that the node at <code>nodePath</code> is not locked by * somebody else than the current session. * * @param nodePath path of node to check * @throws PathNotFoundException * @throws LockException if write access to the specified path is not allowed * @throws RepositoryException if another error occurs */ protected void verifyUnlocked(Path nodePath) throws LockException, RepositoryException { // make sure there's no foreign lock on node at nodePath lockMgr.checkLock(nodePath, session); } /** * Verifies that the node at <code>nodePath</code> is not protected. * * @param nodePath path of node to check * @throws PathNotFoundException if no node exists at <code>nodePath</code> * @throws ConstraintViolationException if write access to the specified * path is not allowed * @throws RepositoryException if another error occurs */ protected void verifyNotProtected(Path nodePath) throws PathNotFoundException, ConstraintViolationException, RepositoryException { NodeState node = getNodeState(nodePath); NodeDef parentDef = ntReg.getNodeDef(node.getDefinitionId()); if (parentDef.isProtected()) { throw new ConstraintViolationException(safeGetJCRPath(nodePath) + ": node is protected"); } } /** * Retrieves the state of the node at <code>nodePath</code> using the given * item state manager. * <p/> * Note that access rights are <b><i>not</i></b> enforced! * * @param srcStateMgr * @param srcHierMgr * @param nodePath * @return * @throws PathNotFoundException * @throws RepositoryException */ protected NodeState getNodeState(ItemStateManager srcStateMgr, HierarchyManager srcHierMgr, Path nodePath) throws PathNotFoundException, RepositoryException { try { ItemId id = srcHierMgr.resolvePath(nodePath); if (id == null || !id.denotesNode()) { throw new PathNotFoundException(safeGetJCRPath(nodePath)); } return (NodeState) getItemState(srcStateMgr, id); } catch (ItemNotFoundException infe) { throw new PathNotFoundException(safeGetJCRPath(nodePath)); } } /** * Retrieves the state of the item with the specified id using the given * item state manager. * <p/> * Note that access rights are <b><i>not</i></b> enforced! * * @param srcStateMgr * @param id * @return * @throws ItemNotFoundException * @throws RepositoryException */ protected ItemState getItemState(ItemStateManager srcStateMgr, ItemId id) throws ItemNotFoundException, RepositoryException { try { return srcStateMgr.getItemState(id); } catch (NoSuchItemStateException nsise) { throw new ItemNotFoundException(safeGetJCRPath(id)); } catch (ItemStateException ise) { String msg = "internal error: failed to retrieve state of " + safeGetJCRPath(id); log.debug(msg); throw new RepositoryException(msg, ise); } } //------------------------------------------------------< private methods > /** * Computes the values of well-known system (i.e. protected) properties. * todo: duplicate code in NodeImpl: consolidate and delegate to NodeTypeInstanceHandler * * @param parent * @param def * @return the computed values */ private InternalValue[] computeSystemGeneratedPropertyValues(NodeState parent, PropDef def) { InternalValue[] genValues = null; /** * todo: need to come up with some callback mechanism for applying system generated values * (e.g. using a NodeTypeInstanceHandler interface) */ // compute system generated values QName declaringNT = def.getDeclaringNodeType(); QName name = def.getName(); if (QName.MIX_REFERENCEABLE.equals(declaringNT)) { // mix:referenceable node type if (QName.JCR_UUID.equals(name)) { // jcr:uuid property genValues = new InternalValue[]{InternalValue.create( parent.getNodeId().getUUID().toString())}; } } else if (QName.NT_BASE.equals(declaringNT)) { // nt:base node type if (QName.JCR_PRIMARYTYPE.equals(name)) { // jcr:primaryType property genValues = new InternalValue[]{InternalValue.create(parent.getNodeTypeName())}; } else if (QName.JCR_MIXINTYPES.equals(name)) { // jcr:mixinTypes property Set mixins = parent.getMixinTypeNames(); ArrayList values = new ArrayList(mixins.size()); Iterator iter = mixins.iterator(); while (iter.hasNext()) { values.add(InternalValue.create((QName) iter.next())); } genValues = (InternalValue[]) values.toArray(new InternalValue[values.size()]); } } else if (QName.NT_HIERARCHYNODE.equals(declaringNT)) { // nt:hierarchyNode node type if (QName.JCR_CREATED.equals(name)) { // jcr:created property genValues = new InternalValue[]{InternalValue.create(Calendar.getInstance())}; } } else if (QName.NT_RESOURCE.equals(declaringNT)) { // nt:resource node type if (QName.JCR_LASTMODIFIED.equals(name)) { // jcr:lastModified property genValues = new InternalValue[]{InternalValue.create(Calendar.getInstance())}; } } else if (QName.NT_VERSION.equals(declaringNT)) { // nt:version node type if (QName.JCR_CREATED.equals(name)) { // jcr:created property genValues = new InternalValue[]{InternalValue.create(Calendar.getInstance())}; } } return genValues; } /** * Recursively removes the given node state including its properties and * child nodes. * <p/> * The removal of child nodes is subject to the following checks: * access rights, locking & versioning status. Referential integrity * (references) is checked on commit. * <p/> * Note that the child node entry refering to <code>targetState</code> is * <b><i>not</i></b> automatically removed from <code>targetState</code>'s * parent. * * @param targetState * @throws RepositoryException if an error occurs */ private void recursiveRemoveNodeState(NodeState targetState) throws RepositoryException { if (targetState.hasChildNodeEntries()) { // remove child nodes // use temp array to avoid ConcurrentModificationException ArrayList tmp = new ArrayList(targetState.getChildNodeEntries()); // remove from tail to avoid problems with same-name siblings for (int i = tmp.size() - 1; i >= 0; i--) { NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) tmp.get(i); NodeId nodeId = entry.getId(); try { NodeState nodeState = (NodeState) stateMgr.getItemState(nodeId); // check if child node can be removed // (access rights, locking & versioning status); // referential integrity (references) is checked // on commit checkRemoveNode(nodeState, targetState.getNodeId(), CHECK_ACCESS | CHECK_LOCK | CHECK_VERSIONING); // remove child node recursiveRemoveNodeState(nodeState); } catch (ItemStateException ise) { String msg = "internal error: failed to retrieve state of " + nodeId; log.debug(msg); throw new RepositoryException(msg, ise); } // remove child node entry targetState.removeChildNodeEntry(entry.getName(), entry.getIndex()); } } // remove properties // use temp set to avoid ConcurrentModificationException HashSet tmp = new HashSet(targetState.getPropertyNames()); for (Iterator iter = tmp.iterator(); iter.hasNext();) { QName propName = (QName) iter.next(); PropertyId propId = new PropertyId(targetState.getNodeId(), propName); try { PropertyState propState = (PropertyState) stateMgr.getItemState(propId); // remove property entry targetState.removePropertyName(propId.getName()); // destroy property state stateMgr.destroy(propState); } catch (ItemStateException ise) { String msg = "internal error: failed to retrieve state of " + propId; log.debug(msg); throw new RepositoryException(msg, ise); } } // now actually do unlink target state targetState.setParentId(null); // destroy target state (pass overlayed state since target state // might have been modified during unlinking) stateMgr.destroy(targetState.getOverlayedState()); } /** * Recursively copies the specified node state including its properties and * child nodes. * * @param srcState * @param srcStateMgr * @param srcAccessMgr * @param destParentId * @param flag one of * <ul> * <li><code>COPY</code></li> * <li><code>CLONE</code></li> * <li><code>CLONE_REMOVE_EXISTING</code></li> * </ul> * @param refTracker tracks uuid mappings and processed reference properties * @return a deep copy of the given node state and its children * @throws RepositoryException if an error occurs */ private NodeState copyNodeState(NodeState srcState, ItemStateManager srcStateMgr, AccessManager srcAccessMgr, NodeId destParentId, int flag, ReferenceChangeTracker refTracker) throws RepositoryException { NodeState newState; try { NodeId id; EffectiveNodeType ent = getEffectiveNodeType(srcState); boolean referenceable = ent.includesNodeType(QName.MIX_REFERENCEABLE); boolean versionable = ent.includesNodeType(QName.MIX_VERSIONABLE); switch (flag) { case COPY: // always create new uuid id = new NodeId(UUID.randomUUID()); if (referenceable) { // remember uuid mapping refTracker.mappedUUID(srcState.getNodeId().getUUID(), id.getUUID()); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?