cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Grzegorz Kossakowski <>
Subject Object Model-related changes in Template generator
Date Thu, 12 Jul 2007 20:34:24 GMT

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.


Grzegorz Kossakowski

View raw message