All (but especially Andrew),
JCR requires an object called a Session. This is very similar to
Hibernate's Session, in the sense that it represents actual read/
write access to the repository. The session gathers all the changes,
and those changes are then flushed all by calling Session.save().
The chief limitation is that Sessions are *not* thread-safe (and not
synchronized, for speed). However, Sessions are fairly fast to open
(JackRabbit is around 1.5 ms, Priha is faster).
My initial feeling would be to make the JCR Session a part of the
WikiContext (or, to be precise, a JCRWikiContext, which would be a
concrete class which would implement a WikiContext interface). When
the WikiContext is created, the Session is created too, and when the
WikiContext expires, the Session is logged out. We could also add a
WikiContext.save() method to flush all changes. This would provide
fairly logical lifecycle management.
The bad thing is that means that we need to carry WikiContext into
quite a few places after that. Unless we turn WikiContext into the
main repository interface as well, providing things like a Search
interface as well. That means that it would inherit pretty much all
of the functionality of the WikiEngine, which might make it a bit too
unwieldy.
My current idea is to turn WikiPages into essentially representatives
of Nodes. Calling WikiPage.getContent() will return the content of
the page and WikiPage.setContent() will set it. This provides a
really neat way of managing the data, since e.g. WikiPage.get/
setAttribute() could be automatically persisted. The bad thing,
obviously, would be that since Nodes contain a reference to the
Session where they came from, you *cannot* cache a WikiPage across
new invocations (e.g. threads).
Retaining the old WikiEngine API is problematic because the passed
arguments only contain Strings. Since there is no session management
in that API, we would need to do Repository.login() every time e.g.
pageExists() is called, and *that* would become a bit too rough. So
my preference would be, frankly, to dump existing WikiEngine API and
make something nicer. We can have a lookalike API, but that's going
to be slow.
An obvious option would be to use a ThreadLocal for a Session, but
that would pretty much make it a global, and the other problem is
that then lifecycle management becomes a bit hazy - if there are
unsaved changes, the session would grow uncontrollably. So there
would need to be a separate flushing action at some point... But
that would allow us to keep the existing API.
Any thoughts? Gotchas? Obvious ideas I've ignored? It would be a
good idea if others read up on the JCR documentation as well - the
spec is fairly well written, but it's quite long.
/Janne