Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java (revision 854) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java (working copy) @@ -349,30 +356,31 @@ * * @see javax.jcr.Workspace#move(java.lang.String, java.lang.String) */ - @SuppressWarnings( "unused" ) public void move( String srcAbsPath, String destAbsPath ) throws PathNotFoundException, RepositoryException { - CheckArg.isNotEmpty(srcAbsPath, "srcAbsPath"); - CheckArg.isNotEmpty(destAbsPath, "destAbsPath"); + CheckArg.isNotNull(srcAbsPath, "srcAbsPath"); + CheckArg.isNotNull(destAbsPath, "destAbsPath"); - // Create the paths ... - PathFactory factory = context.getValueFactories().getPathFactory(); - Path srcPath = null; - Path destPath = null; - try { - srcPath = factory.create(srcAbsPath); - } catch (ValueFormatException e) { - throw new RepositoryException(JcrI18n.invalidPathParameter.text(srcAbsPath, "srcAbsPath"), e); + // Use the session's execution context so that we get the transient namespace mappings + PathFactory pathFactory = session.getExecutionContext().getValueFactories().getPathFactory(); + Path destPath = pathFactory.create(destAbsPath); + + Path.Segment newNodeName = destPath.getSegment(destPath.size() - 1); + // Doing a literal test here because the path factory will canonicalize "/node[1]" to "/node" + if (destAbsPath.endsWith("]")) { + throw new RepositoryException(); } - try { - destPath = factory.create(destAbsPath); - } catch (ValueFormatException e) { - throw new RepositoryException(JcrI18n.invalidPathParameter.text(destAbsPath, "destAbsPath"), e); + + AbstractJcrNode sourceNode = session.getNode(pathFactory.create(srcAbsPath)); + AbstractJcrNode newParentNode = session.getNode(destPath.getParent()); + + if (newParentNode.hasNode(newNodeName.getString(session.getExecutionContext().getNamespaceRegistry()))) { + throw new ItemExistsException(); } - // Perform the copy operation, but use the "to" form (not the "into", which takes the parent) ... - // graph.move(srcPath).to(destPath); - throw new UnsupportedOperationException(); + Graph.Batch operations = session.createBatch(); + newParentNode.editorFor(operations).moveToBeChild(sourceNode, newNodeName.getName()); + operations.execute(); } /** Index: dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWorkspaceTest.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWorkspaceTest.java (revision 854) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWorkspaceTest.java (working copy) @@ -178,7 +178,6 @@ assertThat(workspace.getQueryManager(), notNullValue()); } - @Test public void shouldCreateQuery() throws Exception { String statement = "Some query syntax"; @@ -241,8 +240,8 @@ workspace.move(null, null); } - @Test( expected = UnsupportedOperationException.class ) - public void shouldNotAllowMoveFromPathToAnotherPathInSameWorkspace() throws Exception { + @Test + public void shouldAllowMoveFromPathToAnotherPathInSameWorkspace() throws Exception { workspace.move("/a/b", "/b/b-copy"); }