/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jackrabbit.jcr2spi; import javax.jcr.InvalidItemStateException; import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.jackrabbit.util.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <code>MoveMultipleTest</code>... */ public class MoveMultipleTest extends AbstractMoveTest { private static Logger log = LoggerFactory.getLogger(MoveMultipleTest.class); private String originalPath; @Override protected void setUp() throws Exception { super.setUp(); originalPath = moveNode.getPath(); } @Override protected boolean isSessionMove() { return true; } /** * Transiently move a persisted node multiple times and check results * after each move as well as after saving. */ public void testMultipleMove() throws RepositoryException { // 1. move doMove(moveNode.getPath(), destinationPath); // 2. move String destPath2 = srcParentNode.getPath()+"/"+nodeName1; doMove(destinationPath, destPath2); assertTrue(moveNode.getParent().isSame(srcParentNode)); assertEquals(moveNode.getName(), Text.getName(destPath2)); assertEquals(moveNode.getPath(), destPath2); assertFalse(destParentNode.hasNode(Text.getName(destinationPath))); // 3. move String destPath3 = destParentNode.getPath()+"/"+nodeName4; doMove(destPath2, destPath3); assertTrue(moveNode.getParent().isSame(destParentNode)); assertEquals(moveNode.getName(), Text.getName(destPath3)); assertEquals(moveNode.getPath(), destPath3); assertFalse(srcParentNode.hasNode(Text.getName(destPath2))); testRootNode.save(); assertTrue(moveNode.getParent().isSame(destParentNode)); assertEquals(moveNode.getName(), Text.getName(destPath3)); assertEquals(moveNode.getPath(), destPath3); assertFalse(srcParentNode.hasNode(Text.getName(destPath2))); } /** * Test revert of persisted node after multiple transient moves */ public void testRevertingMultipleMove() throws RepositoryException { doMove(moveNode.getPath(), destinationPath); String destPath2 = srcParentNode.getPath()+"/"+nodeName1; doMove(destinationPath, destPath2); String destPath3 = destParentNode.getPath()+"/"+nodeName4; doMove(destPath2, destPath3); superuser.refresh(false); assertEquals(moveNode.getPath(), originalPath); assertTrue(srcParentNode.hasNode(Text.getName(originalPath))); assertFalse(srcParentNode.hasNode(Text.getName(destPath2))); assertFalse(destParentNode.hasNodes()); } /** * Move a new node multiple times and check the hierarchy after saving. */ public void testMultipleMoveNewNode() throws RepositoryException { // add additional nodes Node moveNode2 = moveNode.addNode(nodeName3, testNodeType); doMove(moveNode2.getPath(), destinationPath); String destPath2 = destParentNode.getPath()+"/"+nodeName4; doMove(moveNode2.getPath(), destPath2); String destPath3 = srcParentNode.getPath()+"/"+nodeName4; doMove(moveNode2.getPath(), destPath3); doMove(moveNode2.getPath(), destinationPath); testRootNode.save(); assertTrue(moveNode2.getParent().isSame(destParentNode)); assertEquals(moveNode2.getName(), Text.getName(destinationPath)); assertEquals(moveNode2.getPath(), destinationPath); assertFalse(moveNode2.hasNodes()); superuser.save(); } /** * Move destination after moving the target node. */ public void testMoveDestination() throws RepositoryException { doMove(moveNode.getPath(), destinationPath); doMove(destParentNode.getPath(), srcParentNode.getPath() + "/" + destParentNode.getName()); superuser.save(); assertTrue(destParentNode.getParent().isSame(srcParentNode)); assertTrue(moveNode.getParent().isSame(destParentNode)); } /** * Separately move the persisted 'moveNode' and its transiently added * child node. */ public void testMoveParentAndChild() throws RepositoryException { // add additional nodes Node moveNode2 = moveNode.addNode(nodeName3, testNodeType); Property childProperty = moveNode2.setProperty(propertyName2, "anyString"); Node childNode = moveNode2.addNode(nodeName4, testNodeType); doMove(moveNode.getPath(), destinationPath); doMove(moveNode2.getPath(), srcParentNode.getPath() + "/" + moveNode2.getName()); assertFalse(moveNode.hasNode(moveNode2.getName())); assertFalse(moveNode.hasNodes()); assertTrue(srcParentNode.getNode(moveNode2.getName()).isSame(moveNode2)); doMove(moveNode.getPath(), originalPath); assertEquals(moveNode.getPath(), originalPath); assertFalse(destParentNode.hasNode(Text.getName(destinationPath))); assertFalse(moveNode.hasNode(moveNode2.getName())); assertFalse(moveNode.hasNodes()); assertTrue(srcParentNode.getNode(moveNode2.getName()).isSame(moveNode2)); superuser.save(); assertFalse(moveNode.hasNodes()); assertTrue(moveNode2.hasNode(childNode.getName())); assertTrue(moveNode2.hasProperty(childProperty.getName())); assertTrue(srcParentNode.getNode(moveNode.getName()).isSame(moveNode)); assertTrue(srcParentNode.getNode(moveNode2.getName()).isSame(moveNode2)); } /** * Move a node that has a child node and finally revert the 'move' operations. */ public void testRevertingMoveParentAndChild() throws RepositoryException { Node moveNode2 = moveNode.addNode(nodeName3, testNodeType); // moveNode2 must be persisted in order not to have it removed upon // refresh(false). moveNode.save(); doMove(moveNode.getPath(), destinationPath); doMove(moveNode2.getPath(), srcParentNode.getPath() + "/" + moveNode2.getName()); doMove(moveNode.getPath(), originalPath); testRootNode.refresh(false); // now all 3 move ops must be reverted assertTrue(moveNode2.getParent().isSame(moveNode)); assertTrue(moveNode.getParent().isSame(srcParentNode)); assertFalse(destParentNode.hasNodes()); assertFalse(srcParentNode.hasNode(moveNode2.getName())); } /** * Separately move the new 'moveNode' and its child node. Save 'add' and * 'move' ops in one step. */ public void testMoveNewParentAndNewChild() throws RepositoryException { Node moveNode2 = moveNode.addNode("moveNode2", testNodeType); Property childProperty = moveNode2.setProperty(propertyName2, "anyString"); Node childNode = moveNode2.addNode("childNode", testNodeType); doMove(moveNode2.getPath(), destinationPath); doMove(childNode.getPath(), srcParentNode.getPath() + "/" + childNode.getName()); doMove(moveNode2.getPath(), srcParentNode.getPath() + "/" + nodeName4); superuser.save(); assertTrue(moveNode2.getName().equals(nodeName4)); assertFalse(moveNode2.hasNodes()); assertTrue(moveNode2.hasProperty(childProperty.getName())); assertTrue(moveNode2.getParent().isSame(srcParentNode)); assertTrue(childNode.getParent().isSame(srcParentNode)); } /** * Separately move the persisted 'moveNode' and its 'new' child node. * Check if reverting the changes removes the 'new' child and moves * the persisted moveNode back. */ public void testRevertingMoveParentAndNewChild() throws RepositoryException { Node moveNode2 = moveNode.addNode(nodeName3, testNodeType); doMove(moveNode.getPath(), destinationPath); doMove(moveNode2.getPath(), srcParentNode.getPath() + "/" + moveNode2.getName()); doMove(moveNode.getPath(), originalPath); testRootNode.refresh(false); // moveNode2 which has never been saved, must be removed try { moveNode2.getParent(); fail("Reverting the move of a 'new' node must remove the new node as well."); } catch (InvalidItemStateException e) { // ok } // the persistent 'moveNode' must be moved back to its original position. assertTrue(moveNode.getParent().isSame(srcParentNode)); assertFalse(destParentNode.hasNodes()); } /** * Move a node with child items without having loaded the children before. * Test if children can be accessed afterwards. */ public void testAccessChildrenAfterMove() throws RepositoryException { Property childProperty = moveNode.setProperty(propertyName2, "anyString"); Node childNode = moveNode.addNode(nodeName2, testNodeType); testRootNode.save(); Session otherSession = getHelper().getReadWriteSession(); try { otherSession.move(originalPath, destinationPath); Node mv = (Node) otherSession.getItem(destinationPath); testRootNode.refresh(false); assertTrue(childNode.isSame(mv.getNode(nodeName2))); assertTrue(childProperty.isSame(mv.getProperty(propertyName2))); } finally { otherSession.logout(); } } }