blob: 8b18c8490e51e0aaefb2ca67da6c2b73472e47a7 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>XSP Internals</title>
<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
<meta content="Ricardo Rocha" name="DC.Creator">
</head>
<body>
<h1>Index</h1>
<p>
This document presents Apache Cocoon's dynamic markup language
framework and its use in implementing XSP:
</p>
<ul>
<li>
<a href="#markup-to-code">
Markup-to-code Transformation
</a>
</li>
<li>
<a href="#cocoon-generators">
XSP and Cocoon Generators
</a>
</li>
<li>
<a href="#programming-language">
The Programming Language Processor
</a>
</li>
<li>
<a href="#compiled-languages">
Compiled Languages
</a>
</li>
<li>
<a href="#interpreted-languages">
Interpreted Languages
</a>
</li>
<li>
<a href="#markup-language">
The Markup Language Processor
</a>
</li>
<li>
<a href="#xsp-language">
The XSP Markup Language
</a>
</li>
<li>
<a href="#dom-xsp">
The DOM-XSP Markup Language
</a>
</li>
<li>
<a href="#program-generator">
The Program Generator
</a>
</li>
<li>
<a href="#named-components">
Named Components
</a>
</li>
<li>
<a href="#sitemap-configuration">
XSP Sitemap Configuration
</a>
</li>
</ul>
<a name="markup-to-code"></a>
<h1>Markup-to-code Transformation</h1>
<p>
XSP is based on a general-purpose markup-to-code transformation engine
built around three key abstractions:
</p>
<ul>
<li>
<strong>Dynamic Markup Language</strong>.
An namespace-qualified XML vocabulary providing
<em>code embedding</em>
directives.
An associated
<em>dynamic markup language processor</em>
transforms static markup interspersed with code embedding directives
into an equivalent
<em>source program string</em>
written in a
<em>target programming language</em>.
Upon execution, the generated program will rebuild the original XML
document as augmented by dynamic content emitted by the embedded code.
</li>
<li>
<strong>Programming Language</strong>.
A procedural language in which the dynamic markup processor generates
source code from an input XML document. Its associated
<em>programming language processor</em>
is responsible for compiling, loading and executing the generated code
within the boundaries of its calling environment.
</li>
<li>
<strong>Program Generator</strong>.
A component that integrates markup and programming language processors
to build and execute markup-generating programs derived from XML
documents. Beyond this "glue" role, this component is responsible for
persistently storing generated programs as well as automatically
rebuilding them should their source XML documents change on disk after
program generation.
</li>
</ul>
<div class="note">
Despite its particular usage for XSP,
<a href="../../apidocs/org/apache/cocoon/components/language/generator/ProgramGenerator.html">
<span class="codefrag">ProgramGenerator</span>
</a>
is not restricted to run in a server pages environment.
</div>
<a name="cocoon-generators"></a>
<h1>XSP and Cocoon Generators</h1>
<p>
As a rule, XSP pages are translated into Cocoon
<a href="../../apidocs/org/apache/cocoon/generation/Generator.html">
<span class="codefrag">Generator</span>'s.
</a>
</p>
<h2>Server Pages Generator Proxy</h2>
<p>
<span class="codefrag">Generator</span>'s created by XSP are invoked exclusively through
<a href="../../apidocs/org/apache/cocoon/generation/ServerPagesGenerator.html">
<span class="codefrag">ServerPagesGenerator</span>,
</a>
a proxy that uses Cocoon's
<a href="#program-generator"><span class="codefrag">ProgramGenerator</span></a>
component to load pages and subsequently delegates actual SAX event
generation to them.
</p>
<div class="note">
The terms <span class="codefrag">Generator</span> and <span class="codefrag">ProgramGenerator</span> are
somewhat confusing. Here, <span class="codefrag">Generator</span> refers to a Cocoon
<span class="codefrag">org.apache.cocoon.generation.Generator</span> instance responsible
for the initial feeding of Cocoon's SAX pipeline.
<span class="codefrag">ProgramGenerator</span>, on the other hand, refers to a Cocoon
component responsible for building and executing programs derived from XML
documents containing dynamic markup:
<a href="../../apidocs/org/apache/cocoon/components/language/generator/ProgramGenerator.html">
<span class="codefrag">org.apache.cocoon.components.language.generator.ProgramGenerator</span>
</a>
</div>
<p>
<span class="codefrag">ServerPagesGenerator</span>
attempts to cope with a not unlikely
possibility: <em>premature</em> termination of proxied generator
execution.
"Premature" here means that the invoked generator may return after
starting one or more SAX events but without properly ending them.
</p>
<p>
While this not an expected scenario in "manual" SAX programming, server
pages may well need to terminate in the middle of document production:
</p>
<pre class="code">
&lt;page&gt;
&lt;title&gt;For Your Eyes Only&lt;/title&gt;
&lt;xsp:logic&gt;
if (!request.getParameter("pet").equals("Cheetah")) {
&lt;p&gt;
Hey, you're not Tarzan!
&lt;/p&gt;
/*** Unclosed SAX events here! ***/
return;
}
&lt;/xsp:logic&gt;
&lt;!-- Multi-racial Jane affair description follows --&gt;
. . .
&lt;/page&gt;
</pre>
<p>
The server pages generator proxy is defined in the sitemap as follows:
</p>
<pre class="code">
. . .
&lt;map:generator
name="serverpages"
src="org.apache.cocoon.generation.ServerPagesGenerator"/&gt;
. . .
&lt;map:pipelines&gt;
&lt;map:pipeline&gt;
. . .
&lt;map:match pattern="/samples/*.xsp"&gt;
&lt;map:generate type="serverpages" src="../samples/documents/{1}.xsp"&gt;
&lt;!--
&lt;parameter name="markup-language" value="xsp"/&gt;
&lt;parameter name="programming-language" value="java"/&gt;
--&gt;
&lt;/map:generate&gt;
&lt;map:transform type="xslt" src="../samples/stalemates/simple-page.xsl"/&gt;
&lt;map:serialize type="html" mime-type="text/html"/&gt;
&lt;/map:match&gt;
. . .
&lt;/map:pipeline&gt;
&lt;/map:pipelines&gt;
</pre>
<p>
Note that parameters <span class="codefrag">markup-language</span> and
<span class="codefrag">programming-language</span> default to
<em>xsp</em> and <em>java</em> respectively.
</p>
<p>
The complete XSP sitemap configuration is explained
<a href="#sitemap-configuration">below</a>.
</p>
<h2>XSP Generators and Compiled Languages</h2>
<p>
For the Java language (and other compiled languages like
<a class="external" href="http://www.mozilla.org/rhino/"><em>Rhino</em></a>
Javascript),
XSP pages are translated into classes extending
<a href="../../apidocs/org/apache/cocoon/generation/AbstractServerPage.html">
<span class="codefrag">AbstractServerPage</span>
</a>.
This class, in turn, extends
<a href="../../apidocs/org/apache/cocoon/generation/ComposerGenerator.html">
<span class="codefrag">ComposerGenerator</span>
</a>,
which gives it access to commonly used components such as
<em>parser</em> or <em>cocoon</em> itself (typically used as
<span class="codefrag">EntityResolver</span> for request URI's).
</p>
<p>
<span class="codefrag">AbstractServerPage</span> implements
<span class="codefrag">org.apache.arch.Modifiable</span>.
This
is tested by <span class="codefrag">ProgramGenerator</span> to assert whether the page has
been invalidated as a result of files it depends on having changed on disk.
These files are typically
<a href="#logicsheet"><em>logicsheets</em></a>
and template files included by means of XInclude.
</p>
<div class="note">
As of this writing, XInclude support is still unimplemented but
will be based on
<a href="mailto:balld.at.webslingerZ.com">Donald Ball</a>'s
(possibly extended)
<a href="../../apidocs/org/apache/cocoon/transformation/XIncludeTransformer.html">
<span class="codefrag">XIncludeTransformer</span>.
</a>
</div>
<p>
<span class="codefrag">AbstractServerPage</span> implements <span class="codefrag">Modifiable</span>
by means of two <em>static</em> variables:
<span class="codefrag">dateCreated</span> and
<span class="codefrag">dependencies</span> (a, possibly empty, array of
<span class="codefrag">File</span>'s pointing to logicsheets and other files included
during the code generation stage).
</p>
<p>
<span class="codefrag">AbstractServerPage</span> also provides a boolean
<span class="codefrag">hasContentChanged()</span> method that is tested by
<span class="codefrag">ServerPagesGenerator</span> to assert whether dynamic content should
not be regenerated for a given request. The default implementation
unconditionally returns <span class="codefrag">true</span>, but can be overridden by XSP
pages based on their interpretation of the Cocoon <span class="codefrag">request</span>
object. This is an <em>experimental</em> feature that will become
meaningful only when a SAX-event caching mechanism is added to Cocoon.
</p>
<p>
Finally, <span class="codefrag">AbstractServerPage</span> also provides a number of utility
methods used to shorten the generation of SAX events not requiring a
namespace.
</p>
<a name="programming-language"></a>
<h1>The Programming Language Processor</h1>
<p>
A Cocoon's
<a href="../../apidocs/org/apache/cocoon/components/language/programming/ProgrammingLanguage.html">
<span class="codefrag">ProgrammingLanguage</span>
</a>
processor exposes the
following methods:
</p>
<ul>
<li>
<span class="codefrag">load</span>.
Load a program from a file in a given directory,
compiling it, if necessary, using a given encoding.
</li>
<li>
<span class="codefrag">instantiate</span>
Create a new instance of a previously loaded program
</li>
<li>
<span class="codefrag">unload</span>
Discard a previously loaded program performing any
necessary cleanup
</li>
<li>
<span class="codefrag">getSourceExtension</span>
Return the canonical source file extension used by
this programming language
</li>
<li>
<span class="codefrag">getCodeFormatter</span>
Return an (optional) instance of
<a href="../../apidocs/org/apache/cocoon/components/language/programming/CodeFormatter.html">
<span class="codefrag">CodeFormatter</span>
</a>
used to beautify source code written in this programming language
</li>
<li>
<span class="codefrag">quoteString</span>
Escape a string constant according to the programming language rules
</li>
</ul>
<p>
A default implementation (<a href="../../apidocs/org/apache/cocoon/components/language/programming/AbstractProgrammingLanguage.html">
<span class="codefrag">AbstractProgrammingLanguage</span>
</a>) is
provided that extends
<span class="codefrag">org.apache.arch.named.AbstractNamedComponent</span>
and retrieves language-related sitemap parameters.
</p>
<h2>Filenames and Encoding</h2>
<p>
<span class="codefrag">load</span> and <span class="codefrag">unload</span> are passed a file/directory
pair used to locate the program.
</p>
<p>
The <span class="codefrag">baseDirectory</span> should be an absolute pathname
pointing to the top-level directory (also known as <em>repository</em>)
containing the program file.
</p>
<p>
The <span class="codefrag">filename</span> is a path, <em>relative to the
<span class="codefrag">baseDirectory</span></em>, pointing to the program file.
</p>
<p>
Source program filenames are built by concatenating the repository's
<span class="codefrag">baseDirectory</span> name, the given <span class="codefrag">filename</span>,
the dot extension separator and the language-specific source or
object <em>extensions</em>. The cross-platform
<span class="codefrag">File.separator</span> is used to ensure portability.
</p>
<div class="note">
The <span class="codefrag">filename</span> must <strong>not</strong> contain any
source or object extension. It may, though, contain subdirectories
depending on its position within the repository tree. Also,
programming languages <strong>must</strong> define a source extension
even when their actual compilers/interpreters do not enforce this. This
is also true of <em>object</em> extensions for compiled languages.
Furthermore, the dot character is <em>always</em> used as the
extension separator.
</div>
<p>
Finally, the (optional) <span class="codefrag">encoding</span> argument specifies the
how the source program file contents are encoded. This argument can be
<span class="codefrag">null</span> to specify the platform's default encoding.
</p>
<a name="program-load"></a>
<h2>Loading Programs</h2>
<p>
Currently, programs returned by the <span class="codefrag">load</span> operation are
"plain" Java <span class="codefrag">Object</span>'s and are not required to implement
any interface or to extend any particular class.
</p>
<div class="note">
This may change in the future so that the loaded program may be
required to provide dependency information (for automatic reloading)
as well as source code information (for debugging purposes).
</div>
<p>
Compiled programs attempt to locate the <em>object program</em> first.
If found, it's loaded in a language-specific way and then returned to
the calling environment.
Failing that, the source file is located and the language-specific
<a href="#compiler">compiler</a> is invoked prior to actual
program loading.
</p>
<p>
Of course, it is an error for the source program file not to exist as
a readable, regular operating system file.
</p>
<a name="program-unload"></a>
<h2>Unloading Programs</h2>
<p>
When a previously loaded program is no longer needed (or becomes
"outdated" as explained below) the language processor may need to
perform cleanup actions, such as releasing memory or (in the case
of Java-like compiled languages)
<a href="#class-loader-reinstantiation">
reinstantiating the class loader</a>.
</p>
<p>
Loaded programs may become outdated as a consequence of events external
to the programming language processor. In a server pages environment,
this is the result of the source XML document (or any of the files
it depends on) having changed on disk.
</p>
<p>
The base class
<span class="codefrag">AbstractProgrammingLanguage</span>
implements
this method <em>as <span class="codefrag">final</span></em> to delete the unloaded
<em>source</em> program file and delegate actual unloading to
method <span class="codefrag">doUnload</span>.
</p>
<p>
Method <span class="codefrag">doUnload</span> is <em>not</em> defined as
<span class="codefrag">abstract</span> in order to relieve interpreted subclasses
from having to implement an empty method when no cleanup is
required.
</p>
<div class="note">
Currently, only the <span class="codefrag">program</span> object is being passed
to <span class="codefrag">unload</span>. It may be possible for some interpreted
languages to also require knowing what file the program was originally
loaded from. In this case, instantiation should take place through
the program object itself, rather than through the language processor
(see <em>Program Instantiation</em> below)
</div>
<a name="program-instantiation"></a>
<h2>Instantiating Programs</h2>
<p>
The <span class="codefrag">program</span> object returned by <span class="codefrag">load</span> must
act as an factory capable of creating <em>program instance</em>
objects on demand.
</p>
<p>
Currently, instantiation is performed by the language processor
given a previously loaded <span class="codefrag">program</span>.
</p>
<p>
Compiled programs use a language-specified
<a href="#class-loader">class loader</a> to create
a new program instance.
</p>
<div class="note">
For compiled languages, it is possible to guarantee that a
generated program implements a given interface or extends a
given class. For interpreted languages, though, it may be
necessary to pass an additional <span class="codefrag">prototype</span> object
to <span class="codefrag">load</span> as to ensure that created instances conform
to a given Java type expected behavior.
</div>
<a name="source-extension"></a>
<h2>Source Extensions</h2>
<p>
All languages are required to return a <em>source extension</em>.
This extension is used to locate source files for subsequent
interpretation or compilation.
</p>
<a name="code-formatting"></a>
<h2>Code Formatting</h2>
<p>
Programming languages may provide a
<a href="../../apidocs/org/apache/cocoon/components/language/programming/CodeFormatter.html">
<span class="codefrag">CodeFormatter</span>
</a>
instance used by code generators to beautify source code.
</p>
<p>
Interface
<span class="codefrag">CodeFormatter</span>
exposes a single method:
<span class="codefrag">formatCode</span>. <span class="codefrag">formatCode</span> takes as
arguments a <span class="codefrag">String</span> containing the source code to
be beautified and an <span class="codefrag">encoding</span> to be preserved
during string conversions.
</p>
<p>
Code formatters can be associated with a programming language
by specifying a <span class="codefrag">code-formatter</span> parameter in its
sitemap configuration:
</p>
<pre class="code">
&lt;parameter name="code-formatter"
value="org.apache.cocoon.components.language.programming.java.JstyleFormatter"/&gt;
</pre>
<div class="note">
Currently,
<a class="external" href="http://astyle.sourceforge.net/">Jstyle</a>
is being used for Java source formatting. This open source project
appears to be stagnated and lacks advanced formatting options
present in other (unfortunately, not open-sourced) products like
<a class="external" href="http://www.jindent.com/">Jindent</a>.
</div>
<a name="string-quoting"></a>
<h2>String Quoting</h2>
<p>
Method <span class="codefrag">quoteString</span> applies the programming language string
constant escaping rules to its input argument.
</p>
<p>
This method exists to assist markup language code generators in
escaping <span class="codefrag">Text</span> XML nodes.
</p>
<a name="compiled-languages"></a>
<h1>Compiled Languages</h1>
<p>
Compiled languages extend the <span class="codefrag">ProgrammingLanguage</span>
abstraction by introducing the notions of <em>compilation</em>
and <em>object extension</em>.
</p>
<p>
A base implementation
<a href="../../apidocs/org/apache/cocoon/components/language/programming/CompiledProgrammingLanguage.html">
(<span class="codefrag">CompiledProgrammingLanguage</span>)
</a>
is provided that adds the following protected variables and
abstract/overridable methods:
</p>
<ul>
<li>Variable <span class="codefrag">compilerClass</span>. Used to create instances
of the language's
<a href="#compiler">compiler</a>.
</li>
<li>Variable <span class="codefrag">deleteSources</span>. Used to state whether
intermediate source files should be deleted after successful
compilation
</li>
<li>Method <span class="codefrag">getObjectExtension</span>. Used to build object
filenames
</li>
<li>Method <span class="codefrag">loadProgram</span>. Used to perform actual program
load after source and (possibly) object files have been located
</li>
<li>Method <span class="codefrag">doUnload</span>. Used to perform cleanup after
program unloading
</li>
</ul>
<div class="note">
Object files are not required to be <em>Java class files</em>.
It's up the the compiled programming language processor to handle
object files.
</div>
<p>
Compiled programming languages must specify their preferred compiler
as a sitemap parameter:
</p>
<pre class="code">
&lt;component-instance name="java"
class="org.apache.cocoon.components.language.programming.java.JavaLanguage"&gt;
. . .
&lt;parameter name="compiler"
value="org.apache.cocoon.components.language.programming.java.Jikes"/&gt;
. . .
&lt;/component-instance&gt;
</pre>
<a name="object-extension"></a>
<h2>Object Extensions</h2>
<p>All compiled languages are required to return a <em>source extension</em>.
This extension is used to locate object files for subsequent loading.</p>
<a name="object-load"></a>
<h2>Object Program Loading</h2>
<p>
Concrete compiled programming languages must implement the abstract
method <span class="codefrag">loadProgram</span> to actually load an <em>object</em>
program resulting from compilation.
</p>
<a name="compilation"></a>
<h2>Program Compilation</h2>
<p>
Compilation is delegated to a sitemap-specified
<span class="codefrag">LanguageCompiler</span> instance, as explained below.
</p>
<a name="compiler"></a>
<h2>Compilers</h2>
<p>
Interface
<a href="../../apidocs/org/apache/cocoon/components/language/programming/LanguageCompiler.html">
<span class="codefrag">LanguageCompiler</span>
</a>
defines the
initialization and behavior for all compilers.
</p>
<p>
Methods exposed by this interface are:
</p>
<ul>
<li>
<span class="codefrag">setFile</span>. Used to specify the source file to
be compiled. This should be an absolute filename
</li>
<li>
<span class="codefrag">setSource</span>. Used to specify the directory where
dependent source files (if any) are stored
</li>
<li>
<span class="codefrag">setDestination</span>. Used to specify the directory where
the generated object files should be placed
</li>
<li>
<span class="codefrag">setClasspath</span>. Used to specify the class loading
path used by the compiler. While this option is named after
Java's <em>classpath</em> system variable, its semantics are
language-independent
</li>
<li>
<span class="codefrag">setEncoding</span>. Used to specify the encoding used
by the input source file
</li>
<li>
<span class="codefrag">compile</span>. The compiler's workhorse (boolean)
</li>
<li>
<span class="codefrag">getErrors</span>. Used to retrieve a list of compilation
error messages should compilation fail
</li>
</ul>
<a name="compiler-error"></a>
<h3>Compiler Errors</h3>
<p>
Error message producer by the compiler must be collected and
massaged by the <span class="codefrag">LanguageCompiler</span> in order to
wrap each of them as a <span class="codefrag">CompilerError</span> instance.
</p>
<p>
Class
<a href="../../apidocs/org/apache/cocoon/components/language/programming/CompilerError.html">
<span class="codefrag">CompilerError</span>
</a>
exposes the following
methods:
</p>
<ul>
<li>
<span class="codefrag">getFile</span>. Returns the program filename originating
the error
</li>
<li>
<span class="codefrag">isError</span>. Asserts whether the error is a server
error or simply a warning
</li>
<li>
<span class="codefrag">getStartLine</span>. Returns the starting line of the
offending code
</li>
<li>
<span class="codefrag">getStartColumn</span>. Returns the starting column (within
the starting line) of the offending code
</li>
<li>
<span class="codefrag">getEndLine</span>. Returns the ending line of the
offending code
</li>
<li>
<span class="codefrag">getEndColumn</span>. Returns the ending column (within
the ending line) of the offending code
</li>
<li>
<span class="codefrag">getMessage</span>. Returns the actual error message text
</li>
</ul>
<a name="java-compilers"></a>
<h3>Java Compilers</h3>
<p>
For the Java language, 2 pluggable compilers are available:
</p>
<ul>
<li>
<em>Javac</em>. A wrapper to Sun's builtin compiler
</li>
<li>
<em>Jikes</em>. A wrapper to IBM's <em>Jikes</em> compiler
</li>
</ul>
<p>
Both of these compilers are based on
<a href="../../apidocs/org/apache/cocoon/components/language/programming/java/AbstractJavaCompiler.html">
<span class="codefrag">AbstractJavaCompiler</span>.
</a>
</p>
<a name="other-compilers"></a>
<h3>Other Compilers</h3>
<p>
Since
<a class="external" href="http://www.mozilla.org/rhino/"><em>Rhino</em></a>
Javascript provides its own, only compiler (<em>jsc</em>),
class <span class="codefrag">JavascriptLanguage</span> doesn't use the compiler
class initialized by <span class="codefrag">CompiledProgrammingLanguage</span>.
</p>
<a name="object-unload"></a>
<h2>Object Program Unloading</h2>
<p>
<span class="codefrag">CompiledProgrammingLanguage</span> extends the default
implementation provided by
<span class="codefrag">AbstractProgrammingLanguage</span>
by deleting the <em>object</em> program file and
delegating actual unloading to the
<span class="codefrag">doUnload</span> method.
</p>
<p>
Method <span class="codefrag">doUnload</span> provides an empty default implementation
that can be overridden by derived compiled languages should unloading
cleanup be actually required.
</p>
<a name="class-loader-reinstantiation"></a>
<p>
For Java-based compiled languages (i.e., those using
<em>class files</em> as their object format, unloading implies
reinstantiating their
<a href="#class-loader">class loader</a>
such that it "forgets" about previously loaded classes thus
becoming able to refresh class files updates since their last
load.
</p>
<p>
This is a commonly-used workaround for the (somewhat buggy)
standard Java class loader, which doesn't provide for an
explicit method for reloading class files.
</p>
<a name="class-loader"></a>
<h2>The Cocoon Class Loader</h2>
<p>
To circumvent standard Java class loaders limitation, Cocoon provides a
simple customized class loader
<a href="../../apidocs/org/apache/cocoon/components/classloader/RepositoryClassLoader.html">
(<span class="codefrag">RepositoryClassLoader</span>)
</a>
that features:
</p>
<ul>
<li>A directory-based extensible classpath that can grow at execution
time
</li>
<li>Class reloading by means of reinstantiation
</li>
</ul>
<p>
<span class="codefrag">RepositoryClassLoader</span> extends
<span class="codefrag">java.lang.ClassLoader</span> adding an
<span class="codefrag">addDirectory</span> method that adds the directory pointed to
by its <span class="codefrag">String</span> argument to its local classpath.
</p>
<p>
Access to <em>protected</em> <span class="codefrag">RepositoryClassLoader</span> class
is proxied through interface
<a href="../../apidocs/org/apache/cocoon/components/classloader/ClassLoaderManager.html">
<span class="codefrag">ClassLoaderManager</span>.
</a>
This interface exposes the following methods:
</p>
<ul>
<li>
<span class="codefrag">addDirectory</span>. Passed to the proxied
<span class="codefrag">RepositoryClassLoader</span>
</li>
<li>
<span class="codefrag">loadClass</span>. Passed to the proxied
<span class="codefrag">RepositortyClassLoader</span>
</li>
<li>
<span class="codefrag">reinstantiate</span>. Used to discard the previous
class loader and create a new one
</li>
</ul>
<p>
Class
<a href="../../apidocs/org/apache/cocoon/components/classloader/ClassLoaderManagerImpl.html">
<span class="codefrag">ClassLoaderManagerImpl</span>
</a>
implements
<span class="codefrag">ClassLoaderManager</span> in a singleton-like fashion that
ensures that only one instance of this class loader exists,
thus ensuring the reinstantiation mechanism works properly.
</p>
<p>
The class loader can be specified in the sitemap on a per-language
basis:
</p>
<pre class="code">
&lt;component-instance name="java"
class="org.apache.cocoon.components.language.programming.java.JavaLanguage"&gt;
. . .
&lt;parameter name="class-loader"
value="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/&gt;
&lt;/component-instance&gt;
</pre>
<p>
Alternatively, the class loader can be specified in the sitemap as
a global component:
</p>
<pre class="code">
&lt;component
role="class-loader"
class="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/&gt;
</pre>
<a name="interpreted-languages"></a>
<h1>Interpreted Languages</h1>
<p>
Interpreted languages for which a Java-based interpreter exists
are supported by means of IBM's outstanding
<a class="external" href="http://www.alphaworks.ibm.com/tech/bsf">
Bean Scripting Framework
</a> (BSF).
</p>
<p>
Currently, BSF supports:
</p>
<ul>
<li>Mozilla Rhino</li>
<li>NetRexx</li>
<li>Jacl</li>
<li>JPython</li>
<li>VBScript (Win32 only)</li>
<li>JScript (Win32 only)</li>
<li>PerlScript (Win32 only)</li>
<li>BML (Not applicable to server pages)</li>
<li>LotusXSL (Not applicable to server pages)</li>
</ul>
<div class="note">
Interpreted language support is still unimplemented!<br>
While BSF is extremely easy to use and very stable, there's still
a challenge in writing code-generation logicsheets for each of this
languages; this task requires familiarity with XSP internals, XSLT
and, above all, the programming language at hand...
</div>
<div class="note">
Despite being supported by BSF, Rhino Javascript is separately
supported by Cocoon as a compiled language in order to take
advantage of automatic class reloading and persistent class file
storage.
</div>
<div class="note">
Since <span class="codefrag">ProgramGenerator</span> clients will typically require
that program instances implement a given interface or extend a given
class, method <span class="codefrag">instantiate</span> in interface
<span class="codefrag">ProgrammingLanguage</span> may need to be augmented with a
<span class="codefrag">prototype</span> interface that can be used by each language
processor to ensure that the program instance can act as a Java
object of the given type.
</div>
<a name="markup-language"></a>
<h1>The Markup Language Processor</h1>
<p>
A Cocoon's
<a href="../../apidocs/org/apache/cocoon/components/language/markup/MarkupLanguage.html">
<span class="codefrag">MarkupLanguage</span>
</a>
processor exposes the
following methods:
</p>
<ul>
<li>
<span class="codefrag">getEncoding</span>.
Return the encoding to be used in program generation and
compilation or <span class="codefrag">null</span> to use the platform's
default encoding
</li>
<li>
<span class="codefrag">generateCode</span>.
Given a DOM <span class="codefrag">Document</span> written in a given
<em>markup language</em>, generate an equivalent program in a given
<em>programming language</em>)
</li>
</ul>
<p>
A base markup language processor implementation is provided in
class
<a href="../../apidocs/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.html">
<span class="codefrag">AbstractMarkupLanguage</span>.
</a>
This class extends
<span class="codefrag">org.apache.arch.named.AbstractNamedComponent</span>
to set the markup language's
associated namespace using the following required parameters:
</p>
<ul>
<li>
<span class="codefrag">prefix</span>.
The markup language's namespace prefix
</li>
<li>
<span class="codefrag">uri</span>.
The markup language's namespace URI
</li>
</ul>
<pre class="code">
&lt;component-instance name="xsp"
class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"&gt;
&lt;parameter name="prefix" value="xsp"/&gt;
&lt;parameter name="uri" value="http://apache.org/xsp"/&gt;
&lt;/component-instance&gt;
</pre>
<p>
<span class="codefrag">AbstractMarkupLanguage</span> adds a number of
abstract/overridable methods that must be implemented by concrete
markup language processors:
</p>
<ul>
<li>
<span class="codefrag">preprocessDocument</span>.
Augment the input DOM <span class="codefrag">Document</span> to prepare it for
simpler, faster logicsheet-based code generation
</li>
<li>
<span class="codefrag">getLogicsheets</span>.
Return the list of logicsheets declared in the input document
according to the syntax of the markup language at hand
</li>
<li>
<span class="codefrag">addDependency</span>.
Add a dependency on an external file. This is used to inform
the concrete markup language processor about XML documents
included by means of XInclude as well as any intervening
logicsheet
</li>
</ul>
<div class="note">
<span class="codefrag">AbstractMarkupLanguage</span> is currently tied to
logicsheets as the <em>only</em> means of generating source
code. While logicsheets provide a very powerful means for
code generation, good design dictates that the actual code
generation mechanism should be decoupled from the dynamic
markup language abstraction.
</div>
<div class="note">
The current code generation strategy is DOM-based. In principle,
this is adequate because document preprocessing may need random
access to document nodes. Code generation is being reconsidered,
however, to overcome this and make it possible to reuse Cocoon's
SAX-based filtering pipeline.
</div>
<a name="markup-encoding"></a>
<h2>Markup Encoding</h2>
<p>
All markup languages must provide a way to declare the XML
document's encoding so that it is preserved during code generation,
beautifying and compilation.
</p>
<p>
This is required for proper i18n support, where the default
encoding usually replaces "exotic" characters with question marks.
</p>
<div class="note">
Ideally, it should be possible to determine the source XML document's
<span class="codefrag">encoding</span> from its declaring
<span class="codefrag">&lt;?xml?&gt;</span> processing instruction. Unfortunately,
XML parsers (both DOM and SAX) don't seem to provide access to it,
thus forcing server pages authors to redundantly specify it.
</div>
<a name="logicsheet-class"></a>
<h2>The Logicsheet class</h2>
<a name="logicsheet"></a>
<p>
A <em>logicsheet</em> is an XML filter used to translate user-defined
dynamic markup into equivalent code embedding directives for a given
markup language.
</p>
<p>
Logicsheets lie at the core of XSP's promise to separate logic from
content and presentation: they make dynamic content generation
capabilities available to content authors not familiar with (and
not interested in) programming.
</p>
<p>
For a detailed description of logicsheets, see
<a href="logicsheet-concepts.html">Logicsheet Concepts</a>.
</p>
<p>
Logicsheets are represented in class
<a href="../../apidocs/org/apache/cocoon/components/language/markup/Logicsheet.html">
<span class="codefrag">Logicsheet</span>.
</a>
This
class exposes the following methods:
</p>
<ul>
<li>
<span class="codefrag">setInputSource</span>.
Set the <span class="codefrag">InputSource</span> pointing to the XSLT
stylesheet to be used for dynamic tag transformation
</li>
<li>
<span class="codefrag">apply</span>.
Apply the stylesheet to a given document
</li>
</ul>
<p>
<span class="codefrag">Logicsheet</span> takes care of preserving all namespaces
defined in the input document. This is necessary when multiple
logicsheets are applied and multiple namespaces are used in the
input document.
</p>
<div class="note">
Currently, <span class="codefrag">Logicsheet</span> is a concrete class. It should
be redefined as an interface in order to decouple it from the use
of XSLT stylesheets. Again, while stylesheets are the "obvious" way
to implement logicsheets, a user-supplied XML filter may also be
used in some cases.
The current implementation uses an ugly
hack where a Xalan stylesheet processor is used to perform
the transformation without an intervening stylesheet processor
wrapping abstraction.
</div>
<a name="named-logicsheet"></a>
<h2>Named Logicsheets</h2>
<p>
As explained in
<a href="logicsheet-concepts.html#logicsheet-object">
Logicsheet Concepts,
</a>
logicsheets are typically associated with a single object type whose
methods it wraps to make them available as
<em>markup commands</em>.
</p>
<p>
Markup commands related to a given object type are grouped under a
single namespace.
</p>
<p>
Class
<a href="../../apidocs/org/apache/cocoon/components/language/markup/NamedLogicsheet.html">
<span class="codefrag">NamedLogicsheet</span>
</a>
extends <span class="codefrag">Logicsheet</span>
to associate it with a namespace. This class exposes the following
additional methods:
</p>
<ul>
<li>
<span class="codefrag">setPrefix</span>.
To set the logicsheet's namespace prefix</li>
<li>
<span class="codefrag">getPrefix</span>.
To retrieve the logicsheet's namespace prefix</li>
<li>
<span class="codefrag">setUri</span>.
To set the logicsheet's namespace URI</li>
<li>
<span class="codefrag">getUri</span>.
To retrieve the logicsheet's namespace URI</li>
</ul>
<p>
Named logicsheets are used as
<a href="#builtin-logicsheets">
builtin logicsheets
</a>
by <span class="codefrag">AbstractMarkupLanguage</span>
to preload logicsheets and make them accessible
to dynamic XML documents without explicit declaration.
</p>
<p>
This feature relieves page authors from the need to explicitly
declare commonly used logicsheets in their documents. Builtin
logicsheets are automatically applied if the document declares
their same namespace URI.
</p>
<div class="note">
The current <span class="codefrag">AbstractMarkupLanguage</span> implementation
wrongly binds named logicsheets based on their namespace
<em>prefix</em> instead of their URI!
</div>
<a name="logicsheet-generator"></a>
<h2>Logicsheet Code Generators</h2>
<p>
Logicsheets translate dynamic tags to equivalent code-embedding
directives expressed in the markup language at hand. They do not,
however, actually emit the final source code program.
</p>
<p>
Code generation as such (i.e., the final production of a string
containing a source program written in a programming language) is
the responsibility of class <span class="codefrag">LogicsheetCodeGenerator</span>.
</p>
<p>
Class
<a href="../../apidocs/org/apache/cocoon/components/language/markup/LogicsheetCodeGenerator.html">
<span class="codefrag">LogicsheetCodeGenerator</span>
</a>
exposes the following methods:
</p>
<ul>
<li>
<span class="codefrag">addLogicsheet</span>.
Add a logicsheet to the generator's logicsheet list.
Logicsheets are applied in the order of their addition.
</li>
<li>
<span class="codefrag">generateCode</span>.
Return a string containing a source program resulting from
successively applying added logicsheets.
</li>
</ul>
<p>
Though "regular" logicsheets as such do not emit source code,
<span class="codefrag">LogicsheetCodeGenerator</span> expects its <em>last</em>
stylesheet to produce <em>a single element</em> containing only
a text node.
</p>
<p>
This final, programming language-specific logicsheet is
responsible for actually expanding code-embedding directives
into source code.
</p>
<p>
For each supported target programming language, markup languages
must provide a <em>core</em> logicsheet.
</p>
<div class="note">
<span class="codefrag">LogicsheetCodeGenerator</span> is currently implemented as a
class. It should be defined as an interface in order to the decouple
the code generator abstraction from its logicsheet-based implementation.
This would allow for alternative code-generation strategies to
be plugged.
</div>
<a name="markup-definition"></a>
<h2>Markup Language Definition</h2>
<p>
Markup languages are defined in the sitemap as follows:
</p>
<pre class="code">
&lt;component-type name="markup-language"&gt;
&lt;component-instance name="xsp"
class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"&gt;
&lt;parameter name="prefix" value="xsp"/&gt;
&lt;parameter name="uri" value="http://apache.org/xsp"/&gt;
&lt;target-language name="java"&gt;
&lt;parameter name="core-logicsheet"
value="resource://org/apache/cocoon/components/language/markup/xsp/java/xsp.xsl"/&gt;
&lt;builtin-logicsheet&gt;
&lt;parameter name="prefix" value="xsp-request"/&gt;
&lt;parameter name="uri" value="http://apache.org/xsp/request/2.0"/&gt;
&lt;parameter name="href"
value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
&lt;/builtin-logicsheet&gt;
&lt;builtin-logicsheet&gt;
&lt;parameter name="prefix" value="xsp-response"/&gt;
&lt;parameter name="uri"
value="http://apache.org/xsp/response/2.0"/&gt;
&lt;parameter name="href"
value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
&lt;/builtin-logicsheet&gt;
&lt;/target-language&gt;
&lt;/component-instance&gt;
&lt;/component-type&gt;
</pre>
<p>
Here, the markup language <em>prefix</em> and <em>uri</em>
are defined together with one or more
<em>supported programming languages</em>.
</p>
<p>
For each supported programming language, a corresponding
<em>core logicsheet</em> is defined as a URL pointing to
its code-generation stylesheet.
</p>
<a name="builtin-logicsheets"></a>
<p>
Optionally, each supported programming language may define
one or more namespace-mapped <em>builtin logicsheets</em>.
</p>
<a name="xsp-language"></a>
<h1>The XSP Markup Language</h1>
<p>
So far, programming and markup languages have been described
in general, without explicitly referring to the XSP language.
</p>
<p>
This section describes how the above described framework is
used to implement XSP in particular. For a description of
logicsheet authoring requirements for XSP in Java, see
<a href="logicsheet-concepts.html#java-logicsheets">
XSLT Logicsheets and XSP for Java.
</a>
</p>
<div class="note">
The XSP syntax is being revised to allow for the omission of the
root <span class="codefrag">&lt;xsp:page&gt;</span> element. This is convenient
for the (typical) case in which all logic has been conveniently
placed in logicsheets so that XSP pages do not need to embed any
code. In this case, there should be no need for the
<span class="codefrag">&lt;xsp:page&gt;</span> element.
</div>
<a name="xsp-encoding"></a>
<h2>Markup Encoding</h2>
<p>Method <span class="codefrag">getEncoding</span> is implemented by class
<a href="../../apidocs/org/apache/cocoon/components/language/markup/xsp/XSPMarkupLanguage.html">
<span class="codefrag">XSPMarkupLanguage</span>
</a>
by retrieving the attribute named
<span class="codefrag">encoding</span> in the root <span class="codefrag">&lt;xsp:page&gt;</span> element.</p>
<div class="note">
In absence of a <span class="codefrag">&lt;xsp:page&gt;</span> root element, the
encoding will be retrieved from an attribute named
<span class="codefrag">xsp:encoding</span> present in the "user" root element.
</div>
<a name="xsp-preprocessing"></a>
<h2>Document Preprocessing</h2>
<p>
<span class="codefrag">XSPMarkupLanguage</span> preprocesses its input document
by:
</p>
<ul>
<li>
Setting the root element <span class="codefrag">file-name</span> attribute to the
<em>base</em> filename of its input source.
</li>
<li>
Setting the root element <span class="codefrag">file-path</span> attribute to the
<em>base</em> directory name of its input source.
</li>
<li>
Setting the root element <span class="codefrag">creation-date</span> attribute to the
current system time
</li>
<li>
Escaping text nodes according to the rules dictated by the
target programming language. This excludes text nodes enclosed
in <span class="codefrag">&lt;xsp:logic&gt;</span> and <span class="codefrag">&lt;xsp:expr&gt;</span>
elements, as they are to be output as code.
</li>
</ul>
<div class="note">
A feature to be added is collecting all text nodes under the document's
root element and replacing them by references to their relative index
position. This will allow for the generation of
<span class="codefrag">contentHandler.characters</span> method calls that reference
<span class="codefrag">char</span> arrays instead of constant <span class="codefrag">String</span>'s.
In addition to saving execution time, this will result in decreased
program size because common substrings can be output by "reusing"
their containing character arrays along with their corresponding
offsets and lengths.
</div>
<a name="xsp-dependencies"></a>
<h2>Dependency Tracking</h2>
<p>
File dependencies passed to <span class="codefrag">XSPMarkupLanguage</span> by
its <span class="codefrag">AbstractMarkupLanguage</span> superclass are stored
in top-level <span class="codefrag">&lt;xsp:dependency&gt;</span> elements.
</p>
<p>
These elements are used by XSP code-generation logicsheets to
populate the <span class="codefrag">File</span> array defined by the generated
classes' <span class="codefrag">AbstractServerPage</span> superclass.
</p>
<a name="xsp-builtin"></a>
<h2>XSP Builtin Logicsheets</h2>
<p>
XSP for Java currently provides only 2 builtin logicsheets:
<span class="codefrag">request</span> and <span class="codefrag">response</span>, associated
with their corresponding Cocoon counterparts.
</p>
<div class="note">
A mechanism is needed for Cocoon to pass additional objects
to XSP pages. In particular, for the servlet execution
environment, access to servlet objects is a must.
</div>
<a name="dom-xsp"></a>
<h1>The DOM-XSP Markup Language</h1>
<p>
The new, SAX-based XSP version for Cocoon is not backwards
compatible with its DOM-based former self.
</p>
<p>
In order to protect the existing DOM-based XSP code base,
a "new" markup language will be added that simply wraps
existing XSP version 1 pages, postprocessing their generated
documents to convert them into SAX events.
</p>
<p>
While this solution implies additional overhead, it provides
a simple path for migrating existing XSP pages.
</p>
<p>
In addition to this straight-forward mechanism, the new,
SAX-based XSP version will overload the <span class="codefrag">xspExpr</span>
method to accept as argument a <span class="codefrag">Node</span> expression
and transform it to equivalent SAX events.
</p>
<p>
For the long run, though, developers are strongly encouraged
to replace their "legacy" DOM pages and classes with equivalent,
faster SAX counterparts.
</p>
<a name="program-generator"></a>
<h1>The Program Generator</h1>
<p>
The
<a href="../../apidocs/org/apache/cocoon/components/language/generator/ProgramGenerator.html">
<span class="codefrag">ProgramGenerator</span>
</a>
interface exposes a single
<span class="codefrag">load</span> method that takes as arguments a <span class="codefrag">File</span>
pointing to a source XML document, as well as a <em>markup</em> and
<em>programming</em> language name pair.
</p>
<p>
This method is responsible for locating, loading and instantiating
a program derived from the given source document. Failing this,
the program is generated and stored in an external, persistent
<em>repository</em>.
</p>
<p>
Once instantiated, the program is kept in an in-memory cache for
speeding up subsequent requests.
</p>
<p>
For each request, the source XML document is checked for changes
and the program instance is queried for dependency changes so that
the program can be automatically regenerated and reloaded if needed.
This default behavior can be disabled by means of a sitemap
parameter.
</p>
<div class="note">
Currently, the program <em>instance</em> (as opposed to the
program object itself) is queried for invalidating changes.
This should change as a consequence of defining a separate
<span class="codefrag">Program</span> abstraction as part of the upcoming
addition of debugging support.
</div>
<p>
A default implementation of <span class="codefrag">ProgramGenerator</span>
is provided that uses a
<a href="../../apidocs/org/apache/cocoon/components/store/FilesystemStore.html">
<span class="codefrag">FilesystemStore</span>
</a>
as
repository:
<a href="../../apidocs/org/apache/cocoon/components/language/generator/ProgramGeneratorImpl.html">
<span class="codefrag">ProgramGeneratorImpl</span>.
</a>
</p>
<a name="program-repository"></a>
<h2>Program Repository</h2>
<p>
<span class="codefrag">FilesystemStore</span> is an implementation of the
<span class="codefrag">Store</span> interface that uses a filesystem,
hierarchical <em>directory</em> as its persistence
mechanism.
</p>
<div class="note">
<span class="codefrag">FilesystemStore</span> implements <span class="codefrag">Store</span>
directly. A higher-level interface (<span class="codefrag">PersistentStore</span>)
should be defined to accommodate other sensible persistent
storage mechanisms such as relational databases or object
databases like
<a class="external" href="http://www.ozone-db.org/">Ozone</a>.
</div>
<p>
<span class="codefrag">FilesystemStore</span> expects the <span class="codefrag">String</span>
representation of its <span class="codefrag">key</span>'s to be <em>filenames</em>
relative to its directory root.
</p>
<p>
Objects returned by <span class="codefrag">FilesystemStore</span>'s
<span class="codefrag">get</span> method are <span class="codefrag">File</span>'s pointing to
their corresponding entries (or <span class="codefrag">null</span> if their
associated file doesn't exit).
</p>
<p>
<span class="codefrag">FilesystemStore</span> stores Java objects according
to the following rules:
</p>
<ul>
<li>
<span class="codefrag">null</span> values generate empty directories</li>
<li>
<span class="codefrag">String</span> values are dumped to text files</li>
<li>All other <span class="codefrag">Object</span>'s are serialized</li>
</ul>
<a name="program-reloading"></a>
<h2>Program Reloading</h2>
<p>
Unless the <span class="codefrag">auto-reload</span> sitemap option is in effect,
<span class="codefrag">ProgramGeneratorImpl</span> will check whether program
instances implement interface <span class="codefrag">Modifiable</span> in order
to assert whether they should be regenerated and reloaded.
</p>
<p>
Method <span class="codefrag">load</span> uses its <span class="codefrag">markupLanguageName</span> and
<span class="codefrag">programmingLanguage</span> arguments to retrieve the corresponding
<a href="#named-components"><span class="codefrag">NamedComponent</span></a>
instances.
</p>
<p>
In server pages mode, these parameters are set by the calling
<span class="codefrag">ServerPagesGenerator</span> from parameters passed via
the sitemap <span class="codefrag">&lt;process&gt;</span> section.
</p>
<p>
The appropriate <span class="codefrag">MarkupLanguage</span> and
<span class="codefrag">ProgrammingLanguage</span> instances are used to generate and
load a program for which an instance is created and then returned to
the calling environment.
</p>
<a name="named-components"></a>
<h1>Named Components</h1>
<p>
In order to support pluggable markup and programming languages,
a new abstraction was added to Cocoon's <span class="codefrag">arch</span>
core interfaces:
<span class="codefrag">org.apache.arch.named.NamedComponent</span>.
</p>
<p>
Interface <span class="codefrag">NamedComponent</span> is simply an extension to
<span class="codefrag">org.apache.arch.Component</span>
that exposes a <span class="codefrag">getName()</span>
method.
</p>
<p>
<span class="codefrag">NamedComponent</span>'s belong to a collection of components
sharing the same Java type and are individually identified by a
name unique within each collection.
</p>
<p>
A
<span class="codefrag">org.apache.arch.named.NamedComponentManager</span>
is a component responsible
for storing and locating <span class="codefrag">NamedComponent</span> instances.
This interface exposes the following methods:
</p>
<ul>
<li>
<span class="codefrag">getComponent</span>. Retrieve a <span class="codefrag">NamedComponent</span>
instance given its <span class="codefrag">type</span> and <span class="codefrag">name</span>.
</li>
<li>
<span class="codefrag">getTypes</span>. Return an <span class="codefrag">Enumeration</span> of all
known <span class="codefrag">NamedComponent</span> types.
</li>
<li>
<span class="codefrag">getComponents</span>. Return an <span class="codefrag">Enumeration</span> of
all <span class="codefrag">NamedComponents</span> within a given <span class="codefrag">type</span>.
</li>
</ul>
<p>
A default implementation is provided for this interface:
<span class="codefrag">org.apache.arch.named.NamedComponentManagerImpl</span>.
</p>
<p>
Class
<span class="codefrag">org.apache.arch.named.AbstractNamedComponent</span>
provides a base implementation
for <span class="codefrag">NamedComponent</span> that extends
<span class="codefrag">org.apache.arch.Configurable</span>.
This class exposes the following methods:
</p>
<ul>
<li>
<span class="codefrag">setConfiguration</span>.
Retrieve named-component sitemap configuration values
converting parameter name/value pairs into <span class="codefrag">Parameters</span>
passed to subclasses for easier initialization
</li>
<li>
<span class="codefrag">setParameters</span>.
An empty method to be overridden by subclasses for parameter-based
initialization
</li>
<li>
<span class="codefrag">setAdditionalConfiguration</span>.
An empty method to be overridden by subclasses when parameter-based
initialization is not sufficient because there are nested
configuration elements in the corresponding sitemap entry
</li>
<li>
<span class="codefrag">getRequiredParameter</span>.
A static convenience method that returns a named parameter as
a <span class="codefrag">String</span> throwing an
<span class="codefrag">IllegalArgumentException</span>
if the parameter was not specified in the sitemap configuration
</li>
</ul>
<a name="sitemap-configuration"></a>
<h1>XSP Sitemap Configuration</h1>
<div class="note">
The sitemap configuration shown here is likely to change in the
near future.
</div>
<p>
A (rather verbose) sitemap definition for XSP follows:
</p>
<pre class="code">
&lt;component role="factory"
class="org.apache.avalon.NamedComponentManagerImpl"&gt;
&lt;component-type name="programming-language"&gt;
&lt;component-instance name="java"
class="org.apache.cocoon.components.language.programming.java.JavaLanguage"&gt;
&lt;parameter name="compiler"
value="org.apache.cocoon.components.language.programming.java.Javac"/&gt;
&lt;parameter name="code-formatter"
value="org.apache.cocoon.components.language.programming.java.JstyleFormatter"/&gt;
&lt;parameter name="class-loader"
value="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/&gt;
&lt;parameter name="delete-sources" value="false"/&gt;
&lt;/component-instance&gt;
&lt;/component-type&gt;
&lt;component-type name="markup-language"&gt;
&lt;component-instance name="xsp"
class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"&gt;
&lt;parameter name="prefix" value="xsp"/&gt;
&lt;parameter name="uri" value="http://apache.org/xsp"/&gt;
&lt;target-language name="java"&gt;
&lt;parameter name="core-logicsheet"
value="resource://org/apache/cocoon/components/language/markup/xsp/java/xsp.xsl"/&gt;
&lt;builtin-logicsheet&gt;
&lt;parameter name="prefix" value="xsp-request"/&gt;
&lt;parameter name="uri" value="http://apache.org/xsp/request/2.0"/&gt;
&lt;parameter name="href"
value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
&lt;/builtin-logicsheet&gt;
&lt;builtin-logicsheet&gt;
&lt;parameter name="prefix" value="xsp-response"/&gt;
&lt;parameter name="uri"
value="http://apache.org/xsp/response/2.0"/&gt;
&lt;parameter name="href"
value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
&lt;/builtin-logicsheet&gt;
&lt;/target-language&gt;
&lt;/component-instance&gt;
&lt;/component-type&gt;
&lt;/component&gt;
&lt;component role="program-generator"
class="org.apache.cocoon.components.language.generator.ProgramGeneratorImpl"&gt;
&lt;parameter name="repository" value="/tmp/repository"/&gt;
&lt;parameter name="auto-reload" value="true"/&gt;
&lt;/component&gt;
&lt;generator name="serverpages"
class="org.apache.cocoon.generation.ServerPagesGenerator"/&gt;
&lt;!--
&lt;component
role="class-loader"
class="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"
/&gt;
--&gt;
&lt;sitemap&gt;
&lt;partition&gt;
&lt;process uri="simple-page.xsp" source="../samples/documents/simple-page.xsp"&gt;
&lt;generator name="serverpages"&gt;
&lt;!--
&lt;parameter name="markup-language" value="xsp"/&gt;
&lt;parameter name="programming-language" value="java"/&gt;
--&gt;
&lt;/generator&gt;
&lt;filter name="xslt"&gt;
&lt;parameter name="stylesheet" value="../samples/documents/simple-page.xsl"/&gt;
&lt;/filter&gt;
&lt;serializer name="html"&gt;
&lt;parameter name="contentType" value="text/html"/&gt;
&lt;/serializer&gt;
&lt;/process&gt;
&lt;/partition&gt;
&lt;/sitemap&gt;
</pre>
</body>
</html>