Hi,

On 18.9.12 16:56, Jukka Zitting wrote:
Hi,

We have a good reasons for adding support for "virtual content", i.e.
content that's accessible through the Oak API, but that's not actually
stored in the underlying MicroKernel. The main reasons that come to my
mind are:

Incidentally I was playing around with something along these lines on top of the Tree interface lately. To see how things work out I implemented a 'mounting' feature to mount a tree onto a sub-tree at a given path. My implementation uses a decorator on top of the Tree interface for tracking the mount point, the host tree and the mounted tree. Still very raw, but workable: https://github.com/mduerig/jackrabbit-oak/commit/9b1492e3c83aaed2f919196cddc60d5915add6f8


1) As we implement workspace support, we need some way to make the
shared /jcr:system subtree visible to all workspaces.
2) The JCR spec mandates some auto-created content to be available
already before transient changes are persisted. That should be fairly
straightforward to implement with virtual content.
3) We could "mount" parts of external repositories to a single content tree.
4) We could implement "views" like in Hippo's facet feature.

The same feature could probably also be easily used to hide existing
content for access control or other reasons.

I was thinking along the same lines with my tree decorator: wouldn't it be cleaner to decorate access control on top of the TreeImpl class instead of intertwining it with the existing functionality.


So how could we best implement something like this?

The implementation should probably go to somewhere between the Oak API
and the MicroKernel, ideally either as an extension point in the Tree
or NodeState implementations.

My tree decorating approach is one way. However I feel this can get pretty complex for other cases where one for example wants to map virtual properties into certain nodes. The main source of complexity is inherited from the complexity of the Tree interface (mutators, navigators, helpers and so on).

Another approach is to implement this at the NodeState level. Since node states are pretty simple and not mutable a read only mounting feature should be pretty simple (virtually for free, that is). For r/w the NodeStateDiff (i.e. JsopDiff) would need to have to know about the mounted content in order to create the correct sequence of updates.

We probably have to experiment with the 2nd approach also to get a better grasp on the alternatives. Maybe we end up with both ways depending on the kind of virtual content to map.

Michael


Additionally, to make sure that the
implementation won't interfere with the performance of normal content
access, this mechanism should probably only be invoked _after_ an
attempt to access normal content has been made. Apart from these
general ideas I don't yet have a good picture of what the detailed
implementation could or should look like.

Like with custom indexes, the configuration settings for such virtual
content should in my mind go into the repository as normal content.
For example, the following hypothetical repository tree would define a
workspace subtree with a view to a shared /jcr:system subtree and a
custom view for the latest 100 nodes in /latest:

     /
         /jcr:system {the global jcr:system tree}
             /... {namespace & node type registries, version store, etc.}
         /my-workspace [jcr:mixinTypes = oak:virtual]
             /oak:virtual
                 /system [jcr:mixinType = oak:mount,
                          globalPath = /jcr:system,
                          mountName = jcr:system]
             /latest [jcr:mixinTypes = oak:virtual]
                 /oak:virtual
                     /view [jcr:mixinType = oak:view,
                            query = "SELECT * FROM [nt:base] ...
                                     ORDER BY [jcr:created] DESC LIMIT 100"]

As before, please share your critiques, improvements and/or alternatives.

BR,

Jukka Zitting

Reply via email to