/* * 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.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import org.apache.jackrabbit.spi.Path; import org.apache.jackrabbit.test.AbstractJCRTest; import org.apache.jackrabbit.test.NotExecutableException; import org.apache.jackrabbit.util.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <code>ReorderMoveTest</code> testing various combinations of move/rename * and reorder with and without intermediate save, revert and other transient * modifications. */ public class ReorderMoveTest extends AbstractJCRTest { private static Logger log = LoggerFactory.getLogger(ReorderMoveTest.class); private Node destParent; private Node srcParent; private String destPath; @Override protected void setUp() throws Exception { super.setUp(); if (!testRootNode.getPrimaryNodeType().hasOrderableChildNodes()) { throw new NotExecutableException("Test node does not have orderable children."); } // create move-destination destParent = testRootNode.addNode(nodeName4, testNodeType); srcParent = testRootNode.addNode(nodeName2, testNodeType); destPath = destParent.getPath() + "/" + nodeName3; testRootNode.save(); } @Override protected void tearDown() throws Exception { destParent = null; srcParent = null; super.tearDown(); } private Node[] createOrderableChildren(boolean sns) throws RepositoryException { String[] childNames; if (sns) { childNames = new String[] {nodeName2, nodeName2, nodeName2, nodeName2}; } else { childNames = new String[] {nodeName1, nodeName2, nodeName3, nodeName4}; } Node[] children = new Node[4]; children[0] = srcParent.addNode(childNames[0], testNodeType); children[1] = srcParent.addNode(childNames[1], testNodeType); children[2] = srcParent.addNode(childNames[2], testNodeType); children[3] = srcParent.addNode(childNames[3], testNodeType); testRootNode.save(); return children; } private static String getRelPath(Node child) throws RepositoryException { if (child == null) { return null; } String path = child.getPath(); return path.substring(path.lastIndexOf('/')+1); } private static void testOrder(Node parent, Node[] children) throws RepositoryException { NodeIterator it = parent.getNodes(); int i = 0; while (it.hasNext()) { Node child = it.nextNode(); assertTrue(child.isSame(children[i])); i++; } } /** * Move a orderable child node and reorder the remaining nodes. */ public void testMoveAndReorder() throws RepositoryException { Node[] children = createOrderableChildren(false); String oldName = children[2].getName(); // move testRootNode.getSession().move(children[2].getPath(), destPath); // reorder srcParent.orderBefore(getRelPath(children[1]), null); testOrder(srcParent, new Node[] {children[0], children[3], children[1]}); testRootNode.save(); testOrder(srcParent, new Node[] {children[0], children[3], children[1]}); assertFalse(srcParent.hasNode(oldName)); } /** * Move a orderable SNS-node and reorder the remaining nodes at source-parent. */ public void testMoveAndReorderSNS() throws RepositoryException { Node[] children = createOrderableChildren(true); String snsName = children[0].getName(); // move testRootNode.getSession().move(children[2].getPath(), destPath); testRootNode.getSession().move(children[1].getPath(), destPath); // reorder srcParent.orderBefore(getRelPath(children[0]), null); testOrder(srcParent, new Node[] {children[3], children[0]}); assertTrue(srcParent.hasNode(snsName+"[1]")); assertTrue(srcParent.hasNode(snsName+"[2]")); assertFalse(srcParent.hasNode(snsName+"[3]")); assertFalse(srcParent.hasNode(snsName+"[4]")); assertFalse(srcParent.hasNode(snsName+"[5]")); testRootNode.save(); testOrder(srcParent, new Node[] {children[3], children[0]}); assertTrue(srcParent.hasNode(snsName+"[1]")); assertTrue(srcParent.hasNode(snsName+"[2]")); assertFalse(srcParent.hasNode(snsName+"[3]")); assertFalse(srcParent.hasNode(snsName+"[4]")); assertFalse(srcParent.hasNode(snsName+"[5]")); // check if move have been successful assertEquals(children[2].getPath(), destPath); assertTrue(children[2].getIndex() == Path.INDEX_DEFAULT); assertEquals(children[1].getPath(), destPath+"[2]"); } /** * Reorder nodes and move one of the reordered siblings * away. Test the ordering of the remaining siblings. */ public void testReorderAndMove() throws RepositoryException { Node[] children = createOrderableChildren(false); // reorder first srcParent.orderBefore(getRelPath(children[0]), null); srcParent.orderBefore(getRelPath(children[3]), getRelPath(children[1])); // move testRootNode.getSession().move(children[3].getPath(), destPath); testOrder(srcParent, new Node[] {children[1], children[2], children[0]}); testRootNode.save(); testOrder(srcParent, new Node[] {children[1], children[2], children[0]}); } /** * Reorder same-name-sibling nodes and move one of the reordered siblings * away. Test the ordering of the remaining siblings. */ public void testReorderAndMoveSNS() throws RepositoryException { Node[] children = createOrderableChildren(true); // reorder first srcParent.orderBefore(getRelPath(children[0]), null); srcParent.orderBefore(getRelPath(children[3]), getRelPath(children[1])); // move testRootNode.getSession().move(children[3].getPath(), destPath); testOrder(srcParent, new Node[] {children[1], children[2], children[0]}); testRootNode.save(); testOrder(srcParent, new Node[] {children[1], children[2], children[0]}); } /** * Any attempt reorder a moved node at its original position must fail. */ public void testReorderMovedNode() throws RepositoryException { Node[] children = createOrderableChildren(false); String relPath = getRelPath(children[2]); testRootNode.getSession().move(children[2].getPath(), destPath); try { srcParent.orderBefore(relPath, null); fail("Reordering a child node that has been moved away must fail."); } catch (ItemNotFoundException e) { // ok } } /** * Move a SNS-node and reorder its original siblings afterwards. * Test if reverting the changes results in the original ordering and * hierarchy. */ public void testRevertMoveAndReorderSNS() throws RepositoryException { Node[] children = createOrderableChildren(true); // move then reorder testRootNode.getSession().move(children[2].getPath(), destPath); srcParent.orderBefore(getRelPath(children[1]), null); srcParent.orderBefore(getRelPath(children[3]), getRelPath(children[0])); testRootNode.refresh(false); testOrder(srcParent, new Node[] {children[0], children[1], children[2], children[3]}); assertFalse(destParent.hasNode(Text.getName(destPath))); } /** * Move a SNS-node, that got its siblings reordered before. * Test if reverting the changes results in the original ordering and * hierarchy. */ public void testRevertReorderAndMoveSNS() throws RepositoryException { Node[] children = createOrderableChildren(true); // reorder then move srcParent.orderBefore(getRelPath(children[1]), null); srcParent.orderBefore(getRelPath(children[3]), getRelPath(children[2])); srcParent.getSession().move(children[2].getPath(), destPath); testRootNode.refresh(false); testOrder(srcParent, new Node[] {children[0], children[1], children[2], children[3]}); assertFalse(destParent.hasNode(Text.getName(destPath))); } /** * Move a SNS-node, that has been reordered before. * Test if reverting the changes results in the original ordering and * hierarchy. */ public void testRevertMoveReorderedSNS() throws RepositoryException { Node[] children = createOrderableChildren(true); // reorder then move srcParent.orderBefore(getRelPath(children[1]), null); srcParent.orderBefore(getRelPath(children[3]), getRelPath(children[2])); srcParent.getSession().move(children[1].getPath(), destPath); testRootNode.refresh(false); testOrder(srcParent, new Node[] {children[0], children[1], children[2], children[3]}); assertFalse(destParent.hasNode(Text.getName(destPath))); } }