String primaryNodeTypeName,
UUID desiredUuid )
throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException,
RepositoryException {
// Determine the path ...
NodeEditor editor = null;
Path path = null;
try {
path = cache.pathFactory().create(relPath);
} catch (org.jboss.dna.graph.property.ValueFormatException e) {
throw new RepositoryException(JcrI18n.invalidPathParameter.text(relPath, "relPath"));
}
if (path.size() == 0) {
throw new RepositoryException(JcrI18n.invalidPathParameter.text(relPath, "relPath"));
}
if (path.getLastSegment().getIndex() > 1 || relPath.endsWith("]")) {
throw new RepositoryException(JcrI18n.invalidPathParameter.text(relPath, "relPath"));
}
if (path.size() > 1) {
// The only segment in the path is the child name ...
Path parentPath = path.getParent();
try {
// Find the parent node ...
Node<JcrNodePayload, JcrPropertyPayload> parentOfNewNode = cache.findNode(nodeId, location.getPath(), parentPath);
editor = cache.getEditorFor(parentOfNewNode);
} catch (RepositoryException e) {
// We're going to throw an exception ... the question is which one ...
try {
Node<JcrNodePayload, JcrPropertyPayload> grandparent;
if (parentPath.size() > 1) {
// Per the TCK, if relPath references a property, then we have to throw a ConstraintViolationException
// So, if we can't find the parent, try for the parent's parent and see if the last segment of the
// parent's
// path contains a property ...
Path grandparentPath = parentPath.getParent();
assert grandparentPath != null;
grandparent = cache.findNode(nodeId, location.getPath(), grandparentPath); // throws
// PathNotFoundException
} else {
grandparent = this.nodeInfo();
}
if (grandparent.getProperty(parentPath.getLastSegment().getName()) != null) {
// Need to throw a ConstraintViolationException since the request was to add a child to
// a property ...
throw new ConstraintViolationException(JcrI18n.invalidPathParameter.text(relPath, "relPath"));
}
} catch (PathNotFoundException e2) {
// eat, since the original exception is what we want ...
}
// Otherwise, just throw the PathNotFoundException ...
throw e;
}
} else {
assert path.size() == 1;
editor = editor();
}
Name childName = path.getLastSegment().getName();
// Determine the name for the primary node type
Name childPrimaryTypeName = null;
if (primaryNodeTypeName != null) {
try {
childPrimaryTypeName = cache.nameFactory().create(primaryNodeTypeName);
} catch (org.jboss.dna.graph.property.ValueFormatException e) {
throw new RepositoryException(JcrI18n.invalidNodeTypeNameParameter.text(primaryNodeTypeName,
"primaryNodeTypeName"));
}
}
// Create the child ...
return editor.createChild(childName, desiredUuid, childPrimaryTypeName);
}