Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java (revision 938) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java (working copy) @@ -60,6 +60,7 @@ import org.jboss.dna.jcr.JcrContentHandler.EnclosingSAXException; import org.jboss.dna.jcr.JcrContentHandler.SaveMode; import org.jboss.dna.jcr.JcrRepository.Option; +import org.jboss.dna.jcr.cache.NodeInfo; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -284,8 +285,25 @@ throw new RepositoryException(JcrI18n.invalidPathParameter.text(destAbsPath, "destAbsPath"), e); } + // Doing a literal test here because the path factory will canonicalize "/node[1]" to "/node" + if (destAbsPath.endsWith("]")) { + throw new RepositoryException(); + } + + /* + * Make sure that the node has a definition at the new location + */ + SessionCache cache = this.session.cache(); + NodeInfo nodeInfo = cache.findNodeInfo(null, srcPath); + NodeInfo parent = cache.findNodeInfo(null, destPath.getParent()); + + // This throws a ConstraintViolationException if there is no matching definition + // In practice, this won't always work until we figure out how to refresh the destination parent's cache entry + cache.findBestNodeDefinition(parent.getUuid(), destPath.getLastSegment().getName(), nodeInfo.getPrimaryTypeName()); + // Perform the copy operation, but use the "to" form (not the "into", which takes the parent) ... graph.copy(srcPath).to(destPath); + } /** Index: dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java (revision 938) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java (working copy) @@ -514,7 +514,8 @@ List mixinTypeNames = node.getMixinTypeNames(); Children children = nodeInfo.getChildren(); - int snsCount = children.getCountOfSameNameSiblingsWithName(newNodeName); + // Need to add one to speculate that this node will be added + int snsCount = children.getCountOfSameNameSiblingsWithName(newNodeName) + 1; JcrNodeDefinition definition = nodeTypes().findChildNodeDefinition(primaryTypeName, mixinTypeNames, newNodeName,