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 md...@apache.org on 2013/07/29 15:32:48 UTC

svn commit: r1508054 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: core/RootImpl.java core/SecureNodeBuilder.java util/LazyValue.java

Author: mduerig
Date: Mon Jul 29 13:32:47 2013
New Revision: 1508054

URL: http://svn.apache.org/r1508054
Log:
OAK-929: Permission changes not visible on root after refresh
Don't pass uninitialised Root to permission provider

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/LazyValue.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeBuilder.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java?rev=1508054&r1=1508053&r2=1508054&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java Mon Jul 29 13:32:47 2013
@@ -60,6 +60,7 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
+import org.apache.jackrabbit.oak.util.LazyValue;
 
 public class RootImpl implements Root {
 
@@ -116,7 +117,12 @@ public class RootImpl implements Root {
      */
     private long modCount;
 
-    private PermissionProvider permissionProvider;
+    private LazyValue<PermissionProvider> permissionProvider = new LazyValue<PermissionProvider>() {
+        @Override
+        protected PermissionProvider createValue() {
+            return getAcConfig().getPermissionProvider(RootImpl.this, subject.getPrincipals());
+        }
+    };
 
     /**
      * New instance bases on a given {@link NodeStore} and a workspace
@@ -146,7 +152,7 @@ public class RootImpl implements Root {
         branch = this.store.branch();
         NodeState root = branch.getHead();
         builder = root.builder();
-        secureBuilder = new SecureNodeBuilder(builder, getPermissionProvider(), getAcContext());
+        secureBuilder = new SecureNodeBuilder(builder, permissionProvider, getAcContext());
         rootTree = new MutableTree(this, secureBuilder, lastMove);
     }
  
@@ -222,7 +228,7 @@ public class RootImpl implements Root {
             branch.rebase();
             reset();
             if (permissionProvider != null) {
-                permissionProvider.refresh();
+                permissionProvider.get().refresh();
             }
         }
     }
@@ -234,7 +240,7 @@ public class RootImpl implements Root {
         reset();
         modCount = 0;
         if (permissionProvider != null) {
-            permissionProvider.refresh();
+            permissionProvider.get().refresh();
         }
     }
 
@@ -298,7 +304,7 @@ public class RootImpl implements Root {
      */
     private Subject getCommitSubject() {
         return new Subject(true, subject.getPrincipals(),
-                Collections.singleton(getPermissionProvider()), Collections.<Object>emptySet());
+                Collections.singleton(permissionProvider.get()), Collections.<Object>emptySet());
     }
 
     @Override
@@ -367,7 +373,7 @@ public class RootImpl implements Root {
      */
     NodeState getSecureBase() {
         NodeState root = branch.getBase();
-        return new SecureNodeState(root, getPermissionProvider(), getAcContext());
+        return new SecureNodeState(root, permissionProvider.get(), getAcContext());
     }
 
     // TODO better way to determine purge limit. See OAK-175
@@ -390,14 +396,6 @@ public class RootImpl implements Root {
         return builder.getNodeState();
     }
 
-    @Nonnull
-    private PermissionProvider getPermissionProvider() {
-        if (permissionProvider == null) {
-            permissionProvider = createPermissionProvider();
-        }
-        return permissionProvider;
-    }
-
     /**
      * Purge all pending changes to the underlying {@link NodeStoreBranch}.
      */
@@ -415,11 +413,6 @@ public class RootImpl implements Root {
     }
 
     @Nonnull
-    private PermissionProvider createPermissionProvider() {
-        return getAcConfig().getPermissionProvider(this, subject.getPrincipals());
-    }
-
-    @Nonnull
     private Context getAcContext() {
         return getAcConfig().getContext();
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeBuilder.java?rev=1508054&r1=1508053&r2=1508054&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeBuilder.java Mon Jul 29 13:32:47 2013
@@ -39,6 +39,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.util.LazyValue;
 
 class SecureNodeBuilder implements NodeBuilder {
 
@@ -61,7 +62,7 @@ class SecureNodeBuilder implements NodeB
     /**
      * Permissions provider for evaluating access rights to the underlying raw builder
      */
-    private final PermissionProvider permissionProvider;
+    private final LazyValue<PermissionProvider> permissionProvider;
 
     /**
      * Access control context for evaluating access rights to the underlying raw builder
@@ -89,8 +90,8 @@ class SecureNodeBuilder implements NodeB
      */
     private SecurityContext securityContext;
 
-    SecureNodeBuilder(@Nonnull NodeBuilder builder, @Nonnull PermissionProvider permissionProvider,
-            @Nonnull Context acContext) {
+    SecureNodeBuilder(@Nonnull NodeBuilder builder,
+            @Nonnull LazyValue<PermissionProvider> permissionProvider, @Nonnull Context acContext) {
         this.rootBuilder = this;
         this.parent = null;
         this.name = null;
@@ -312,9 +313,11 @@ class SecureNodeBuilder implements NodeB
     private SecurityContext getSecurityContext() {
         if (securityContext == null || rootBuilder.baseRevision != baseRevision) {
             if (parent == null) {
-                securityContext = new SecurityContext(builder.getNodeState(), permissionProvider, acContext);
+                securityContext = new SecurityContext(
+                        builder.getNodeState(), permissionProvider.get() , acContext);
             } else {
-                securityContext = parent.getSecurityContext().getChildContext(name, parent.builder.getChildNode(name).getBaseState());
+                securityContext = parent.getSecurityContext().getChildContext(
+                        name, parent.builder.getChildNode(name).getBaseState());
             }
             baseRevision = rootBuilder.baseRevision;
         }

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/LazyValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/LazyValue.java?rev=1508054&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/LazyValue.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/LazyValue.java Mon Jul 29 13:32:47 2013
@@ -0,0 +1,37 @@
+package org.apache.jackrabbit.oak.util;
+
+/**
+ * An instances of this class represents a lazy value of type {@code T}.
+ * {@code LazyValue} implements an evaluate by need semantics:
+ * {@link #createValue()} is called exactly once when {@link #get()}
+ * is called for the first time.
+ * <p>
+ * {@code LazyValue} instances are thread safe.
+ */
+public abstract class LazyValue<T> {
+    private volatile T value;
+
+    /**
+     * Factory method called to create the value on an as need basis.
+     * @return a new instance for {@code T}.
+     */
+    protected abstract T createValue();
+
+    /**
+     * Get value. Calls {@link #createValue()} if called for the first time.
+     * @return  the value
+     */
+    public T get () {
+        // Double checked locking is fine since Java 5 as long as value is volatile.
+        // See http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
+        if (value == null) {
+            synchronized (this) {
+                if (value == null) {
+                    value = createValue();
+                }
+            }
+        }
+        return value;
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/LazyValue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/LazyValue.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL