Index: src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeBuilder.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeBuilder.java (revision 1584342) +++ src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeBuilder.java (working copy) @@ -22,11 +22,15 @@ import javax.annotation.Nonnull; import org.apache.jackrabbit.oak.api.Blob; +import org.apache.jackrabbit.oak.commons.PathUtils; import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder; +import org.apache.jackrabbit.oak.spi.state.ApplyDiff; import org.apache.jackrabbit.oak.spi.state.NodeBuilder; import org.apache.jackrabbit.oak.spi.state.NodeState; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static org.apache.jackrabbit.oak.spi.state.AbstractNodeState.checkValidName; /** * A node builder implementation for DocumentMK. @@ -63,6 +67,11 @@ @Override public boolean moveTo(NodeBuilder newParent, String newName) { + checkNotNull(newParent); + checkValidName(newName); + if (isRoot() || !exists() || newParent.hasChildNode(newName)) { + return false; + } if (newParent instanceof DocumentNodeBuilder) { // check if this builder is an ancestor of newParent or newParent DocumentNodeBuilder parent = (DocumentNodeBuilder) newParent; @@ -78,11 +87,37 @@ } } } - return super.moveTo(newParent, newName); + if (newParent.exists()) { + // remember current root state and reset root in case + // something goes wrong + NodeState rootState = root.getNodeState(); + boolean success = false; + try { + annotateSourcePath(); + NodeState nodeState = getNodeState(); + new ApplyDiff(newParent.child(newName)).apply(nodeState); + removeRecursive(this); + success = true; + return true; + } finally { + if (!success) { + root.reset(rootState); + } + } + } else { + return false; + } } @Override public Blob createBlob(InputStream stream) throws IOException { return root.createBlob(stream); } + + private static void removeRecursive(NodeBuilder builder) { + for (String name : builder.getChildNodeNames()) { + removeRecursive(builder.getChildNode(name)); + } + builder.remove(); + } } Index: src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentRootBuilder.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentRootBuilder.java (revision 1584342) +++ src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentRootBuilder.java (working copy) @@ -41,7 +41,7 @@ * Number of content updates that need to happen before the updates * are automatically purged to the private branch. */ - static final int UPDATE_LIMIT = Integer.getInteger("update.limit", 1000); + static final int UPDATE_LIMIT = Integer.getInteger("update.limit", 10000); /** * The underlying store