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");
+     }   
 }