Hi,

It's been three times that I reverted my changes introducing ObjectModel interface and using it in Template generator. I must admit that I got stuck in unproductive state because I'm constantly unhappy with the design. Let me share my troubles in a hope that someone is much clever than me and will give some advise.

As discussed earlier[1][2], Object Model will be simple Map that can contain more than item for each key and preserves order in which items were added. I found (after several attempts to invent one myslef) MultiMap[3] interesting and close to what I want to achieve. It resulted in very simple ObjectModelImpl[4] that is only a prototype and will be replaced by Spring's, scoped bean that will utilize CallStack as Daniel proposed earlier.

I wanted to use ObjectModel interface in cocoon-template-impl and cocoon-expression-langauge-impl modules. After reading all the code I found that current implementation is little unsatisfying. I'll explain my concerns.

Let's examine how ExpressionContext[5] class looks like and what's purpose. Basically, it's a holder for data passed to expression evaluators. It can contain several named variables, context bean and namespace table. This class is really vague for me because:
  * it's not clear what's the difference between context bean and named 
variables (you can put everything everywhere)
  * namespace table is very mysterious thing when it comes to general data 
holder and seems to be very specific

To find out what's the purpose for variabales/context bean you must take a look at all implementations of Expression interface and find that it's rather JXPath-specific feature. If ExpressionContext holds something as variable ("variable1") you can access that data by using "$variable1/[...]" expression, if the same data is held as context bean it's available by "./[...]". Other expression languages implementations ignore variables completely so if you happened to rely on this feature you are in big trouble. How intuitive...

Namespace table is also very specific to JXPath (because only JXPath has concept of namespace implemented) and I'll not discuss in detail how it works. It only makes me wonder why it is put in rather general ExpressionContext class. Situation is even more worst because Template generator uses this namespace table for its very internal reasons (emitting right SAX events, cleaning up namespace declarations and so on).

I'll show you, as an example, execute() method of 
o.a.c.template.script.event.Event class:

    public Event execute(final XMLConsumer consumer,
                         ExpressionContext expressionContext,
                         ExecutionContext executionContext,
                         MacroContext macroContext, Event startEvent, Event 
endEvent)
        throws SAXException {
        return getNext();
    }

You can see that method's signature is already quite fat - there are three different contexts. What I'm going to propose is not much better because I want to introduce one more argument (NamespaceTable namespaces) and change existing ExpressionContext expressionContext to ObjectModel objectModel. I just want to move namespace handling out of general interface for data holders.

Before calling Expression#evaluate() I would like to add namespace table to Object Model with "namespace" (or similiar) key so it's available for JXPath implementation.

Ok, I'm not sure if such approach of slimming interface to absolute minimum and putting things in a Map is right but nothing better comes to my mind.


Could you give your advice? I'm really afraid that I'd made a commit only to 
realize that my changes are dumb and there is better design.


[1] http://article.gmane.org/gmane.text.xml.cocoon.devel/73700
[2] http://article.gmane.org/gmane.text.xml.cocoon.devel/73760
[3] 
http://jakarta.apache.org/commons/collections/apidocs/org/apache/commons/collections/MultiMap.html
[4] http://article.gmane.org/gmane.text.xml.cocoon.cvs/24747
[5] http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-expression-language/cocoon-expression-language-api/src/main/java/org/apache/cocoon/components/expression/ExpressionContext.java?view=markup

--
Grzegorz Kossakowski
http://reflectingonthevicissitudes.wordpress.com/

Reply via email to