Author: angela
Date: Tue Nov 22 17:46:45 2016
New Revision: 1770863

URL: http://svn.apache.org/viewvc?rev=1770863&view=rev
Log:
OAK-5025 : Speed up ACE node name generation

Added:
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/AceCreationTest.java
Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/Util.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
    
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java?rev=1770863&r1=1770862&r2=1770863&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
 Tue Nov 22 17:46:45 2016
@@ -280,10 +280,11 @@ public class AccessControlManagerImpl ex
             aclTree = createAclTree(oakPath, tree);
         }
         aclTree.setOrderableChildren(true);
-        for (ACE ace : acl.getEntries()) {
-            boolean isAllow = ace.isAllow();
-            String nodeName = Util.generateAceName(aclTree, isAllow);
-            String ntName = (isAllow) ? NT_REP_GRANT_ACE : NT_REP_DENY_ACE;
+        List<ACE> entries = acl.getEntries();
+        for (int i = 0; i < entries.size(); i++) {
+            ACE ace = entries.get(i);
+            String nodeName = Util.generateAceName(ace, i);
+            String ntName = (ace.isAllow()) ? NT_REP_GRANT_ACE : 
NT_REP_DENY_ACE;
 
             NodeUtil aceNode = new NodeUtil(aclTree).addChild(nodeName, 
ntName);
             aceNode.setString(REP_PRINCIPAL_NAME, 
ace.getPrincipal().getName());

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/Util.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/Util.java?rev=1770863&r1=1770862&r2=1770863&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/Util.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/Util.java
 Tue Nov 22 17:46:45 2016
@@ -27,6 +27,7 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ACE;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
@@ -113,22 +114,20 @@ final class Util implements AccessContro
     }
 
     /**
-     * Create a unique valid name for the Permission nodes to be save.
+     * Create a valid name for the ACE node based on the entry and it's index.
      *
-     * @param aclTree The acl for which a new ACE name should be generated.
-     * @param isAllow If the ACE is allowing or denying.
+     * @param ace The access control entry.
+     * @param index The index of the entry in the list
      * @return the name of the ACE node.
      */
     @Nonnull
-    public static String generateAceName(@Nonnull Tree aclTree, boolean 
isAllow) {
-        int i = 0;
-        String hint = (isAllow) ? "allow" : "deny";
-        String aceName = hint;
-        while (aclTree.hasChild(aceName)) {
-            aceName = hint + i;
-            i++;
+    public static String generateAceName(@Nonnull ACE ace, int index) {
+        String hint = (ace.isAllow()) ? "allow" : "deny";
+        if (index == 0) {
+            return hint;
+        } else {
+            return hint + index;
         }
-        return aceName;
     }
 
     public static int getImportBehavior(AuthorizationConfiguration config) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java?rev=1770863&r1=1770862&r2=1770863&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
 Tue Nov 22 17:46:45 2016
@@ -44,10 +44,12 @@ import javax.jcr.security.AccessControlP
 import javax.jcr.security.AccessControlPolicyIterator;
 import javax.jcr.security.Privilege;
 
+import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
+import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
@@ -1396,6 +1398,65 @@ public class AccessControlManagerImplTes
         }
     }
 
+    @Test
+    public void testSetPolicyModifiesRoot() throws Exception {
+        ACL acl = getApplicablePolicy(testPath);
+        assertTrue(acl.addAccessControlEntry(testPrincipal, testPrivileges));
+        assertFalse(root.hasPendingChanges());
+
+        acMgr.setPolicy(testPath, acl);
+        assertTrue(root.hasPendingChanges());
+
+        root.commit();
+
+        acl = (ACL) acMgr.getPolicies(testPath)[0];
+        assertEquals(1, acl.getAccessControlEntries().length);
+
+        acl.addEntry(EveryonePrincipal.getInstance(), testPrivileges, false, 
getGlobRestriction("*/something"));
+        acMgr.setPolicy(testPath, acl);
+        assertTrue(root.hasPendingChanges());
+
+        root.commit();
+
+        acl = (ACL) acMgr.getPolicies(testPath)[0];
+        assertEquals(2, acl.getAccessControlEntries().length);
+    }
+
+    @Test
+    public void testSetPolicyWithRestrictions() throws Exception {
+        ACL acl = getApplicablePolicy(testPath);
+        acl.addEntry(testPrincipal, testPrivileges, true, 
ImmutableMap.of(AccessControlConstants.REP_GLOB, 
getValueFactory().createValue("/a/b")));
+        acl.addEntry(testPrincipal, testPrivileges, true, 
ImmutableMap.of(AccessControlConstants.REP_GLOB, 
getValueFactory().createValue("/c/d")));
+        acMgr.setPolicy(testPath, acl);
+        root.commit();
+
+        ACL l = (ACL) acMgr.getPolicies(testPath)[0];
+        assertEquals(2, l.getAccessControlEntries().length);
+    }
+
+    @Test
+    public void testSetPolicyCreatesIndexedAceNodeNames() throws Exception {
+        ACL acl = getApplicablePolicy(testPath);
+        assertTrue(acl.addAccessControlEntry(testPrincipal, testPrivileges));
+        assertTrue(acl.addEntry(testPrincipal, testPrivileges, true, 
ImmutableMap.of(AccessControlConstants.REP_GLOB, 
getValueFactory().createValue("/*/a"))));
+        assertTrue(acl.addEntry(EveryonePrincipal.getInstance(), 
testPrivileges, false));
+        assertTrue(acl.addEntry(EveryonePrincipal.getInstance(), 
testPrivileges, false, ImmutableMap.of(AccessControlConstants.REP_GLOB, 
getValueFactory().createValue("/*/a"))));
+        acMgr.setPolicy(testPath, acl);
+        root.commit();
+
+        acl = (ACL) acMgr.getPolicies(testPath)[0];
+        assertEquals(4, acl.getAccessControlEntries().length);
+
+        Iterable<Tree> aceTrees = 
root.getTree(testPath).getChild(AccessControlConstants.REP_POLICY).getChildren();
+        String[] aceNodeNames = 
Iterables.toArray(Iterables.transform(aceTrees, new Function<Tree, String>() {
+            @Override
+            public String apply(Tree aceTree) {
+                return aceTree.getName();
+            }
+        }), String.class);
+        assertArrayEquals(new String[]{"allow", "allow1", "deny2", "deny3"}, 
aceNodeNames);
+    }
+
     //--------------------------< removePolicy(String, AccessControlPolicy) 
>---
     @Test
     public void testRemovePolicy() throws Exception {

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java?rev=1770863&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java
 Tue Nov 22 17:46:45 2016
@@ -0,0 +1,109 @@
+/*
+ * 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.security.authorization.accesscontrol;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ACE;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+public class UtilTest extends AbstractSecurityTest {
+
+    private static final String DENY = "deny";
+    private static final String ALLOW = "allow";
+
+    private PrivilegeBitsProvider bitsProvider;
+
+    @Override
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        bitsProvider = new PrivilegeBitsProvider(root);
+    }
+
+    @Test
+    public void testGenerateName() throws AccessControlException {
+        ACE ace = new TestAce(true);
+        String name = Util.generateAceName(ace, 0);
+
+        assertTrue(name.startsWith(ALLOW));
+        assertEquals(ALLOW, name);
+        assertEquals(name, Util.generateAceName(ace, 0));
+
+        name = Util.generateAceName(ace, 1);
+        assertTrue(name.startsWith(ALLOW));
+        assertEquals(ALLOW + 1, name);
+        assertEquals(name, Util.generateAceName(ace, 1));
+    }
+
+    @Test
+    public void testGenerateName2() throws AccessControlException {
+        ACE ace = new TestAce(false);
+        String name = Util.generateAceName(ace, 0);
+
+        assertTrue(name.startsWith(DENY));
+        assertEquals(DENY, name);
+        assertEquals(name, Util.generateAceName(ace, 0));
+
+        name = Util.generateAceName(ace, 2);
+        assertTrue(name.startsWith(DENY));
+        assertEquals(DENY + 2, name);
+        assertEquals(name, Util.generateAceName(ace, 2));
+    }
+
+    @Test
+    public void testGenerateNameDifferentAllow() throws Exception {
+        ACE allow = new TestAce(false);
+        ACE deny = new TestAce(true);
+
+        assertNotEquals(Util.generateAceName(allow, 0), 
Util.generateAceName(deny, 0));
+        assertNotEquals(Util.generateAceName(allow, 1), 
Util.generateAceName(deny, 1));
+        assertNotEquals(Util.generateAceName(allow, 20), 
Util.generateAceName(deny, 20));
+        assertNotEquals(Util.generateAceName(allow, 0), 
Util.generateAceName(deny, 1));
+        assertNotEquals(Util.generateAceName(allow, 1), 
Util.generateAceName(deny, 20));
+
+    }
+
+    private final class TestAce extends ACE {
+
+        public TestAce(boolean isAllow) throws AccessControlException {
+            super(EveryonePrincipal.getInstance(), 
bitsProvider.getBits(PrivilegeConstants.JCR_READ), isAllow, null, 
NamePathMapper.DEFAULT);
+        }
+
+        @Override
+        public Privilege[] getPrivileges() {
+            try {
+                return 
privilegesFromNames(bitsProvider.getPrivilegeNames(getPrivilegeBits()));
+            } catch (RepositoryException e) {
+                throw new RuntimeException(e.getMessage());
+            }
+        }
+    }
+}

Modified: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java?rev=1770863&r1=1770862&r2=1770863&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
 Tue Nov 22 17:46:45 2016
@@ -42,6 +42,7 @@ import org.apache.commons.io.FileUtils;
 import 
org.apache.jackrabbit.oak.benchmark.authentication.external.ExternalLoginTest;
 import 
org.apache.jackrabbit.oak.benchmark.authentication.external.SyncAllExternalUsersTest;
 import 
org.apache.jackrabbit.oak.benchmark.authentication.external.SyncExternalUsersTest;
+import org.apache.jackrabbit.oak.benchmark.authorization.AceCreationTest;
 import org.apache.jackrabbit.oak.benchmark.wikipedia.WikipediaImport;
 import org.apache.jackrabbit.oak.fixture.JackrabbitRepositoryFixture;
 import org.apache.jackrabbit.oak.fixture.OakFixture;
@@ -116,6 +117,8 @@ public class BenchmarkRunner {
                         
.withOptionalArg().ofType(Long.class).defaultsTo(AbstractLoginTest.NO_CACHE);
         OptionSpec<Integer> numberOfGroups = parser.accepts("numberOfGroups", 
"Number of groups to create.")
                         
.withOptionalArg().ofType(Integer.class).defaultsTo(LoginWithMembershipTest.NUMBER_OF_GROUPS_DEFAULT);
+        OptionSpec<Integer> numberOfInitialAce = 
parser.accepts("numberOfInitialAce", "Number of ACE to create before running 
the test.")
+                
.withOptionalArg().ofType(Integer.class).defaultsTo(AceCreationTest.NUMBER_OF_INITIAL_ACE_DEFAULT);
         OptionSpec<Boolean> nestedGroups = parser.accepts("nestedGroups", "Use 
nested groups.")
                         
.withOptionalArg().ofType(Boolean.class).defaultsTo(false);
         OptionSpec<Integer> batchSize = parser.accepts("batchSize", "Batch 
size before persisting operations.")
@@ -150,6 +153,9 @@ public class BenchmarkRunner {
                 
.withOptionalArg().ofType(Boolean.class).defaultsTo(Boolean.FALSE);
         OptionSpec<String> autoMembership = parser.accepts("autoMembership", 
"Ids of those groups a given external identity automatically become member of.")
                 
.withOptionalArg().ofType(String.class).withValuesSeparatedBy(',');
+        OptionSpec<Boolean> transientWrites = parser.accepts("transient", "Do 
not save data.")
+                .withOptionalArg().ofType(Boolean.class)
+                .defaultsTo(Boolean.FALSE);
         OptionSpec<String> nonOption = parser.nonOptions();
         OptionSpec help = parser.acceptsAll(asList("h", "?", "help"), "show 
help").forHelp();
         OptionSet options = parser.parse(args);
@@ -325,6 +331,8 @@ public class BenchmarkRunner {
                     randomUser.value(options)),
             new ConcurrentWriteACLTest(itemsToRead.value(options)),
             new ConcurrentEveryoneACLTest(runAsAdmin.value(options), 
itemsToRead.value(options)),
+            new AceCreationTest(batchSize.value(options), 
numberOfInitialAce.value(options), transientWrites.value(options)),
+
             ReadManyTest.linear("LinearReadEmpty", 1, ReadManyTest.EMPTY),
             ReadManyTest.linear("LinearReadFiles", 1, ReadManyTest.FILES),
             ReadManyTest.linear("LinearReadNodes", 1, ReadManyTest.NODES),

Added: 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/AceCreationTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/AceCreationTest.java?rev=1770863&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/AceCreationTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/authorization/AceCreationTest.java
 Tue Nov 22 17:46:45 2016
@@ -0,0 +1,130 @@
+package org.apache.jackrabbit.oak.benchmark.authorization;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import 
org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.benchmark.AbstractTest;
+import org.apache.jackrabbit.oak.spi.security.authentication.SystemSubject;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+import javax.security.auth.Subject;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Random;
+
+public class AceCreationTest extends AbstractTest {
+
+    public static final int NUMBER_OF_INITIAL_ACE_DEFAULT = 0;
+    private final int numberOfAce;
+    private final int numberOfInitialAce;
+    private final boolean transientWrites;
+    private String nodePath;
+
+    private Session transientSession;
+
+    public AceCreationTest(int numberOfAce, int numberOfInitialAce, boolean 
transientWrites) {
+        super();
+        this.numberOfAce = numberOfAce;
+        this.numberOfInitialAce = numberOfInitialAce;
+        this.transientWrites = transientWrites;
+    }
+
+    @Override
+    protected void beforeSuite() throws Exception {
+        super.beforeSuite();
+
+        Session session = createOrGetSystemSession();
+        nodePath = session.getRootNode().addNode("test" + new 
Random().nextInt()).getPath();
+
+        save(session, transientWrites);
+        logout(session, transientWrites);
+    }
+
+    @Override
+    protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        Session session = createOrGetSystemSession();
+        createAce(session, numberOfInitialAce);
+
+        save(session, transientWrites);
+        logout(session, transientWrites);
+    }
+
+    @Override
+    protected void afterTest() throws Exception {
+        Session session = createOrGetSystemSession();
+
+        AccessControlManager acm = session.getAccessControlManager();
+        for (AccessControlPolicy policy : acm.getPolicies(nodePath)) {
+            acm.removePolicy(nodePath, policy);
+        }
+        save(session, transientWrites);
+
+        super.afterTest();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            if (transientSession != null) {
+                transientSession.logout();
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    @Override
+    protected void runTest() throws Exception {
+        Session session = createOrGetSystemSession();
+
+        createAce(session, numberOfAce);
+        save(session, transientWrites);
+        logout(session, transientWrites);
+    }
+
+    private void createAce(Session session, int count) throws 
RepositoryException {
+        AccessControlManager acManager = session.getAccessControlManager();
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acManager, nodePath);
+
+        for (int i = 0; i < count; i++) {
+            ImmutableMap<String, Value> restrictions = 
ImmutableMap.of(AccessControlConstants.REP_GLOB, 
session.getValueFactory().createValue(i + ""));
+            acl.addEntry(EveryonePrincipal.getInstance(), 
AccessControlUtils.privilegesFromNames(acManager, 
Privilege.JCR_ADD_CHILD_NODES), true, restrictions);
+        }
+
+        acManager.setPolicy(nodePath, acl);
+    }
+
+    private static void save(Session session, boolean transientWrites) throws 
RepositoryException {
+        if (!transientWrites) {
+            session.save();
+        }
+    }
+
+    private static void logout(Session session, boolean transientWrites) {
+        if (!transientWrites) {
+            session.logout();
+        }
+    }
+
+    private Session createOrGetSystemSession() throws 
PrivilegedActionException {
+        if(transientWrites && transientSession != null) {
+            return transientSession;
+        }
+
+        return (transientSession = 
Subject.doAsPrivileged(SystemSubject.INSTANCE, new 
PrivilegedExceptionAction<Session>() {
+            @Override
+            public Session run() throws Exception {
+                return getRepository().login(null, null);
+            }
+        }, null));
+    }
+}


Reply via email to