Author: tomekr
Date: Mon Sep 11 13:49:04 2017
New Revision: 1808026
URL: http://svn.apache.org/viewvc?rev=1808026&view=rev
Log:
OAK-6644: Use ReadOnlyNodeBuilder for the read-only mounts
Modified:
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/NodeMap.java
Modified:
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java?rev=1808026&r1=1808025&r2=1808026&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java
(original)
+++
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java
Mon Sep 11 13:49:04 2017
@@ -724,23 +724,10 @@ public class CompositeNodeStoreTest {
//assertTrue(builderFromState.getBaseState().getBoolean("newProperty")); //
FIXME
}
- @Test
+ @Test (expected = UnsupportedOperationException.class)
public void readOnlyMountRejectsChanges() throws Exception {
- NodeState oldState = store.getRoot();
- try {
- NodeBuilder builder = store.getRoot().builder();
- builder.getChildNode("readOnly").child("newChild");
- builder.getChildNode("libs").child("otherChild");
- store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
- } catch (CommitFailedException e) {
- // expected
- // validate that changes were not applied
- CountingDiff countingDiff = new CountingDiff();
- store.getRoot().compareAgainstBaseState(oldState, countingDiff);
- assertThat("Unexpected number of changes",
countingDiff.getNumChanges(), equalTo(0));
- } catch ( Exception e ) {
- throw e;
- }
+ NodeBuilder builder = store.getRoot().builder();
+ builder.getChildNode("readOnly").child("newChild");
}
@Test
Modified:
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java?rev=1808026&r1=1808025&r2=1808026&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java
(original)
+++
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java
Mon Sep 11 13:49:04 2017
@@ -50,8 +50,14 @@ class CommitHookEnhancer implements Comm
Map<MountedNodeStore, NodeState> beforeStates = newHashMap();
Map<MountedNodeStore, NodeState> afterStates = newHashMap();
for (MountedNodeStore mns : ctx.getNonDefaultStores()) {
- afterStates.put(mns,
mns.getNodeStore().rebase(builder.getNodeBuilder(mns)));
- beforeStates.put(mns, builder.getNodeBuilder(mns).getBaseState());
+ if (mns.getMount().isReadOnly()) {
+ NodeState root = mns.getNodeStore().getRoot();
+ afterStates.put(mns, root);
+ beforeStates.put(mns, root);
+ } else {
+ afterStates.put(mns,
mns.getNodeStore().rebase(builder.getNodeBuilder(mns)));
+ beforeStates.put(mns,
builder.getNodeBuilder(mns).getBaseState());
+ }
}
afterStates.put(ctx.getGlobalStore(), after);
beforeStates.put(ctx.getGlobalStore(), before);
Modified:
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java?rev=1808026&r1=1808025&r2=1808026&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java
(original)
+++
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeBuilder.java
Mon Sep 11 13:49:04 2017
@@ -42,14 +42,11 @@ class CompositeNodeBuilder implements No
private final CompositionContext ctx;
- private NodeMap<NodeBuilder> nodeBuilders;
+ private final NodeMap<NodeBuilder> nodeBuilders;
- private final MountedNodeStore owningStore;
-
- CompositeNodeBuilder(String path, NodeMap<NodeBuilder> nodeBuilders,
CompositionContext ctx) {
+ CompositeNodeBuilder(NodeMap<NodeBuilder> nodeBuilders, CompositionContext
ctx) {
this.ctx = ctx;
this.nodeBuilders = nodeBuilders;
- this.owningStore = ctx.getOwningStore(path);
}
NodeBuilder getNodeBuilder(MountedNodeStore mns) {
@@ -58,12 +55,12 @@ class CompositeNodeBuilder implements No
@Override
public CompositeNodeState getNodeState() {
- return new CompositeNodeState(getPath(), nodeBuilders.getAndApply(n ->
n.exists() ? n.getNodeState() : MISSING_NODE), ctx);
+ return new CompositeNodeState(getPath(),
nodeBuilders.getAndApply((mns, b) -> b.exists() ? b.getNodeState() :
MISSING_NODE), ctx);
}
@Override
public CompositeNodeState getBaseState() {
- return new CompositeNodeState(getPath(),
nodeBuilders.getAndApply(NodeBuilder::getBaseState), ctx);
+ return new CompositeNodeState(getPath(),
nodeBuilders.getAndApply((mns, b) -> b.getBaseState()), ctx);
}
// node or property-related methods ; directly delegate to wrapped builder
@@ -213,7 +210,7 @@ class CompositeNodeBuilder implements No
if (!ctx.shouldBeComposite(childPath)) {
return
nodeBuilders.get(ctx.getOwningStore(childPath)).getChildNode(name);
}
- return new CompositeNodeBuilder(childPath, nodeBuilders.lazyApply(b ->
b.getChildNode(name)), ctx);
+ return new CompositeNodeBuilder(nodeBuilders.lazyApply((mns, b) ->
b.getChildNode(name)), ctx);
}
@Override
@@ -226,14 +223,14 @@ class CompositeNodeBuilder implements No
checkState(exists(), "This builder does not exist: " +
PathUtils.getName(getPath()));
String childPath = simpleConcat(getPath(), name);
final MountedNodeStore childStore = ctx.getOwningStore(childPath);
- if (childStore != owningStore &&
!nodeBuilders.get(childStore).exists()) {
+ if (childStore != ctx.getGlobalStore() &&
!nodeBuilders.get(childStore).exists()) {
throw new IllegalStateException("The mount root doesn't exist: " +
getPath() + " for " + childStore);
}
final NodeBuilder childBuilder =
nodeBuilders.get(childStore).setChildNode(name, nodeState);
if (!ctx.shouldBeComposite(childPath)) {
return childBuilder;
}
- return new CompositeNodeBuilder(childPath, nodeBuilders.lazyApply(b ->
b.getChildNode(name)).replaceNode(childStore, childBuilder), ctx);
+ return new CompositeNodeBuilder(nodeBuilders.lazyApply((mns, b) ->
b.getChildNode(name)).replaceNode(childStore, childBuilder), ctx);
}
@Override
@@ -252,7 +249,7 @@ class CompositeNodeBuilder implements No
}
private NodeBuilder getWrappedNodeBuilder() {
- return nodeBuilders.get(owningStore);
+ return nodeBuilders.get(ctx.getGlobalStore());
}
String getPath() {
Modified:
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java?rev=1808026&r1=1808025&r2=1808026&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java
(original)
+++
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeState.java
Mon Sep 11 13:49:04 2017
@@ -26,6 +26,7 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
+import org.apache.jackrabbit.oak.spi.state.ReadOnlyBuilder;
import java.util.List;
@@ -54,15 +55,12 @@ class CompositeNodeState extends Abstrac
private final CompositionContext ctx;
- private final MountedNodeStore owningStore;
-
private final String path;
CompositeNodeState(String path, NodeMap<NodeState> nodeStates,
CompositionContext ctx) {
this.path = ctx.getPathCache().get(path);
this.ctx = ctx;
this.nodeStates = nodeStates;
- this.owningStore = ctx.getOwningStore(getPath());
}
NodeState getNodeState(MountedNodeStore mns) {
@@ -109,7 +107,7 @@ class CompositeNodeState extends Abstrac
if (!ctx.shouldBeComposite(childPath)) {
return
nodeStates.get(ctx.getOwningStore(childPath)).getChildNode(name);
}
- NodeMap<NodeState> newNodeStates = nodeStates.lazyApply(n ->
n.getChildNode(name));
+ NodeMap<NodeState> newNodeStates = nodeStates.lazyApply((mns, n) ->
n.getChildNode(name));
return new CompositeNodeState(childPath, newNodeStates, ctx);
}
@@ -159,9 +157,9 @@ class CompositeNodeState extends Abstrac
if (base instanceof CompositeNodeState) {
CompositeNodeState multiBase = (CompositeNodeState) base;
NodeStateDiff wrappingDiff = new WrappingDiff(diff, multiBase);
- boolean full =
getWrappedNodeState().compareAgainstBaseState(multiBase.getWrappedNodeState(),
new ChildrenDiffFilter(wrappingDiff, owningStore, true));
+ boolean full =
getWrappedNodeState().compareAgainstBaseState(multiBase.getWrappedNodeState(),
new ChildrenDiffFilter(wrappingDiff, ctx.getGlobalStore(), true));
for (MountedNodeStore mns :
ctx.getContributingStoresForNodes(path, nodeStates)) {
- if (owningStore == mns) {
+ if (ctx.getGlobalStore() == mns) {
continue;
}
NodeStateDiff childrenDiffFilter = new
ChildrenDiffFilter(wrappingDiff, mns, false);
@@ -178,11 +176,17 @@ class CompositeNodeState extends Abstrac
// write operations
@Override
public CompositeNodeBuilder builder() {
- return new CompositeNodeBuilder(getPath(),
nodeStates.lazyApply(NodeState::builder), ctx);
+ return new CompositeNodeBuilder(nodeStates.lazyApply((mns, n) -> {
+ if (mns.getMount().isReadOnly()) {
+ return new ReadOnlyBuilder(n);
+ } else {
+ return n.builder();
+ }
+ }), ctx);
}
private NodeState getWrappedNodeState() {
- return nodeStates.get(owningStore);
+ return nodeStates.get(ctx.getGlobalStore());
}
private boolean belongsToStore(MountedNodeStore mns, String childName) {
Modified:
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java?rev=1808026&r1=1808025&r2=1808026&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java
Mon Sep 11 13:49:04 2017
@@ -224,9 +224,14 @@ public class CompositeNodeStore implemen
CompositeNodeBuilder nodeBuilder = (CompositeNodeBuilder) builder;
Map<MountedNodeStore, NodeState> resultStates = newHashMap();
for (MountedNodeStore mountedNodeStore :
ctx.getAllMountedNodeStores()) {
- NodeStore nodeStore = mountedNodeStore.getNodeStore();
- NodeBuilder partialBuilder =
nodeBuilder.getNodeBuilder(mountedNodeStore);
- NodeState result = nodeStore.reset(partialBuilder);
+ NodeState result;
+ if (mountedNodeStore.getMount().isReadOnly()) {
+ result = mountedNodeStore.getNodeStore().getRoot();
+ } else {
+ NodeStore nodeStore = mountedNodeStore.getNodeStore();
+ NodeBuilder partialBuilder =
nodeBuilder.getNodeBuilder(mountedNodeStore);
+ result = nodeStore.reset(partialBuilder);
+ }
resultStates.put(mountedNodeStore, result);
}
return ctx.createRootNodeState(resultStates);
Modified:
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/NodeMap.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/NodeMap.java?rev=1808026&r1=1808025&r2=1808026&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/NodeMap.java
(original)
+++
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/NodeMap.java
Mon Sep 11 13:49:04 2017
@@ -22,6 +22,7 @@ import com.google.common.collect.Immutab
import org.apache.jackrabbit.oak.spi.mount.Mount;
import java.util.Map;
+import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -48,18 +49,22 @@ public class NodeMap<T> {
return suppliers.get(nodeStore).get();
}
- public <R> NodeMap<R> getAndApply(Function<T, R> function) {
+ public <R> NodeMap<R> getAndApply(BiFunction<MountedNodeStore, T, R>
function) {
ImmutableMap.Builder<MountedNodeStore, CacheableSupplier<R>>
newSuppliers = ImmutableMap.builder();
- suppliers.forEach((mns, node) -> newSuppliers.put(mns,
node.getAndApply(function)));
+ suppliers.forEach((mns, node) -> newSuppliers.put(mns,
node.getAndApply(curry(function, mns))));
return new NodeMap<>(newSuppliers.build());
}
- public <R> NodeMap<R> lazyApply(Function<T, R> function) {
+ public <R> NodeMap<R> lazyApply(BiFunction<MountedNodeStore, T, R>
function) {
ImmutableMap.Builder<MountedNodeStore, CacheableSupplier<R>>
newSuppliers = ImmutableMap.builder();
- suppliers.forEach((mns, node) -> newSuppliers.put(mns,
node.lazyApply(function)));
+ suppliers.forEach((mns, node) -> newSuppliers.put(mns,
node.lazyApply(curry(function, mns))));
return new NodeMap<>(newSuppliers.build());
}
+ private static <T, U, R> Function<U, R> curry(BiFunction<T, U, R>
function, T value) {
+ return u -> function.apply(value, u);
+ }
+
public NodeMap<T> replaceNode(MountedNodeStore nodeStore, T node) {
ImmutableMap.Builder<MountedNodeStore, CacheableSupplier<T>>
newSuppliers = ImmutableMap.builder();
suppliers.forEach((mns, n) -> {
@@ -77,7 +82,7 @@ public class NodeMap<T> {
private volatile T value;
- public CacheableSupplier(Supplier<T> supplier) {
+ private CacheableSupplier(Supplier<T> supplier) {
this.supplier = supplier;
}