cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ricardo Rocha <>
Subject Re: Thoughts on a data-driven web site
Date Fri, 23 Jun 2000 04:44:12 GMT
Oops! My previous posting is dead wrong, sorry.

More relevant comments on this subject below.

> A related point: how can a taglib maintain state across all pages
> which use it? For instance, could you write a counter tag that would
> track how many times it was hit across all pages that reference it?
> I suppose you could store a field in a database somewhere, but a
> static variable in a class would be much cleaner. (Of course, I
> don't know why you'd want this particular function... =)

The correct way to achieve the desired effect is:

<xsl:stylesheet xmlns:...>
    <xsl:apply-templates select="@*"/>
. . .
<xsl:template match="hit-count">
. . . 

where "" would contain:

public class Counter {
  private static int counter = 0;
  private static synchronized int hitCount() {
    return ++counter;

Now the relevant stuff:

By properly defining code-generation templates, logicsheets
can be used to generate Producer classes equivalent to _any_
hand-written class. The above example illustrates this;
there's no intrinsic limitation to logicsheets that prevent
you from achieving practically any effect you'd be able to
achieve if writing producers by hand...

> I noticed the following in util.xsl:
>     <xsp:logic> {
>       String __name = ...
>       ...
>     } </xsp:logic>
> and in sql.xsl:
>         <xsp:logic>
>                 {
>                 Integer max_rows = ...
>                 String max_rows_string = ...
>                 ...
>         }
>         </xsp:logic>
> I assumed (perhaps incorrectly) that the "{}" were there to prevent
> variable conflicts with other taglibs. Upon further investigation, I
> did confirm that code chunks from XSP-based taglibs (in Cocoon1) are
> merged to form a single XSP producer/generator, which means you're
> relying on taglib writers to "play nicely".

I agree with you Jonathan, inlining "raw" code like this is indeed
bad practice...

It's always possible to generate bad code if some basic principles are
not observed. I'd say this is true of all languages and code generators.

For logicsheet authoring, the most important such basic principle is
probably the following: dynamic tags should be substituted _only_ by
method calls. One should _never_ inline "raw" code: its dangerous,
error-prone and reveals lack of in-advance design.

This is so because dynamic tag embodies either 1) a well-defined
_operation_ on a well-defined object or 2) a well-defined object or
system _property_.

This discipline usually results in dynamic tag names being verbs:
<sql:create-connection>, <request:get-parameter>. Nouns may be adequate
for instance properties or global, single-valued properties like
<system-time/> or the above <hit-count/> example. Of course, static
tag names are almost always nouns.

Logicsheets are just code-generation templates that group related
tag substitution rules. An obvious criteria under which a set of dynamic
tags are considered "related" is when they all represent operations or
properties defined on the same object type.

This leads naturally to associating logicsheets with namespaces: each
logicsheet deals with a single object type (or a small, cohessive
of related object types) so that it makes sense to qualify dynamic tags
with a namespace named after the underlying object type(s).

>> Logicsheets are translated into XSLT stylesheets, not to Java
>> code.
> Ah... Here's where we diverge.I view taglibs as compiled classes
> capable of maintaining (minimal) state and connecting to external
> application servers to do the heavy lifting of content retreival
> (reducing work for cocoon's JDK, and introducing the possibility
> to use *clusters* of machines to produce a CPU-intensive page).

An important clarification: logicsheets are used for 2 fundamentally
different purposes:

- Program generation
- Dynamic tag substitution

Program generation logicsheets (which I've informally called
"last-step logicsheets" -a misnomer?-) contain the skeleton of a
program compilation unit (for example, a Java class).

Examples: org.apache.cocoon.processor.xsp.xsp-java.xsl in Cocoon1
in Cocoon2.

Each target program type requires a separate program generation
logicsheet: one for Generators, one for Filters, and so on.

A dynamic tag substitution logicsheet, on the other hand, simply
replaces occurrences of a dynamic tag by free-form code to be
later inlined in the program skeleton.

The same dynamic tag substitution logicsheet could be conceivably
used for different target program types. For instance: in a servlet
environment, <session:get-attribute> can be legitimatelly used in
both Generator and Filter XSP pages.

When you say you view logicsheets as compiled classes you're
probably refering to program-generation logicsheets.

In both cases (program generation, dynamic tag substitution),
logicsheets are just code-generation templates; they're not compilable

> After rereading your comments and reading other new posts to the
> thread (most notably Stefano's), I think I have a better 
> understanding of how logicsheets/taglibs are currently implemented
> (btw, what is the distinction between those two terms, if any?).

Stefano originally coined the term "logicsheet" in what seems an
to "stylesheets" in the context of our Holly Grail: content/style/logic
separation. Today, I find this term more appropriate than "taglib"
I used in the original XSP documentation, though).

There are 2 reasons why I changed my mind on this:

1) The term "logicsheet" applies to both dynamic tag substitution _and_
   program generation templates. A logicsheet can be a collection of tag
   definitions, yes, but it can also be a complete program template.

2) The term "taglib" is also used by JSP for a similar (but not
   concept and I felt it was convenient to differentiate the two. XSP
   generation is based on XML templates, rather than on programmatic,
   tag interpretation or a markup-language-specific code generation



View raw message