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/05/01 13:40:51 UTC

svn commit: r1477956 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ oak-core/src/main/java/org/apache/jackrabbit/oak/util/ oak-jcr/src/main/java/...

Author: mduerig
Date: Wed May  1 11:40:50 2013
New Revision: 1477956

URL: http://svn.apache.org/r1477956
Log:
OAK-798: Review / refactor TreeImpl and related classes
reduce usage of deprecated API: replace getLocation with getTree and exists, replace usages of TreeLocation with Tree in oak-jcr

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadOnlyVersionManager.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TreeUtil.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ItemDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionHistoryDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionManagerDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/ReadWriteVersionManager.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadOnlyVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadOnlyVersionManager.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadOnlyVersionManager.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadOnlyVersionManager.java Wed May  1 11:40:50 2013
@@ -29,7 +29,6 @@ import javax.jcr.UnsupportedRepositoryOp
 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.api.TreeLocation;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.core.IdentifierManager;
@@ -48,9 +47,10 @@ public abstract class ReadOnlyVersionMan
      *         {@code Root} returned by {@link #getWorkspaceRoot()}.
      */
     @Nonnull
-    protected abstract TreeLocation getVersionStorageLocation();
+    protected abstract Tree getVersionStorage();
 
     /**
+    /**
      * @return the {@code Root} of the workspace.
      */
     @Nonnull
@@ -118,13 +118,13 @@ public abstract class ReadOnlyVersionMan
             RepositoryException {
         checkVersionable(versionable);
         String uuid = versionable.getProperty(VersionConstants.JCR_UUID).getValue(Type.STRING);
-        return TreeUtil.getTree(getVersionStorageLocation(), getVersionHistoryPath(uuid));
+        return TreeUtil.getTree(getVersionStorage(), getVersionHistoryPath(uuid));
     }
 
     /**
      * Returns the path of the version history for the given {@code uuid}.
      * The returned path is relative to the version storage tree as returned
-     * by {@link #getVersionStorageLocation()}.
+     * by {@link #getVersionStorage()}.
      *
      * @param uuid the uuid of the versionable node
      * @return the relative path of the version history for the given uuid.

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java Wed May  1 11:40:50 2013
@@ -18,23 +18,6 @@
  */
 package org.apache.jackrabbit.oak.plugins.version;
 
-import java.util.Collections;
-import java.util.Iterator;
-import javax.annotation.Nonnull;
-
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Root;
-import org.apache.jackrabbit.oak.api.TreeLocation;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.core.IdentifierManager;
-import org.apache.jackrabbit.oak.core.ImmutableRoot;
-import org.apache.jackrabbit.oak.core.ImmutableTree;
-import org.apache.jackrabbit.oak.namepath.NamePathMapper;
-import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.util.TODO;
-
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.apache.jackrabbit.JcrConstants.JCR_BASEVERSION;
 import static org.apache.jackrabbit.JcrConstants.JCR_CREATED;
@@ -58,6 +41,24 @@ import static org.apache.jackrabbit.JcrC
 import static org.apache.jackrabbit.JcrConstants.NT_VERSIONLABELS;
 import static org.apache.jackrabbit.oak.plugins.version.VersionConstants.REP_VERSIONSTORAGE;
 
+import java.util.Collections;
+import java.util.Iterator;
+
+import javax.annotation.Nonnull;
+
+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.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.core.IdentifierManager;
+import org.apache.jackrabbit.oak.core.ImmutableRoot;
+import org.apache.jackrabbit.oak.core.ImmutableTree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.util.TODO;
+
 /**
  * TODO document
  */
@@ -74,8 +75,8 @@ class ReadWriteVersionManager extends Re
 
     @Nonnull
     @Override
-    protected TreeLocation getVersionStorageLocation() {
-        return new ImmutableTree(versionStorageNode.getNodeState()).getLocation();
+    protected Tree getVersionStorage() {
+        return new ImmutableTree(versionStorageNode.getNodeState());
     }
 
     @Nonnull

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java Wed May  1 11:40:50 2013
@@ -18,6 +18,9 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import static org.apache.jackrabbit.oak.api.Type.STRING;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+
 import java.text.ParseException;
 import java.util.ArrayList;
 
@@ -30,9 +33,6 @@ import org.apache.jackrabbit.oak.query.a
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
 
-import static org.apache.jackrabbit.oak.api.Type.STRING;
-import static org.apache.jackrabbit.oak.api.Type.STRINGS;
-
 /**
  * A fulltext "contains(...)" condition.
  */
@@ -114,7 +114,7 @@ public class FullTextSearchImpl extends 
             }
 
             Tree tree = getTree(path);
-            if (tree == null) {
+            if (tree == null || !tree.exists()) {
                 return false;
             }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java Wed May  1 11:40:50 2013
@@ -98,7 +98,7 @@ public class PropertyValueImpl extends D
             return matchesPropertyType(p) ? p : null;
         }
         Tree tree = getTree(selector.currentPath());
-        if (tree == null) {
+        if (tree == null || !tree.exists()) {
             return null;
         }
         if (!asterisk) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Wed May  1 11:40:50 2013
@@ -210,7 +210,7 @@ public class SelectorImpl extends Source
             scanCount++;
             currentRow = cursor.next();
             Tree tree = getTree(currentRow.getPath());
-            if (tree == null) {
+            if (tree == null || !tree.exists()) {
                 continue;
             }
             if (!matchesAllTypes && !evaluateTypeMatch(tree)) {
@@ -290,7 +290,7 @@ public class SelectorImpl extends Source
             }
             propertyName = PathUtils.getName(propertyName);
         }
-        if (t == null) {
+        if (t == null || !t.exists()) {
             return null;
         }
         if (propertyName.equals(Query.JCR_PATH)) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TreeUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TreeUtil.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TreeUtil.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TreeUtil.java Wed May  1 11:40:50 2013
@@ -63,7 +63,7 @@ public final class TreeUtil {
     @CheckForNull
     private static String getStringInternal(Tree tree,
                                             String propertyName,
-                                            Type<? extends String> type) {
+                                            Type<String> type) {
         PropertyState property = tree.getProperty(propertyName);
         if (property != null && !property.isArray()) {
             return property.getValue(type);
@@ -101,6 +101,7 @@ public final class TreeUtil {
      * @return  tree location located at {@code path} from {@code start}
      */
     @Nonnull
+    @Deprecated
     public static TreeLocation getTreeLocation(TreeLocation start, String path) {
         TreeLocation loc = start;
         for (String element : Text.explode(path, '/', false)) {
@@ -123,6 +124,7 @@ public final class TreeUtil {
      * @return  tree location located at {@code path} from {@code start}
      */
     @Nonnull
+    @Deprecated
     public static TreeLocation getTreeLocation(Tree start, String path) {
         return getTreeLocation(start.getLocation(), path);
     }
@@ -137,21 +139,34 @@ public final class TreeUtil {
      * @return  tree located at {@code path} from {@code start} or {@code null}
      */
     @CheckForNull
+    @Deprecated
     public static Tree getTree(TreeLocation start, String path) {
         return getTreeLocation(start, path).getTree();
     }
 
     /**
-     * Return the tree located at the passed {@code path} from the location of
-     * the {@code start} tree or {@code null} if no such tree exists or is accessible.
-     * Equivalent to {@code getTreeLocation(start.getLocation(), path).getTree()}.
+     * Return the possibly non existing tree located at the passed {@code path} from
+     * the location of the start {@code tree} or {@code null} if {@code path} results
+     * in a parent of the root.
      *
-     * @param start  start tree
+     * @param tree  start tree
      * @param path  path from the start tree
      * @return  tree located at {@code path} from {@code start} or {@code null}
      */
     @CheckForNull
-    public static Tree getTree(Tree start, String path) {
-        return getTreeLocation(start.getLocation(), path).getTree();
+    public static Tree getTree(Tree tree, String path) {
+        for (String element : Text.explode(path, '/', false)) {
+            if (PathUtils.denotesParent(element)) {
+                if (tree.isRoot()) {
+                    return null;
+                } else {
+                    tree = tree.getParent();
+                }
+            } else if (!PathUtils.denotesCurrent(element)) {
+                tree = tree.getChild(element);
+            }  // else . -> skip to next element
+        }
+        return tree;
     }
+
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Wed May  1 11:40:50 2013
@@ -16,11 +16,22 @@
  */
 package org.apache.jackrabbit.oak.jcr;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Collections.singleton;
+import static javax.jcr.Property.JCR_LOCK_IS_DEEP;
+import static javax.jcr.Property.JCR_LOCK_OWNER;
+import static javax.jcr.PropertyType.UNDEFINED;
+import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.NAMES;
+
 import java.io.InputStream;
 import java.math.BigDecimal;
 import java.util.Calendar;
 import java.util.Iterator;
 import java.util.Set;
+
 import javax.annotation.Nonnull;
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Binary;
@@ -80,16 +91,6 @@ import org.apache.jackrabbit.value.Value
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.Collections.singleton;
-import static javax.jcr.Property.JCR_LOCK_IS_DEEP;
-import static javax.jcr.Property.JCR_LOCK_OWNER;
-import static javax.jcr.PropertyType.UNDEFINED;
-import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
-import static org.apache.jackrabbit.oak.api.Type.NAME;
-import static org.apache.jackrabbit.oak.api.Type.NAMES;
-
 /**
  * TODO document
  *
@@ -520,11 +521,7 @@ public class NodeImpl<T extends NodeDele
                         new Predicate<NodeDelegate>() {
                             @Override
                             public boolean apply(NodeDelegate state) {
-                                try {
-                                    return ItemNameMatcher.matches(toJcrPath(state.getName()), namePattern);
-                                } catch (InvalidItemStateException e) {
-                                    return false;
-                                }
+                                return ItemNameMatcher.matches(toJcrPath(state.getName()), namePattern);
                             }
                         });
 
@@ -543,11 +540,7 @@ public class NodeImpl<T extends NodeDele
                         new Predicate<NodeDelegate>() {
                             @Override
                             public boolean apply(NodeDelegate state) {
-                                try {
-                                    return ItemNameMatcher.matches(toJcrPath(state.getName()), nameGlobs);
-                                } catch (InvalidItemStateException e) {
-                                    return false;
-                                }
+                                return ItemNameMatcher.matches(toJcrPath(state.getName()), nameGlobs);
                             }
                         });
 
@@ -596,11 +589,7 @@ public class NodeImpl<T extends NodeDele
                         new Predicate<PropertyDelegate>() {
                             @Override
                             public boolean apply(PropertyDelegate entry) {
-                                try {
-                                    return ItemNameMatcher.matches(toJcrPath(entry.getName()), namePattern);
-                                } catch (InvalidItemStateException e) {
-                                    return false;
-                                }
+                                return ItemNameMatcher.matches(toJcrPath(entry.getName()), namePattern);
                             }
                         });
 
@@ -619,11 +608,7 @@ public class NodeImpl<T extends NodeDele
                         new Predicate<PropertyDelegate>() {
                             @Override
                             public boolean apply(PropertyDelegate entry) {
-                                try {
-                                    return ItemNameMatcher.matches(toJcrPath(entry.getName()), nameGlobs);
-                                } catch (InvalidItemStateException e) {
-                                    return false;
-                                }
+                                return ItemNameMatcher.matches(toJcrPath(entry.getName()), nameGlobs);
                             }
                         });
 
@@ -1020,6 +1005,7 @@ public class NodeImpl<T extends NodeDele
             getNode(relPath).restore(version, removeExisting);
         } else {
             // TODO
+            TODO.unimplemented();
         }
     }
 
@@ -1123,8 +1109,8 @@ public class NodeImpl<T extends NodeDele
         String lockIsDeep = getOakPathOrThrow(JCR_LOCK_IS_DEEP);
         try {
             Root root = session.getLatestRoot();
-            Tree tree = root.getTreeOrNull(dlg.getPath());
-            if (tree == null) {
+            Tree tree = root.getTree(dlg.getPath());
+            if (!tree.exists()) {
                 throw new ItemNotFoundException();
             }
             tree.setProperty(lockOwner, userID);
@@ -1196,8 +1182,8 @@ public class NodeImpl<T extends NodeDele
         String lockIsDeep = getOakPathOrThrow(JCR_LOCK_IS_DEEP);
         try {
             Root root = sessionDelegate.getContentSession().getLatestRoot();
-            Tree tree = root.getTreeOrNull(dlg.getPath());
-            if (tree == null) {
+            Tree tree = root.getTree(dlg.getPath());
+            if (!tree.exists()) {
                 throw new ItemNotFoundException();
             }
             tree.removeProperty(lockOwner);

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ItemDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ItemDelegate.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ItemDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ItemDelegate.java Wed May  1 11:40:50 2013
@@ -17,7 +17,6 @@
 
 package org.apache.jackrabbit.oak.jcr.delegate;
 
-import static com.google.common.base.Objects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import javax.annotation.CheckForNull;
@@ -25,8 +24,6 @@ import javax.annotation.Nonnull;
 import javax.jcr.InvalidItemStateException;
 
 import org.apache.jackrabbit.oak.api.Tree.Status;
-import org.apache.jackrabbit.oak.api.TreeLocation;
-import org.apache.jackrabbit.oak.commons.PathUtils;
 
 /**
  * Abstract base class for {@link NodeDelegate} and {@link PropertyDelegate}
@@ -35,33 +32,23 @@ public abstract class ItemDelegate {
 
     protected final SessionDelegate sessionDelegate;
 
-    /** The underlying {@link org.apache.jackrabbit.oak.api.TreeLocation} of this item. */
-    private final TreeLocation location;
-
-    ItemDelegate(SessionDelegate sessionDelegate, TreeLocation location) {
+    ItemDelegate(SessionDelegate sessionDelegate) {
         this.sessionDelegate = checkNotNull(sessionDelegate);
-        this.location = checkNotNull(location);
     }
 
-    public abstract boolean isProtected() throws InvalidItemStateException;
-
     /**
      * Get the name of this item
      * @return oak name of this item
      */
     @Nonnull
-    public String getName() throws InvalidItemStateException {
-        return PathUtils.getName(getPath());
-    }
+    public abstract String getName();
 
     /**
      * Get the path of this item
      * @return oak path of this item
      */
     @Nonnull
-    public String getPath() throws InvalidItemStateException {
-        return getLocation().getPath();  // never null
-    }
+    public abstract String getPath();
 
     /**
      * Get the parent of this item or {@code null}.
@@ -69,51 +56,27 @@ public abstract class ItemDelegate {
      * is not accessible.
      */
     @CheckForNull
-    public NodeDelegate getParent() throws InvalidItemStateException {
-        return NodeDelegate.create(sessionDelegate, getLocation().getParent());
-    }
-
-    public void checkNotStale() throws InvalidItemStateException {
-        if (isStale()) {
-            throw new InvalidItemStateException("stale");
-        }
-    }
-
-    /**
-     * Determine whether this item is stale
-     * @return  {@code true} iff stale
-     */
-    public boolean isStale() {
-        return !location.exists();
-    }
+    public abstract NodeDelegate getParent();
 
     /**
      * Get the status of this item.
      * @return  {@link Status} of this item or {@code null} if not available.
      */
     @CheckForNull
-    public Status getStatus() {
-        return location.getStatus();
-    }
+    public abstract Status getStatus();
 
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("location", location).toString();
-    }
-
-    //------------------------------------------------------------< internal >---
+    public abstract boolean isProtected() throws InvalidItemStateException;
 
     /**
-     * The underlying {@link org.apache.jackrabbit.oak.api.TreeLocation} of this item.
-     * @return  tree location of the underlying item
-     * @throws InvalidItemStateException if the location points to a stale item
+     * Determine whether this item is stale
+     * @return  {@code true} iff stale
      */
-    @Nonnull
-    TreeLocation getLocation() throws InvalidItemStateException {
-        if (!location.exists()) {
-            throw new InvalidItemStateException("Item is stale");
+    public abstract boolean isStale();
+
+    public void checkNotStale() throws InvalidItemStateException {
+        if (isStale()) {
+            throw new InvalidItemStateException("stale");
         }
-        return location;
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java Wed May  1 11:40:50 2013
@@ -16,8 +16,11 @@
  */
 package org.apache.jackrabbit.oak.jcr.delegate;
 
+import static com.google.common.base.Objects.toStringHelper;
 import static com.google.common.collect.Iterables.addAll;
 import static com.google.common.collect.Iterables.contains;
+import static com.google.common.collect.Iterators.filter;
+import static com.google.common.collect.Iterators.transform;
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Sets.newHashSet;
 import static java.util.Collections.emptyList;
@@ -72,11 +75,9 @@ import javax.jcr.nodetype.NoSuchNodeType
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
-import com.google.common.collect.Iterators;
-
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.api.TreeLocation;
+import org.apache.jackrabbit.oak.api.Tree.Status;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.core.IdentifierManager;
@@ -91,26 +92,56 @@ import org.apache.jackrabbit.oak.util.Tr
  */
 public class NodeDelegate extends ItemDelegate {
 
+    /** The underlying {@link org.apache.jackrabbit.oak.api.Tree} of this node. */
+    private final Tree tree;
+
     /**
-     * Create a new {@code NodeDelegate} instance for a valid {@code TreeLocation}. That
-     * is for one where {@code getTree() != null}.
+     * Create a new {@code NodeDelegate} instance for an existing {@code Tree}. That
+     * is for one where {@code exists() == true}.
      *
      * @param sessionDelegate
-     * @param location
-     * @return
+     * @param tree
+     * @return  A new {@code NodeDelegate} instance or {@code null} if {@code tree}
+     *          doesn't exist.
      */
-    static NodeDelegate create(SessionDelegate sessionDelegate, TreeLocation location) {
-        return location.getTree() == null
-                ? null
-                : new NodeDelegate(sessionDelegate, location);
+    static NodeDelegate create(SessionDelegate sessionDelegate, Tree tree) {
+        return tree.exists() ? new NodeDelegate(sessionDelegate, tree) : null;
     }
 
     protected NodeDelegate(SessionDelegate sessionDelegate, Tree tree) {
-        super(sessionDelegate, tree.getLocation());
+        super(sessionDelegate);
+        this.tree = tree;
+    }
+
+    @Override
+    @Nonnull
+    public String getName() {
+        return tree.getName();
+    }
+
+    @Override
+    @Nonnull
+    public String getPath() {
+        return tree.getPath();
     }
 
-    private NodeDelegate(SessionDelegate sessionDelegate, TreeLocation location) {
-        super(sessionDelegate, location);
+    @Override
+    @CheckForNull
+    public NodeDelegate getParent() {
+        return tree.isRoot()
+            ? null
+            : create(sessionDelegate, tree.getParent());
+    }
+
+    @Override
+    public boolean isStale() {
+        return !tree.exists();
+    }
+
+    @Override
+    @CheckForNull
+    public Status getStatus() {
+        return tree.getStatus();
     }
 
     @Nonnull
@@ -121,43 +152,41 @@ public class NodeDelegate extends ItemDe
     @Override
     public boolean isProtected() throws InvalidItemStateException {
         Tree tree = getTree();
+        if (tree.isRoot()) {
+            return false;
+        }
 
-        Tree parent = tree.getParentOrNull();
-        if (parent != null) {
-            String name = tree.getName();
-            Tree typeRoot = sessionDelegate.getRoot().getTreeOrNull(NODE_TYPES_PATH);
-            List<Tree> types = getEffectiveType(parent, typeRoot);
+        Tree parent = tree.getParent();
+        String name = tree.getName();
+        Tree typeRoot = sessionDelegate.getRoot().getTree(NODE_TYPES_PATH);
+        List<Tree> types = getEffectiveType(parent, typeRoot);
 
-            boolean protectedResidual = false;
-            for (Tree type : types) {
-                if (contains(getNames(type, OAK_PROTECTED_CHILD_NODES), name)) {
-                    return true;
-                } else if (!protectedResidual) {
-                    protectedResidual = getBoolean(
-                            type, OAK_HAS_PROTECTED_RESIDUAL_CHILD_NODES);
-                }
+        boolean protectedResidual = false;
+        for (Tree type : types) {
+            if (contains(getNames(type, OAK_PROTECTED_CHILD_NODES), name)) {
+                return true;
+            } else if (!protectedResidual) {
+                protectedResidual = getBoolean(
+                        type, OAK_HAS_PROTECTED_RESIDUAL_CHILD_NODES);
             }
+        }
 
-            // Special case: There are one or more protected *residual*
-            // child node definitions. Iterate through them to check whether
-            // there's a matching, protected one.
-            if (protectedResidual) {
-                Set<String> typeNames = newHashSet();
-                for (Tree type : getEffectiveType(tree, typeRoot)) {
-                    typeNames.add(getName(type, JCR_NODETYPENAME));
-                    addAll(typeNames, getNames(type, OAK_SUPERTYPES));
-                }
+        // Special case: There are one or more protected *residual*
+        // child node definitions. Iterate through them to check whether
+        // there's a matching, protected one.
+        if (protectedResidual) {
+            Set<String> typeNames = newHashSet();
+            for (Tree type : getEffectiveType(tree, typeRoot)) {
+                typeNames.add(getName(type, JCR_NODETYPENAME));
+                addAll(typeNames, getNames(type, OAK_SUPERTYPES));
+            }
 
-                for (Tree type : types) {
-                    Tree definitions = type.getChildOrNull(OAK_RESIDUAL_CHILD_NODE_DEFINITIONS);
-                    if (definitions != null) {
-                        for (String typeName : typeNames) {
-                            Tree definition = definitions.getChildOrNull(typeName);
-                            if (definition != null
-                                    && getBoolean(definition, JCR_PROTECTED)) {
-                                return true;
-                            }
-                        }
+            for (Tree type : types) {
+                Tree definitions = type.getChild(OAK_RESIDUAL_CHILD_NODE_DEFINITIONS);
+                for (String typeName : typeNames) {
+                    Tree definition = definitions.getChild(typeName);
+                    if (getBoolean(definition, JCR_PROTECTED)) {
+                        return true;
                     }
                 }
             }
@@ -168,7 +197,7 @@ public class NodeDelegate extends ItemDe
 
     boolean isProtected(String property) throws InvalidItemStateException {
         Tree tree = getTree();
-        Tree typeRoot = sessionDelegate.getRoot().getTreeOrNull(NODE_TYPES_PATH);
+        Tree typeRoot = sessionDelegate.getRoot().getTree(NODE_TYPES_PATH);
         List<Tree> types = getEffectiveType(tree, typeRoot);
 
         boolean protectedResidual = false;
@@ -186,13 +215,11 @@ public class NodeDelegate extends ItemDe
         // there's a matching, protected one.
         if (protectedResidual) {
             for (Tree type : types) {
-                Tree definitions = type.getChildOrNull(OAK_RESIDUAL_PROPERTY_DEFINITIONS);
-                if (definitions != null) {
-                    for (Tree definition : definitions.getChildren()) {
-                        // TODO: check for matching property type?
-                        if (getBoolean(definition, JCR_PROTECTED)) {
-                            return true;
-                        }
+                Tree definitions = type.getChild(OAK_RESIDUAL_PROPERTY_DEFINITIONS);
+                for (Tree definition : definitions.getChildren()) {
+                    // TODO: check for matching property type?
+                    if (getBoolean(definition, JCR_PROTECTED)) {
+                        return true;
                     }
                 }
             }
@@ -229,10 +256,9 @@ public class NodeDelegate extends ItemDe
      */
     @CheckForNull
     public PropertyDelegate getPropertyOrNull(String relPath) throws RepositoryException {
-        TreeLocation propertyLocation = getChildLocation(relPath);
-        return propertyLocation.getProperty() == null
-                ? null
-                : new PropertyDelegate(sessionDelegate, propertyLocation);
+        Tree parent = getTree(PathUtils.getParentPath(relPath));
+        String name = PathUtils.getName(relPath);
+        return PropertyDelegate.create(sessionDelegate, parent, name);
     }
 
     /**
@@ -246,7 +272,9 @@ public class NodeDelegate extends ItemDe
      */
     @Nonnull
     public PropertyDelegate getProperty(String relPath) throws RepositoryException {
-        return new PropertyDelegate(sessionDelegate, getChildLocation(relPath));
+        Tree parent = getTree(PathUtils.getParentPath(relPath));
+        String name = PathUtils.getName(relPath);
+        return new PropertyDelegate(sessionDelegate, parent, name);
     }
 
     /**
@@ -256,7 +284,18 @@ public class NodeDelegate extends ItemDe
      */
     @Nonnull
     public Iterator<PropertyDelegate> getProperties() throws InvalidItemStateException {
-        return propertyDelegateIterator(getTree().getProperties().iterator());
+        return transform(filter(getTree().getProperties().iterator(), new Predicate<PropertyState>() {
+                @Override
+                public boolean apply(PropertyState property) {
+                    return !property.getName().startsWith(":");
+                }
+                }),
+                new Function<PropertyState, PropertyDelegate>() {
+                    @Override
+                    public PropertyDelegate apply(PropertyState propertyState) {
+                        return new PropertyDelegate(sessionDelegate, tree, propertyState.getName());
+                    }
+                });
     }
 
     /**
@@ -278,7 +317,8 @@ public class NodeDelegate extends ItemDe
      */
     @CheckForNull
     public NodeDelegate getChild(String relPath) throws RepositoryException {
-        return create(sessionDelegate, getChildLocation(relPath));
+        Tree tree = getTree(relPath);
+        return tree == null ? null : create(sessionDelegate, tree);
     }
 
     /**
@@ -312,19 +352,18 @@ public class NodeDelegate extends ItemDe
     public void orderBefore(String source, String target)
             throws ItemNotFoundException, InvalidItemStateException {
         Tree tree = getTree();
-        if (tree.getChildOrNull(source) == null) {
+        if (!tree.getChild(source).exists()) {
             throw new ItemNotFoundException("Not a child: " + source);
-        } else if (target != null && tree.getChildOrNull(target) == null) {
+        } else if (target != null && !tree.getChild(target).exists()) {
             throw new ItemNotFoundException("Not a child: " + target);
         } else {
-            tree.getChildOrNull(source).orderBefore(target);
+            tree.getChild(source).orderBefore(target);
         }
     }
 
     public boolean canAddMixin(String typeName) throws RepositoryException {
-        Tree typeRoot = sessionDelegate.getRoot().getTreeOrNull(NODE_TYPES_PATH);
-        Tree type = typeRoot.getChildOrNull(typeName);
-        if (type != null) {
+        Tree type = sessionDelegate.getRoot().getTree(NODE_TYPES_PATH).getChild(typeName);
+        if (type.exists()) {
             return !getBoolean(type, JCR_IS_ABSTRACT)
                     && getBoolean(type, JCR_ISMIXIN);
         } else {
@@ -334,10 +373,8 @@ public class NodeDelegate extends ItemDe
     }
 
     public void addMixin(String typeName) throws RepositoryException {
-        Tree typeRoot = sessionDelegate.getRoot().getTreeOrNull(NODE_TYPES_PATH);
-
-        Tree type = typeRoot.getChildOrNull(typeName);
-        if (type == null) {
+        Tree type = sessionDelegate.getRoot().getTree(NODE_TYPES_PATH).getChild(typeName);
+        if (!type.exists()) {
             throw new NoSuchNodeTypeException(
                     "Node type " + typeName + " does not exist");
         } else if (getBoolean(type, JCR_IS_ABSTRACT)) {
@@ -357,9 +394,9 @@ public class NodeDelegate extends ItemDe
             return;
         }
 
-        Set<String> submixins = newHashSet(getNames(type, OAK_MIXIN_SUBTYPES));
+        Set<String> subMixins = newHashSet(getNames(type, OAK_MIXIN_SUBTYPES));
         for (String mixin : getNames(tree, JCR_MIXINTYPES)) {
-            if (typeName.equals(mixin) || submixins.contains(mixin)) {
+            if (typeName.equals(mixin) || subMixins.contains(mixin)) {
                 return;
             }
             mixins.add(mixin);
@@ -367,7 +404,7 @@ public class NodeDelegate extends ItemDe
 
         mixins.add(typeName);
         tree.setProperty(JCR_MIXINTYPES, mixins, NAMES);
-        autoCreateItems(tree, type, typeRoot);
+        autoCreateItems(tree, type, sessionDelegate.getRoot().getTree(NODE_TYPES_PATH));
     }
 
     /**
@@ -379,8 +416,8 @@ public class NodeDelegate extends ItemDe
     @Nonnull
     public PropertyDelegate setProperty(PropertyState propertyState) throws RepositoryException {
         Tree tree = getTree();
-        String name = propertyState.getName();
-        PropertyState old = tree.getProperty(name);
+        String propName = propertyState.getName();
+        PropertyState old = tree.getProperty(propName);
         if (old != null && old.isArray() && !propertyState.isArray()) {
             throw new ValueFormatException("Attempt to assign a single value to multi-valued property.");
         }
@@ -388,7 +425,7 @@ public class NodeDelegate extends ItemDe
             throw new ValueFormatException("Attempt to assign multiple values to single valued property.");
         }
         tree.setProperty(propertyState);
-        return new PropertyDelegate(sessionDelegate, tree.getLocation().getChild(name));
+        return new PropertyDelegate(sessionDelegate, tree, propName);
     }
 
     /**
@@ -407,7 +444,7 @@ public class NodeDelegate extends ItemDe
             return null;
         }
 
-        Tree typeRoot = sessionDelegate.getRoot().getTreeOrNull(NODE_TYPES_PATH);
+        Tree typeRoot = sessionDelegate.getRoot().getTree(NODE_TYPES_PATH);
         if (typeName == null) {
             typeName = getDefaultChildType(typeRoot, tree, name);
             if (typeName == null) {
@@ -418,7 +455,6 @@ public class NodeDelegate extends ItemDe
         }
 
         Tree child = internalAddChild(tree, name, typeName, typeRoot);
-
         return new NodeDelegate(sessionDelegate, child);
     }
 
@@ -439,13 +475,18 @@ public class NodeDelegate extends ItemDe
         getTree().setOrderableChildren(enable);
     }
 
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("tree", tree).toString();
+    }
+
     //------------------------------------------------------------< internal >---
 
     private Tree internalAddChild(
             Tree parent, String name, String typeName, Tree typeRoot)
             throws RepositoryException {
-        Tree type = typeRoot.getChildOrNull(typeName);
-        if (type == null) {
+        Tree type = typeRoot.getChild(typeName);
+        if (!type.exists()) {
             throw new NoSuchNodeTypeException(
                     "Node type " + typeName + " does not exist");
         } else if (getBoolean(type, JCR_IS_ABSTRACT)) {
@@ -468,49 +509,45 @@ public class NodeDelegate extends ItemDe
     private void autoCreateItems(Tree tree, Tree type, Tree typeRoot)
             throws RepositoryException {
         // TODO: use a separate oak:autoCreatePropertyDefinitions
-        Tree properties = type.getChildOrNull(OAK_NAMED_PROPERTY_DEFINITIONS);
-        if (properties != null) {
-            for (Tree definitions : properties.getChildren()) {
-                String name = definitions.getName();
-                if (name.equals("oak:primaryType")
-                        || name.equals("oak:mixinTypes")) {
-                    continue;
-                } else if (name.equals("oak:uuid")) {
-                    name = JCR_UUID;
-                }
-                for (Tree definition : definitions.getChildren()) {
-                    if (getBoolean(definition, JCR_AUTOCREATED)) {
-                        if (!tree.hasProperty(name)) {
-                            PropertyState property =
-                                    autoCreateProperty(name, definition);
-                            if (property != null) {
-                                tree.setProperty(property);
-                            } else {
-                                throw new RepositoryException(
-                                        "Unable to auto-create value for "
-                                        + PathUtils.concat(tree.getPath(), name));
-                            }
+        Tree properties = type.getChild(OAK_NAMED_PROPERTY_DEFINITIONS);
+        for (Tree definitions : properties.getChildren()) {
+            String name = definitions.getName();
+            if (name.equals("oak:primaryType")
+                    || name.equals("oak:mixinTypes")) {
+                continue;
+            } else if (name.equals("oak:uuid")) {
+                name = JCR_UUID;
+            }
+            for (Tree definition : definitions.getChildren()) {
+                if (getBoolean(definition, JCR_AUTOCREATED)) {
+                    if (!tree.hasProperty(name)) {
+                        PropertyState property =
+                                autoCreateProperty(name, definition);
+                        if (property != null) {
+                            tree.setProperty(property);
+                        } else {
+                            throw new RepositoryException(
+                                    "Unable to auto-create value for "
+                                    + PathUtils.concat(tree.getPath(), name));
                         }
-                        break;
                     }
+                    break;
                 }
             }
         }
 
         // TODO: use a separate oak:autoCreateChildNodeDefinitions
-        Tree childNodes = type.getChildOrNull(OAK_NAMED_CHILD_NODE_DEFINITIONS);
-        if (childNodes != null) {
-            for (Tree definitions : childNodes.getChildren()) {
-                String name = definitions.getName();
-                for (Tree definition : definitions.getChildren()) {
-                    if (getBoolean(definition, JCR_AUTOCREATED)) {
-                        if (!tree.hasChild(name)) {
-                            String typeName =
-                                    getName(definition, JCR_DEFAULTPRIMARYTYPE);
-                            internalAddChild(tree, name, typeName, typeRoot);
-                        }
-                        break;
+        Tree childNodes = type.getChild(OAK_NAMED_CHILD_NODE_DEFINITIONS);
+        for (Tree definitions : childNodes.getChildren()) {
+            String name = definitions.getName();
+            for (Tree definition : definitions.getChildren()) {
+                if (getBoolean(definition, JCR_AUTOCREATED)) {
+                    if (!tree.hasChild(name)) {
+                        String typeName =
+                                getName(definition, JCR_DEFAULTPRIMARYTYPE);
+                        internalAddChild(tree, name, typeName, typeRoot);
                     }
+                    break;
                 }
             }
         }
@@ -563,34 +600,26 @@ public class NodeDelegate extends ItemDe
      * @param childName name of the new child node
      * @return name of the default type, or {@code null} if not available
      */
-    private String getDefaultChildType(
+    private static String getDefaultChildType(
             Tree typeRoot, Tree parent, String childName) {
         List<Tree> types = getEffectiveType(parent, typeRoot);
 
         // first look for named node definitions
         for (Tree type : types) {
-            Tree named = type.getChildOrNull(OAK_NAMED_CHILD_NODE_DEFINITIONS);
-            if (named != null) {
-                Tree definitions = named.getChildOrNull(childName);
-                if (definitions != null) {
-                    String defaultName =
-                            findDefaultPrimaryType(typeRoot, definitions);
-                    if (defaultName != null) {
-                        return defaultName;
-                    }
-                }
+            Tree named = type.getChild(OAK_NAMED_CHILD_NODE_DEFINITIONS);
+            Tree definitions = named.getChild(childName);
+            String defaultName = findDefaultPrimaryType(typeRoot, definitions);
+            if (defaultName != null) {
+                return defaultName;
             }
         }
 
         // then check residual definitions
         for (Tree type : types) {
-            Tree definitions = type.getChildOrNull(OAK_RESIDUAL_CHILD_NODE_DEFINITIONS);
-            if (definitions != null) {
-                String defaultName =
-                        findDefaultPrimaryType(typeRoot, definitions);
-                if (defaultName != null) {
-                    return defaultName;
-                }
+            Tree definitions = type.getChild(OAK_RESIDUAL_CHILD_NODE_DEFINITIONS);
+            String defaultName = findDefaultPrimaryType(typeRoot, definitions);
+            if (defaultName != null) {
+                return defaultName;
             }
         }
 
@@ -606,15 +635,15 @@ public class NodeDelegate extends ItemDe
 
         String primary = getName(tree, JCR_PRIMARYTYPE);
         if (primary != null) {
-            Tree type = typeRoot.getChildOrNull(primary);
-            if (type != null) {
+            Tree type = typeRoot.getChild(primary);
+            if (type.exists()) {
                 types.add(type);
             }
         }
 
         for (String mixin : getNames(tree, JCR_MIXINTYPES)) {
-            Tree type = typeRoot.getChildOrNull(mixin);
-            if (type != null) {
+            Tree type = typeRoot.getChild(mixin);
+            if (type.exists()) {
                 types.add(type);
             }
         }
@@ -622,7 +651,7 @@ public class NodeDelegate extends ItemDe
         return types;
     }
 
-    private String findDefaultPrimaryType(Tree typeRoot, Tree definitions) {
+    private static String findDefaultPrimaryType(Tree typeRoot, Tree definitions) {
         for (Tree definition : definitions.getChildren()) {
             String defaultName = getName(definition, JCR_DEFAULTPRIMARYTYPE);
             if (defaultName != null) {
@@ -634,27 +663,26 @@ public class NodeDelegate extends ItemDe
 
     @Nonnull // FIXME this should be package private. OAK-672
     public Tree getTree() throws InvalidItemStateException {
-        Tree tree = getLocation().getTree();
-        if (tree == null) {
-            throw new InvalidItemStateException();
+        if (!tree.exists()) {
+            throw new InvalidItemStateException("Item is stale");
         }
         return tree;
     }
 
     // -----------------------------------------------------------< private >---
 
-    private TreeLocation getChildLocation(String relPath) throws RepositoryException {
+    private Tree getTree(String relPath) throws RepositoryException {
         if (PathUtils.isAbsolute(relPath)) {
             throw new RepositoryException("Not a relative path: " + relPath);
         }
 
-        return TreeUtil.getTreeLocation(getLocation(), relPath);
+        return TreeUtil.getTree(tree, relPath);
     }
 
     private Iterator<NodeDelegate> nodeDelegateIterator(
             Iterator<Tree> children) {
-        return Iterators.transform(
-                Iterators.filter(children, new Predicate<Tree>() {
+        return transform(
+                filter(children, new Predicate<Tree>() {
                     @Override
                     public boolean apply(Tree tree) {
                         return !tree.getName().startsWith(":");
@@ -668,24 +696,6 @@ public class NodeDelegate extends ItemDe
                 });
     }
 
-    private Iterator<PropertyDelegate> propertyDelegateIterator(
-            Iterator<? extends PropertyState> properties) throws InvalidItemStateException {
-        final TreeLocation location = getLocation();
-        return Iterators.transform(
-                Iterators.filter(properties, new Predicate<PropertyState>() {
-                    @Override
-                    public boolean apply(PropertyState property) {
-                        return !property.getName().startsWith(":");
-                    }
-                }),
-                new Function<PropertyState, PropertyDelegate>() {
-                    @Override
-                    public PropertyDelegate apply(PropertyState propertyState) {
-                        return new PropertyDelegate(sessionDelegate, location.getChild(propertyState.getName()));
-                    }
-                });
-    }
-
     // Generic property value accessors. TODO: add to Tree?
 
     private static boolean getBoolean(Tree tree, String name) {
@@ -714,5 +724,4 @@ public class NodeDelegate extends ItemDe
             return emptyList();
         }
     }
-
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java Wed May  1 11:40:50 2013
@@ -16,13 +16,18 @@
  */
 package org.apache.jackrabbit.oak.jcr.delegate;
 
+import static com.google.common.base.Objects.toStringHelper;
+
+import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.jcr.InvalidItemStateException;
 import javax.jcr.ValueFormatException;
 
 import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.TreeLocation;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Tree.Status;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 
 /**
  * {@code PropertyDelegate} serve as internal representations of {@code Property}s.
@@ -32,18 +37,69 @@ import org.apache.jackrabbit.oak.api.Typ
  */
 public class PropertyDelegate extends ItemDelegate {
 
-    PropertyDelegate(SessionDelegate sessionDelegate, TreeLocation location) {
-        super(sessionDelegate, location);
+    /** The underlying {@link org.apache.jackrabbit.oak.api.Tree} of this property's parent */
+    private final Tree parent;
+
+    private final String name;
+
+    /**
+     * Create a new property delegate for an existing parent.
+     * @param sessionDelegate
+     * @param parent  parent tree
+     * @param name  property name
+     * @return  {@code PropertyDelegate} instance or {@code null} if either {@code parent}
+     *          does not exist or does not have a property {@code name}.
+     */
+    @CheckForNull
+    static PropertyDelegate create(SessionDelegate sessionDelegate, Tree parent, String name) {
+        return parent.exists() && parent.hasProperty(name) ?
+            new PropertyDelegate(sessionDelegate, parent, name)
+            : null;
+    }
+
+    PropertyDelegate(SessionDelegate sessionDelegate, Tree parent, String name) {
+        super(sessionDelegate);
+        this.parent = parent;
+        this.name = name;
+    }
+
+    @Override
+    @Nonnull
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    @Nonnull
+    public String getPath() {
+        return PathUtils.concat(parent.getPath(), name);
+    }
+
+    @Override
+    @CheckForNull
+    public NodeDelegate getParent() {
+        return NodeDelegate.create(sessionDelegate, parent);
+    }
+
+    @Override
+    public boolean isStale() {
+        return !parent.exists() || !parent.hasProperty(name);
+    }
+
+    @Override
+    @CheckForNull
+    public Status getStatus() {
+        return parent.getPropertyStatus(name);
     }
 
     @Override
     public boolean isProtected() throws InvalidItemStateException {
-        return getParent().isProtected(getName());
+        return getParent().isProtected(name);
     }
 
     @Nonnull
     public PropertyState getPropertyState() throws InvalidItemStateException {
-        PropertyState p = getLocation().getProperty();
+        PropertyState p = parent.getProperty(name);
         if (p == null) {
             throw new InvalidItemStateException();
         }
@@ -84,17 +140,23 @@ public class PropertyDelegate extends It
         return p;
     }
 
-    public void setState(PropertyState propertyState) throws InvalidItemStateException {
-        if (!getLocation().set(propertyState)) {
-            throw new InvalidItemStateException();
-        }
+    public void setState(PropertyState propertyState) {
+        parent.setProperty(propertyState);
     }
 
     /**
      * Remove the property
      */
-    public void remove() throws InvalidItemStateException {
-        getLocation().remove();
+    public void remove() {
+        parent.removeProperty(name);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("parent", parent)
+                .add("property", parent.getProperty(name))
+                .toString();
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java Wed May  1 11:40:50 2013
@@ -39,7 +39,6 @@ import org.apache.jackrabbit.oak.api.Con
 import org.apache.jackrabbit.oak.api.QueryEngine;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.api.TreeLocation;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.core.IdentifierManager;
 import org.slf4j.Logger;
@@ -162,7 +161,7 @@ public class SessionDelegate {
      */
     @CheckForNull
     public NodeDelegate getNode(String path) {
-        return NodeDelegate.create(this, getLocation(path));
+        return NodeDelegate.create(this, root.getTree(path));
     }
 
     @CheckForNull
@@ -179,10 +178,9 @@ public class SessionDelegate {
      */
     @CheckForNull
     public PropertyDelegate getProperty(String path) {
-        TreeLocation location = root.getLocation(path);
-        return location.getProperty() == null
-            ? null
-            : new PropertyDelegate(this, location);
+        Tree parent = root.getTree(PathUtils.getParentPath(path));
+        String name = PathUtils.getName(path);
+        return PropertyDelegate.create(this, parent, name);
     }
 
     public boolean hasPendingChanges() {
@@ -220,21 +218,21 @@ public class SessionDelegate {
      */
     public void copy(String srcPath, String destPath) throws RepositoryException {
         // check destination
-        Tree dest = getTree(destPath);
-        if (dest != null) {
+        Tree dest = root.getTree(destPath);
+        if (dest.exists()) {
             throw new ItemExistsException(destPath);
         }
 
         // check parent of destination
         String destParentPath = PathUtils.getParentPath(destPath);
-        Tree destParent = getTree(destParentPath);
-        if (destParent == null) {
+        Tree destParent = root.getTree(destParentPath);
+        if (!destParent.exists()) {
             throw new PathNotFoundException(PathUtils.getParentPath(destPath));
         }
 
         // check source exists
-        Tree src = getTree(srcPath);
-        if (src == null) {
+        Tree src = root.getTree(srcPath);
+        if (!src.exists()) {
             throw new PathNotFoundException(srcPath);
         }
 
@@ -260,21 +258,21 @@ public class SessionDelegate {
         Root moveRoot = transientOp ? root : contentSession.getLatestRoot();
 
         // check destination
-        Tree dest = moveRoot.getTreeOrNull(destPath);
-        if (dest != null) {
+        Tree dest = moveRoot.getTree(destPath);
+        if (dest.exists()) {
             throw new ItemExistsException(destPath);
         }
 
         // check parent of destination
         String destParentPath = PathUtils.getParentPath(destPath);
-        Tree destParent = moveRoot.getTreeOrNull(destParentPath);
-        if (destParent == null) {
+        Tree destParent = moveRoot.getTree(destParentPath);
+        if (!destParent.exists()) {
             throw new PathNotFoundException(PathUtils.getParentPath(destPath));
         }
 
         // check source exists
-        Tree src = moveRoot.getTreeOrNull(srcPath);
-        if (src == null) {
+        Tree src = moveRoot.getTree(srcPath);
+        if (!src.exists()) {
             throw new PathNotFoundException(srcPath);
         }
 
@@ -300,22 +298,6 @@ public class SessionDelegate {
         return root;
     }
 
-    @Nonnull
-    TreeLocation getLocation(String path) {
-        return root.getLocation(path);
-    }
-
-    /**
-     * Get the {@code Tree} with the given path
-     * @param path  oak path
-     * @return  tree at the given path or {@code null} if no such tree exists or
-     * if the tree at {@code path} is not accessible.
-     */
-    @CheckForNull
-    private Tree getTree(String path) {
-        return root.getTreeOrNull(path);
-    }
-
     /**
      * Wraps the given {@link CommitFailedException} instance using the
      * appropriate {@link RepositoryException} subclass based on the

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionHistoryDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionHistoryDelegate.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionHistoryDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionHistoryDelegate.java Wed May  1 11:40:50 2013
@@ -55,8 +55,8 @@ public class VersionHistoryDelegate exte
 
     @Nonnull
     public VersionDelegate getRootVersion() throws RepositoryException {
-        Tree rootVersion = getTree().getChildOrNull(VersionConstants.JCR_ROOTVERSION);
-        if (rootVersion == null) {
+        Tree rootVersion = getTree().getChild(VersionConstants.JCR_ROOTVERSION);
+        if (!rootVersion.exists()) {
             throw new RepositoryException("Inconsistent version storage. " +
                     "VersionHistory does not have a root version");
         }
@@ -67,8 +67,8 @@ public class VersionHistoryDelegate exte
     public VersionDelegate getVersion(@Nonnull String versionName)
             throws VersionException, RepositoryException {
         checkNotNull(versionName);
-        Tree version = getTree().getChildOrNull(versionName);
-        if (version == null) {
+        Tree version = getTree().getChild(versionName);
+        if (!version.exists()) {
             throw new VersionException("No such Version: " + versionName);
         }
         return VersionDelegate.create(sessionDelegate, version);
@@ -86,7 +86,7 @@ public class VersionHistoryDelegate exte
         String id = p.getValue(Type.REFERENCE);
         Tree version = sessionDelegate.getIdManager().getTree(id);
         if (version == null) {
-            throw new VersionException("Invalid label: " + label + "(" + id + ")");
+            throw new VersionException("Invalid label: " + label + '(' + id + ')');
         }
         return VersionDelegate.create(sessionDelegate, version);
     }
@@ -137,7 +137,7 @@ public class VersionHistoryDelegate exte
         return Iterators.transform(versions.values().iterator(), new Function<String, VersionDelegate>() {
             @Override
             public VersionDelegate apply(String name) {
-                return VersionDelegate.create(sessionDelegate, thisTree.getChildOrNull(name));
+                return VersionDelegate.create(sessionDelegate, thisTree.getChild(name));
             }
         });
     }
@@ -152,8 +152,8 @@ public class VersionHistoryDelegate exte
      */
     @Nonnull
     private Tree getVersionLabelsTree() throws RepositoryException {
-        Tree versionLabels = getTree().getChildOrNull(VersionConstants.JCR_VERSIONLABELS);
-        if (versionLabels == null) {
+        Tree versionLabels = getTree().getChild(VersionConstants.JCR_VERSIONLABELS);
+        if (!versionLabels.exists()) {
             throw new RepositoryException("Inconsistent version storage. " +
                     "VersionHistory does not have jcr:versionLabels child node");
         }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionManagerDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionManagerDelegate.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionManagerDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/VersionManagerDelegate.java Wed May  1 11:40:50 2013
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.oak.jcr.delegate;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import javax.annotation.Nonnull;
 import javax.jcr.InvalidItemStateException;
 import javax.jcr.RepositoryException;
@@ -23,11 +25,8 @@ import javax.jcr.UnsupportedRepositoryOp
 
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.api.TreeLocation;
 import org.apache.jackrabbit.oak.jcr.version.ReadWriteVersionManager;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 /**
  * {@code VersionManagerDelegate}...
  */
@@ -37,25 +36,25 @@ public class VersionManagerDelegate {
      * TODO: this assumes the version store is in the same workspace.
      */
     private static final String VERSION_STORAGE_PATH
-            = "/" + JcrConstants.JCR_SYSTEM + "/" + JcrConstants.JCR_VERSIONSTORAGE;
+            = '/' + JcrConstants.JCR_SYSTEM + '/' + JcrConstants.JCR_VERSIONSTORAGE;
 
     private final SessionDelegate sessionDelegate;
 
     private final ReadWriteVersionManager versionManager;
 
     public static VersionManagerDelegate create(SessionDelegate sessionDelegate) {
-        TreeLocation location = sessionDelegate.getRoot().getLocation(VERSION_STORAGE_PATH);
-        return new VersionManagerDelegate(sessionDelegate, location);
+        Tree versionStorage = sessionDelegate.getRoot().getTree(VERSION_STORAGE_PATH);
+        return new VersionManagerDelegate(sessionDelegate, versionStorage);
     }
 
     private VersionManagerDelegate(SessionDelegate sessionDelegate,
-                                   TreeLocation versionStorageLocation) {
+                                   Tree versionStorage) {
         this.sessionDelegate = sessionDelegate;
         this.versionManager = new ReadWriteVersionManager(
-                versionStorageLocation,
+                versionStorage,
                 sessionDelegate.getRoot()) {
             @Override
-            protected void refresh() throws RepositoryException {
+            protected void refresh() {
                 VersionManagerDelegate.this.sessionDelegate.refresh(true);
             }
         };
@@ -123,11 +122,6 @@ public class VersionManagerDelegate {
     @Nonnull
     private static Tree getTree(@Nonnull NodeDelegate nodeDelegate)
             throws InvalidItemStateException {
-        Tree t = checkNotNull(nodeDelegate).getLocation().getTree();
-        if (t == null) {
-            throw new InvalidItemStateException("Node does not exist: " +
-                    nodeDelegate.getPath());
-        }
-        return t;
+        return checkNotNull(nodeDelegate).getTree();
     }
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/ReadWriteVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/ReadWriteVersionManager.java?rev=1477956&r1=1477955&r2=1477956&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/ReadWriteVersionManager.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/ReadWriteVersionManager.java Wed May  1 11:40:50 2013
@@ -26,7 +26,6 @@ import javax.jcr.UnsupportedRepositoryOp
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.api.TreeLocation;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
@@ -38,12 +37,12 @@ import org.apache.jackrabbit.oak.plugins
  */
 public class ReadWriteVersionManager extends ReadOnlyVersionManager {
 
-    private final TreeLocation versionStorageLocation;
+    private final Tree versionStorage;
     private final Root workspaceRoot;
 
-    public ReadWriteVersionManager(@Nonnull TreeLocation versionStorageLocation,
-                                   @Nonnull Root workspaceRoot) {
-        this.versionStorageLocation = checkNotNull(versionStorageLocation);
+    public ReadWriteVersionManager(@Nonnull Tree versionStorage,
+            @Nonnull Root workspaceRoot) {
+        this.versionStorage = checkNotNull(versionStorage);
         this.workspaceRoot = checkNotNull(workspaceRoot);
     }
 
@@ -61,8 +60,8 @@ public class ReadWriteVersionManager ext
 
     @Override
     @Nonnull
-    protected TreeLocation getVersionStorageLocation() {
-        return versionStorageLocation;
+    protected Tree getVersionStorage() {
+        return versionStorage;
     }
 
     @Override
@@ -115,7 +114,7 @@ public class ReadWriteVersionManager ext
                 throw new RepositoryException(e);
             }
         }
-        return getBaseVersion(getWorkspaceRoot().getTreeOrNull(versionable.getPath()));
+        return getBaseVersion(getWorkspaceRoot().getTree(versionable.getPath()));
     }
 
     /**