Author: chetanm
Date: Wed Oct 19 15:13:47 2016
New Revision: 1765657
URL: http://svn.apache.org/viewvc?rev=1765657&view=rev
Log:
OAK-1312 - Bundle nodes into a document
Handle the case where nodes gets removed and recreated within same commit. The
meta props are now filtered out from getProperties listing. However they can be
looked up via direct lookup via property name.
This ensures that NodeState level operations do not interfere with meta
properties used for bundling
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlorUtils.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlingTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java?rev=1765657&r1=1765656&r2=1765657&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java
Wed Oct 19 15:13:47 2016
@@ -90,7 +90,7 @@ class CommitDiff implements NodeStateDif
commit.addNode(new DocumentNodeState(store,
child.getRootBundlePath(),
new RevisionVector(commit.getRevision())));
}
- setChildrenFlagOnAdd(child);
+ setOrTouchChildrenFlag(child);
return after.compareAgainstBaseState(EMPTY_NODE,
new CommitDiff(store, commit, child, builder, blobs));
}
@@ -113,6 +113,7 @@ class CommitDiff implements NodeStateDif
if (child.isBundlingRoot()) {
commit.removeNode(child.getRootBundlePath(), before);
}
+ setOrTouchChildrenFlag(child);
return MISSING_NODE.compareAgainstBaseState(before,
new CommitDiff(store, commit, child, builder, blobs));
}
@@ -144,7 +145,7 @@ class CommitDiff implements NodeStateDif
}
}
- private void setChildrenFlagOnAdd(BundlingHandler child) {
+ private void setOrTouchChildrenFlag(BundlingHandler child) {
//Add hasChildren marker for bundling case
String propName = null;
if (child.isBundledNode()){
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java?rev=1765657&r1=1765656&r2=1765657&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
Wed Oct 19 15:13:47 2016
@@ -218,7 +218,9 @@ public class DocumentNodeState extends A
@Nonnull
@Override
public Iterable<? extends PropertyState> getProperties() {
- return properties.values();
+ //Filter out the meta properties related to bundling from
+ //generic listing of props
+ return Iterables.filter(properties.values(),
BundlorUtils.NOT_BUNDLOR_PROPS);
}
@Override
@@ -272,6 +274,9 @@ public class DocumentNodeState extends A
@Override
public long getPropertyCount() {
+ if (bundlingContext.isBundled()){
+ return Iterables.size(getProperties());
+ }
return properties.size();
}
@@ -782,6 +787,10 @@ public class DocumentNodeState extends A
return rootProperties;
}
+ public boolean isBundled(){
+ return matcher.isMatch();
+ }
+
public Map<String, PropertyState> getAllProperties(){
return rootProperties;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java?rev=1765657&r1=1765656&r2=1765657&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlingHandler.java
Wed Oct 19 15:13:47 2016
@@ -124,6 +124,9 @@ public class BundlingHandler {
removeDeletedChildProperties(state, childContext);
} else {
childContext = getBundlorContext(childPath, state);
+ if (childContext.isBundling()){
+ removeBundlingMetaProps(state, childContext);
+ }
}
return new BundlingHandler(registry, childContext, childPath, state);
}
@@ -148,6 +151,15 @@ public class BundlingHandler {
return true;
}
+ @Override
+ public String toString() {
+ String result = path;
+ if (isBundledNode()){
+ result = path + "( Bundling root - " + getRootBundlePath() + ")";
+ }
+ return result;
+ }
+
private String childPath(String name){
return PathUtils.concat(path, name);
}
@@ -172,8 +184,19 @@ public class BundlingHandler {
String propName = ps.getName();
//In deletion never touch child status related meta props
//as they are not to be changed once set
- if (!propName.startsWith(DocumentBundlor.HAS_CHILD_PROP_PREFIX))
+ if (!propName.startsWith(DocumentBundlor.HAS_CHILD_PROP_PREFIX)) {
childContext.removeProperty(ps.getName());
+ }
+ }
+ }
+
+ private static void removeBundlingMetaProps(NodeState state,
BundlingContext childContext) {
+ //Explicitly remove meta prop related to bundling as it would not
+ //be part of normal listing of properties and hence would not be
deleted
+ //as part of diff
+ PropertyState bundlorConfig =
state.getProperty(DocumentBundlor.META_PROP_PATTERN);
+ if (bundlorConfig != null){
+ childContext.removeProperty(DocumentBundlor.META_PROP_PATTERN);
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlorUtils.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlorUtils.java?rev=1765657&r1=1765656&r2=1765657&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlorUtils.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/BundlorUtils.java
Wed Oct 19 15:13:47 2016
@@ -26,6 +26,7 @@ import java.util.Map;
import javax.annotation.Nonnull;
+import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -35,6 +36,13 @@ import org.apache.jackrabbit.oak.commons
import static
org.apache.jackrabbit.oak.plugins.document.bundlor.DocumentBundlor.META_PROP_NODE;
public final class BundlorUtils {
+ public static final Predicate<PropertyState> NOT_BUNDLOR_PROPS = new
Predicate<PropertyState>() {
+ @Override
+ public boolean apply(PropertyState input) {
+ return
!input.getName().startsWith(DocumentBundlor.BUNDLOR_META_PROP_PREFIX);
+ }
+ };
+
public static Map<String, PropertyState> getMatchingProperties(Map<String,
PropertyState> props, Matcher matcher){
if (!matcher.isMatch()){
@@ -57,10 +65,6 @@ public final class BundlorUtils {
continue;
}
- if (propertyPath.endsWith(META_PROP_NODE)){
- continue;
- }
-
//Extract property name from relative property path
final String newKey = PathUtils.getName(propertyPath);
PropertyState value = e.getValue();
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java?rev=1765657&r1=1765656&r2=1765657&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlor.java
Wed Oct 19 15:13:47 2016
@@ -35,6 +35,10 @@ import static org.apache.jackrabbit.oak.
public class DocumentBundlor {
/**
+ * Prefix used for various meta properties used for bundling
+ */
+ public static final String BUNDLOR_META_PROP_PREFIX = ":doc-";
+ /**
* Hidden property to store the pattern as part of NodeState
* TODO - Also store the NodeType
*/
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlingTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlingTest.java?rev=1765657&r1=1765656&r2=1765657&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlingTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/bundlor/DocumentBundlingTest.java
Wed Oct 19 15:13:47 2016
@@ -49,7 +49,6 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -110,7 +109,11 @@ public class DocumentBundlingTest {
NodeState root = store.getRoot();
NodeState fileNodeState = root.getChildNode("test");
assertTrue(fileNodeState.getChildNode("book.jpg").exists());
-
assertTrue(fileNodeState.getChildNode("book.jpg").getChildNode("jcr:content").exists());
+ NodeState contentNode =
fileNodeState.getChildNode("book.jpg").getChildNode("jcr:content");
+ assertTrue(contentNode.exists());
+
+ assertEquals(1, contentNode.getPropertyCount());
+ assertEquals(1, Iterables.size(contentNode.getProperties()));
assertNull(getNodeDocument("/test/book.jpg/jcr:content"));
assertNotNull(getNodeDocument("/test/book.jpg"));
@@ -498,7 +501,6 @@ public class DocumentBundlingTest {
}
- @Ignore("FIXEME")
@Test
public void recreatedBundledNode() throws Exception{
NodeBuilder builder = store.getRoot().builder();
@@ -570,6 +572,42 @@ public class DocumentBundlingTest {
assertFalse(hasNodeProperty("/test/book.jpg", concat("comments",
DocumentBundlor.META_PROP_NODE)));
}
+ @Test
+ public void bundlingPatternRemovedAndBundledNodeRecreated() throws
Exception{
+ NodeBuilder builder = store.getRoot().builder();
+ NodeBuilder fileNode = newNode("nt:file");
+ fileNode.child("jcr:content").setProperty("jcr:data", "foo");
+ builder.child("test").setChildNode("book.jpg",
fileNode.getNodeState());
+ merge(builder);
+
+ assertTrue(hasNodeProperty("/test/book.jpg", concat("jcr:content",
DocumentBundlor.META_PROP_NODE)));
+
+ //Delete the bundled node structure
+ builder = store.getRoot().builder();
+ builder.child("test").child("book.jpg").remove();
+ merge(builder);
+
+ //Change bundling pattern
+ builder = store.getRoot().builder();
+ NodeBuilder ntfile = childBuilder(builder,
BundlingConfigHandler.CONFIG_PATH+"/nt:file");
+ ntfile.remove();
+ merge(builder);
+
+ //Create a new node with same path
+ builder = store.getRoot().builder();
+ fileNode = newNode("nt:file");
+ fileNode.child("jcr:content").setProperty("jcr:data", "foo");
+ fileNode.child("metadata").setProperty("jcr:data", "foo");
+ fileNode.child("comments").setProperty("jcr:data", "foo");
+ builder.child("test").setChildNode("book.jpg",
fileNode.getNodeState());
+ merge(builder);
+
+ //New pattern should be effective
+ assertNotNull(getNodeDocument("/test/book.jpg"));
+ assertFalse(hasNodeProperty("/test/book.jpg", concat("metadata",
DocumentBundlor.META_PROP_NODE)));
+ assertFalse(hasNodeProperty("/test/book.jpg", concat("comments",
DocumentBundlor.META_PROP_NODE)));
+ }
+
private void createTestNode(String path, NodeState state) throws
CommitFailedException {
String parentPath = PathUtils.getParentPath(path);
NodeBuilder builder = store.getRoot().builder();