incubator-jspwiki-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Janne Jalkanen <>
Subject Re: JCR integration
Date Mon, 09 Feb 2009 15:36:47 GMT
public class WikiPage
   private Node m_node;

   public String getContentAsString()
      return m_node.getProperty("wiki:content").getString();

Getting a new Node reference for each access is simply too expensive,
and so would pre-emptively fetching all metadata into memory also be.

We can't subclass nor implement, due to the way JCR API is
designed.  Node is an interface, which you receive from the JCR
Session with Session.getItem();


On Mon, Feb 09, 2009 at 08:18:28AM -0500, Andrew Jaquith wrote:
> Janne, is WikiPage == Node? (subclass or implementation). Seems like  
> there's an implied tight coupling between the two...
> On Feb 9, 2009, at 4:12, Janne Jalkanen <> wrote:
>>> Re-reading your e-mail, I *think* I understand the comment you made
>>> about not wanting to keep a ThreadLocal field in ContentManager that
>>> keeps a reference to the current Session. But why keep the Session?
>>> Couldn't a getPage() operation open a new Session, get the page, then
>>> close the Session and return the page? Then there'd be no reason to
>>> stash the Session anywhere.
>> The problem is that the Node keeps a reference to a Session, and the
>> WikiPage holds a reference to the Node (if it does not, it is
>> impossible to manipulate the content of the repository through
>> WikiPage methods, such as get/setAttribute()).
>> So, if getPage() closes the session, all attempts to use the WikiPage
>> for anything will fail spectacularly.
>>> Or alternatively, maybe you (we) guarantee that any time we get a
>>> Session we have to complete work on the session, then call refresh(),
>>> before returning. That would mean you could keep ThreadLocals in
>>> ContentManager. But maybe I'm missing your point about the exception
>>> cases. Could you explain further?
>> Guaranteeing calling Session.refresh() means the following pattern:
>> m_engine = ... // Get engine somehow
>> try
>> {
>>   WikiPage p = m_engine.getPage(...)
>>   // Do something
>> }
>> finally
>> {
>>   // This must be done here, or exceptions will go upwards and
>>   // one might end up with unpurged data in the Session.
>>   m_engine.getContentManager().refresh(); // Calls Session.refresh()
>> }
>> So in the end this pattern is *exactly* the same as the pattern above,
>> with the exception that this does not explicitly state the start of
>> the Session, and leaves the lifecycle muddy.  We can't call
>> refresh in our WikiFilter because that does not work for embedders.
>> Note that for the most part, the pattern I suggested will only affect
>> WikiFilter and WikiContextFactory, since those are the ones who get
>> WikiEngine. Most of our APIs get a WikiContext, and for plugin writers
>> *nothing* would change (because they did not acquire a WikiEngine,
>> they just used WikiContext.getEngine()).
>> /Janne

View raw message