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/08 14:25:02 UTC
svn commit: r1500689 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/core/ImmutableTree.java
main/java/org/apache/jackrabbit/oak/core/ReadOnlyTree.java
test/java/org/apache/jackrabbit/oak/core/ImmutableTreeTest.java
Author: mduerig
Date: Mon Jul 8 12:25:01 2013
New Revision: 1500689
URL: http://svn.apache.org/r1500689
Log:
OAK-889: Add respect orderable children capability in ImmutableTree#getChildren
credits to Antonio for the patch
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ImmutableTree.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ReadOnlyTree.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/ImmutableTreeTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ImmutableTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ImmutableTree.java?rev=1500689&r1=1500688&r2=1500689&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ImmutableTree.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ImmutableTree.java Mon Jul 8 12:25:01 2013
@@ -18,19 +18,15 @@ package org.apache.jackrabbit.oak.core;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.jackrabbit.oak.api.Type.STRING;
-
-import java.util.Iterator;
-
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
-
+import com.google.common.base.Function;
import com.google.common.base.Objects;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
@@ -176,37 +172,12 @@ public final class ImmutableTree extends
* This implementation does not respect ordered child nodes, but always
* returns them in some implementation specific order.
* <p/>
- * TODO: respect orderable children (needed?)
*
* @return the children.
*/
@Override
public Iterable<Tree> getChildren() {
- return new Iterable<Tree>() {
- @Override
- public Iterator<Tree> iterator() {
- final Iterator<? extends ChildNodeEntry> iterator = state.getChildNodeEntries().iterator();
- return new Iterator<Tree>() {
- @Override
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
- @Override
- public Tree next() {
- ChildNodeEntry entry = iterator.next();
- return new ImmutableTree(
- ImmutableTree.this,
- entry.getName(), entry.getNodeState());
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
- };
+ return super.getChildren();
}
//-------------------------------------------------------------< Object >---
@@ -263,6 +234,16 @@ public final class ImmutableTree extends
return PathUtils.concat(getParent().getIdentifier(), getName());
}
}
+
+ @Override
+ protected Function<String, Tree> createChild(){
+ return new Function<String, Tree>() {
+ @Override
+ public Tree apply(String name) {
+ return new ImmutableTree(ImmutableTree.this, name, state.getChildNode(name));
+ }
+ };
+ }
//--------------------------------------------------------------------------
public interface ParentProvider {
@@ -286,7 +267,6 @@ public final class ImmutableTree extends
}
public static final class DefaultParentProvider implements ParentProvider {
-
private ImmutableTree parent;
DefaultParentProvider(ImmutableTree parent) {
@@ -298,4 +278,5 @@ public final class ImmutableTree extends
return parent;
}
}
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ReadOnlyTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ReadOnlyTree.java?rev=1500689&r1=1500688&r2=1500689&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ReadOnlyTree.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ReadOnlyTree.java Mon Jul 8 12:25:01 2013
@@ -21,22 +21,31 @@ package org.apache.jackrabbit.oak.core;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
import static org.apache.jackrabbit.oak.api.Type.STRING;
+import static org.apache.jackrabbit.oak.spi.state.NodeStateUtils.isHidden;
import java.util.Iterator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
public class ReadOnlyTree implements Tree {
+
+ /**
+ * Internal and hidden property that contains the child order
+ */
+ public static final String OAK_CHILD_ORDER = ":childOrder";
/**
* Parent of this tree, {@code null} for the root
@@ -159,38 +168,25 @@ public class ReadOnlyTree implements Tre
* This implementation does not respect ordered child nodes, but always
* returns them in some implementation specific order.
* <p/>
- * TODO: respect orderable children (needed?)
*
* @return the children.
*/
@Override
public Iterable<Tree> getChildren() {
- return new Iterable<Tree>() {
- @Override
- public Iterator<Tree> iterator() {
- final Iterator<? extends ChildNodeEntry> iterator =
- state.getChildNodeEntries().iterator();
- return new Iterator<Tree>() {
- @Override
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
+ Iterable<String> childNames;
+ if (hasOrderableChildren()) {
+ childNames = getOrderedChildNames();
+ } else {
+ childNames = state.getChildNodeNames();
+ }
+ return transform(
+ filter(childNames, new Predicate<String>() {
@Override
- public Tree next() {
- ChildNodeEntry entry = iterator.next();
- return new ReadOnlyTree(
- ReadOnlyTree.this,
- entry.getName(), entry.getNodeState());
+ public boolean apply(String name) {
+ return !isHidden(name);
}
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
- };
+ }),
+ createChild());
}
@Override
@@ -251,4 +247,56 @@ public class ReadOnlyTree implements Tre
return PathUtils.concat(parent.getIdentifier(), name);
}
}
+
+ /**
+ * @return {@code true} if this tree has orderable children;
+ * {@code false} otherwise.
+ */
+ private boolean hasOrderableChildren() {
+ return state.hasProperty(OAK_CHILD_ORDER);
+ }
+
+ /**
+ * Returns the ordered child names. This method must only be called when
+ * this tree {@link #hasOrderableChildren()}.
+ *
+ * @return the ordered child names.
+ */
+ private Iterable<String> getOrderedChildNames() {
+ assert hasOrderableChildren();
+ return new Iterable<String>() {
+ @Override
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ final PropertyState childOrder = state.getProperty(OAK_CHILD_ORDER);
+ int index = 0;
+
+ @Override
+ public boolean hasNext() {
+ return index < childOrder.count();
+ }
+
+ @Override
+ public String next() {
+ return childOrder.getValue(STRING, index++);
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ };
+ }
+
+ protected Function<String, Tree> createChild(){
+ return new Function<String, Tree>() {
+ @Override
+ public Tree apply(String name) {
+ return new ReadOnlyTree(ReadOnlyTree.this, name, state.getChildNode(name));
+ }
+ };
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/ImmutableTreeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/ImmutableTreeTest.java?rev=1500689&r1=1500688&r2=1500689&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/ImmutableTreeTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/ImmutableTreeTest.java Mon Jul 8 12:25:01 2013
@@ -18,11 +18,11 @@
*/
package org.apache.jackrabbit.oak.core;
+import static org.apache.jackrabbit.oak.OakAssert.assertSequence;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-
import org.apache.jackrabbit.oak.OakBaseTest;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.ContentSession;
@@ -32,6 +32,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+
public class ImmutableTreeTest extends OakBaseTest {
private Root root;
@@ -118,4 +119,34 @@ public class ImmutableTreeTest extends O
// success
}
}
+
+ @Test
+ public void orderBefore() throws Exception {
+ TreeImpl t = (TreeImpl) root.getTree("/x/y/z");
+
+ t.addChild("node1");
+ t.addChild("node2");
+ t.addChild("node3");
+
+
+ t.getChild("node1").orderBefore("node2");
+ t.getChild("node3").orderBefore(null);
+
+ root.commit();
+
+ ImmutableTree tree = new ImmutableTree(t.getNodeState());
+ assertSequence(tree.getChildren(), "node1", "node2", "node3");
+
+ t.getChild("node3").orderBefore("node2");
+ root.commit();
+
+ tree = new ImmutableTree(t.getNodeState());
+ assertSequence(tree.getChildren(), "node1", "node3", "node2");
+
+ t.getChild("node1").orderBefore(null);
+ root.commit();
+
+ tree = new ImmutableTree(t.getNodeState());
+ assertSequence(tree.getChildren(), "node3", "node2", "node1");
+ }
}