Author: tomekr
Date: Fri Apr 28 07:15:00 2017
New Revision: 1792992

URL: http://svn.apache.org/viewvc?rev=1792992&view=rev
Log:
OAK-6132: Backport oak-upgrade to 1.0 and 1.2

-backported NodeBuilderTree

Added:
    
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/
    
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/AbstractMutableTree.java
    
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/NodeBuilderTree.java

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/AbstractMutableTree.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/AbstractMutableTree.java?rev=1792992&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/AbstractMutableTree.java
 (added)
+++ 
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/AbstractMutableTree.java
 Fri Apr 28 07:15:00 2017
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade.tree;
+
+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.Lists.newArrayListWithCapacity;
+import static org.apache.jackrabbit.oak.api.Type.NAMES;
+import static 
org.apache.jackrabbit.oak.plugins.tree.TreeConstants.OAK_CHILD_ORDER;
+import static org.apache.jackrabbit.oak.spi.state.NodeStateUtils.isHidden;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+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.core.HiddenTree;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.plugins.tree.AbstractTree;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+
+/**
+ * {@code AbstractMutableTree} extends {@code AbstractTree} with 
implementations
+ * for most write methods of {@code Tree}. Furthermore it handles the ordering
+ * of siblings.
+ */
+public abstract class AbstractMutableTree extends AbstractTree {
+
+    protected AbstractMutableTree(@Nonnull String name, @Nonnull NodeBuilder 
nodeBuilder) {
+        super(name, nodeBuilder);
+    }
+
+    protected abstract AbstractMutableTree getParentOrNull();
+
+    protected abstract NodeBuilder getNodeBuilder();
+
+    @Override
+    @Nonnull
+    public AbstractMutableTree getParent() {
+        AbstractMutableTree parent = getParentOrNull();
+        checkState(parent != null, "root tree does not have a parent");
+        return parent;
+    }
+
+    @Override
+    @Nonnull
+    public Tree getChild(@Nonnull String name) throws IllegalArgumentException 
{
+        if (!isHidden(name)) {
+            return createChild(name);
+        } else {
+            return new HiddenTree(this, name);
+        }
+    }
+
+    @Override
+    public boolean remove() {
+        String name = getName();
+        AbstractMutableTree parent = getParentOrNull();
+        if (parent != null && parent.hasChild(name)) {
+            getNodeBuilder().remove();
+            NodeBuilder parentBuilder = parent.getNodeBuilder();
+            PropertyState order = parentBuilder.getProperty(OAK_CHILD_ORDER);
+            if (order != null) {
+                List<String> names = newArrayListWithCapacity(order.count());
+                for (String n : order.getValue(NAMES)) {
+                    if (!n.equals(name)) {
+                        names.add(n);
+                    }
+                }
+                parentBuilder.setProperty(OAK_CHILD_ORDER, names, NAMES);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Nonnull
+    @Override
+    public Tree addChild(@Nonnull String name) throws IllegalArgumentException 
{
+        checkArgument(!isHidden(name));
+        if (!hasChild(name)) {
+            NodeBuilder nodeBuilder = getNodeBuilder();
+            nodeBuilder.setChildNode(name);
+            PropertyState order = nodeBuilder.getProperty(OAK_CHILD_ORDER);
+            if (order != null) {
+                List<String> names = newArrayListWithCapacity(order.count() + 
1);
+                for (String n : order.getValue(NAMES)) {
+                    if (!n.equals(name)) {
+                        names.add(n);
+                    }
+                }
+                names.add(name);
+                nodeBuilder.setProperty(OAK_CHILD_ORDER, names, NAMES);
+            }
+        }
+        return createChild(name);
+    }
+
+
+    @Override
+    public void setOrderableChildren(boolean enable) {
+        if (enable) {
+            updateChildOrder(true);
+        } else {
+            getNodeBuilder().removeProperty(OAK_CHILD_ORDER);
+        }
+    }
+
+    /**
+     * Updates the child order to match any added or removed child nodes that
+     * are not yet reflected in the {@link 
org.apache.jackrabbit.oak.plugins.tree.TreeConstants#OAK_CHILD_ORDER}
+     * property. If the {@code force} flag is set, the child order is set
+     * in any case, otherwise only if the node already is orderable.
+     *
+     * @param force whether to add child order information if it doesn't exist
+     */
+    protected void updateChildOrder(boolean force) {
+        if (force || hasOrderableChildren()) {
+            getNodeBuilder().setProperty(PropertyStates.createProperty(
+                    OAK_CHILD_ORDER, getChildNames(), Type.NAMES));
+        }
+    }
+
+    @Override
+    public boolean orderBefore(@Nullable String name) {
+        String thisName = getName();
+        AbstractMutableTree parent = getParentOrNull();
+        if (parent == null) {
+            return false; // root does not have siblings
+        } else if (thisName.equals(name)) {
+            return false; // same node
+        }
+
+        // perform the reorder
+        List<String> names = newArrayListWithCapacity(10000);
+        NodeBuilder builder = parent.getNodeBuilder();
+        boolean found = false;
+
+        // first try reordering based on the (potentially out-of-sync)
+        // child order property in the parent node
+        for (String n : builder.getNames(OAK_CHILD_ORDER)) {
+            if (n.equals(name) && parent.hasChild(name)) {
+                names.add(thisName);
+                found = true;
+            }
+            if (!n.equals(thisName)) {
+                names.add(n);
+            }
+        }
+
+        // if the target node name was not found in the parent's child order
+        // property, we need to fall back to recreating the child order list
+        if (!found) {
+            names.clear();
+            for (String n : parent.getChildNames()) {
+                if (n.equals(name)) {
+                    names.add(thisName);
+                    found = true;
+                }
+                if (!n.equals(thisName)) {
+                    names.add(n);
+                }
+            }
+        }
+
+        if (name == null) {
+            names.add(thisName);
+            found = true;
+        }
+
+        if (found) {
+            builder.setProperty(OAK_CHILD_ORDER, names, NAMES);
+            return true;
+        } else {
+            // no such sibling (not existing or not accessible)
+            return false;
+        }
+    }
+
+    @Override
+    public void setProperty(@Nonnull PropertyState property) {
+        checkArgument(!isHidden(checkNotNull(property).getName()));
+        getNodeBuilder().setProperty(property);
+    }
+
+    @Override
+    public <T> void setProperty(@Nonnull String name, @Nonnull T value) throws 
IllegalArgumentException {
+        checkArgument(!isHidden(checkNotNull(name)));
+        getNodeBuilder().setProperty(name, checkNotNull(value));
+    }
+
+    @Override
+    public <T> void setProperty(@Nonnull String name, @Nonnull T value, 
@Nonnull Type<T> type)
+            throws IllegalArgumentException {
+        checkArgument(!isHidden(checkNotNull(name)));
+        getNodeBuilder().setProperty(name, checkNotNull(value), 
checkNotNull(type));
+    }
+
+    @Override
+    public void removeProperty(@Nonnull String name) {
+        getNodeBuilder().removeProperty(checkNotNull(name));
+    }
+}
\ No newline at end of file

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/NodeBuilderTree.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/NodeBuilderTree.java?rev=1792992&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/NodeBuilderTree.java
 (added)
+++ 
jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/tree/NodeBuilderTree.java
 Fri Apr 28 07:15:00 2017
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade.tree;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+
+/**
+ * A mutable {@code Tree} implementation based on an underlying
+ * {@code NodeBuilder}, which tracks all changes recorded through
+ * this tree's mutator methods.
+ */
+public final class NodeBuilderTree extends AbstractMutableTree {
+
+    private final NodeBuilderTree parent;
+
+    private final String name;
+
+    private final NodeBuilder nodeBuilder;
+
+    /**
+     * Create a new {@code AbstractTree} instance
+     *
+     * @param nodeBuilder {@code NodeBuilder} for the underlying node state
+     * @param name        name of the tree
+     */
+    public NodeBuilderTree(@Nonnull String name, @Nonnull NodeBuilder 
nodeBuilder) {
+        this(null, nodeBuilder, name);
+    }
+
+    protected NodeBuilderTree(@Nullable NodeBuilderTree parent, @Nonnull 
NodeBuilder nodeBuilder,
+                              @Nonnull String name) {
+        super(name, nodeBuilder);
+        this.parent = parent;
+        this.name = name;
+        this.nodeBuilder = nodeBuilder;
+    }
+
+    @Override
+    @CheckForNull
+    protected AbstractMutableTree getParentOrNull() {
+        return parent;
+    }
+
+    @Nonnull
+    @Override
+    protected NodeBuilder getNodeBuilder() {
+        return nodeBuilder;
+    }
+
+    @Nonnull
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    @Nonnull
+    protected NodeBuilderTree createChild(@Nonnull String name) throws 
IllegalArgumentException {
+        return new NodeBuilderTree(this, 
nodeBuilder.getChildNode(checkNotNull(name)), name);
+    }
+
+}
\ No newline at end of file


Reply via email to