Introducing Cocoon 2.0
by Stefano Mazzocchi
|
Pages: 1, 2
The Cocoon Sitemap
We call the following XML fragment the "sitemap". It's the configuration document which tells Cocoon how to create the resources identified by various URIs. The sitemap is akin to the blueprints of a site, telling Cocoon how to assemble components into pipelines that produce both static and dynamic resources.
<map:pipeline>
<map:match pattern="hello.html">
<map:generate src="docs/samples/hello-page.xml"/>
<map:transform src="stylesheets/page/simple-page2html.xsl"/>
<map:serialize type="html"/>
</map:match>
<map:match pattern="hello.wml">
<map:generate src="docs/samples/hello-page.xml"/>
<map:transform src="stylesheets/page/simple-page2wml.xsl"/>
<map:serialize type="wap"/>
</map:match>
<map:match pattern="hello.vml">
<map:generate src="docs/samples/hello-page.xml"/>
<map:transform src="stylesheets/page/simple-page2vml.xsl"/>
<map:serialize type="xml"/>
</map:match>
<map:match pattern="hello.svg">
<map:generate src="docs/samples/hello-page.xml"/>
<map:transform src="stylesheets/page/simple-page2svg.xsl"/>
<map:serialize type="svg2jpeg"/>
</map:match>
<map:match pattern="hello.wrl">
<map:generate src="docs/samples/hello-page.xml"/>
<map:transform src="stylesheets/page/simple-page2vrml.xsl"/>
<map:serialize type="vrml"/>
</map:match>
<map:match pattern="hello.pdf">
<map:generate src="docs/samples/hello-page.xml"/>
<map:transform src="stylesheets/page/simple-page2fo.xsl"/>
<map:serialize type="fo2pdf"/>
</map:match>
</map:pipeline>
This fragment is the "hello world" equivalent for Cocoon, allowing Cocoon to say "hello world" to your browser using HTML, to your WAP phone using WML, to your voice client using VoiceXML, or by rendering an SVG into a JPG image, presenting a VRML world, or even producing the PDF for your printing needs. And all using the following XML document as input:
<?xml version="1.0"?>
<page>
<title>Hello</title>
<content>
<para>This is my first Cocoon2 page!</para>
</content>
</page>
If only I'd had this back in 1998 for java.apache.org.
Now that you understand components it's easier to understand the following part of the sitemap:
1) <map:match pattern="hello.html">
2) <map:generate src="hello-page.xml"/>
3) <map:transform src="hello-stylesheet.xsl"/>
4) <map:serialize type="html"/>
</map:match>
The first line "matches" the incoming request for the given URI "hello.html". The second generates using the default generator, FileGenerator in this case, and throws into the SAX pipeline the events that the parser emits from parsing the file docs/samples/hello-page.xml. Line three calls the default transformer, XSLTTransformer, with the given stylesheet. Finally, line 4 calls the HTMLSerializer.
In short, the server resource indentified by "hello.html" is produced by parsing the "hello-page.xml", apply an XSLT stylesheet, "hello-stylesheet.xsl", and serializing the results as HTML.
But what, I can imagine you saying, about verbosity? I don't want to do this for every URI I have to serve. Don't worry. Another example should suffice.
<map:match pattern="sites/*.apache.org">
<map:generate src="/sites/{1}_apache_org.xml"/>
<map:transform src="/sites/{1}_apache_org-html.xsl"/>
<map:serialize/>
</map:match>
The "*" symbol is matched against a token. Then, this matched token replaces {1}. So when requesting "sites/xml.apache.org" we'll get the equivalent of
<map:generate src="/sites/xml_apache_org.xml"/> <map:transform src="/sites/xml_apache_org-html.xsl"/> <map:serialize/>
Or when requesting "sites/jakarta.apache.org" we'll get the equivalent of
<map:generate src="/sites/jakarta_apache_org.xml"/> <map:transform src="/sites/jakarta_apache_org-html.xsl"/> <map:serialize/>
Perhaps you were wondering about regular expressions? The entire sitemap is extensible since the implementation of the <map:match> behavior is pluggable, just like any other sitemap component. So this sitemap fragment
<map:match type="regexp" pattern="^/xerces-(j|c|p)/(.*)$">
<map:generate src="/xerces/{1}/{2}.xml"/>
<map:transform src="styles/document2html.xsl"/>
<map:serialize/>
</map:match>
indicates that you should use the "regexp" matcher instead of the default one. If you request /xerces-j/index the file generator parses the file xerces/j/index.xml; if you request /xerces-p/installing you transform xerces/p/installing and so on.
But while matchers match at the beginning of the pipeline, there is another component, "selector", that is capable of selecting different components inside the pipeline. For example, this sitemap fragment
<map:match pattern="images/logo">
<map:generate src="./images/logo.svg"/>
<map:select type="browser">
<map:when test="accepts('image/png')">
<map:serialize type="svg2png"/>
</map:when>
<map:otherwise>
<map:serialize type="svg2jpg"/>
</map:otherwise>
</map:select>
</map:match>
selects the serializer depending on browser capabilities.
Other Features
In addition to its pipeline architecture and extensible sitemap, Cocoon has some other interesting features and design properties. It is very extensible. Almost everything in Cocoon is written as a component. You can write your own components to work with existing ones and to reuse in different applications.
Because the sitemap contains special semantics that allow you to aggregate content from different sources into the same document and to associate different namespaces with these different sources, Cocoon is an ideal tool for content aggregation.
Cocoon allows you to add your own protocol handlers to connect to
sources that can be retrieved via URI. This wraps around the
java.net classes to avoid the limitation of a single
URLHandlerFactory.
Cocoon is able to call itself via the cocoon:// protocol. For example, this sitemap fragment is the one used to generate the Cocoon documentation
<map:match pattern="*.html">
<map:aggregate element="site">
<map:part src="cocoon:/book-{1}.xml"/>
<map:part src="cocoon:/body-{1}.xml"/>
</map:aggregate>
<map:transform src="stylesheets/site2xhtml.xsl">
<map:parameter name="use-request-parameters" value="true"/>
<map:parameter name="header" value="graphics/{1}-header.jpg"/>
</map:transform>
<map:serialize/>
</map:match>
It uses both content aggregation and recursive calls to aggregate a sidebar with the document body.
Another very important sitemap component is called "action", and it encapsulates headless logic which performs side-effects on the flow of information. Examples include the FormValidatorAction which validates the input of a form using a schema-like description, or the series of Database*Actions which deal with databases, or the series of Session*Actions which deal with client state persistance.
Cocoon also provides adaptive caching. Site resources, even those which are dynamically generated (since Cocoon components may be implemented to be cache-aware), can be cached inside Cocoon. This prevents wasting CPU cycles to regenerate resources which can be cached.
eXtensible Server Page (XSP) is a SAX-aware server page technology that extends the concept of JSP for XML content. XSPs are compiled into Cocoon Generators and generate SAX events directly, unlike JSPs which are compiled into servlets and require a subsequent parse stage. XSPs allow you to associate dynamic behavior with tags in a particular namespace and "logicsheets", which are XSLT stylesheets that transform tags into XSP logic and allow better separation beween code and content.
Conclusion
Cocoon is currently based on many other Apache projects -- Ant, Avalon, Xerces, Xalan, FOP, Batik, Velocity, Regexp -- but due to its high modularity, it has ful support for alternative implementations of underlying W3C technologies.
The Cocoon development community is one of the more active under the Apache Software Foundation: boasting more than 15 active developers, around 500 subscribers of the development mail list, and around 1100 on the user list. We consider Cocoon 2.0 stable in both implementation and API: this means that we consider it safe to be used for production environments. And it's already being used on many such projects.
You can find more information about Apache Cocoon at its home page, from which it may also be downloaded.
- Find a migration study
2003-06-05 13:47:46 Miguel Fernandez - Another successful story
2002-03-04 05:47:34 Beat De Martin - Another successful story
2002-08-04 02:32:52 Ivelin Ivanov - Cocoon 2 used for E-Banking Systems
2002-02-20 05:24:56 Sonego Massimo - Cocoon 2 used for E-Banking Systems
2002-08-04 02:33:10 Ivelin Ivanov - Cocoon 2 used for E-Banking Systems
2002-03-04 05:49:33 Beat De Martin - Using Cocoon to Publish Books
2002-02-15 07:20:16 Roy Tennant - Using Cocoon to Publish Books
2002-08-04 02:33:36 Ivelin Ivanov - Using Cocoon to Publish Books
2002-02-20 05:32:32 Sonego Massimo - Using Cocoon to Publish Books
2002-11-28 01:25:38 Henning Koester - About Cocoon
2002-02-15 04:25:26 ekrem aksoy