| <!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"> |
| <page> |
| <title>For Your Eyes Only</title> |
| |
| <xsp:logic> |
| if (!request.getParameter("pet").equals("Cheetah")) { |
| <p> |
| Hey, you're not Tarzan! |
| </p> |
| |
| /*** Unclosed SAX events here! ***/ |
| return; |
| } |
| </xsp:logic> |
| <!-- Multi-racial Jane affair description follows --> |
| . . . |
| </page> |
| </pre> |
| <p> |
| The server pages generator proxy is defined in the sitemap as follows: |
| </p> |
| <pre class="code"> |
| . . . |
| <map:generator |
| name="serverpages" |
| src="org.apache.cocoon.generation.ServerPagesGenerator"/> |
| . . . |
| <map:pipelines> |
| <map:pipeline> |
| . . . |
| <map:match pattern="/samples/*.xsp"> |
| <map:generate type="serverpages" src="../samples/documents/{1}.xsp"> |
| <!-- |
| <parameter name="markup-language" value="xsp"/> |
| <parameter name="programming-language" value="java"/> |
| --> |
| </map:generate> |
| <map:transform type="xslt" src="../samples/stalemates/simple-page.xsl"/> |
| <map:serialize type="html" mime-type="text/html"/> |
| </map:match> |
| . . . |
| </map:pipeline> |
| </map:pipelines> |
| </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"> |
| <parameter name="code-formatter" |
| value="org.apache.cocoon.components.language.programming.java.JstyleFormatter"/> |
| </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"> |
| <component-instance name="java" |
| class="org.apache.cocoon.components.language.programming.java.JavaLanguage"> |
| . . . |
| <parameter name="compiler" |
| value="org.apache.cocoon.components.language.programming.java.Jikes"/> |
| . . . |
| </component-instance> |
| </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"> |
| <component-instance name="java" |
| class="org.apache.cocoon.components.language.programming.java.JavaLanguage"> |
| . . . |
| <parameter name="class-loader" |
| value="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/> |
| </component-instance> |
| </pre> |
| <p> |
| Alternatively, the class loader can be specified in the sitemap as |
| a global component: |
| </p> |
| <pre class="code"> |
| <component |
| role="class-loader" |
| class="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/> |
| </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"> |
| <component-instance name="xsp" |
| class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"> |
| <parameter name="prefix" value="xsp"/> |
| <parameter name="uri" value="http://apache.org/xsp"/> |
| </component-instance> |
| </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"><?xml?></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"> |
| <component-type name="markup-language"> |
| <component-instance name="xsp" |
| class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"> |
| <parameter name="prefix" value="xsp"/> |
| <parameter name="uri" value="http://apache.org/xsp"/> |
| |
| <target-language name="java"> |
| <parameter name="core-logicsheet" |
| value="resource://org/apache/cocoon/components/language/markup/xsp/java/xsp.xsl"/> |
| |
| <builtin-logicsheet> |
| <parameter name="prefix" value="xsp-request"/> |
| <parameter name="uri" value="http://apache.org/xsp/request/2.0"/> |
| <parameter name="href" |
| value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/> |
| </builtin-logicsheet> |
| |
| <builtin-logicsheet> |
| <parameter name="prefix" value="xsp-response"/> |
| <parameter name="uri" |
| value="http://apache.org/xsp/response/2.0"/> |
| <parameter name="href" |
| value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/> |
| </builtin-logicsheet> |
| </target-language> |
| </component-instance> |
| </component-type> |
| </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"><xsp:page></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"><xsp:page></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"><xsp:page></span> element.</p> |
| <div class="note"> |
| In absence of a <span class="codefrag"><xsp:page></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"><xsp:logic></span> and <span class="codefrag"><xsp:expr></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"><xsp:dependency></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"><process></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"> |
| <component role="factory" |
| class="org.apache.avalon.NamedComponentManagerImpl"> |
| |
| <component-type name="programming-language"> |
| <component-instance name="java" |
| class="org.apache.cocoon.components.language.programming.java.JavaLanguage"> |
| <parameter name="compiler" |
| value="org.apache.cocoon.components.language.programming.java.Javac"/> |
| <parameter name="code-formatter" |
| value="org.apache.cocoon.components.language.programming.java.JstyleFormatter"/> |
| <parameter name="class-loader" |
| value="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/> |
| <parameter name="delete-sources" value="false"/> |
| </component-instance> |
| </component-type> |
| |
| <component-type name="markup-language"> |
| <component-instance name="xsp" |
| class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"> |
| <parameter name="prefix" value="xsp"/> |
| <parameter name="uri" value="http://apache.org/xsp"/> |
| |
| <target-language name="java"> |
| <parameter name="core-logicsheet" |
| value="resource://org/apache/cocoon/components/language/markup/xsp/java/xsp.xsl"/> |
| |
| <builtin-logicsheet> |
| <parameter name="prefix" value="xsp-request"/> |
| <parameter name="uri" value="http://apache.org/xsp/request/2.0"/> |
| <parameter name="href" |
| value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/> |
| </builtin-logicsheet> |
| |
| <builtin-logicsheet> |
| <parameter name="prefix" value="xsp-response"/> |
| <parameter name="uri" |
| value="http://apache.org/xsp/response/2.0"/> |
| <parameter name="href" |
| value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/> |
| </builtin-logicsheet> |
| </target-language> |
| </component-instance> |
| </component-type> |
| </component> |
| |
| <component role="program-generator" |
| class="org.apache.cocoon.components.language.generator.ProgramGeneratorImpl"> |
| <parameter name="repository" value="/tmp/repository"/> |
| <parameter name="auto-reload" value="true"/> |
| </component> |
| |
| <generator name="serverpages" |
| class="org.apache.cocoon.generation.ServerPagesGenerator"/> |
| |
| <!-- |
| <component |
| role="class-loader" |
| class="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl" |
| /> |
| --> |
| |
| <sitemap> |
| <partition> |
| <process uri="simple-page.xsp" source="../samples/documents/simple-page.xsp"> |
| <generator name="serverpages"> |
| <!-- |
| <parameter name="markup-language" value="xsp"/> |
| <parameter name="programming-language" value="java"/> |
| --> |
| </generator> |
| <filter name="xslt"> |
| <parameter name="stylesheet" value="../samples/documents/simple-page.xsl"/> |
| </filter> |
| <serializer name="html"> |
| <parameter name="contentType" value="text/html"/> |
| </serializer> |
| </process> |
| </partition> |
| </sitemap> |
| </pre> |
| |
| |
| |
| </body> |
| </html> |