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