Jonas Ekstedt wrote:

On Tue, 2004-11-23 at 12:51 +0100, Daniel Fagerstrom wrote:
snip...


The main question now IMO is what tag framework we should base JXTG 2.0 on. The candidates that has been mentioned this far are: Jelly, the taglib, Carsten's taglib and Jonas taglib (are there more alternatives). I discussed Jelly with Carsten and the conclusion was that it doesn't fit that well in Cocoon. I don't know Carsten's plans for his taglib. Jonas need to some advertising of his taglib and explain how it relates to the alternatives.



Hello, I didn't have the time to do a proper presentation of the template transformer last week but I'll try to explain it a bit. First of all let me say that I have updated the download and the new version can be found at: http://home.student.uu.se/j/joek8725/template.zip

The idea of the transformer is to be a replacement for JXTG. All JX tags
can easily be implemented as Tag classes. It supports JSTL expressions
using commons-el but not XPath (XPath support could perhaps be provided
using JSTLs ability to define functions). Expressions are also
converted using the conversion block discussed before.

Similar to taglib it allows extending by tag classes. These tags are
configured in sitemap.xmap (as opposed to taglib which does it in
cocoon.xconf) which allows for reconfiguration without restarting
cocoon.

Variables are done a wee bit differently to taglib. The transformer has
a stack of maps that contains all variables. The
TemplateObjectModelHelper populates the bottom Map. Tags can then
introduce new variable contexts by pushing and popping maps on the
stack. The variables in lower maps are still "gettable" but can be
overloaded by whatever variables the tags introduce in the new context.
As an example here is the ForTag:

public class ForTag extends AbstractTag {

   String var;
   int begin;
   int end;
   int step;
   RecordingConsumer recorder;

   public void start() {
        var = getAttribute("var", null);
        begin = evalInt(getAttribute("begin"));
        end = evalInt(getAttribute("end"));
        step = evalInt(getAttribute("step", "1"));

        recorder = new RecordingConsumer();
        transformer.pushConsumer(recorder);
   }

   public void end() {
        SaxBuffer buffer = recorder.getSaxBuffer();

        variables.push();
        for (int i = begin; i <= end; i+= step) {
            if (var != null)
                variables.put(var, new Integer(i));
            play(buffer);
        }
        variables.pop();
   }

}

As you can see in the end() method the variable context is first pushed
(which adds a Map on the stack) and later popped when the buffer has
been played.

Another feature visible from the sample above is that it allows tags to
do whatever it wants with the body content. The transformer keeps a
stack of consumers that tags operate on by pushing and popping.
Currently I've implemented a RecordingConsumer and an IgnoringConsumer
(which simple ignores the body content).


To summarize the template transformer is basically a merge of the
features of taglib (tag classes) and jxtg (expression evaluation) with
the added benefit of object conversion.

Cheers Jonas


Thanks for your explanation. I have evaluated your code in more detail and have some comments:


First I think your code is much easier to follow than the taglib. Your design is much simpler whithout losing any power, AFAICS. And as one of the main requirements for the JXTG successor is suportable code, I think that it would be better to base JXTG 2.0 on your code than the taglib.

The variable stack and configuring the choice of taglibs in the sitemap seem better than the coresponding things for taglib.

The major point to make it suitable for replacing JXTG, is to package it as a generator instead and implement it with pre-compilation of the template as in JXTG. One of the advantages with JXTG is it's performance and without pre-compilation I would guess that it hard to match that performance. See http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=105029949912114&w=2.

Another important point from my POV is how to write tags. After having compared Jelly's taglib mechanism with the JSP inspired way I must say that I prefer Jelly's way. In Jelly you just have a "doTag(XMLOutput)" instead of the JSP taglib inspired "begin()" and "end()" methods. And if you want to use the content of your tag you just call "invokeBody(XMLOutput)", and the framework take care of all XML recording etc.

I'll give a more detailed explanation and some design ideas for the two above points in another post.

                                    ---o0o---

Now some less important and technical points about the code:

For attribute and character evaluation in the tag framework, IMHO it should be the taglib's responsibility to parse the text and find the expressions inside "${<expr>}". Then the taglib let the expression language (EL) component take care of the expression. In your implementation the EL component takes care about the whole text.

I think the TemplateTransformer should be completely responsible for handling the consumer stack. That makes the contracts and the concern areas for the Consumers more focused.

o.a.c.xml.ContentHandlerWrapper does the same thing as the AbstractIdentityTransformer, AFAICS.

/Daniel




Reply via email to