ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Java and XML: Web Publishing Frameworks
Pages: 1, 2, 3, 4, 5, 6, 7, 8

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.

Example 9-7: Sample XSP Page

<?xml version="1.0"?>
<?cocoon-process type="xsp"?>
<?cocoon-process type="xslt"?>
<?xml-stylesheet href="myStylesheet.xsl" type="text/xsl"?>
 
<xsp:page language="java" 
          xmlns:xsp="http://www.apache.org/1999/XSP/Core"
>
  
 <xsp:logic>
  private static int numHits = 0; 
  
  private synchronized int getNumHits(  ) { 
   return ++numHits; 
  }
 </xsp:logic>
 
 <page>
  <title>Hit Counter</title>
  
  <p>I've been requested <xsp:expr>getNumHits(  )</xsp:expr> times.</p>
 </page>
</xsp:page>

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.

Example 9-8: XSL Stylesheet for Example 9-7

<?xml version="1.0"?>
 
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
>
 
  <xsl:template match="page">
    <xsl:processing-instruction name="cocoon-format">
      type="text/html"
    </xsl:processing-instruction>
    <html>
      <head>
        <title><xsl:value-of select="title"/></title>
      </head>
      <body>
        <xsl:apply-templates select="*[not(self::title)]" />
      </body>
    </html>
  </xsl:template>
 
  <xsl:template match="p">
    <p align="center">
      <xsl:apply-templates />
    </p>
  </xsl:template>
 
</xsl:stylesheet>

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:

<xsl:template match="paragraph">
  <fo:block font-size="12pt" space-before.optimum="12pt" 
            text-align="justified">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>
 
<xsl:template match="authorComment">
  <fo:block font-size="10pt" font-style="italic" color="blue" 
            space-before.optimum="12pt" 
            text-align="justified">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

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.

Example 9-9: XSP Version of Example 9-1

<?xml version="1.0"?>
 
<?cocoon-process type="xsp"?>
<?cocoon-process type="xslt"?>
<?xml-stylesheet href="XSL/JavaXML.fo.xsl" type="text/xsl"?>
 
<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>
 
  <!-- Content of Chapter -->
 
</book>
</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.

Example 9-10: HTML Frontend for User to Select a "Role"

<html>
 <head>
  <title>Welcome to the Java and XML Book in Progress</title>
 </head>
 
 <body>
  <h1 align="center"><i>Java and XML</i> Book in Progress</h2>
  <center>
   <form action="/chapterOne.xml" method="POST">
    Select your role:
    <select name="userRole">
     <option value="author">I'm the Author</option>
     <option value="editor">I'm the Editor</option>
     <option value="reader">I'm a Reader</option>
    </select>
    <br />
    Enter your password:
    <input type="password" name="password" size="8" />
    <br /><br />
    <input type="submit" value="Take me to the Book!" />
   </form>
  </center>
 </body>
</html>

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:

<xsp:logic>
 boolean authorOrEditor = false;
 
 // Perform logic to see if user is an author or editor
 <![CDATA[
 String[] roleValues = request.getParameterValues("userRole");
 String[] passwordValues = request.getParameterValues("password");
 if ((roleValues != null) && (passwordValues != null)) {
   String userRole = roleValues[0];
   String password = passwordValues[0];
   if (userRole.equals("author") && password.equals("brett")) {
     authorOrEditor = true;
   } else
   if (userRole.equals("editor") && password.equals("mike")) {
     authorOrEditor = true;
   }
 ]]>
 }
 
 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>

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:

<xsp:logic>
 boolean authorOrEditor = false;
 
 String[] roleValues = 
   request.getParameterValues(&quot;userRole&quot;);
 String[] passwordValues = 
   request.getParameterValues(&quot;password&quot;);
 if ((roleValues != null) &amp;&amp; 
     (passwordValues != null)) {
   String userRole = roleValues[0];
   String password = passwordValues[0];
   if (userRole.equals("author") &amp;&amp; 
       password.equals("brett")) {
     authorOrEditor = true;
   } else
   if (userRole.equals("editor") &amp;&amp; 
       password.equals("mike")) {
     authorOrEditor = true;
   }
 }
...
</xsp:logic>

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

Figure 9-7

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

Figure 9-8

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.

Example 9-11: XSP Logicsheet

<?xml version="1.0"?>
 
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsp="http://www.apache.org/1999/XSP/Core"
  xmlns:JavaXML="http://www.oreilly.com/catalog/javaxml/"
>
  <xsl:template match="xsp:page">
    <xsp:page>
      <xsl:copy>
        <xsl:apply-templates select="@*"/>
      </xsl:copy>
 
      <xsl:apply-templates/>
    </xsp:page>
  </xsl:template>
 
  <xsl:template match="@*|*|text()|processing-instruction(  )">
    <xsl:copy>
      <xsl:apply-templates 
           select="@*|*|text()|processing-instruction(  )"/>
    </xsl:copy>
  </xsl:template>
 
</xsl:stylesheet>

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:

<xsl:template match="xsp:page">
  <xsp:page>
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
    </xsl:copy>
 
    <xsp:structure>
      <xsp:include>java.util.Date</xsp:include>
      <xsp:include>java.text.SimpleDateFormat</xsp:include>
    </xsp:structure>
 
    <xsp:logic>
      private String getDraftDate(  ) {
        return (new SimpleDateFormat("MM/dd/yyyy"))
          .format(new Date(  ));
      }
 
      private String getTitle(int chapterNum, String chapterTitle) {
        return "Chapter " + chapterNum + ": " + chapterTitle;
      }
    </xsp:logic>
 
    <xsl:apply-templates/>
  </xsp:page>
</xsl:template>

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:

<!-- Create formatted title -->
<xsl:template match="JavaXML:draftTitle">
  <xsp:expr>getTitle(<xsl:value-of select="@chapterNum" />,
                     "<xsl:value-of select="@chapterTitle" />")
  </xsp:expr> - <xsp:expr>getDraftDate(  )</xsp:expr>
</xsl:template>
 
<xsl:template match="@*|*|text()|processing-instruction(  )">
  <xsl:copy>
    <xsl:apply-templates 
         select="@*|*|text()|processing-instruction(  )"/>
  </xsl:copy>
</xsl: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:

processor.xsp.library.context.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/context.xsl
processor.xsp.library.cookie.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/cookie.xsl
processor.xsp.library.global.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/global.xsl
processor.xsp.library.request.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/request.xsl
processor.xsp.library.response.java =
  resource://org/apache/cocoon/processor/xsp/library/java/response.xsl
processor.xsp.library.session.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/session.xsl
processor.xsp.library.util.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/util.xsl
 
processor.xsp.library.JavaXML.java = 
  file:///usr/local/jakarta-tomcat/webapps/ROOT/XSL/JavaXML.xsp.xsl

For Windows systems, this would be:

processor.xsp.library.context.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/context.xsl
processor.xsp.library.cookie.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/cookie.xsl
processor.xsp.library.global.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/global.xsl
processor.xsp.library.request.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/request.xsl
processor.xsp.library.response.java =
  resource://org/apache/cocoon/processor/xsp/library/java/response.xsl
processor.xsp.library.session.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/session.xsl
processor.xsp.library.util.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/util.xsl
 
processor.xsp.library.JavaXML.java = 
  file:///C:/java/jakarta-tomcat/webapps/ROOT/XSL/JavaXML.xsp.xsl

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 libraries
CLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/xerces_1_0_3.jar
CLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/xalan_0_20_0.jar
CLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/fop_0_12_1.jar
CLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/cocoon.jar
CLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/logicsheets.jar
 
for i in ${TOMCAT_HOME}/lib/* ; do
  CLASSPATH=${CLASSPATH}:$i
done
 
CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar

And on Windows:

set CLASSPATH=.
set CLASSPATH=%TOMCAT_HOME%\classes
 
rem Cocoon classes and libraries
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\xerces_1_0_3.jar
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\xalan_1_0_0.jar
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\fop_0_12_1.jar
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\cocoon.jar
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\logicsheets.jar
 
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\webserver.jar
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\jasper.jar
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\xml.jar
set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\servlet.jar
set CLASSPATH=%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:

processor.xsp.library.context.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/context.xsl
processor.xsp.library.cookie.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/cookie.xsl
processor.xsp.library.global.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/global.xsl
processor.xsp.library.request.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/request.xsl
processor.xsp.library.response.java =
  resource://org/apache/cocoon/processor/xsp/library/java/response.xsl
processor.xsp.library.session.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/session.xsl
processor.xsp.library.util.java = 
  resource://org/apache/cocoon/processor/xsp/library/java/util.xsl
 
processor.xsp.logicsheet.JavaXML.java = resource://JavaXML.xsp.xsl

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:

<?xml version="1.0"?>
 
<?cocoon-process type="xsp"?>
<?cocoon-process type="xslt"?>
<?xml-stylesheet href="XSL/JavaXML.fo.xsl" type="text/xsl"?>
 
<xsp:page 
  language="java" 
  xmlns:xsp="http://www.apache.org/1999/XSP/Core"
  xmlns:JavaXML="http://www.oreilly.com/catalog/javaxml/"
>
<book>
...

With the tag library now available for use, we can finally add in theJavaXML:draftTitle element to our XML document, chapterOne.xml :

<contents>
  <chapter id="chapterOne">
    <title>
      <JavaXML:draftTitle chapterNum="1" 
                          chapterTitle="Introduction" 
      />
    </title>

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

Figure 9-9

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.

Pages: 1, 2, 3, 4, 5, 6, 7, 8

Next Pagearrow