XSP

XSP stands for Extensible Server Pages,
and is perhaps the most important development coming out of the Cocoon
project. Certainly you, Constant Reader, are familiar with Java Server Pages (
JSP). JSP (in a nutshell) allow tags and inline Java code to be inserted into
an otherwise normal HTML page, and then when the JSP page is requested, the
resulting code is executed and the results are inserted right into the output
HTML.[4] This has taken the Java and ASP worlds by storm,
ostensibly simplifying server-side Java programming and allowing a separation
of output and logic. However, there are still some significant problems.
First, JSP does not really provide a separation of content and presentation.
This is the same problem we have been talking about time and time again;
changes to a banner, the color of a font, and text sizes require the JSP (with
the inline Java and JavaBean references) to be modified. It also mingles
content (pure data) with presentation in the same way static HTML does.
Second, there is no ability to transform the JSP into any other format, or use
it across applications, because the JSP specification is designed primarily
for delivery of output.

XSP remedies both these problems. First, XSP is, at its heart,
simply XML. Take a look at the sample XSP page in Example
9-7.

All XML conventions are followed; for now, think of the xsp:logic element contents as "off-limits" to the XML
parser; we'll discuss that later. Other than that, the entire document is XML
with some new elements. In fact, it references an XSL stylesheet that has
nothing remarkable about it at all, as seen in Example
9-8.

Thus, XSP easily handles the first major problem of JSP: it
allows the separation of content from presentation. This separation allows
developers to handle content generation (as the XSP page can be generated from
a servlet or other Java code as well as being static), while XML and XSL
authors can handle presentation and styling through modification of the XSL
stylesheet applied to the XSP page. Just as easily, XSP solves the other
significant deficiency of JSP: because XSP processing occurs before any
stylesheets are applied, the resultant XML document can be transformed into
any other format. This maintains all the advantages of XML, as the XSP page
can be transferred between applications as well as being used just for
presentation.

Creating an XSP Page

Now that you have had a taste of XSP, let's build our own XSP
page. For this example, let's continue looking at the XML documents we have
already created. We revisit the XML document we constructed earlier. This
document represents a portion of the first chapter of this book, and was
transformed into a PDF document. Instead of simply using this document for
display, let's assume that the author (me!) wants to let his editor view the
document as it is being written. However, in addition to the text of the book,
the editor should be able to see comments from the author that the public
should not see: for example, questions about style and formatting. First,
let's add the comment to the chapterOne.xml file we
built earlier:

... <contents> <chapter id="chapterOne"> <title>Chapter 1: Introduction</title> <paragraph>XML. These three letters have brought shivers to almost every developer in the world today at some point in the last two years. While those shivers were often fear at another acronym to memorize, excitement at the promise of a new technology, or annoyance at another source of confusion for today's developer, they were shivers all the same. Surprisingly, almost every type of response was well merited with regard to XML. It is another acronym to memorize, and in fact brings with it a dizzying array of companions: XSL, XSLT, PI, DTD, XHTML, and more. It also brings with it a huge promise-what Java did for portability of code, XML claims to do for portability of data. Sun has even been touting the rather ambitious slogan"Java + XML = Portable Code + Portable Data" in recent months. And yes, XML does bring with it a significant amount of confusion. We will seek to unravel and demystify XML, without being so abstract and general as to be useless, and without diving in so deeply that this becomes just another droll specification to wade through. This is a book for you, the Java developer, who wants to understand the hype and use the tools that XML brings to the table.</paragraph> <authorComment>Is the formatting of this first paragraph OK? I wonder if we should break this into two separate paragraphs. Let me know what you think, Mike.</authorComment> <paragraph>Today's web application now faces a wealth of problems that were not even considered ten years ago. Systems that are distributed across thousands of miles must perform quickly and flawlessly. Data from heterogeneous systems, databases, directory services, and applications must be transferred without a single decimal place being lost. Applications must be able to communicate not only with other business components, but other business systems altogether, often across companies as well as technologies. Clients are no longer limited to thick clients, but can be web browsers that support HTML, mobile phones that support Wireless Application Protocol (WAP), or handheld organizers with entirely different markup languages altogether. Data, and the transformation of that data, has become the crucial centerpiece of every application being developed today.</paragraph> </chapter> </contents></book>

With this comment now in our XML document, let's add a
corresponding entry into our XSL stylesheet, JavaXML.fo.xsl:

With this new entry, the comments will appear slightly smaller
than the rest of the text, italicized, and in blue. Now let's turn our XML
document into an XSP page (as in Example
9-9) by adding the needed processing instructions for Cocoon, and
surrounding the elements within a new root element, xsp:page.

Before adding XSP logic to determine whether or not to show the
comment, let's build a simple HTML page letting the viewer select whether he
or she is the book's editor. In a real application, this could be a page that
handles authentication and determines a user's role; for our example, it lets
the user select if they are the author, the editor, or just a curious reader,
and enter a password for verification. An HTML page that does this is shown in
Example
9-10. You can save this file as entry.html in your
web server's document root.

Also notice that we submit the HTML form directly to our XSP
page. In this example, our XSP acts similarly to a servlet. We want it to read
the request parameters, determine what user role was selected, authenticate
that role using the password supplied, and finally determine whether we should
show the comment. To begin, let's define aboolean
variable; this variable will hold the result of comparing the request
parameters to see if the user is an author or editor and supplied a correct
password. We then check the value of that variable, and if it is true, display the authorComment element:

<xsp:page language="java" xmlns:xsp="http://www.apache.org/1999/XSP/Core"><book> <cover> <title>Java and XML</title> <author>Brett McLaughlin</author> </cover>... is a book for you, the Java developer, who wants to understand the hype and use the tools that XML brings to the table.</paragraph> <xsp:logic> boolean authorOrEditor = false; // Perform logic to see if user is an author or editor if (authorOrEditor) { <xsp:content> <authorComment>Is the formatting of this first paragraph OK? I wonder if we should break this into two separate paragraphs. Let me know what you think, Mike.</authorComment> </xsp:content> } </xsp:logic> <paragraph>Today&apos;s web application now faces a wealth of problems that were not even considered ten years ago. Systems that are...

This shouldn't look too odd to you; other than the XSP-specific
tags, we're just defining a variable and checking its value. If the variable
evaluates totrue, the authorComment element is added to the XSP page's output;
otherwise, the element is not included in the output. One interesting thing to
note is that we surround the actual XML document output within the xsp:logic block with an xsp:content element (which in turn is within the outer
xsp:page element). This ensures that the XSP
processor does not try to interpret any elements or text within the block as
XSP structures. This again is an improvement to JSP; the same code in JSP
might look like this:

<% if (authorOrEditor) {%> <authorComment> Is the formatting of this first paragraph OK? I wonder if we should break this into two separate paragraphs. Let me know what you think, Mike.</authorComment><% }%>

This is not very structured, as the JSP block ends before the
authorComment element begins; then a new block is
appended after the element, which closes the brackets opened in the first JSP
block. It is very easy to mismatch coding structures or forget to add matching
JSP blocks; the XSP paradigm forces every open element to be closed (standard
XML well-formedness) and one block of code is matched with one element.

With our logical structures in place, we just need to interpret
the request parameters. We use the built-in XSP variable request, which mimics the Servlet HttpServletRequest object. The following code additions
read the value of theuserRole and password request parameters (if they exist); the value is
then compared with the roles that can see the comments (author and editor). If
a match occurs, the password is checked as well. If the password matches the
key for the supplied role, theboolean variable is
set totrue, and the authorComments element is part of the XML output:

Notice that we enclose a good bit of this logic within a CDATA tag. Remember that XSP is still evaluated as XML,
and must follow the rules of an XML document; but the double quotes and
ampersands we use in the Java fragments are not allowed in XML documents;
instead of escaping these characters, and getting a very strange XSP fragment,
we use theCDATA tag so that we can write standard
Java code. Without this, we would have to code as follows:

You can now test out our entry page and the resultant PDF
generated from the XML. You should get output similar to Figure
9-7 if you direct your web browser to
http://<hostname>:<port>/entry.html.

Figure 9-7.Entry HTML page

Select the role of author, and use the password "brett";
otherwise use the editor role with the password "mike." Either case gives you
the PDF output shown in Figure
9-8.

Figure 9-8.Generated PDF with comments showing

The one thing we have not yet done is isolate our logic from our
content. Just as JSP allows inclusion of JavaBeans to abstract the content and
presentation from the logic of an application component, XSP allows tag
libraries to be created. These tag libraries can then allow XML tags to
trigger the matching code within a tag library.

Using XSP Tag Libraries

In addition to showing comments based on the user, we should
indicate that the chapter is in a draft state; additionally, the current date
can be shown to indicate the date of the draft (the intention would be that
the date be frozen when the chapter is considered complete). Instead of adding
inline Java tags to load the current date, we can create a custom tag library
for this purpose. While we are at it, let's look at creating an XSP element
that takes in the chapter number and title and formats the complete title.
This function will handle the insertion of the draft date we have been talking
about. To do this, we first need to create a tag library that is available to
our XSP page. Much of the tag library is based on an XSL stylesheet. We can
start with the skeleton in Example
9-11, which passes anything it receives through as output. Save this
skeleton as JavaXML.xsp.xsl in the XSL/ subdirectory. Be sure to include the JavaXML namespace declaration, as we will use it to match
elements within that namespace used in our XSP pages.

By matching thexsp:page tag, we
ensure that all elements are matched and handled within this stylesheet, or
logicsheet in XSP parlance. We can now add Java
methods for the templates within this logicsheet to call:

Several new XSP elements are introduced here. First, xsp:structure is used to surround several xsp:include statements. These work just like their Java
counterpart,include, by making the specified Java
classes available for use by their unqualified name (rather than the complete
package name). Once these are available, we define and implement two methods:
one that creates a chapter title from the chapter number and textual title,
and one that returns the current date as a formatted String. These methods are available to any elements
within this logicsheet.

We now need to define the element that specifies when an XSP
result should replace an XML element. We have already defined the JavaXML namespace in the document root element, so we use
that as the namespace for our tag library elements. Add the following
template:

When a document with this tag library uses the element JavaXML:draftTitle, the result of the method getTitle( ) will be prepended to a dash (-), and then the returned value of the getDraftDate( ) method will be appended to that result.
TheJavaXML:draftTitle element also expects two
attributes to be declared: the chapter number and the textual title of the
chapter. We signify to the XSP processor that we are calling a defined method
by enclosing the method call within a set of <xsp:expr> tags. To
indicate that the second argument (the chapter title) is a String, we enclose it within quotes. Since the chapter
number should be treated as anint, it is left
without quotation marks.

Once you have completed the XSP logicsheet (available online at
the book's web site as well), you need to make it accessible to Cocoon. This
can be done one of two ways: the first is to specify the location of the file
as a URI, which allows the servlet engine (and therefore Cocoon) to locate the
logicsheet. For example, to add our XSP logicsheet to Cocoon's set of
resources through its URI, you could add the following line to your cocoon.properties file on a Unix-based system:

While this is handy for testing, it is not a very good solution
for uncoupling your logicsheets from the servlet engine, and also adds quite a
bit of maintenance overhead when adding new logicsheets: a new line would have
to be added to the Cocoon properties file for new logicsheets to be
available.[5] An alternative method for loading logicsheets is to
allow specification of a resource in the servlet engine's classpath. This
allows all of your custom logicsheets to be added to a jar file, and that jar file to be
added to the servlet engine classpath. In addition, new logicsheets can be put
within the jar file, providing a central location for
storing your custom XSP logicsheets. From the XSL/
subdirectory in your web server's document root, perform the following command
to create a jar file that contains our logicsheet:

jar cvf logicsheets.jar JavaXML.xsp.xsl

Move the created logicsheets.jar archive
into your <TOMCAT_HOME>/lib/ directory
with the other Cocoon libraries. Now we need to add this library to Tomcat's
class path; edit the tomcat.sh or tomcat.bat file, located in the
<TOMCAT_HOME>/bin/ directory. In Unix, the edited file would look
like this:

CLASSPATH=.# Cocoon classes and librariesCLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/xerces_1_0_3.jarCLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/xalan_0_20_0.jarCLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/fop_0_12_1.jarCLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/cocoon.jarCLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/logicsheets.jarfor i in ${TOMCAT_HOME}/lib/* ; do CLASSPATH=${CLASSPATH}:$idoneCLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar

With our logicsheet available, we can now let Cocoon know where
to look forJavaXML namespace references within XSP
pages. Edit the cocoon.properties file you earlier put
in the<TOMCAT_HOME>/conf/ directory. Locate the section that lists the
various Cocoon XSP resources, and add the new logicsheet reference:

Because our logicsheet is not nested within any subdirectories
in the logicsheets.jar file, we simply use the name of
the logicsheet as its resource path. Finally, you will need to restart the
servlet engine. This will reload the cocoon.properties
file, and the logicsheet will be available for use. As the Cocoon engine is
used to handle requests, any XSP page that declares that it uses the JavaXML will have available to it the logicsheet
specified as theJavaXML library. So our XSP page
needs to add a namespace declaration for the JavaXML namespace:

We replace the hardcoded chapter title with the element defined
in our tag library. This should generate the title with the chapter number,
chapter title, and the date of the draft. Accessing this new version of our
XSP page results in the output shown in Figure
9-9.

Figure 9-9.Output of XSP using a tag library

Certainly these are simple examples, and we have only scratched
the surface of what XSP allows. Even this simple example allows the title to
be converted to a different form when the chapter is complete, without
modifying the content or presentation of the page, but only the XSP
logicsheet. In the same way, XSP allows the creation of very strict contracts
separating presentation from content from application logic. Adding
server-side Java components such as Enterprise JavaBeans can bring business
logic into the equation. Rather than using a less flexible solution like JSP
that is coupled to HTML and a presentation format, using XSP allows a looser
coupling of components and thus a better solution for application development.
XSP also promises to be key in the upcoming version of Cocoon, Cocoon 2.0,
which we look at now.