Index: src/main/java/org/apache/jackrabbit/core/ItemImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/ItemImpl.java (revision 492483) +++ src/main/java/org/apache/jackrabbit/core/ItemImpl.java (working copy) @@ -23,6 +23,7 @@ import org.apache.jackrabbit.core.nodetype.NodeTypeImpl; import org.apache.jackrabbit.core.nodetype.PropDef; import org.apache.jackrabbit.core.nodetype.PropertyDefinitionImpl; +import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; import org.apache.jackrabbit.core.security.AccessManager; import org.apache.jackrabbit.core.state.ItemState; import org.apache.jackrabbit.core.state.ItemStateException; @@ -474,6 +475,9 @@ */ AccessManager accessMgr = session.getAccessManager(); + NodeTypeManagerImpl ntMgr = session.getNodeTypeManager(); + ItemValidator validator = new ItemValidator(ntMgr.getNodeTypeRegistry(), + session.getHierarchyManager(), session.getNamespaceResolver()); // walk through list of dirty transient items and validate each while (dirtyIter.hasNext()) { ItemState itemState = (ItemState) dirtyIter.next(); @@ -495,12 +499,11 @@ // the transient item is a node NodeState nodeState = (NodeState) itemState; ItemId id = nodeState.getNodeId(); - NodeImpl node = (NodeImpl) itemMgr.getItem(id); - NodeDefinition def = node.getDefinition(); + NodeDefinition def = ntMgr.getNodeDefinition(nodeState.getDefinitionId()); // primary type - NodeTypeImpl pnt = (NodeTypeImpl) node.getPrimaryNodeType(); + NodeTypeImpl pnt = ntMgr.getNodeType(nodeState.getNodeTypeName()); // effective node type (primary type incl. mixins) - EffectiveNodeType ent = node.getEffectiveNodeType(); + EffectiveNodeType ent = validator.getEffectiveNodeType(nodeState); /** * if the transient node was added (i.e. if it is 'new'), * check its node's node type against the required node type @@ -516,7 +519,7 @@ * the transient node's primary node type does not * satisfy the 'required primary types' constraint */ - String msg = node.safeGetJCRPath() + String msg = itemMgr.safeGetJCRPath(id) + " must be of node type " + ntReq.getName(); log.debug(msg); throw new ConstraintViolationException(msg); @@ -537,7 +540,7 @@ continue; } if (!nodeState.hasPropertyName(pd.getName())) { - String msg = node.safeGetJCRPath() + String msg = itemMgr.safeGetJCRPath(id) + ": mandatory property " + pd.getName() + " does not exist"; log.debug(msg); @@ -549,7 +552,7 @@ for (int i = 0; i < cnda.length; i++) { NodeDef cnd = cnda[i]; if (!nodeState.hasChildNodeEntry(cnd.getName())) { - String msg = node.safeGetJCRPath() + String msg = itemMgr.safeGetJCRPath(id) + ": mandatory child node " + cnd.getName() + " does not exist"; log.debug(msg); @@ -560,9 +563,8 @@ // the transient item is a property PropertyState propState = (PropertyState) itemState; ItemId propId = propState.getPropertyId(); - PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propId); PropertyDefinitionImpl def = - (PropertyDefinitionImpl) prop.getDefinition(); + ntMgr.getPropertyDefinition(propState.getDefinitionId()); /** * check value constraints @@ -579,7 +581,7 @@ def.unwrap(), values); } catch (RepositoryException e) { // repack exception for providing verboser error message - String msg = prop.safeGetJCRPath() + ": " + e.getMessage(); + String msg = itemMgr.safeGetJCRPath(propId) + ": " + e.getMessage(); log.debug(msg); throw new ConstraintViolationException(msg); } @@ -613,13 +615,13 @@ } } } catch (RepositoryException re) { - String msg = prop.safeGetJCRPath() + String msg = itemMgr.safeGetJCRPath(propId) + ": failed to check REFERENCE value constraint"; log.debug(msg); throw new ConstraintViolationException(msg, re); } if (!satisfied) { - String msg = prop.safeGetJCRPath() + String msg = itemMgr.safeGetJCRPath(propId) + ": does not satisfy the value constraint " + constraints[0]; // just report the 1st log.debug(msg); @@ -676,7 +678,7 @@ // walk through list of transient items and persist each one while (iter.hasNext()) { ItemState itemState = (ItemState) iter.next(); - ItemImpl item = itemMgr.getItem(itemState.getId()); + ItemImpl item = itemMgr.getItem(itemState); // persist state of transient item item.makePersistent(); } @@ -750,14 +752,18 @@ private boolean initVersionHistories(Iterator iter) throws RepositoryException { // walk through list of transient items and search for new versionable nodes boolean createdTransientState = false; + NodeTypeManagerImpl ntMgr = session.getNodeTypeManager(); + ItemValidator validator = new ItemValidator(ntMgr.getNodeTypeRegistry(), + session.getHierarchyManager(), session.getNamespaceResolver()); while (iter.hasNext()) { ItemState itemState = (ItemState) iter.next(); if (itemState.isNode()) { - NodeImpl node = (NodeImpl) itemMgr.getItem(itemState.getId()); - if (node.isNodeType(QName.MIX_VERSIONABLE)) { - if (!node.hasProperty(QName.JCR_VERSIONHISTORY)) { + NodeState nodeState = (NodeState) itemState; + EffectiveNodeType nt = validator.getEffectiveNodeType(nodeState); + if (nt.includesNodeType(QName.MIX_VERSIONABLE)) { + if (!nodeState.hasPropertyName(QName.JCR_VERSIONHISTORY)) { + NodeImpl node = (NodeImpl) itemMgr.getItem(itemState.getId()); VersionManager vMgr = session.getVersionManager(); - NodeState nodeState = (NodeState) itemState; /** * check if there's already a version history for that * node; this would e.g. be the case if a versionable Index: src/main/java/org/apache/jackrabbit/core/ItemManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/ItemManager.java (revision 492483) +++ src/main/java/org/apache/jackrabbit/core/ItemManager.java (working copy) @@ -326,6 +326,33 @@ } /** + * Returns the item instance for the given item state. + * @param state the item state + * @return the item instance for the given item state. + * @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 Index: src/main/java/org/apache/jackrabbit/core/observation/EventStateCollection.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/observation/EventStateCollection.java (revision 492483) +++ src/main/java/org/apache/jackrabbit/core/observation/EventStateCollection.java (working copy) @@ -365,13 +365,8 @@ // node created NodeState n = (NodeState) state; NodeId parentId = n.getParentId(); - NodeState parent; - // unknown if parent node is also new - if (stateMgr.hasItemState(parentId)) { - parent = (NodeState) stateMgr.getItemState(parentId); - } else { - parent = (NodeState) changes.get(parentId); - } + // the parent of an added item is always modified or new + NodeState parent = (NodeState) changes.get(parentId); NodeTypeImpl nodeType = getNodeType(parent, session); Set mixins = parent.getMixinTypeNames(); Path path = getPath(n.getNodeId(), hmgr);