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();