boolean aclScope )
throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException,
RepositoryException {
// Parse the primary type name ...
Name childPrimaryTypeName = null;
try {
childPrimaryTypeName = session.nameFactory().create(primaryNodeTypeName);
} catch (org.modeshape.jcr.value.ValueFormatException e) {
throw new RepositoryException(JcrI18n.invalidNodeTypeNameParameter.text(primaryNodeTypeName, "primaryNodeTypeName"));
}
// Resolve the relative path ...
Path path = null;
try {
path = session.pathFactory().create(relPath);
} catch (org.modeshape.jcr.value.ValueFormatException e) {
throw new RepositoryException(JcrI18n.invalidPathParameter.text(relPath, "relPath"));
}
if (path.size() == 0 || path.isIdentifier() || path.getLastSegment().getIndex() > 1 || relPath.endsWith("]")) {
throw new RepositoryException(JcrI18n.invalidPathParameter.text(relPath, "relPath"));
}
if (path.size() > 1) {
// The relative path points to another node, so look for it ...
Path parentPath = path.getParent();
try {
// Find the parent node ...
AbstractJcrItem parent = session.findItem(this, parentPath);
if (parent instanceof AbstractJcrNode) {
// delegate to the parent node ...
Name childName = path.getLastSegment().getName();
// MODE-1920: check add_child_node permission on parent node
if (!aclScope) {
session.checkPermission(absolutePathFor(parent.path(), path.getLastSegment()),
ModeShapePermissions.ADD_NODE);
}
return ((AbstractJcrNode)parent).addChildNode(childName, childPrimaryTypeName, desiredKey, false, aclScope);
} else if (parent instanceof AbstractJcrProperty) {
// Per the TCK, if relPath references a property, then we have to throw a ConstraintViolationException.
throw new ConstraintViolationException(JcrI18n.invalidPathParameter.text(relPath, "relPath"));
}
} catch (ItemNotFoundException e) {
// We have to convert to a path not found ...
throw new PathNotFoundException(e.getMessage(), e.getCause());
} catch (RepositoryException e) {
throw e;
}
}
// Otherwise, the path has size == 1 and it specifies the child ...
if (!aclScope) {
session.checkPermission(this, ModeShapePermissions.ADD_NODE);
}
Name childName = path.getLastSegment().getName();
return addChildNode(childName, childPrimaryTypeName, desiredKey, false, aclScope);
}