jackrabbit-oak-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Dürig <mdue...@apache.org>
Subject Re: Oak API - a top down look
Date Thu, 19 Apr 2012 14:41:58 GMT

On 19.4.12 9:48, Angela Schreiber wrote:
> 1. workspace story
> ------------------------------------------------------------------------
> as already stated in reply to felix/jukkas discussion in this thread
> that i have a different preference regarding on the relationship
> between ContentSession and JCR Session/Workspace... but i am convinced
> that we can reach consensus on this once we have a better picture on
> access control, permission evaluation, versioning and representation of
> repository-level content as this most probably will have an impact.

Having ContentSession.getContentTree() return the whole tree is a more 
general approach than returning only the tree of a given workspace. That 
is, workspace operations can be implemented on top of that, where in the 
other case we'd need some special workspace operations in the API. So 
this all boils down to a questions of API granularity and content model: 
Do we want to expose workspaces explicitly at the Oak api level? What 
are the use cases (on that API level)? If we don't, what is the draw 
back for Oak API consumers having to cope with the content model directly?

What about going the general way (i.e. getContentTree returns the whole 
tree with all workspaces beneath it) and providing an utility class 
'JCRView' in oak-core which projects the content tree to a given 
workspace and 'mounts' the jcr:system node? This way we would get both: 
a sufficiently general API and avoid having Oak API consumers to 
re-implement commonly needed functionality.

> 2. access control restrictions
> ------------------------------------------------------------------------
> there is one thing that we have to keep in mind when it comes to
> the ContentTree interface and the information it exposes to the oak-jcr:
> due to the fact that permission evaluation will be located in oak-core
> the ContentTree might be incomplete. a given user may not be able
> to read the root node but having access to items somewhere in the
> subtree.
> thus:
>> ContentSession session = ...;
>> ContentTree tree = session.getCurrentContentTree();
> if the tree here really represents a node that might be problematic
> (and the name seems rather misleading to me in this case).

It represents a sub-tree which in turn might contain sub-trees. As such 
I like that name better than node. However, we might have different 
perceptions of what constitutes nodes and trees.

> however, if we look at ContentTree as an abstract point in the
> hierarchy that is identified by an identifier that might work.
> but then the ContentTree interface should not have methods that
> actually belong to a Node... or we need the possibility to determine
> if there is an accessible 'NodeState' with a given 'tree'.
> second we need to have the ability to access item information
> somewhere in the subtree without having to traverse (see above).
> there are for sure multiple possibilities to achieve this, such
> as e.g.
> - ContentSession.getCurrentContentTree take (must have) a path
> -> contentree was more of a node again
> -> how do you assert then that transient modifications are
> always persisted together since we don't want to support
> Item#save() any more???
> - ContentTree in addition has a method getNodeState that would
> actually represent the Node. the tree was then just the
> representation of the path and the modifier/access methods
> should rather be moved to NodeState.

I think we don't need a separate NodeState. Isn't having navigational 
methods on ContentTree sufficient? I.e. something along the lines of:

   interface ContentTree {
     ContentTree getParent();
     ContentTree getChild(String name);
     // ...

BTW: this would make


equivalent to


Regarding incomplete trees caused by insufficient permissions: I'm not 
sure whether I fully grasp this yet. Given path /x/y and a user who can 
read y but not x. Does this mean that

session.getRootNode().getNode("x").getNode("y") fails,
session.getNode("/x/y") succeds, and
session.getRootNode("x/y") succeeds

or are there additional twists to it?

If there are no relevant additional twists, I think above ContentTree 
interface would still be sufficient. But let me get a better 
understanding of it before I start arguing into the blue ;-)


> - ...
> kind regards
> angela
>> The returned `ContentTree` instance belongs to the client and its
>> state is
>> only modified in response to method calls made by the client.
>> `ContentTree`
>> instances are *not* thread-safe, so the client needs to ensure that
>> they are
>> not accessed concurrently from multiple threads. Content trees are
>> recursive data structures that consist of named properties and subtrees
>> that share the same namespace, but are accessed through separate methods
>> like outlined below:
>> ContentTree tree = ...;
>> for (PropertyState property : tree.getProperties()) {
>> ...;
>> }
>> for (ContentTree subtree : tree.getSubtrees()) {
>> ...;
>> }
>> The repository content snapshot exposed by a `ContentTree` instance may
>> become invalid over time due to garbage collection of old content, at
>> which
>> point an outdated snapshot will start throwing
>> `IllegalStateExceptions` to
>> indicate that the snapshot is no longer available. To access more recent
>> content, a client should either call `getCurrentContentTree()` to acquire
>> a fresh now content snapshot or use the `refresh()` method to update a
>> given `ContentTree` to the latest state of the content repository:
>> ContentTree tree = ...;
>> tree.refresh();
>> In addition to reading repository content, the client can also make
>> modifications to the content tree. Such content changes remain local
>> to the particular `ContentTree` instance (and related subtrees) until
>> explicitly committed. For example, the following code creates and commits
>> a new subtree containing nothing but a simple property:
>> ContentTree tree = ...;
>> ContentTree subtree = tree.addSubtree("hello");
>> subtree.setProperty("message", "Hello, World!");
>> tree.commit();
>> Even other `ContentTree` instances acquired from the same
>> `ContentSession`
>> won't see such changes until they've been committed and the other trees
>> refreshed. This allows a client to track multiple parallel sets of
>> changes
>> with just a single authenticated session.

View raw message