Hi,

There is some discussion around how (relative) paths should be handled within Oak [1, 2, 3].

Initially (well, way back) there was a clear definition what an oak path (in contrast to a JCR path) is. That definition got somewhat lost/blurred along the way.

Currently an oak path as returned by PathMapper.getOakPath() is a string consisting of elements separated by a forward slashes. Elements are names or the special element parent (..). The parent element never occurs after a name element (that is, parent elements only occur at the beginning of an oak path. An oak path starting with a forward slash is an absolute path. All other paths are relative. Only relative oak paths may contain parent elements.

Semantically an absolute oak path refers to an item in a tree such that
- / refers to the root of the tree,
- <absolute-oak-path>/name refers to the child "name" of the node referred to by <absolute-oak-path>,

and a relative oak path refers to an item in a tree such that for any item i
- "" refers to i,
- <relative-oak-path>/name refers to the child "name" of the node referred to by <relative-oak-path>, - <relative-oak-path>/.. refers to the parent of the node referred to by <relative-oak-path>.

As I mentioned in OAK-426 I think it is unnecessary and even wrong to push handling of special path elements down to oak-core since this would mix the concerns of interpreting names with tree navigation and access. It further breaks modularisation since this would tear plugin functionality into core. Interpretation of paths and names should stay entirely in oak-jcr and the respective plugins.

However, this currently leads to some amount of duplicate code in oak-jcr (LocationUtil, NodeUtil.getOrAddTree, NodeDelegate.getChildLocation). To factor this out I see two possibilities:

1. Consolidate the three different implementations into one factoring out the commonalities and simplify by levering the properties of above path definition.

2. Pass the functionality down to TreeImpl.getChild() through a new parameter of type NameResolver:

interface NameResolver {
  TreeLocation resolve(String name, TreeLocation location);
}

With the first approach client code would have to go through a utility class explicitly. With the second approach clients would be forced to used the utility through having to pass it to TreeLocation.getChild(). The second approach could also be made working on JCR paths directly by implementing a JCR version of above NameResolver.

Michael


[1] http://markmail.org/message/66q4nf2aj4b424z3
[2] https://issues.apache.org/jira/browse/OAK-426
[3] https://issues.apache.org/jira/browse/OAK-369

Reply via email to