blob: cda5374825602818efeae01d25a011176a18f7c6 [file] [log] [blame]
/*
* 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));
}
}