Return-Path: X-Original-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9B2EE10A05 for ; Thu, 18 Jul 2013 11:30:12 +0000 (UTC) Received: (qmail 46680 invoked by uid 500); 18 Jul 2013 11:30:12 -0000 Delivered-To: apmail-jackrabbit-oak-commits-archive@jackrabbit.apache.org Received: (qmail 46633 invoked by uid 500); 18 Jul 2013 11:30:11 -0000 Mailing-List: contact oak-commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: oak-dev@jackrabbit.apache.org Delivered-To: mailing list oak-commits@jackrabbit.apache.org Received: (qmail 46581 invoked by uid 99); 18 Jul 2013 11:30:09 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Jul 2013 11:30:09 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Jul 2013 11:30:05 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 6A045238897A; Thu, 18 Jul 2013 11:29:43 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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/ Date: Thu, 18 Jul 2013 11:29:43 -0000 To: oak-commits@jackrabbit.apache.org From: angela@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130718112943.6A045238897A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 readPaths; + private final Cache> userEntryCache; + private final Cache> groupEntryCache; + private PrivilegeBitsProvider bitsProvider; CompiledPermissionImpl(@Nonnull Set 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 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 getEntryIterator(@Nonnull EntryPredicate predicate) { Iterator userEntries = (userTrees.isEmpty()) ? Iterators.emptyIterator() : - new EntryIterator(userTrees, predicate); + new EntryIterator(userEntryCache, userTrees, predicate); Iterator groupEntries = (groupTrees.isEmpty()) ? Iterators.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 { private final Collection principalTrees; + private final Cache> 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 principalTrees, + private EntryIterator(@Nonnull Cache> cache, + @Nonnull Map 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 getNextEntries() { - ImmutableSortedSet.Builder entries = new ImmutableSortedSet.Builder(new EntryComparator()); - for (Tree principalRoot : principalTrees) { + Collection entries = cache.getIfPresent(path); + if (entries == null) { + ImmutableSortedSet.Builder 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.emptyIterator() : Iterators.filter(entries.iterator(), predicate); + } + } + + private final class EntriesLoader extends CacheLoader> { + + private final Map principalTrees; + + private EntriesLoader(Map principalTrees) { + this.principalTrees = principalTrees; + } + + @Override + public Collection load(String path) throws Exception { + ImmutableSortedSet.Builder 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();