cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leszek Gawron <lgaw...@mobilebox.pl>
Subject Re: [Design] JXTG 2.0
Date Fri, 26 Nov 2004 21:23:56 GMT
Jonas Ekstedt wrote:
> On Wed, 2004-11-24 at 20:50 +0100, Daniel Fagerstrom wrote:
> Hello. I have made an attempt to implement what you describe above
> (filed it in bugzilla http://issues.apache.org/bugzilla/show_bug.cgi?
> id=25288). The block contains a JXTemplateGenerator that compiles a
> template to a script, caches it and then invokes it.
Gosh you're fast. This week I hadn't even time to keep up with the 
mailing list.

> Script compilation
> ------------------
> 
> A template is compiled into a Script by a ScriptCompiler. The script
> compiler consumes SAX events and stores tokens representing those events
> in the Script. Here's the Token interface:
> 
> public interface Token {
>     public int getStart();
>     public void setStart(int start);
> 
>     public int getEnd();
>     public void setEnd(int end);
> }
> 
> As an example of what a Script might look like, consider the following
> xml snippet:
> 
> <root>
>   <item attr="1">
>     Some text
>   </item>
>   <item attr="2">
> </root>
> 
> If we disregard whitespace this will be translated to the following
> Script.
> 
> PlainElementToken start=0, end=8, bodyStart=1, localname="root"
> PlainElementToken start=1, end=5, bodyStart=4, localname="item"
> AttributeToken    start=2, end=4,              localname="attr"
> CharactersToken   start=3, end=4,              characters="1"
> CharactersToken   start=4, end=5,              characters="Some text"
> PlainElementToken start=5, end=8, bodyStart=7, localname="item"
> AttributeToken    start=6, end=8,              localname="attr"
> CharactersToken   start=7, end=8,              characters="2"
> 
> A difference with SaxBuffer is that SaxBuffer stores separate objects
> for open and close event (eg startElement/endElement). The reason for
> doing it this way is that it is now much easier to play parts of the
> buffer. Eg if we want to play the body of the root element we know that
> we should invoke the tokens between bodyStart and end (ie 1 to 7
> inclusive)
Can you differentiate <item></item> and <item/> in your implementation?

> Another difference that can be seen above is that attributes are stored
> as tokens in the script just like any other type of SAX event. The
> beauty of this approach is that when expression tokens are introduced
> there will be no difference between how expressions in body content are
> stored to expressions in attributes. For example:
> 
> <root attr="AA ${1+1} BB">
>   CC ${2+2} DD
> </root>
tricky ! :)

> Tags
> ----
> 
> In addition to the tokens mentioned in the samples above a user can make
> custom tags by implementing the Tag interface.
> 
> public interface Tag extends ElementToken {
>     public void invoke(JXTGContext context) throws Exception;
> }
> 
> public interface ElementToken extends Token {
>     public int getBodyStart();
>     public void setBodyStart(int bodyStart);
> }
> 
> A Tag is a Token and is placed inside the Script just like other tokens
> (so they need to be thread safe). The ScriptCompiler uses a
> TagRepository (configured in the generator entry in sitemap.xmap) to
> differentiate between registered tags (stored as TagS in the Script) and
> normal elements (stored as PlainElementTokenS).
> 
> 
> Script invokation
> -----------------
> 
> When the script has been compiled and cached it is then invoked by a
> ScriptInvoker. The ScriptInvoker walks through the script and fires of
> the appropriate SAX events. When it stumbles upon a Tag it executes
> Tag.invoke(context). The tag has the choice of firing off SAX of its own
> or invoking its body through AbstractTag.invokeBody(context).
> 
> 
> Cache handling
> --------------
> 
> Unfortunately I don't know all that much about how cacheing works so the
> implementation can best be described as naive in that respect.
The script should be able to store a map of directives/processing 
instructions.

<root>
   <core:processing-instruction name="cache-key" 
value="${bizData.calculateCacheKey()}"/>
   <core:processing-instruction name="cache-validity" 
value="${bizData.calculateCacheValidity()}"/>

Via a processing instruction the user defines the cache-key and 
cache-validity. It is user's responsibility to implement appropriate 
logic. Cocoon queries the generator for caching info and the generator 
returns what the user has set up. That's all.

I will take care of that as I have implemented the first (faulty :)) 
caching in JXTG.

> * I would really appreciate comments on exception handling as I don't
> really know what is considered best practices.
Which exceptions are you talking about?

One more thing: ScriptCompiler should store locator info for every tag 
so if the compilation error or runtime error gets thrown user can be 
informed of the exact place where problem occured.

> * What does JX stand for?

Good question.
This is I think the first post about JXTG:
http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=105112321916125&w=2

Should we create a separate block for JXTG 2.0? I think scratchpad would 
be enough for now. WDYT?

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
Project Manager                                    MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Mime
View raw message