cocoon-docs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From da...@cocoon.zones.apache.org
Subject [DAISY] Created: Sitemap evaluation
Date Fri, 03 Mar 2006 17:03:30 GMT
A new document has been created.

http://cocoon.zones.apache.org/daisy/documentation/853.html

Document ID: 853
Branch: main
Language: default
Name: Sitemap evaluation
Document Type: Cocoon Document
Created: 3/3/06 3:35:11 PM
Creator (owner): Bruno Dumon
State: publish

Parts
=====

Content
-------
Mime type: text/xml
Size: 10300 bytes
Content:
<html>
<body>

<h1>Intro</h1>

<p>While you can probably understand the basics of a simple sitemap just by
looking at it, for some constructs it is essential to have some understanding of
how the sitemap is evaluated by Cocoon. Here we will look a bit deeper into
that.</p>

<h1>What you already knew</h1>

<p>When a request enters Cocoon, Cocoon uses a so-called sitemap to determine
what should be done. The sitemap is an XML file. There is one root sitemap
called sitemap.xmap which is located in the root of the Cocoon webapp. The root
sitemap can mount other sitemaps, allowing modularisation of Cocoon-based
applications.</p>

<h1>Sitemap evaluation result</h1>

<p>To decide how a request should be handled, Cocoon starts by looking in the
map:pipelines element of the sitemap. Usually this starts from the root sitemap
(an exception are 'internal requests' which can be relative to the 'current
sitemap').</p>

<p>Skipping the details of the sitemap evaluation for a moment, the final result
of the evaluation of the sitemap can be one of the following:</p>

<ul>
<li>an XML-based pipeline is executed (map:generator or map:aggregate,
map:transform's, map:serialize)</li>
<li>a reader is executed (map:reader) (a reader's purpose is to serve binary
content without using an XML pipeline)</li>
<li>a flow controller is called to:</li>
<ul>
<li>start a new flow (<tt>&lt;map:call function="..."/&gt;</tt>)</li>
<li>continue an existing flow (<tt>&lt;map:call continuation="..."/&gt;</tt>)
</li>
</ul>

<li>a redirect is performed (map:redirect-to), which can be:</li>
<ul>
<li>an HTTP redirect (a redirect response is sent to the browser to point the
browser to a new URL)</li>
<li>an internal Cocoon redirect (does not involve HTTP)</li>
</ul>

<li>none of these, in which Cocoon will give the error message "No pipeline
matched request".</li>
</ul>

<h1>The simplest pipeline</h1>

<p>The simplest pipeline specification is the one that does nothing:</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>Suppose you have a sitemap containing this. Now when a request enters Cocoon,
Cocoon evaluates the content of the map:pipelines element to decide what to do.
However, here we have specified nothing, thus Cocoon will respond with the error
"No pipeline matched request".</p>

<h1>Matchers and readers</h1>

<p>To determine how a request should be handled, one of the more important tools
available in the sitemap is the matcher. A matcher typically tests on some
aspect of the request, most commonly the requested URL path.</p>

<p>For example:</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
    &lt;map:match pattern="mydoc.pdf"&gt;
      &lt;map:read src="blabla/mydoc.pdf"/&gt;
    &lt;/map:match&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>Lets see what happens now if a user request the mydoc.pdf file by entering an
URL like 'http://somehost/mydoc.pdf' in the location bar of the browser.
Remember that a reader was one of the 'final evaluation results' mentioned
above. When Cocoon encounters the reader, it knows all it has to know to finish
of this request (which is asking the reader to do its thing) so it does not look
anymore at the rest of the sitemap.</p>

<p>Suppose the sitemap would have looked like this:</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
    &lt;map:match pattern="mydoc.pdf"&gt;
      &lt;map:read src="blabla/mydoc.pdf"/&gt;
      &lt;map:read src="anotherfile.pdf"/&gt;
    &lt;/map:match&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>Notice the second map:read element. Since Cocoon will stop evaluating the
sitemap once it encounters the first map:read, it will do nothing with, nor
complain about, the presence of the second map:read element.</p>

<h1>XML pipelines</h1>

<p>Cocoon is all about generating pages using XML-processing-pipelines (to be
technically correct, it are SAX-processing-pipelines). In the examples till now,
we have each time seen the map:pipeline(s) element, and they didn't really
define an XML-pipeline. Instead,<br/>
the map:pipelines element can describe how an XML-pipeline can be composed, it
is not the pipeline itself. When the word pipeline is used in Cocoon context, it
usually refers to the XML-pipeline, not to the map:pipelines sitemap element.
</p>

<p>Lets look at an example of the specification of an XML-pipeline in the
sitemap:</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
    &lt;map:match pattern="page.html"&gt;
      &lt;map:generate src="page.xml"/&gt;
      &lt;map:transform src="page2html.xsl"/&gt;
      &lt;map:serialize/&gt;
    &lt;/map:match&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>This could be interpreted as follows: when a request is done for the
'page.html', execute the described generator-transform-serialize pipeline.</p>

<p>In reality, this is how Cocoon looks at it:</p>

<ul>
<li>At the start of the sitemap evaluation, Cocoon creates an empty pipeline
object</li>
<li>The first matcher matches, so Cocoon will look at its child elements</li>
<li>A map:generate element is encountered: put it aside in the pipeline object
</li>
<li>Then a map:transform element is encountered: put it aside in the pipeline
object</li>
<li>Then a map:serialize element is encountered: put it aside in the pipeline
object</li>
<li>Once a serializer is encountered, Cocoon knows enough to finish of this
request (it can execute the XML-pipeline), so it doesn't look further to the
rest of the pipeline.</li>
</ul>

<p>For the simple example above, this reasoning might seem overkill, but it is
essential to more complex sitemaps. One important thing is that when an element
such as a generator or transformer is encountered, these aren't executed
immediately. First a complete pipeline must be found, up to the serializer,
before Cocoon can execute it.</p>

<p>Here is another pipeline, which will do exactly the same as the example
above:</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
    &lt;map:match pattern="page.html"&gt;
      &lt;map:generate src="page.xml"/&gt;
      &lt;map:transform src="page2html.xsl"/&gt;
    &lt;/map:match&gt;

    &lt;map:match pattern="page.html"&gt;
      &lt;map:serialize/&gt;
    &lt;/map:match&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>Of course, it serves no purpose (here) to write the pipeline like this.</p>

<p>Another example of a pipeline which does exactly the same when page.html is
request, but not when page.pdf is requested:</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
    &lt;map:match pattern="page.html"&gt;
      &lt;map:generate src="page.xml"/&gt;
      &lt;map:transform src="page2html.xsl"/&gt;
    &lt;/map:match&gt;

    &lt;map:match pattern="page.pdf"&gt;
      &lt;map:read src="page.pdf"/&gt;
    &lt;/map:match&gt;

    &lt;map:match pattern="page.html"&gt;
      &lt;map:serialize/&gt;
    &lt;/map:match&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>When page.html is requested, first the first matcher will match, and the
generator and transformer will be put aside in the pipeline object. The second
matcher does not match so its content is ignored. The third matcher matches
again, a serialize element is encountered thus the collected pipeline will be
executed, and the remainder of the sitemap is ignored (if any).</p>

<p>Another example:</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
    &lt;map:match pattern="page.html"&gt;
      &lt;map:generate src="page.xml"/&gt;
      &lt;map:transform src="page2html.xsl"/&gt;
      &lt;map:read src="page.xml"/&gt;
      &lt;map:serialize/&gt;
    &lt;/map:match&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>What will Cocoon do in this case? Well lets follow the usual reasoning:</p>

<ul>
<li>start evaluation at top of the map:pipelines element</li>
<li>a matcher is encountered which matches</li>
<li>map:generate is encountered: put it aside in the pipeline object</li>
<li>map:transform is encountered: put it aside in the pipeline object</li>
<li>map:read is encountered. When encountering a reader, Cocoon knows enough to
finish of this request (namely by executing this reader), so it doesn't look any
further at the rest of the sitemap. The generator and transformer put aside in
the pipeline object are ignored.</li>
</ul>

<p>It is an error to have more then one generator in a pipeline, or to have a
pipeline with only a serializer and no generator. Thus when Cocoon encounters a
second generator when a generator has already been set, it will give the error
"Generator already set.". When a map:serialize is encountered before a
generator, it will give the error "Must set a generator before setting
serializer".</p>

<p class="note">Everywhere we talk about map:generate or generators, you can
substitute this by map:aggregate, which is just a special kind of generator.</p>

<h1>Actions</h1>

<p>A sitemap action, map:act, is simply some Java code that can be called. The
action implementation can return either null or a map. When it returns null, the
child elements of the map:act will not be considered, thus a map:act can also
serve as an 'if'.</p>

<p>To go back to our topic at hand, sitemap evaluation, it is important to note
that when a map:act is encountered, it is executed immediately. This makes that
the following to pipeline definitions are equivalent:</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
    &lt;map:match pattern="page.html"&gt;
      &lt;map:act type="something"/&gt;
      &lt;map:generate src="page.xml"/&gt;
      &lt;map:transform src="page2html.xsl"/&gt;
      &lt;map:serialize/&gt;
    &lt;/map:match&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>and</p>

<pre>&lt;map:pipelines&gt;
  &lt;map:pipeline&gt;
    &lt;map:match pattern="page.html"&gt;
      &lt;map:generate src="page.xml"/&gt;
      &lt;map:act type="something"/&gt;
      &lt;map:transform src="page2html.xsl"/&gt;
      &lt;map:serialize/&gt;
    &lt;/map:match&gt;
  &lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>

<p>Remember that when Cocoon encounters map:generate during the evaluation of
the sitemap, it does not execute the generator immediately, but puts it aside in
a pipeline object.</p>

</body>
</html>

Collections
===========
The document belongs to the following collections: documentation

Mime
View raw message