| /* |
| * 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.oak.plugins.tree.impl; |
| |
| import java.util.List; |
| import com.google.common.base.Function; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Lists; |
| import org.apache.jackrabbit.JcrConstants; |
| import org.apache.jackrabbit.oak.AbstractSecurityTest; |
| import org.apache.jackrabbit.oak.api.PropertyState; |
| import org.apache.jackrabbit.oak.api.Tree; |
| import org.apache.jackrabbit.oak.plugins.tree.TreeConstants; |
| import org.apache.jackrabbit.oak.plugins.tree.TreeType; |
| import org.apache.jackrabbit.oak.plugins.tree.TreeTypeProvider; |
| import org.apache.jackrabbit.oak.plugins.tree.TreeUtil; |
| import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration; |
| import org.apache.jackrabbit.oak.util.NodeUtil; |
| import org.apache.jackrabbit.util.Text; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| |
| public class ImmutableTreeTest extends AbstractSecurityTest { |
| |
| private static final String HIDDEN_PATH = "/oak:index/acPrincipalName/:index"; |
| |
| private ImmutableTree immutable; |
| |
| @Before |
| public void setUp() throws Exception { |
| Tree tree = root.getTree("/"); |
| NodeUtil node = new NodeUtil(tree); |
| node.addChild("x", JcrConstants.NT_UNSTRUCTURED).addChild("y", JcrConstants.NT_UNSTRUCTURED).addChild("z", JcrConstants.NT_UNSTRUCTURED); |
| |
| Tree orderable = node.addChild("orderable", JcrConstants.NT_UNSTRUCTURED).getTree(); |
| orderable.setOrderableChildren(true); |
| root.commit(); |
| |
| immutable = new ImmutableTree(((AbstractTree) root.getTree("/")).getNodeState()); |
| } |
| |
| @After |
| public void tearDown() { |
| root = null; |
| } |
| |
| @Test |
| public void testGetPath() { |
| assertEquals("/", immutable.getPath()); |
| |
| immutable = immutable.getChild("x"); |
| assertEquals("/x", immutable.getPath()); |
| |
| immutable = immutable.getChild("y"); |
| assertEquals("/x/y", immutable.getPath()); |
| |
| immutable = immutable.getChild("z"); |
| assertEquals("/x/y/z", immutable.getPath()); |
| } |
| |
| @Test |
| public void testGetNodeState() { |
| assertNotNull(immutable.getNodeState()); |
| |
| for (Tree child : immutable.getChildren()) { |
| assertTrue(child instanceof ImmutableTree); |
| assertNotNull(((ImmutableTree) child).getNodeState()); |
| } |
| } |
| |
| @Test |
| public void testRootIsRoot() { |
| assertTrue(immutable.isRoot()); |
| } |
| |
| @Test(expected = IllegalStateException.class) |
| public void testRootGetParent() { |
| immutable.getParent(); |
| } |
| |
| @Test |
| public void testGetParent() { |
| ImmutableTree child = immutable.getChild("x"); |
| assertNotNull(child.getParent()); |
| assertEquals("/", child.getParent().getPath()); |
| } |
| |
| @Test(expected = UnsupportedOperationException.class) |
| public void testGetParentDisconnected() { |
| ImmutableTree child = immutable.getChild("x"); |
| ImmutableTree disconnected = new ImmutableTree(ImmutableTree.ParentProvider.UNSUPPORTED, child.getName(), child.getNodeState()); |
| disconnected.getParent(); |
| } |
| |
| @Test |
| public void testGetName() { |
| assertEquals("x", immutable.getChild("x").getName()); |
| } |
| |
| @Test |
| public void testHiddenGetName() { |
| assertEquals(Text.getName(HIDDEN_PATH), getHiddenTree(immutable).getName()); |
| } |
| |
| @Test |
| public void testNonExistingGetName() { |
| assertEquals("nonExisting", immutable.getChild("nonExisting").getName()); |
| } |
| |
| @Test |
| public void testRootGetName() { |
| assertEquals("", immutable.getName()); |
| } |
| |
| @Test |
| public void testExists() { |
| ImmutableTree child = immutable.getChild("x"); |
| assertTrue(child.exists()); |
| } |
| |
| @Test |
| public void testHiddenExists() { |
| assertTrue(getHiddenTree(immutable).exists()); |
| } |
| |
| @Test |
| public void testNonExisting() { |
| ImmutableTree child = immutable.getChild("nonExisting"); |
| assertNotNull(child); |
| assertFalse(child.exists()); |
| } |
| |
| @Test |
| public void testRootGetStatus() { |
| assertSame(Tree.Status.UNCHANGED, immutable.getStatus()); |
| } |
| |
| @Test |
| public void testGetStatus() { |
| assertSame(Tree.Status.UNCHANGED, immutable.getChild("x").getStatus()); |
| } |
| |
| @Test |
| public void testHiddenGetStatus() { |
| assertSame(Tree.Status.UNCHANGED, getHiddenTree(immutable).getStatus()); |
| } |
| |
| @Test |
| public void testNonExistingGetStatus() { |
| assertSame(Tree.Status.UNCHANGED, immutable.getChild("nonExisting").getStatus()); |
| } |
| |
| @Test |
| public void testHasChild() { |
| assertTrue(immutable.hasChild("x")); |
| } |
| |
| @Test |
| public void testHasHiddenChild() { |
| ImmutableTree parent = (ImmutableTree) TreeUtil.getTree(immutable, Text.getRelativeParent(HIDDEN_PATH, 1)); |
| assertNotNull(parent); |
| assertTrue(parent.hasChild(Text.getName(HIDDEN_PATH))); |
| } |
| |
| @Test |
| public void testGetHiddenNode() { |
| ImmutableTree hidden = getHiddenTree(immutable); |
| assertNotNull(hidden); |
| } |
| |
| |
| @Test |
| public void testHasHiddenProperty() { |
| ImmutableTree orderable = immutable.getChild("orderable"); |
| assertTrue(orderable.hasProperty(TreeConstants.OAK_CHILD_ORDER)); |
| } |
| |
| @Test |
| public void testGetHiddenProperty() { |
| ImmutableTree orderable = immutable.getChild("orderable"); |
| assertNotNull(orderable.getProperty(TreeConstants.OAK_CHILD_ORDER)); |
| } |
| |
| @Test |
| public void testGetPropertyStatus() { |
| ImmutableTree orderable = immutable.getChild("orderable"); |
| assertSame(Tree.Status.UNCHANGED, orderable.getPropertyStatus(TreeConstants.OAK_CHILD_ORDER)); |
| } |
| |
| @Test |
| public void testGetProperties() { |
| ImmutableTree orderable = immutable.getChild("orderable"); |
| List<String> propNames = Lists.newArrayList(TreeConstants.OAK_CHILD_ORDER, JcrConstants.JCR_PRIMARYTYPE); |
| |
| for (PropertyState ps : orderable.getProperties()) { |
| assertTrue(propNames.remove(ps.getName())); |
| } |
| assertEquals(2, orderable.getPropertyCount()); |
| } |
| |
| @Test |
| public void testGetPropertyCount() { |
| ImmutableTree orderable = immutable.getChild("orderable"); |
| assertEquals(2, orderable.getPropertyCount()); |
| } |
| |
| @Test |
| public void orderBefore() throws Exception { |
| Tree t = root.getTree("/x/y/z"); |
| NodeUtil n = new NodeUtil(t); |
| n.addChild("node1", JcrConstants.NT_UNSTRUCTURED); |
| n.addChild("node2", JcrConstants.NT_UNSTRUCTURED); |
| n.addChild("node3", JcrConstants.NT_UNSTRUCTURED); |
| |
| t.getChild("node1").orderBefore("node2"); |
| t.getChild("node3").orderBefore(null); |
| |
| root.commit(); |
| |
| ImmutableTree tree = new ImmutableTree(((AbstractTree) t).getNodeState()); |
| assertSequence(tree.getChildren(), "node1", "node2", "node3"); |
| |
| t.getChild("node3").orderBefore("node2"); |
| root.commit(); |
| |
| tree = new ImmutableTree(((AbstractTree) t).getNodeState()); |
| assertSequence(tree.getChildren(), "node1", "node3", "node2"); |
| |
| t.getChild("node1").orderBefore(null); |
| root.commit(); |
| |
| tree = new ImmutableTree(((AbstractTree) t).getNodeState()); |
| assertSequence(tree.getChildren(), "node3", "node2", "node1"); |
| } |
| |
| private static ImmutableTree getHiddenTree(@NotNull ImmutableTree immutable) { |
| return (ImmutableTree) TreeUtil.getTree(immutable, HIDDEN_PATH); |
| } |
| |
| private static void assertSequence(Iterable<Tree> trees, String... names) { |
| List<String> actual = Lists.newArrayList(Iterables.transform(trees, new Function<Tree, String>() { |
| @Nullable |
| @Override |
| public String apply(Tree input) { |
| return input.getName(); |
| } |
| })); |
| assertEquals(Lists.newArrayList(names), actual); |
| } |
| |
| @Test |
| public void testSetType() { |
| assertNull(immutable.getType()); |
| |
| immutable.setType(TreeType.VERSION); |
| assertSame(TreeType.VERSION, immutable.getType()); |
| |
| immutable.setType(TreeType.DEFAULT); |
| assertSame(TreeType.DEFAULT, immutable.getType()); |
| } |
| |
| @Test |
| public void testGetTypeForImmutableTree() { |
| TreeTypeProvider typeProvider = new TreeTypeProvider(getConfig(AuthorizationConfiguration.class).getContext()); |
| for (String path : new String[] {"/", "/testPath"}) { |
| Tree t = getRootProvider().createReadOnlyRoot(root).getTree(path); |
| assertEquals(TreeType.DEFAULT, typeProvider.getType(t)); |
| // also for repeated calls |
| assertEquals(TreeType.DEFAULT, typeProvider.getType(t)); |
| |
| // the type of an immutable tree is set after the first call irrespective of the passed parent type. |
| assertEquals(TreeType.DEFAULT, typeProvider.getType(t, TreeType.DEFAULT)); |
| assertEquals(TreeType.DEFAULT, typeProvider.getType(t, TreeType.HIDDEN)); |
| } |
| } |
| |
| @Test |
| public void testGetTypeForImmutableTreeWithParent() { |
| TreeTypeProvider typeProvider = new TreeTypeProvider(getConfig(AuthorizationConfiguration.class).getContext()); |
| |
| Tree t = getRootProvider().createReadOnlyRoot(root).getTree("/:hidden/testPath"); |
| assertEquals(TreeType.HIDDEN, typeProvider.getType(t, TreeType.HIDDEN)); |
| |
| // the type of an immutable tree is set after the first call irrespective of the passed parent type. |
| assertEquals(TreeType.HIDDEN, typeProvider.getType(t)); |
| assertEquals(TreeType.HIDDEN, typeProvider.getType(t, TreeType.DEFAULT)); |
| assertEquals(TreeType.HIDDEN, typeProvider.getType(t, TreeType.ACCESS_CONTROL)); |
| assertEquals(TreeType.HIDDEN, typeProvider.getType(t, TreeType.VERSION)); |
| } |
| } |