SitemapModelComponent Contracts
The SitemapModelComponent
The SitemapModelComponent identifies the contract between the Sitemap and
your pipeline components that create or transform information. The types of
components that fit within this umbrella are your Generators, Transformers, and
your Readers. It is very important to note that all components implementing this
interface must be pooled or created on demand. This is due to the separation
between the setup and the execution. If you don't ensure every instance of the
component is unique within a pipeline, or across pipelines, then the setup
process will start killing all the other setups and you will end up with serious
race conditions. It's not that they need synchronized keywords applied to the
methods, its that the methods have to be called in a certain order. This is by
design. If you really think about it, due to the SAX infrastructure we would
still need to keep them synchronized because the order of SAX events affects the
validity of your XML document.
The Sitemap will call the setup() method to prepare the component
for use. This is where you start the process of getting your information ready
to generate your results. The Sitemap provides the following information:
- SourceResolver--to find resources within your context.
- Object Model--a java.util.Map that contains the request and session
information.
- Source--the value of the "src" attribute in the sitemap.
- Parameters--the sitemap parameters passed into your component.
The setup method can throw one of three different types of exceptions which
would abort the processing of the pipeline. These exceptions are:
- ProcessingException--the preferred type of exception. Essentially wrap
anything with one of these.
- SAXException--a problem reading an XML document will generate one of these.
- IOException--when you can't find a file or there is a problem with the
filesystem.
The SourceResolver passed into your SitemapModelComponent is used to find
other resources. It will behave with the same properties as your sitemap. So if
you are in a mounted sitemap handling a certain segment of requests, any
relative URLs resolved by the SourceResolver will be relative to that sitemap.
However, the real fun comes with the types of requests we can make. Cocoon
understands several different protocols, including embedding a call to another
pipeline within your generated document.
Note: TODO: details of working with the SourceResolver
Working with the Object Model
The object model that your component gets to use is essentially a
java.util.Map. So how do we find what we need to get our job done?
After all a key for a Java Map is just an Object--it could be anything.
Thankfully, Cocoon provides a class to help you find your information:
org.apache.cocoon.environment.ObjectModelHelper.
You will be able to find the Cocoon Context, Request, and Response objects.The Context and Request objects are simplified forms of the ServletContext
and ServletRequest objects--however they do allow Cocoon to be invoked from the
command line as well. The Response object follows the same vein, and does not
provide any access to the output stream. That is because it is only the
responsibility of a SitemapOutputComponent to send the results down the output
stream. So why provide access to the Response object at all? It is for two
reasons: so that you can add or modify response headers before the pipeline is
executed, or that you can signal a redirect.
The source provided by the Sitemap is the value of the attribute "src" in the
sitemap. For example:
<map:transformer type="custom" src="{1}.xsl"/>
Will resolve the name based on the substitution values and then pass the
resolved name to the component. Let's say we matched on the pattern "status/*"
with the url "status/printfriendly". The Sitemap will resolve the source to
"printfriendly.xsl" using the definition above. The source is not necessary all
the time, although you may find it much more convenient than retrieving
information from a request object or the parameters.
Working with the Parameters
The parameters object allows you to pull information in much the same way as
you would in the sitemap. The
org.apache.avalon.framework.parameters.Parameters
object is the same as the one from the Excalibur project, and you have the same
interface there.
Note: You can get parent parameters using paths in the name. For
example, getParameter("../mrn") will get the "mrn" value from a parent
Parameters object.
The parameters are set in the sitemap using the <map:parameter
name="foo" value="bar"/> to set the parameter "foo" with the value
"bar". An example would look like this:
<map:generator type="myspecialgen" src="foo">
<!-- these parameters are passed in -->
<map:parameter name="foo" value="bar"/>
<map:parameter name="nav" value="{request:bar}"/>
</map:generator>
Sometimes you may find some weirdness with parameters if you are setting some
values in flowscript and expecting to see them in your generator. In that case
you may find it much more convenient to pass values within the Request
attributes.