You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2013/07/18 13:29:43 UTC
svn commit: r1504433 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/
oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/
Author: angela
Date: Thu Jul 18 11:29:42 2013
New Revision: 1504433
URL: http://svn.apache.org/r1504433
Log:
OAK-915: test case illustrating the issue (currently marked to be ignored)
Added:
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CopyTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java?rev=1504433&r1=1504432&r2=1504433&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java Thu Jul 18 11:29:42 2013
@@ -31,6 +31,9 @@ import javax.annotation.Nullable;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterators;
import com.google.common.primitives.Longs;
@@ -64,6 +67,9 @@ class CompiledPermissionImpl implements
private final Set<String> readPaths;
+ private final Cache<String, Collection<PermissionEntry>> userEntryCache;
+ private final Cache<String, Collection<PermissionEntry>> groupEntryCache;
+
private PrivilegeBitsProvider bitsProvider;
CompiledPermissionImpl(@Nonnull Set<Principal> principals,
@@ -88,6 +94,13 @@ class CompiledPermissionImpl implements
}
}
}
+
+ userEntryCache = CacheBuilder.newBuilder().maximumSize(10000).recordStats()
+ .build();
+ //.build(new EntriesLoader(userTrees));
+ groupEntryCache = CacheBuilder.newBuilder().maximumSize(10000).recordStats()
+ .build();
+ //.build(new EntriesLoader(groupTrees));
}
//------------------------------------------------< CompiledPermissions >---
@@ -95,19 +108,39 @@ class CompiledPermissionImpl implements
public void refresh(@Nonnull ImmutableTree permissionsTree,
@Nonnull PrivilegeBitsProvider bitsProvider) {
this.bitsProvider = bitsProvider;
+ boolean refreshU = false;
+ boolean refreshG = false;
// test if a permission has been added for those principals that didn't have one before
for (Principal principal : principals) {
Map<String, Tree> target = getTargetMap(principal);
Tree principalRoot = getPrincipalRoot(permissionsTree, principal);
String pName = principal.getName();
+ boolean isGroup = (principal instanceof Group);
if (principalRoot.exists()) {
if (!target.containsKey(pName) || !principalRoot.equals(target.get(pName))) {
target.put(pName, principalRoot);
+ if (isGroup) {
+ refreshG = true;
+ } else {
+ refreshU = true;
+ }
}
} else {
- target.remove(pName);
+ if (target.remove(pName) != null) {
+ if (isGroup) {
+ refreshG = true;
+ } else {
+ refreshU = true;
+ }
+ }
}
}
+ if (refreshG) {
+ groupEntryCache.invalidateAll();
+ }
+ if (refreshU) {
+ userEntryCache.invalidateAll();
+ }
}
@Override
@@ -264,10 +297,10 @@ class CompiledPermissionImpl implements
private Iterator<PermissionEntry> getEntryIterator(@Nonnull EntryPredicate predicate) {
Iterator<PermissionEntry> userEntries = (userTrees.isEmpty()) ?
Iterators.<PermissionEntry>emptyIterator() :
- new EntryIterator(userTrees, predicate);
+ new EntryIterator(userEntryCache, userTrees, predicate);
Iterator<PermissionEntry> groupEntries = (groupTrees.isEmpty()) ?
Iterators.<PermissionEntry>emptyIterator():
- new EntryIterator(groupTrees, predicate);
+ new EntryIterator(groupEntryCache, groupTrees, predicate);
return Iterators.concat(userEntries, groupEntries);
}
@@ -327,6 +360,7 @@ class CompiledPermissionImpl implements
private class EntryIterator implements Iterator<PermissionEntry> {
private final Collection<Tree> principalTrees;
+ private final Cache<String, Collection<PermissionEntry>> cache;
private final EntryPredicate predicate;
// the next oak path for which to retrieve permission entries
@@ -336,8 +370,10 @@ class CompiledPermissionImpl implements
// the next permission entry
private PermissionEntry next;
- private EntryIterator(@Nonnull Map<String, Tree> principalTrees,
+ private EntryIterator(@Nonnull Cache<String, Collection<PermissionEntry>> cache,
+ @Nonnull Map<String, Tree> principalTrees,
@Nonnull EntryPredicate predicate) {
+ this.cache = cache;
this.principalTrees = principalTrees.values();
this.predicate = predicate;
this.path = Strings.nullToEmpty(predicate.path);
@@ -382,19 +418,49 @@ class CompiledPermissionImpl implements
@Nonnull
private Iterator<PermissionEntry> getNextEntries() {
- ImmutableSortedSet.Builder<PermissionEntry> entries = new ImmutableSortedSet.Builder(new EntryComparator());
- for (Tree principalRoot : principalTrees) {
+ Collection entries = cache.getIfPresent(path);
+ if (entries == null) {
+ ImmutableSortedSet.Builder<PermissionEntry> es = new ImmutableSortedSet.Builder(new EntryComparator());
+ for (Tree principalRoot : principalTrees) {
+ String name = PermissionUtil.getEntryName(path);
+ Tree parent = principalRoot;
+ while (parent.hasChild(name)) {
+ parent = parent.getChild(name);
+ PermissionEntry pe = new PermissionEntry(parent, restrictionProvider);
+ es.add(pe);
+// if (predicate.apply(pe)) {
+// es.add(pe);
+// }
+ }
+ }
+ entries = es.build();
+ cache.put(path, entries);
+ }
+ return (entries == null) ? Iterators.<PermissionEntry>emptyIterator() : Iterators.filter(entries.iterator(), predicate);
+ }
+ }
+
+ private final class EntriesLoader extends CacheLoader<String, Collection<PermissionEntry>> {
+
+ private final Map<String, Tree> principalTrees;
+
+ private EntriesLoader(Map<String, Tree> principalTrees) {
+ this.principalTrees = principalTrees;
+ }
+
+ @Override
+ public Collection<PermissionEntry> load(String path) throws Exception {
+ ImmutableSortedSet.Builder<PermissionEntry> es = new ImmutableSortedSet.Builder(new EntryComparator());
+ for (Tree principalRoot : principalTrees.values()) {
String name = PermissionUtil.getEntryName(path);
Tree parent = principalRoot;
while (parent.hasChild(name)) {
parent = parent.getChild(name);
PermissionEntry pe = new PermissionEntry(parent, restrictionProvider);
- if (predicate.apply(pe)) {
- entries.add(pe);
- }
+ es.add(pe);
}
}
- return entries.build().iterator();
+ return es.build();
}
}
Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CopyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CopyTest.java?rev=1504433&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CopyTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/CopyTest.java Thu Jul 18 11:29:42 2013
@@ -0,0 +1,113 @@
+/*
+ * 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.jcr;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class CopyTest extends AbstractRepositoryTest {
+
+ private static final String TEST_NODE = "test_node";
+ private static final String TEST_PATH = '/' + TEST_NODE;
+
+ public CopyTest(NodeStoreFixture fixture) {
+ super(fixture);
+ }
+
+ @Before
+ public void setup() throws RepositoryException {
+ Session session = getAdminSession();
+ ValueFactory valueFactory = session.getValueFactory();
+ Node root = session.getRootNode();
+ Node foo = root.addNode("foo");
+ foo.setProperty("stringProp", "stringVal");
+ foo.setProperty("intProp", 42);
+ foo.setProperty("mvProp", new Value[]{
+ valueFactory.createValue(1),
+ valueFactory.createValue(2),
+ valueFactory.createValue(3),
+ });
+ root.addNode("bar");
+ root.addNode(TEST_NODE);
+ session.save();
+ }
+
+ @Test
+ public void testCopyNode() throws RepositoryException {
+ Session session = getAdminSession();
+
+ Node node = session.getNode(TEST_PATH);
+ node.addNode("source").addNode("node");
+ node.addNode("target");
+ session.save();
+
+ session.getWorkspace().copy(TEST_PATH + "/source/node", TEST_PATH + "/target/copied");
+
+ assertTrue(node.hasNode("source/node"));
+ assertTrue(node.hasNode("target/copied"));
+ }
+
+ @Ignore("OAK-915") // FIXME
+ @Test
+ public void testCopyReferenceableNode() throws Exception {
+ Session session = getAdminSession();
+
+ Node node = session.getNode(TEST_PATH);
+ node.addNode("source").addNode("node").addMixin(JcrConstants.MIX_REFERENCEABLE);
+ node.addNode("target");
+ session.save();
+
+ session.getWorkspace().copy(TEST_PATH + "/source/node", TEST_PATH + "/target/copied");
+
+ assertTrue(node.hasNode("source/node"));
+ assertTrue(node.hasNode("target/copied"));
+ Node copy = node.getNode("target/copied");
+ assertTrue(copy.isNodeType(JcrConstants.MIX_REFERENCEABLE));
+ assertFalse(copy.getUUID().equals(node.getNode("source/node").getUUID()));
+ }
+
+ @Ignore("OAK-915") // FIXME
+ @Test
+ public void testCopyReferenceableChildNode() throws Exception {
+ Session session = getAdminSession();
+
+ Node node = session.getNode(TEST_PATH);
+ node.addNode("source").addNode("node").addNode("child").addMixin(JcrConstants.MIX_REFERENCEABLE);
+ node.addNode("target");
+ session.save();
+
+ session.getWorkspace().copy(TEST_PATH + "/source/node", TEST_PATH + "/target/copied");
+
+ assertTrue(node.hasNode("source/node"));
+ assertTrue(node.hasNode("target/copied"));
+
+ Node childCopy = node.getNode("target/copied/child");
+ assertTrue(childCopy.isNodeType(JcrConstants.MIX_REFERENCEABLE));
+ assertFalse(childCopy.getUUID().equals(node.getNode("source/node/child").getUUID()));
+ }
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java?rev=1504433&r1=1504432&r2=1504433&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java Thu Jul 18 11:29:42 2013
@@ -18,14 +18,6 @@
*/
package org.apache.jackrabbit.oak.jcr;
-import static java.util.Arrays.asList;
-import static org.apache.jackrabbit.commons.JcrUtils.getChildNodes;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -35,7 +27,6 @@ import java.math.BigDecimal;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
-
import javax.jcr.Binary;
import javax.jcr.GuestCredentials;
import javax.jcr.InvalidItemStateException;
@@ -68,6 +59,14 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
+import static java.util.Arrays.asList;
+import static org.apache.jackrabbit.commons.JcrUtils.getChildNodes;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
public class RepositoryTest extends AbstractRepositoryTest {
private static final String TEST_NODE = "test_node";
private static final String TEST_PATH = '/' + TEST_NODE;
@@ -1619,21 +1618,6 @@ public class RepositoryTest extends Abst
}
@Test
- public void workspaceCopy() throws RepositoryException {
- Session session = getAdminSession();
-
- Node node = getNode(TEST_PATH);
- node.addNode("source").addNode("node");
- node.addNode("target");
- session.save();
-
- session.getWorkspace().copy(TEST_PATH + "/source/node", TEST_PATH + "/target/copied");
-
- assertTrue(node.hasNode("source/node"));
- assertTrue(node.hasNode("target/copied"));
- }
-
- @Test
public void invalidItemStateExceptionOnRemovedNode() throws Exception {
Session session = getAdminSession();