Stefano Mazzocchi wrote:


Cocoon Blocks
-------------

author: Stefano Mazzocchi
status: working draft
version: 1.1

(see the end of the document for changes from the previous version)


DISCLAIMER: This document must be considered as a working draft and may be updated at any time.

OK. Let me throw in some material for version 1.2 ;-)

Throughout this paper, examples show blocks providing "resources" to their users (such as stylesheets of images), but the word "service" is used several times to identify what is provided by a block, and IMO services are more important to define a block contract than resources.

Most of this was already stated after version 1.0, back in July. See http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=102538716114027&w=2

Here is the most relevant part :

<old-post-quote>

please note the

block:skin:/stylesheets/site2xhtml.xslt

IMHO, this example goes strongly against the benefits that blocks want to bring. The functionnality brought by the 'skin' block is... skinning. It's not an XSL stylesheet at a particular location. What if someone has written the killer skin for his site, but this skin requires a multi-stage pipeline that cannot be represented by a single stylesheet ?

The contract of a block should be services identified by their URI, and not files at well-known locations (even if these 'files' are in fact produced by a pipeline).

So what about something like :
...
</map:aggregate>
<map:call resource="block:skin:/site2xhtml"/>
</map:match>

This call "jumps" to a service provided by the block and its URI is part of the block's contract. We don't care (because we don't have to) if the service is implemented by an XSL or by the next-generation transformer.

What the "jump" does is feed a pipeline in the block with the result of the current pipeline. The whole pipeline is terminated in the called block.

But just as a pipeline can serialize or not depending on if it's an internal request or not (see SitemapSource), the same service could be used as a transformation. We could then write something like :
...
</map:aggregate>
<map:transform type="pipeline" src="block:skin:/site2xhtml"/>
<map:transform type="urlencoder"/>
<map:serialize/>
</map:match>

By considering blocks as pipeline services, we really achieve true polymorphism for blocks, because we totally abstract the way their contracts are implemented.

[note that all the above isn't in fact block-specific and can be made today inside a single sitemap]

</old-post-quote>

After this we had a long conversation about the semantics to be used to identify which part of a pipeline we want the caller to use, which unfortunately fell flat because I wasn't able to make you understand my thoughts. I'd like someday to have the luck Carsten had recently to meet you for real. Too bad the GetTogether is the same week as the ApacheCon :-(

Anyway, let's forget for now these syntactic problems. The important thing above is that a block should provide services by means of pipeline URIs and not resources.

If we were to compare a block with a Java class (not so silly, since blocks now have inheritance), a pipeline service would be a method and a resource would be an attribute. Is it good programming practice to define a class contract by its attributes ? No, and the same applies to blocks, if we want their contracts to be solid enough to accept various implementations.

I have kept below only parts that show the use of services :

<snip/>

Improvement #1: component-oriented deployment
---------------------------------------------

Let me give you a possible use-case scenario.

Let us suppose that we implement WAR-like package deployment on top of Cocoon and that your application requires both PDF serialization and SVG->PNG rasterization.

Then, you implement another cocoon web application and you still require PDF generation.

Unfortunatley, since WAR-like installation isolates the packages and their classloaders, you have to install the PDF serialization libraries twice.

Thus the idea of blocks as units of deployable service. Here is a picture:

So the main idea of blocks is about services. Great !

<snip/>

Improvement #2: polymorphic behavior
------------------------------------

<snip/>

Here, the webapp1 requires "fo-pdf" serialization services but it does not care (nor should!) which implementation of this service is actually located into the system.

Sure : the "fo-pdf" _service_ can be implemented by a single serializer, or by some transformations preceding another serializer. This clearly cannot be a resource.

<snip/>

Improvement #3: block inheritance
---------------------------------

<snip/>

The best solution is to allow my block to explicitly "extend" that block and inherits the resources that it doesn't contain.

Side note : we must not forget to allow a block to call services/resources of its parent block (like a "super" call in Java).

<snip/>

 +---------------------------+
 | Part 2: technical details |
 +---------------------------+

<snip/>

Resource dereferencing
----------------------

<snip/>

For example, the myblock.cob/sitemap.xmap file could contain a global
matcher which works like this:

<map:match pattern="**/*.html">
<map:generate src="{1}.xml"/>
<map:transform src="block:skin:/stylesheets/document2html.xslt"/>
<map:serialize/>
</map:match>

please note the

block:skin:/stylesheets/document2html.xslt

Here is what triggered this idea of "pipeline services" ! This example only shows publication of _resources_ (i.e. static files) by the block !

<snip/>

TODO
----

1) blocks should allow to depend on 'ranges' of behavior versions. Let's try to come up with a way to describe those ranges effectively.

IIRC, there's something in Avalon to handle this.

<snip/>

Ok. I hope this time this notion of "pipeline services" will go further and that we will solve the misunderstanding we had 4 months ago...

Sylvain

--
Sylvain Wallez Anyware Technologies
http://www.apache.org/~sylvain http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to