xml-general mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@locus.apache.org
Subject cvs commit: xml-site/sources/cocoon ldapprocessor-sbk.xml xspprocessor-sbk.xml
Date Tue, 18 Jan 2000 16:56:36 GMT
stefano     00/01/18 08:56:35

  Added:       sources/cocoon ldapprocessor-sbk.xml xspprocessor-sbk.xml
  Log:
  new files
  
  Revision  Changes    Path
  1.1                  xml-site/sources/cocoon/ldapprocessor-sbk.xml
  
  Index: ldapprocessor-sbk.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <s1 title="LDAP Processor">
  	
  	
  		<s2 title="Description">
  			<p>LdapProcessor is a processor for Cocoon that performs LDAP queries, translates the resultset into an XML fragment, and inserts the fragment in the original document.The Ldap Processor was written for a project where I work, and carried back over into the Cocoon project.  </p>
  		</s2>
  		<s2 title="Installation">
  			<p>Check your cocoon.properties for this line and add it if it's not already there:</p>
  			<source>processor.type.ldap = org.apache.cocoon.processor.ldap.LdapProcessor</source>
  		</s2>
  		<s2 title="Configuration">
  			<p>Add this PI to the XML files to which you wish to add LDAP queries:</p>
  			<source>&lt;?cocoon:process type="ldap"?&gt;</source>
  			<p>You probably want this before any "xslt" processing directives. Then add LDAP connection information to your XML files. The tagset for LDAP server defitions looks like this:</p>
  			<source>&lt;ldap-defs&gt;
   &lt;ldap-server name=foo_server"&gt;
    &lt;initializer&gt;com.sun.jndi.ldap.LdapCtxFactory&lt;/initializer&gt;
    &lt;ldap-serverurl&gt;ldap://ldap.weber.edu&lt;/ldap-serverurl&gt;
   &lt;/ldap-server&gt;
  &lt;/ldap-defs&gt;
  </source>
  			<p>This tagset will be removed from the document after processing.</p>
  			<p>In addition to the ldap-server element, you can also have querydefs tags in your ldap-defs node. A ldap-defs node must have a unique name attribute. ldap-query tags (described below) may reference a querydefs tag in their defs attribute, which causes the ldap-query tag's attributes to default to the attributes of the querydefs tag. This is useful for setting commonly used groups of attributes. You may also specify a default querydefs. Here is an example:</p>
  			<source>&lt;querydefs name="standard" doc-element="options" 
    row-element="option" server="foo"/&gt;
  &lt;query defs="standard"/&gt;</source>
  			<p>is equivalent to</p>
  			<source>&lt;ldap-query doc-element="options" row-element="option" connection="foo"/&gt;</source>
  			<p>You can also flag a querydefs node as the default for all query tags by setting the default attribute to yes. Note that ldap-query tags can always override the defaults.</p>
  		</s2>
  		<s2 title="Usage">
  			<p>Add LDAP queries to your XML files. The tagset looks like this:</p>
  			<source>&lt;ldap-query server="foo_server"&gt;
   sn=*Green*
  &lt;/ldap-query&gt;</source>
  			<p>This will be replaced by a tagset that looks something like this:</p>
  			<source>&lt;ldapsearch&gt;
   &lt;searchresult ID="CN=DGREEN,OU=TBE,OU=AST,OU=ACAD,O=WSU"&gt;
    &lt;telephonenumber&gt;801-626-6821&lt;/telephonenumber&gt;
    &lt;facsimiletelephonenumber&gt;801-626-6650&lt;/facsimiletelephonenumber&gt;
    &lt;title&gt;PROFESSOR/TELECOMMUNICATIONS AND BUSINESS EDUCATION&lt;/title&gt;
    &lt;givenname&gt;Diana&lt;/givenname&gt;
    &lt;sn&gt;Green&lt;/sn&gt;
    &lt;l&gt;B2 218&lt;/l&gt;
    &lt;ou&gt;TELECOM &amp; BUSINESS ED &lt;/ou&gt;
    &lt;mail&gt;DGREEN@weber.edu&lt;/mail&gt;
    &lt;initials&gt;J&lt;/initials&gt;
    &lt;cn&gt;DGREEN&lt;/cn&gt;
    &lt;objectclass&gt;newPilotPerson&lt;/objectclass&gt;
    &lt;objectclass&gt;organizationalPerson&lt;/objectclass&gt;
    &lt;objectclass&gt;person&lt;/objectclass&gt;
    &lt;objectclass&gt;top&lt;/objectclass&gt;
   &lt;/searchresult&gt;
  &lt;/ldapsearch&gt;</source>
  			<p>You can also have the LdapProcessor substitute values from the servlet request into your query. The syntax for that is:</p>
  			<source>&lt;ldap-query name="foo_server"&gt;
   sn=*{@name}*
  &lt;/ldap-query&gt;</source>
  			<p>This is, of course, highly configurable by setting attributes of the query tag. A partial list of attributes is:</p>
  			<ul>
  				<li><em>doc-element</em> - The tag with which to wrap the whole shebang. Default is ldapresults. If an empty string is specified, e.g. doc-element="", the whole shebang will not be wrapped.</li>
  				
  				<li><em>row-element</em> - The tag with which to wrap each row. Default is searchresult. Same deal as with doc-element.</li>
  				
  				<li><em>id-attribute</em> - What is the name of the attribute that uniquely identifies the rows? Default is ID. This is, of course, meaningless if row-element is set to an empty string.</li>
  				
  				<li><em>variable-left-delimiter</em> - What string delimits variables in the query on the left side? Default is {@.</li>
  				
  				<li><em>variable-right-delimiter</em> - What string delimits variables in the query on the right side? Default is }.</li>
  				
  			</ul>
  		</s2>
  		<s2 title="Error Handling">
  			<p>In a perfect world, nothing would ever go wrong in your queries but this is not a perfect world. In our world, you can check for Exceptions in your stylesheets and present them to your users in a nice way. The tags used to render the error are configurable using attributes from the query tag. The attributes in question are:</p>
  			<ul>
  				<li><em>error-element</em> - The name of the error-element to create, default is error.</li>
  				
  				<li><em>error-message-attribute</em> - The name of the attribute of the error-element in which to put the Exception's message. Default is message.</li>
  				
  				<li><em>error-message-element</em> - The name of the child element of the error-element in which to put the Exception's message. The default is to not do so.</li>
  				
  				<li><em>error-stacktrace-attribute</em> - The name of the attribute of the error-element in which to put the Exception's stacktrace. The default is to not do so.</li>
  				
  				<li><em>error-stacktrace-element</em> - The name of the child element of the error-element in which to put the Exception's stacktrace. The default is to not do so.</li>
  				
  				<li><em>error-message-text</em> - The text to pass out as an error message instead of the Exception's own message. This is useful for displaying user friendly error messages. The default is to use the Exception's message.</li>
  				
  			</ul>
  			<p>So by default, when an Exception occurs, the processor generates this XML:</p>
  			<source>&lt;error message="The server is on fire."/&gt;</source>
  		</s2>
  		<s2 title="Notes and Disclaimers">
  			<p>The LdapProcessor was written borrowing a lot of ideas and code form Donald Ball's SQLProcessor.  Any similarity to his code is purely intended...:)  Thanks to Donald for writing good, clean code, and being a good sport about me plagerizing in the name of ultimate 'code re-use'.</p>
  		</s2>
  		<s2 title="Planned Features">
  			<ul>
  				<li>support for different context paramaters such as authtype, protocol, and principal.</li>
  				<li>the ability to retrieve binary objects such as certificates and images.</li>
  				<li>the ability to add different Contols such as a SortContorl for server side sorting.</li>
  			</ul>
  		</s2>
  	
  </s1>
  
  
  1.1                  xml-site/sources/cocoon/xspprocessor-sbk.xml
  
  Index: xspprocessor-sbk.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <s1 title="XSP Processor">
    
  
    
      <s2 title="Introduction">
        <p>
          <ref>XSP</ref>
           (<jump href="http://xml.apache.org/cocoon/xsp.html">eXtensible Server Pages</jump>)
          is Cocoon's technology for building web applications based on dynamic
          XML content.
        </p>
  
        <p>
          Beyond static content (i. e., hand-written documents produced
          by web authors), web applications demand <ref>dynamic content
          generation</ref> capabilities, where XML documents or fragments
          are programmatically produced at request time.
        </p>
  
        <p>
          In this context, content is the result of computations based on request
          parameters and, often, on access to external data sources such as
          databases or remote server processes.
        </p>
  
        <p>
          This distinction in content origin extends the "traditional"
          regions of web publishing (<ref>content</ref> and <ref>presentation</ref>)
          to also encompass that of <ref>logic</ref>.
        </p>
  
        <p>
          Dynamic web content generation has traditionally been addressed by
          embedding procedural code into otherwise static markup.
        </p>
  
        <p>
          This approach is fully supported by XSP. Consider the following example:
        </p>
  
        <source>. . .
  &lt;p&gt;
    Good
    &lt;xsp:logic&gt;
      String timeOfDay = (
        new SimpleDateFormat("aa")
      ).format(new Date());
  
      if (timeOfDay.equals("AM")) {
        &lt;xsp:content&gt;Morning&lt;/xsp:content&gt;
      } else {
        &lt;xsp:content&gt;Afternoon&lt;/xsp:content&gt;
      }
    &lt;/xsp:logic&gt;!
  &lt;/p&gt;
  . . .</source>
  
        <p>
          Upon XSP processing, this XML fragment will yield:
        </p>
  
        <source>&lt;p&gt;Good Morning!&lt;/p&gt;</source>
  
        <p>
          before noon and:
        </p>
  
        <source>&lt;p&gt;Good Afternoon!&lt;/p&gt;</source>
  
        <p>
          afterwards.
        </p>
  
        <p>
          While the above may appear simple (to a Java developer,
          that is!), XSP has been conceived to allow web authors
          to generate dynamic content without forcing them to learn
          a programming language.
        </p>
  
        <p>
          Thus, XSP allows us to rephrase our example as:
        </p>
  
        <source>...
  &lt;p&gt;Good &lt;util:time-of-day/&gt;!&lt;/p&gt;
  ...</source>
  
        <p>
          where <code>&lt;util:time-of-day/&gt;</code> is a
          <ref>library tag</ref> encapsulating dynamic content
          in a simple, transparent way.
        </p>
  
        <p>
          This feature promotes an ideal division of labor
          where:
        </p>
  
        <ul>
          <li>
            <ref>Application Developers</ref> encapsulate application
            logic in a consistent, intuitive dynamic tagset
          </li>
          <li>
            <ref>Content authors</ref> use an application-oriented
            markup vocabulary (augmented with dynamic tags) to
            produce XML documents
          </li>
          <li>
            <ref>Presentation designers</ref> write XSLT stylesheets
            to render the resulting content as visually appealing web
            pages
          </li>
        </ul>
  
        <p>
          Of course, for those of us subject to "real world" constraints,
          XSP also supports the time-honored approach of first using
          embedded logic and then incrementally evolving the resulting
          pages into a well-structured web application.
        </p>
  
        <p>
          These concepts are illustrated in the XSP Samples included in the
          distribution.
        </p>
  
      </s2>
  
      <s2 title="What is an XSP Page?">
        <p>
          An XSP page is a Cocoon XML document containing tag-based
          directives that specify how to generate dynamic content
          at request time.
        </p>
  
        <p>
          Upon Cocoon processing, these directives are replaced by
          generated content so that the resulting, augmented XML
          document can be subject to further processing (typically
          an XSLT transformation)
        </p>
  
        <p>
          XSP pages are transformed into Cocoon <ref>producers</ref>,
          typically as Java classes, though any scripting language
          for which a Java-based processor exists could also be used.
        </p>
  
        <p>
          Directives can be either XSP built-in processing tags or
          user-defined library tags.
          XSP built-in tags are used to embed procedural logic,
          substitute expressions and dynamically build XML nodes.
          User-defined library tags act as templates that dictate
          how program code is generated from information encoded in
          each dynamic tag.
        </p>
      </s2>
  
      <s2 title="A Simple Example: Embedded Logic">
        <p>
          In the following XSP page, the Java language is used to
          generate some dynamic content:
        </p>
  
        <source>&lt;?xml version="1.0"?&gt;
  &lt;?cocoon-process type="xsp"?&gt;
  &lt;?cocoon-process type="xslt"?&gt;
  &lt;?xml-stylesheet href="sample.xsl" type="text/xsl"?&gt;
  
  &lt;xsp:page language="java" xmlns:xsp="http://www.apache.org/1999/XSP/Core"&gt;
    &lt;page title="Time of Day"&gt;
    
      &lt;xsp:logic&gt;
        // Define a variable to hold the time of day
        Date now = new Date();
      &lt;/xsp:logic&gt;
    
      &lt;p&gt;
        To the best of my knowledge, it's now
        &lt;!-- Substitute time of day here --&gt;
        &lt;xsp:expr&gt;now&lt;/xsp:expr&gt;
      &lt;/p&gt;
    &lt;/page&gt;
  &lt;/xsp:page&gt;</source>
  
        <p>
          Upon Cocoon processing, this page should yield something
          like:
        </p>
  
        <source>&lt;html&gt;
  &lt;head&gt;&lt;title&gt;Time of Day&lt;/title&gt;&lt;/head&gt;
  &lt;body&gt;
    &lt;h3 style="color: navy; text-align: center"&gt;Time of Day&lt;/h3&gt;
    &lt;p&gt;It's now Thu Dec 23 20:11:18 PST 1999&lt;/p&gt;
  &lt;/body&gt;
  &lt;/html&gt;</source>
  
        <p>
          Let's dissect this example:
        </p>
  
        <s3 title="The XSP Processing Instruction">
          <p>
            Two processing instructions are used in our example
            to control how Cocoon processes its XML content:
          </p>
  
          <ul>
            <li>
              <code>&lt;?cocoon-process type="xsp"?&gt;</code><br/>
              instructs Cocoon to generate a program (a 
              <ref>producer</ref>) that rebuilds the static portions
              of the document as augmented by the embedded logic
            </li>
            <li>
              <code>&lt;?cocoon-process type="xslt"?&gt;</code><br/>
              <code>&lt;?xml-stylesheet href="sample.xsl" type="text/xsl"?&gt;</code><br/>
              instructs Cocoon to apply the sample.xsl XSLT stylesheet to
              the XML tree resulting from executing the generated
              XSP producer program
            </li>
          </ul>
  
          <p>
            Note that it is <ref>not</ref> mandatory for an XSP page to
            be further processed by XSLT. Any (or none) other Cocoon XML
            processing step(s) may be subsequently applied depending on
            application requeriments.
          </p>
        </s3>
  
        <s3 title="The XSP Namespace">
          <p>
            All XSP directives belong to the <code>&lt;xsp:&gt;</code>
            namespace.
          </p>
  
          <p>
            Also, XSP pages are <ref>required</ref> to have an
            <code>&lt;xsp:page&gt;</code> root element:
          </p>
  
          <source>&lt;xsp:page language="java" xmlns:xsp="http://www.apache.org/1999/XSP/Core"&gt;</source>
  
          <p>
            The <code>&lt;xsp:page&gt;</code> root element can specify
            the programming language used in the XSP page by means of
            the <code>language</code> attribute. If this attribute is
            omitted, <ref>java</ref> will be used.
          </p>
  
          <p>
            The root element must also specify the XSP namespace URL
            by means of the <code>xmlns:</code> attribute. As will be
            explained later, this attribute is also used to introduce
            user-supplied tag libraries.
          </p>
  
          <p>
            Finaly, the XSP root element must contain <ref>only one</ref>
            non-XSP nested element. Such element (<code>&lt;page&gt;</code>
            in the above example) will become the root element of the
            generated document.
          </p>
        </s3>
  
        <s3 title="The Logic Tags">
          <p>
            In our example, the "user" root element contains:
          </p>
  
          <source>&lt;page title="Time of Day"&gt;
      &lt;xsp:logic&gt;
        // Define a variable to hold the time of day
        Date now = new Date();
      &lt;/xsp:logic&gt;
      &lt;p&gt;
        To the best of my knowledge, it's now
        &lt;!-- Substitute time of day here --&gt;
        &lt;xsp:expr&gt;now&lt;/xsp:expr&gt;
      &lt;/p&gt;
    &lt;/page&gt;</source>
  
          <p>
            Here, we use the two essential XSP logic tags:
          </p>
  
          <ul>
            <li>
              <code>&lt;xsp:logic&gt;</code>. This tag encloses
              developer-supplied program logic. Such logic will be
              transcribed verbatim into the generated Cocoon
              producer.
            </li>
            <li>
              <code>&lt;xsp:expr&gt;</code>. This tag evaluates
              a program expression and substitutes its value as
              a <code>Text</code> DOM node in the resulting
              document.
            </li>
          </ul>
  
          <p>
            In the fragment:
          </p>
  
          <source>&lt;xsp:logic&gt;
    // Define a variable to hold the time of day
    Date now = new Date();
  &lt;/xsp:logic&gt;</source>
  
          <p>
            a new variable (<code>now</code>) is declared that can
            be subsequently referenced anywhere in the remaining
            page content.
          </p>
  
          <p>
            Note that, in this particular example, it's not necessary
            to fully specify the Java type (<code>java.util.Date</code>)
            because XSP automatically generates <code>import</code>
            statements for the most commonly used Java libraries.
          </p>
  
          <p>
            In the fragment:
          </p>
  
          <source>&lt;!-- Substitute time of day here --&gt;
  &lt;xsp:expr&gt;now&lt;/xsp:expr&gt;</source>
  
          <p>
            the variable <code>now</code> is referenced so that its
            value is inlined in the resulting XML document as a
            <code>Text</code> node.
          </p>
  
          <p>
            Note also that it's not necessary to explicitly cast
            <code>now</code> to <code>String</code>.
            <code>&lt;xsp:expr&gt;</code> takes care
            of converting all Java types so that values are properly
            converted depending on context.
          </p>
  
          <p>
            In general, <code>&lt;xsp:expr&gt;</code> values are inlined
            according to the following rules:
          </p>
  
          <ul>
            <li>
              Primitive Java types (<code>int</code>, <code>long</code>,
              etc) are converted to their <code>String</code> representation
              and wrapped as <code>Text</code>
            </li>
            <li>
              Java objects are wrapped as follows:
                <ul>
                  <li>
                    <code>String</code>s are directly wrapped as
                    <code>Text</code>
                  </li>
                  <li>
                    Arrays are wrapped as <code>DocumentFragments</code>
                    and each element is recursively applied these same
                    transformation rules.
                  </li>
                  <li>
                    Non-string objects are converted to <code>String</code>
                    (by means of their <code>toString</code> method)
                    and subsquently wrapped as <code>Text</code>.
                    Note that some types may not provide a suitable
                    string representation, so they may require a
                    more elaborate expression
                  </li>
                </ul>
            </li>
          </ul>
  
          <p>
            A nice XSP feature (not present in other server pages
            technologies) is that the <code>&lt;xsp:logic&gt;</code>
            element allows for the arbitrary nesting of other markup
            without the need to "prematurely" close it. For example:
          </p>
  
          <source>&lt;table&gt;
    &lt;xsp:logic&gt;
      for (int i = 0; i &amp;lt; countries.length; i++) {
        &lt;tr&gt;
          &lt;td&gt;
            &lt;xsp:expr&gt;countries[i].getName()&lt;/xsp:expr&gt;
          &lt;/td&gt;
          &lt;td&gt;
            &lt;xsp:expr&gt;countries[i].getCurrency()&lt;/xsp:expr&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
      }
    &lt;/table&gt;
  &lt;/xsp:logic&gt;</source>
  
          <p>
            If such nesting was not allowed, the purely programmatic
            alternative would be considerably more complex:
          </p>
  
          <source>
  &lt;table&gt;
    &lt;xsp:logic&gt;
      for (int i = 0; i &amp;lt; countries.length; i++) {
        // &lt;tr&gt;
        xspParentNode = xspCurrentNode;
        xspNodeStack.push(xspParentNode);
        xspCurrentNode = document.createElement("tr");
        xspParentNode.appendChild(xspCurrentNode);
  
        // &lt;td&gt;name&lt;/td&gt;
        xspParentNode = xspCurrentNode;
        xspNodeStack.push(xspParentNode);
        xspCurrentNode = document.createElement("td");
        xspParentNode.appendChild(xspCurrentNode);
        xspCurrentNode.appendChild(
          document.createTextNode(countries[i].getName())
        );
        xspCurrentNode = (Node) xspNodeStack.pop();
  
        // &lt;td&gt;currency&lt;/td&gt;
        xspParentNode = xspCurrentNode;
        xspNodeStack.push(xspParentNode);
        xspCurrentNode = document.createElement("td");
        xspParentNode.appendChild(xspCurrentNode);
        xspCurrentNode.appendChild(
          document.createTextNode(countries[i].getCurrency())
        );
        xspCurrentNode = (Node) xspNodeStack.pop();
  
        // &lt;/tr&gt;
        xspCurrentNode = (Node) xspNodeStack.pop();
      }
    &lt;/xsp:logic&gt;
  &lt;/table&gt;
  </source>
  
  	<p>
  	  Note, however, that it is <ref>not</ref> allowed to nest 
            <code>&lt;xsp:expr&gt;</code> tags directly inside
            <code>&lt;xsp:logic&gt;</code>. For an expression
  	  to be inlined inside an <code>&lt;xsp:logic&gt;</code>
  	  element, it must be escaped by surrounding it with an
            <code>&lt;xsp:content&gt;</code> tag. Example:
  	</p>
  
  	<source>
  &lt;xsp:logic&gt;
    for (int i = 0; i &amp;lt; parameterValues.length; i++) {
      &lt;xsp:content&gt;
        &lt;xsp:expr&gt;parameterValues[i]&lt;/xsp:expr&gt;
      &lt;/xsp:content&gt;
      &lt;br/&gt;
    }
  &lt;/xsp:logic&gt;
  </source>
  
          <p>
            The observant reader may have noticed a rather
            unpleasant feature in the above code: the
            <ref>less-than</ref> sign (<code>&lt;</code>)
            must be represented as <code>&amp;lt;</code>!
          </p>
  
          <p>
            This is an undesirable (but unavoidable) consequence
            of the <code>&lt;</code> and <code>&amp;</code>
            characters being special to XML parsers.
          </p>
  
          <p>
            A workaround is to escape code chunks contaning the
            <ref>less-than</ref> (<code>&lt;</code>) and
            <ref>ampersand</ref> (<code>&amp;</code>) characters as
            <ref>CDATA</ref> sections:
          </p>
  
          <source>&lt;table&gt;
    &lt;xsp:logic&gt;&lt;![CDATA[
      for (int i = 0; i &lt; countries.length; i++)]]&gt;
        &lt;tr&gt;
         . . .
        &lt;/tr&gt;
      }
    &lt;/table&gt;
  &lt;/xsp:logic&gt;</source>
  
          <p>
            Caution must be exercised, though, to avoid enclosing
            static markup inside the <code>&lt;![CDATA]]&gt;</code>
            section, as this will result in syntax errors upon
            compiling the generated Cocoon producer!
          </p>
        </s3>
  
      </s2>
  
      <s2 title="Another Example: Tag Libraries">
        <p>
          In the following example, a developer-supplied <ref>tag
          library</ref> is used instead of embedding procedural code:
        </p>
  
        <source>&lt;?xml version="1.0"?&gt;
  &lt;?cocoon-process type="xsp"?&gt;
  &lt;?cocoon-process type="xslt"?&gt;
  &lt;?xml-stylesheet href="sample.xsl" type="text/xsl"?&gt;
  
  &lt;xsp:page
    language="java"
    xmlns:xsp="http://www.apache.org/1999/XSP/Core"
    xmlns:example="http://www.plenix.com/DTD/XSP/Example"
  &gt;
    &lt;page title="Time of Day"&gt;
      &lt;p&gt;
        To the best of my knowledge, it's now
        &lt;!-- Substitute time of day here --&gt;
        &lt;example:time-of-day format="yy/MM/dd hh:mm:ss aa"/&gt;
      &lt;/p&gt;
    &lt;/page&gt;
  &lt;/xsp:page&gt;</source>
  
        <p>
          Here, the web author is shielded from programming
          complexities at the expense of additional developer
          effort in devising and implementing a proper dynamic
          tagset.
        </p>
  
        <p>
          As mentioned early, this is the "ideal" XSP scenario:
          dynamic content generation requirements are identified
          before hand and represented in reusable tag libraries.
          Web authors can then focus on their their "true"
          purpose in life: producing content.
        </p>
  
        <p>
          XSP uses XSLT stylesheets for source code generation.
          Thus, each dynamic tag in a library is supported by an
          XSLT template containing the program logic to be
          generated. Upon execution, generated logic will yield
          the dynamic content encoded by its underlying dynamic
          tag.
        </p>
  
        <p>
          Without yet delving into the finer details of the XSP
          object model, let's see how the <ref>example</ref> tag
          library stylesheet looks like:
        </p>
  
        <source>&lt;?xml version="1.0"?&gt;
  &lt;xsl:stylesheet
    xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
    xmlns:xsp="http://www.apache.org/1999/XSP/Core"
    xmlns:example="http://www.plenix.com/DTD/XSP/Example"
  &gt;
    &lt;xsl:template match="xsp:page"&gt;
      &lt;xsp:page&gt;
        &lt;xsl:copy&gt;
          &lt;xsl:apply-templates select="@*"/&gt;
        &lt;/xsl:copy&gt;
        &lt;xsp:structure&gt;
          &lt;xsp:include&gt;java.util.Date&lt;/xsp:include&gt;
          &lt;xsp:include&gt;java.text.SimpleDateFormat&lt;/xsp:include&gt;
        &lt;/xsp:structure&gt;
        &lt;xsp:logic&gt;
          /* "Example" Class Level Logic */
          private static String formatDate(Date date, String pattern) {
            if (pattern == null || pattern.length() == 0) {
              pattern = "yyyy/MM/dd hh:mm:ss aa";
            }
            return (new SimpleDateFormat(pattern)).format(date);
          }
        &lt;/xsp:logic&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/xsp:page&gt;
    &lt;/xsl:template&gt;
    &lt;xsl:template match="example:time-of-day"&gt;
      &lt;xsp:expr&gt;
        formatDate(new Date(), "&lt;xsl:value-of select="@format"/&gt;")
      &lt;/xsp:expr&gt;
    &lt;/xsl:template&gt;
    &lt;xsl:template match="@*|node()" priority="-1"&gt;
      &lt;xsl:copy&gt;&lt;xsl:apply-templates select="@*|node()"/&gt;&lt;/xsl:copy&gt;
    &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;</source>
  
        <p>
          Let's focus our attention on 4 key features of
          this library:
        </p>
  
        <ul>
          <li>Namespace</li>
          <li>Structure</li>
          <li>Class-level logic</li>
          <li>Tag code templates</li>
        </ul>
  
        <s3 title="Library Namespace">
          <p>
            Each XSP library defines a <ref>separate</ref> XML
            namespace:
          </p>
  
          <source>xmlns:example="http://www.plenix.com/DTD/XSP/Example"</source>
  
          <p>
            Thus, all dynamic tags should belong to the same namespace
            associated with their defining library
          </p>
  
          <source>&lt;example:time-of-day format="hh:mm:ss"/&gt;</source>
  
          <p>
            While this discipline is not enforced by XSP, developers
            are strongly encouraged to follow this pattern because it
            prevents ambiguities and promotes document readability.
          </p>
        </s3>
  
        <s3 title="Program Structure">
          <p>
            The <code>&lt;xsp:structure&gt;</code> section provides
            the context for program-level declarations such
            as the Java <code>import</code> directive.
          </p>
  
          <source>&lt;xsp:structure&gt;
    &lt;xsp:include&gt;java.util.Date&lt;/xsp:include&gt;
    &lt;xsp:include&gt;java.text.SimpleDateFormat&lt;/xsp:include&gt;
  &lt;/xsp:structure&gt;</source>
  
          <p>
            The <code>&lt;xsp:structure&gt;</code> tag may contain
            zero or more <code>&lt;xsp:include&gt;</code> directives,
            each specifying an external program module to be made
            available to the generated XSP program.
          </p>
  
          <p>
            Note that the exact semantics of this elments is
            language-dependent. For Java, it corresponds to
            an <code>import</code> statement. For Fesi
            Javascript, for example, it may be interpreted as
            a <code>load()</code> function call.
          </p>
  
          <p>
            In our example, we're importing the
            <code>java.util.Date</code> and
            <code>java.text.SimpleDateFormat</code>
            class definitions.
          </p>
  
          <p>
            In all honesty, though, including
            <code>java.util.Date</code> is redundant because
            XSP always imports <code>java.util.*</code>. It's
            included here only to emphasize that the
            <ref>example</ref> library depends on it.
          </p>
  
          <p>
            <code>java.text.SimpleDateFormat</code>, on the other
            hand, <ref>must</ref> be included, because it's not among
            XSP's "preferred" Java packages.
          </p>
        </s3>
  
        <s3 title="Class-level logic">
          <p>
            In general, XSP class-level declarations (such as instance
            variables or methods) are defined by means of
            <code>&lt;xsp:logic&gt;</code> blocks
            <ref>placed outside the user root element</ref>.
          </p>
  
          <p>
            XSP libraries exploit this feature to declare class-level
            variables and methods used by code generated in reponse to
            the use of dynamic tags in XSP pages.
          </p>
  
          <p> 
            In our example, the following method is used to generate
            a <code>String</code> representation of the current system
            time:
          </p>
  
          <source>&lt;xsp:logic&gt;
    /* "Example" Class Level Logic */
    private static String formatDate(Date date, String pattern) {
      if (pattern == null || pattern.length() == 0) {
        pattern = "yyyy/MM/dd hh:mm:ss aa";
      }
      return (new SimpleDateFormat(pattern)).format(date);
    }
  &lt;/xsp:logic&gt;</source>
  
          <p>
            Dynamic tag templates may then refer to this method.
          </p>
        </s3>
  
        <s3 title="Tag Code template">
          <p>
            Finally, each dynamic tag must provide an associated
            XSLT template that dictates what source code must be
            generated whenever the tag is encountered in an XSP
            page.
          </p>
  
          <p>
            Note that the source code to be generated must be
            enclosed in either an <code>&lt;xsp:expr&gt;</code>
            or an <code>&lt;xsp:logic&gt;</code> element. This
            is so because these XSP tags will be later evaluated
            by the XSP built-in library (itself an XSLT stylesheet!)
          </p>
  
          <source>&lt;xsl:template match="example:time-of-day"&gt;
    &lt;xsp:expr&gt;
      formatDate(new Date(), "&lt;xsl:value-of select="@format"/&gt;")
    &lt;/xsp:expr&gt;
  &lt;/xsl:template&gt;</source>
  
          <p>
            In this example, each reference to a
            <code>&lt;example:time-of-day&gt;</code> tag
            will be replaced by a corresponding
            <code>&lt;xsp:expr&gt;</code> "call". Thus,
            if an XSP page using the <ref>example</ref>
            library contains:
          </p>
  
          <source>&lt;example:time-of-day format="hh:mm:ss"/&gt;</source>
  
          <p>
            XSP will expand this reference to:
          </p>
  
          <source>&lt;xsp:expr&gt;formatDate(new Date(), "hh:mm:ss")&lt;/xsp:expr&gt;</source>
  
          <p>
            during library processing. Upon source program
            generation this directive will be finally
            expanded
            to:
          </p>
  
          <source>
  xspCurrentNode.appendChild(
    xspExpr(
      formatDate(new Date(), "hh:mm:ss"),
      document
    )
  );
          </source>
  
          <p>
            where the <code>xspExpr()</code> built-in method is
            overloaded to wrap all possible Java types as a
            <code>Text</code> Node.
          </p>
  
          <p>
            Finicky developers may prefer to map dynamic tags to
            <ref>bean</ref> method calls, as opposed to inlining
            "raw" Java code.
          </p>
          
          <p>
            While some may consider this a matter of taste, using
            bean properties and methods <ref>is</ref> certainly
            advisable because it isolates library code from
            implementation details. This would allow, for instance,
            for a complex Enterprise Java Bean to be modified
            without impacting existing XSP pages.
          </p>
        </s3>
  
      </s2>
  
      <s2 title="The XSP Tagset">
        <s3 title="Tag List">
          <ul>
            <li>
              <code>&lt;xsp:page&gt;</code><br/>
              This element is the root of all XSP pages and
              specifies the scripting language and the tag
              libraries used by a particular XSP page
            </li>
            <li>
              <code>&lt;xsp:structure&gt;</code><br/>
              This top-level element encloses source
              program-level declarations such as
              <code>&lt;xsp:include&gt;</code>
            </li>
            <li>
              <code>&lt;xsp:include&gt;</code><br/>
              This element is used to import external
              module definitions in a language-dependent
              way
            </li>
            <li>
              <code>&lt;xsp:logic&gt;</code><br/>
              This element is used to embed procedural
              logic in an XSP page. Enclosed code is
              transcribed verbatim into the generated
              <code>XSPPage</code> producer. Other
              XSP or user markup may be nested inside
              this tag
            </li>
            <li>
              <code>&lt;xsp:content&gt;</code><br/>
              This element is used to embed "regular"
              XML content inside an
              <code>&lt;xsp:logic&gt;</code> block
              so that no nested additional
              <code>&lt;xsp:logic&gt;</code>
              sections are required
            </li>
            <li>
              <code>&lt;xsp:expr&gt;</code><br/>
              This element inlines a program
              expression as a <code>Text</code> node,
              except when used directly inside another
              <code>&lt;xsp:&gt;</code> element,
  	    where it is substituted as an
  	    expression, not a node. If you
  	    want to substitute an
              <code>&lt;xsp:expr&gt;</code> tag
  	    as a node inside another XSP
  	    tag, you must enclose it in an
              <code>&lt;xsp:content&gt;</code> element.
            </li>
            <li>
              <code>&lt;xsp:element&gt;</code><br/>
              This tag is used to dynamically build
              an element when its attribute values
              are not known at compile time
            </li>
            <li>
              <code>&lt;xsp:attribute&gt;</code><br/>
              This element is used to dynamically provide
              attribute values for a given element (which
              can be specified statically as markup or
              dynamically by means of
              <code>&lt;xsp:element&gt;</code>).
              This tag is typically used in conjunction
              with <code>&lt;xsp:expr&gt;</code>,
  	    where the substituted expression is
  	    always cast to <code>String</code>
            </li>
            <li>
              <code>&lt;xsp:pi&gt;</code><br/>
              This element is used to dynamically create
              a processing instruction.
            </li>
            <li>
              <code>&lt;xsp:comment&gt;</code><br/>
              This element is used to dynamically create
              an XML comment.
            </li>
          </ul>
        </s3>
  
        <s3 title="Notes on Tag Usage">
  
          <s4 title="&lt;xsp:page&gt;">
            <p>
              The <code>&lt;xsp:page&gt;</code> root element
              has an optional <code>language</code> attribute
              that defaults to <ref>java</ref>. Other scripting
              languages (both interpreted and compiled) will
              be supported in the near future.
            </p>
    
            <p>
              The <code>&lt;xsp:page&gt;</code> root element
              requires one or more <code>xmlns:</code> attributes
              specifying tag libraries. These attributes specify
              each tag library's DTD location as a URL.
            </p>
    
            <p>
              At least the built-in XSP (currently,
              <code>xmlns:xsp="http://www.apache.org/1999/XSP/Core"</code>)
              library must be specified.
            </p>
    
            <p>
              The order in which <code>xmlns:</code> attributes appear
              dictates library processing order. The XSP built-in
              library, though, is always applied last, regardless of its
              position in the <code>xmlns:</code> attribute list.
            </p>
      
            <p>
              The <code>&lt;xsp:page&gt;</code> element can only
              have <ref>one</ref> user element. This element
              becomes the root of the generated XML document.
            </p>
    
            <p>
              Only the following node types are valid as direct
              descendants of the <code>&lt;xsp:page&gt;</code>
              root element:
            </p>
    
            <ul>
              <li>
                Zero or more <code>&lt;xsp:structure&gt;</code>
                elements.
              </li>
              <li>
                Zero or more <code>&lt;xsp:logic&gt;</code>
                elements.
              </li>
              <li>
                The user root element: as in <ref>Highlander</ref>,
                there can be only one.
              </li>
            </ul>
    
            <p>
              <code>&lt;xsp:logic&gt;</code>
              blocks that are direct descendants of the
              <code>&lt;xsp:page&gt;</code> root element
              (i. e., placed <ref>outside</ref> the
              user root element) are generated as
              class-level logic. This is used for declaring
              class fields and methods.
            </p>
      
    
            <p>
              Top-level processing instructions (other than
              <code>&lt;?cocoon-process type="xsp"?&gt;</code>)
              are preserved in the generated XML document.
              This is convenient, for example, for subsequent
              XSLT processing.
            </p>
    
            <p>
              Some Java packages are always imported by
              default. As such, they do not require
              explicit <code>&lt;xsp:include&gt;</code>
              directives. These packages are:
            </p>
      
            <ul>
              <li><code>java.io.*;</code></li>
              <li><code>java.util.*;</code></li>
              <li><code>org.w3c.dom.*;</code></li>
              <li><code>org.xml.sax.*;</code></li>
              <li><code>javax.servlet.*;</code></li>
              <li><code>javax.servlet.http.*;</code></li>
              <li><code>org.apache.cocoon.parser.*;</code></li>
              <li><code>org.apache.cocoon.producer.*;</code></li>
              <li><code>org.apache.cocoon.framework.*;</code></li>
              <li><code>org.apache.cocoon.processor.xsp.*;</code></li>
            </ul>
          </s4>
    
          <s4 title="&lt;xsp:logic&gt; and &lt;xsp:content&gt;">
            <p>
              <code>&lt;xsp:content&gt;</code>
              can be used inside
              <code>&lt;xsp:logic&gt;</code>
              blocks to avoid the recursive nesting of
              additional <code>&lt;xsp:logic&gt;</code>
              elements. Thus, the following XSP fragment
              (which contains nested
              <code>&lt;xsp:logic&gt;</code> blocks):
            </p>
    
          <source>. . .
    &lt;p&gt;
      Good
        &lt;xsp:logic&gt;
          String timeOfDay = (new SimpleDateFormat("aa")).format(new Date());
          if (timeOfDay.equals("AM")) {
        &lt;/xsp:logic&gt;
      Morning
        &lt;xsp:logic&gt;
          } else {
        &lt;/xsp:logic&gt;
      Afternoon
        &lt;xsp:logic&gt;
          }
        &lt;/xsp:logic&gt;!
    &lt;/p&gt;
    . . .</source>
    
            <p>
              can be rewritten as:
            </p>
    
          <source>. . .
    &lt;p&gt;
      Good
      &lt;xsp:logic&gt;
        String timeOfDay = (new SimpleDateFormat("aa")).format(new Date());
    
        if (timeOfDay.equals("AM")) {
          &lt;xsp:content&gt;Morning&lt;/xsp:content&gt;
        } else {
          &lt;xsp:content&gt;Afternoon&lt;/xsp:content&gt;
        }
      &lt;/xsp:logic&gt;!
    &lt;/p&gt;
    . . .</source>
      
            <p>
              Note that this does not work in cases where a
              non-empty element would be "truncated" by an
              interspersed <code>&lt;xsp:logic&gt;</code>
              block. Thus, the following example cannot be
              reduced by means of <code>&lt;xsp:content&gt;</code>
            </p>
    
            <source>&lt;xsp:logic&gt;
      Enumeration enum = request.getParameterNames();
      while (enum.hasMoreElements()) {
        String parameterName = (String) enum.nextElement();
        String[] parameterValues =
          request.getParameterValues(parameterName);
      
        &lt;tr&gt;
          &lt;td valign="top"&gt;
            &lt;xsp:expr&gt;parameterName&lt;/xsp:expr&gt;
          &lt;/td&gt;
    
          &lt;!-- Trouble here --&gt;
          &lt;td&gt;
    
          &lt;xsp:logic&gt;
            for (int i = 0; i &amp;lt; parameterValues.length; i++) {
              &lt;xsp:content&gt;
                &lt;xsp:expr&gt;parameterValues[i]&lt;/xsp:expr&gt;
              &lt;/xsp:content&gt;
              &lt;br/&gt;
            }
          &lt;/xsp:logic&gt;
    
          &lt;/td&gt;
          &lt;!-- End trouble --&gt;
    
        &lt;/tr&gt;
      }
    &lt;/xsp:logic&gt;</source>
    
            <p>
              because the second <code>&lt;td&gt;</code> would be
              "cut short" by any intervening
              <code>&lt;xsp:content&gt;</code>.
            </p>
          </s4>
    
          <s4 title="&lt;xsp:element&gt; and &lt;xsp:attribute&gt;">
            <p>
              The <code>&lt;xsp:element&gt;</code> tag
              (which requires a <code>name</code> attribute)
              is used in those cases where the element
              name is known at compile time, but its
              attribute values are not. For example:
            </p>
  
            <source>&lt;xsp:logic&gt;
    for (int i = 0; i &amp;lt; languages.length; i++) {
     &lt;tr&gt;
       &lt;td&gt;
           &lt;img&gt;
             &lt;xsp:attribute name="src"&gt;img/
               &lt;xsp:expr&gt;languages[i].getCode()&lt;/xsp:expr&gt;
             .gif&lt;/xsp:attribute&gt;
           &lt;/img&gt;
       &lt;/td&gt;
       &lt;td&gt;
           &lt;xsp:expr&gt;languages[i].getName()&lt;/xsp:expr&gt;
       &lt;/td&gt;
     &lt;/tr&gt;
    }
  &lt;/xsp:logic&gt;</source>
  
            <p>
              Only XML text and <code>&lt;xsp:expr&gt;</code> are
              valid inside an <code>&lt;xsp:attribute&gt;</code>
              element.
            </p>
  
            <p>
              Note that whitespace is significant inside
              <code>&lt;xsp:attribute&gt;</code>
              so indenting <code>&lt;xsp:attribute&gt;</code>
              content may result in spurious space being
              generated. Unless you <ref>really</ref> need
              to generate spaces as part of the attribute
              value, resist the temptation to write something
              like:
            </p>
  
            <source>&lt;img&gt;
    &lt;xsp:attribute name="src"&gt;
      img/
      &lt;xsp:expr&gt;
        languages[i].getCode()
      &lt;/xsp:expr&gt;
      .gif
    &lt;/xsp:attribute&gt;
  &lt;/img&gt;</source>
  
            <p>
              Finally, if an element name is <ref>not</ref>
              known at compile time, you must programatically
              create it:
            </p>
  
            <source>&lt;xsp:logic&gt;
    String tagName = null;
    if (ordered) {
      tagName = "ol";
    } else {
      tagName = "ul";
    }
    xspParentElement = xspCurrentElement;
    xspNodeStack.push(xspParentElement);
    xspCurrentElement = document.createElement(tagName);
  &lt;/xsp:logic&gt;
  
    &lt;li&gt;Item 1&lt;/li&gt;
    &lt;li&gt;Item 2&lt;/li&gt;
    &lt;li&gt;Item 3&lt;/li&gt;
  
  &lt;xsp:logic&gt;
    xspCurrentElement = (Node) xspNodeStack.pop();
  &lt;/xsp:logic&gt;</source>
  
            <p>
              This may be alleviated in future XSP versions
              by introducing an idiom similar to the XSLT way
              of substituting dynamic expressions inside
              attributes values:
            </p>
  
            <source>&lt;xsp:element name='{ordered ? "ol" : "ul"}'&gt;
    &lt;li&gt;Item 1&lt;/li&gt;
    &lt;li&gt;Item 2&lt;/li&gt;
    &lt;li&gt;Item 3&lt;/li&gt;
  &lt;/xsp:element&gt;</source>
      
          </s4>
      
          <s4 title="&lt;xsp:pi&gt;">
            <p>
              The <code>&lt;xsp:pi&gt;</code> element
              requires a <code>target</code> attribute
              specifying the processing instruction name.
            </p>
  
            <p>
              <code>&lt;xsp:expr&gt;</code> is not yet
              supported to provide a value for a processing
              instruction's <ref>data</ref>. Only textual, constant
              values are allowed:
            </p>
  
            <source>&lt;xsp:pi name="cocoon-process"&gt;type="xslt"&lt;/xsp:pi&gt;</source>
      
            <p>
              In the future, <code>&lt;xsp:pi&gt;</code> may be
              renamed to <code>&lt;xsp:processing-instruction&gt;</code>
              to achieve compatibility with XSLT.
            </p>
          </s4>
      
          <s4 title="&lt;xsp:comment&gt;">
            <p>
              Note that dynamically created comments
              (<code>&lt;xsp:comment&gt;</code>)
              may be removed by subsequent XSLT processing.
            </p>
          </s4>
        </s3>
  
      </s2>
  
      <s2 title="The XSP Object Model">
  
        <s3 title="Processors and Producers">
        <p>
          A <ref>processor</ref> is a Cocoon Java type that
          takes a DOM tree as input and produces another
          (possibly modified) DOM tree as output. This
          concept is similar to that of a Unix "filter"
          in a command pipeline.
        </p>
  
        <p>
          The XSP engine is implemented as a Cocooon processor
          that accepts an XSP page as input.  The first time a
          given XSP page is processed, it is translated into an
          equivalent source program which is then compiled, loaded
          and executed. Subsequent requests for the same XSP page
          result in the execution of the generated program.
          As you may expect, the output DOM tree returned by the
          XSP engine processor is actually built by the generated
          program.
        </p>
  
        <p>
          XSP pages are compiled into Cocoon producers.
          A <ref>producer</ref> is a Cocoon Java type normally used to
          "feed" the initial XML content to the Cocoon processing
          pipeline.
          </p>
  
        <p>
            Thus, for example, when Cocoon serves a static, "regular"
            XML document, file contents are actually delivered by
          Cocoon's built-in <code>FileProducer</code>.
        </p>
  
          <p>
          Whereas other related server pages technologies (such as
          JSP) generate <ref>servlets</ref>, XSP generates producers
          instead. This is so because, among other reasons,
          the servlet model does not yet provide a mechanism for
          portably and efficiently post-processing XML content.
          </p>
        </s3>
  
        <s3 title="XSP Built-in Objects">
        <p>
          XSP defines an abstract producer (<code>XSPPage</code>)
          as the base class for generated programs.
        </p>
  
        <p>
          This class exposes a simple object model that can
          be easily used by XSP developers to programmatically
          control how XML content is generated.
        </p>
  
        <p>
          The following objects are accesible inside an XSP
          page:
        </p>
  
        <ul>
          <li>
            <code>request</code>.
            A Cocoon-supplied wrapper to the standard
            <code>HttpServletRequest</code> object.
            This wrapper provides all the functionality
            defined for its JSDK interface counterpart.
            This object is typically used to retrieve
            Http form parameters as well as to get
            header and cookie information.
          </li>
          <li>
            <code>response</code>.
            A Cocoon-supplied wrapper to the standard
            <code>HttpServletResponse</code> object.
            This wrapper provides most of the
            functionality defined for its JSDK
            interface counterpart,
            <ref>except for access to the</ref>
            <code>ServletOutputStream</code><ref>object
            and its associated writer</ref>.
            This restriction
            is necessary to ensure consistent Cocoon
            servlet output and does not impose any
            limitation to XML processing. Other suitable,
            non-output operations (such as setting headers,
            cookies or content types) are allowed
          </li>
          <li>
            <code>session</code>.
            The standard <code>HttpSession</code> servlet
            object. This object is typically used to
            store data associated with a user HTTP session
          </li>
          <li>
            <code>servletContext</code>.
            The standard <code>ServletContext</code>
            object. This object is typically used to
            store application-level data by means
            of its <code>setAttribute</code> and
            <code>getAttribute</code> methods. Other
            uses include determining the real path
            of a URL as dictated by the underlying web
            server virtual directory structure. Note
            that the application-level data sharing
            capabilities offered by this object are
            available only for JSDK version 2.2 and
            higher. To circumvent this for JSDK prior
            to 2.2, use the <code>xspGlobal</code>
            object (explained below)
          </li>
          <li>
            <code>document</code>.
            An XSP-supplied <code>org.w3c.Document</code>
            object.  Initially empty, this object is populated
            by the generated <code>XSPPage</code> producer
            and is typically used as a node factory
            (<code>document.createElement()</code>,
            <code>document.createProcessingInstruction()</code>,
            etc)
          </li>
          <li>
            <code>xspGlobal</code>.
            An XSP-supplied global dictionary offering
            the same <code>setAttribute</code> and
            <code>getAttribute</code> services supported
            by the standard <code>ServletContext</code>
            object. This surrogate exists only to provide
            application-level data sharing for older
            servlet engines (prior to 2.2). Note that,
            while providing a means for application-level
            data sharing for older servlet engines,
            such global data cannot be shared with non-Cocoon
            servlets or JSP pages. For this purpose, use
            the standard <code>servletContext</code> object.
            <code>xspGlobal</code> may be deprecated in future
            XSP versions
          </li>
          <li>
            <code>xspNodeStack</code>.
            A <code>java.util.Stack</code> used to control
            element nesting in the XSP page <code>Document</code>
            object. Extreme caution must be exercised in
            using this object as all DOM manipulations
            take effect on its top element. Note: 
            <code>java.util.Stack</code> was introduced
            in Java2. It should be replaced by an
            equivalent JDK1.1 implementation!
          </li>
          <li>
            <code>xspCurrentNode</code>.
            An <code>org.w3c.Node</code> object corresponding
            to the node being currently populated
          </li>
          <li>
            <code>xspParentNode</code>.
            An <code>org.w3c.Node</code> object corresponding
            to the parent of the node being currently
            populated. This object is normally the top element
            of the <code>xspNodeStack</code>
          </li>
          <li>
            <code>xspParser</code>.
            A Cocoon-supplied DOM parser which may be used
            to create new documents and parse external
            XML documents
          </li>
        </ul>
  
        <p>
          In addition to the above objects, the <code>XSPPage</code>
          contains an <code>xspExpr()</code> method than can be
          used to wrap any Java value as an <code>org.w3c.Text</code>
          object. Example:
        </p>
  
        <source>xspCurrentElement.appendChild(
    document.createTextNode("It's now ")
  );
  xspCurrentElement.appendChild(
    xspExpr(new Date())
  );
  </source>
       </s3>
  
       <s3 title="The XSP Util Class">
         <p>
           In addition to the above infrastructure objects and methods,
           XSP provides a utility class offering a number of DOM, HTTP
           and file manipulation services implemented as public
           static methods:
         </p>
  
         <s4 title="DOM Utility Methods">
           <ul>
             <li>
               <code>Node cloneNode(Node node, Document factory)</code>.<br/>
               This method performs a deep copy of its <code>node</code>
               argument using the <code>factory</code> document as the
               creator for the copied nodes. This is typically used to
               embed external XML documents into the XSP page
               <code>document</code> object. This is required because
               DOM Level 1 parsers do not allow for a node to be
               appended as child to another node if the two belong
               to different document instances
             </li>
             <li>
               <code>String toMarkup(Node node)</code>.<br/>
               This method generates an indented String representation
               of its <code>node</code> argument. This is typically
               used to embed a textual, non-DOM representation of
               external XML files as well as for debugging purposes
             </li>
           </ul>
         </s4>
  
         <s4 title="HTTP Utility Methods">
           <ul>
             <li>
               <code>String encodeMarkup(String string)</code>.<br/>
               This method scans its <code>string</code> argument
               replacing occurrences of markup delimiters as
               follows:<br/>
               1) <code>&lt;</code> is replaced by <code>&amp;lt;</code><br/>
               2) <code>&gt;</code> is replaced by <code>&amp;gt;</code><br/>
               3) <code>&amp;</code> is replaced by <code>&amp;amp;</code><br/>
             </li>
             <li>
               <code>String formEncode(String text)</code>.<br/>
               This method converts its <code>text</code> argument
               to <ref>x-www-form-urlencode</ref> format, as required
               by HTTP form query strings. This method is actually
               a wrapper for <code>java.net.URLEncoder.encode</code>
             </li>
             <li>
               <code>String formDecode(String text)</code>.<br/>
               This method converts its <code>text</code> argument
               from <ref>x-www-form-urlencode</ref> format to a
               <code>String</code> representation. This method is
               actually a wrapper for
               <code>java.net.URLDecoder.decode</code> (introduced
               in Java2) and exists solely to provide this
               functionality for JDK1.1
             </li>
           </ul>
         </s4>
    
         <s4 title="File Utility Methods">
           <ul>
             <li>
               <code>String pathComponent(String filename)</code>.<br/>
               This method interprets its <code>filename</code>
               argument as a file name and removes the last
               component to yield only the directory path
               information.
               This conversion is performed in an operating
               system-independent manner
             </li>
             <li>
               <code>String fileComponent(String filename)</code>.<br/>
               This method interprets its <code>filename</code>
               argument as a file name and removes the leading
               path component to yield only the file name
               portion, including the file name extension,
               if any.
               This conversion is performed in an operating
               system-independent manner
             </li>
             <li>
               <code>String baseName(String filename)</code>.<br/>
               This method interprets its <code>filename</code>
               argument as a file name and removes the leading
               path component to yield only the base file name
               <ref>excluding</ref> the last <ref>dot</ref> file
               extension, if any.
               This conversion is performed in an operating
               system-independent manner
             </li>
             <li>
               <code>String baseName(String filename, String suffix)</code>.<br/>
               This method interprets its <code>filename</code>
               argument as a file name and removes the leading
               path component to yield only the base file name
               <ref>excluding</ref> the last occurerence of the
               extension given by its
               <code>suffix</code> argument.
               This conversion is performed in an operating
               system-independent manner
             </li>
             <li>
               <code>String normalizedBaseName(String filename)</code>.<br/>
               This method interprets its <code>filename</code>
               argument as a file name and removes the leading
               path component to yield only the base file name
               <ref>excluding</ref> the last <ref>dot</ref> file
               extension, if any. The resulting filename is
               then scanned for non-alphanumeric characters
               which are replaced by <ref>underscore</ref>
               (<code>_</code>). An underscore is also
               preprended to each directory component.
               This is used to map file names to valid Java
               identifiers.
               This conversion is performed in an operating
               system-independent manner
             </li>
             <li>
               <code>String relativeFilename(String filename, HttpServletRequest request, ServletContext context)</code>.<br/>
               This method is used to build a fully qualified pathname
               for a <code>filename</code> relative to the <code>request</code>
               URI. This is typically used to open operating system files
               given a name relative to the request's virtual path
             </li>
             <li>
               <code>String relativeFilename(String filename, HttpServletRequest request)</code>.<br/>
               This method is used to build a fully qualified pathname
               for a <code>filename</code> relative to the <code>request</code>
               URI. This is typically used to open operating system files
               given a name relative to the request's virtual path. This
               variant depends on the deprecated
               <code>HttpServletRequest.getRealPath</code> method and
               exists only for compatibility with older JSDK's in which
               the <code>ServletContext</code> object did not provide
               a <code>getRealPath()</code> method
             </li>
             <li>
               <code>String requestRealPath(HttpServletRequest request, ServletContext context)</code>.<br/>
               This method is used to retrieve the fully qualified
               real path associated with a given <code>request</code>
               in a way that is operating system-independent and portable
               between older and newer versions of the JSDK API
             </li>
           </ul>
         </s4>
    
         <s4 title="String Utility Methods">
           <ul>
             <li>
               <code>String[] split(String line)</code>.<br/>
               This method converts its <code>line</code> string
               argument to a <code>String</code> array using
               whitespace (blanks, tabs, carriage returns and
               newlines) as field separators
             </li>
             <li>
               <code>String[] split(String line, String delimiter)</code>.<br/>
               This method converts its <code>line</code> string
               argument to a <code>String</code> array using
               the characters in its <code>delimiter</code>
               argument as field separators
             </li>
             <li>
               <code>boolean isAlphaNumeric(char c)</code>.<br/>
               This method tests its <code>c</code> argument to
               assert whether it is an underscore, a lowercase or
               uppercase letter or a digit
             </li>
           </ul>
         </s4>
  
       </s3>
      </s2>
  
      <s2 title="Other Scripting Languages">
        <p>
          XSP has been designed to support other scripting
  	languages, in addition to Java. In principle, any
  	programming language for which a Java-based
  	interpreter exists could be used to script
  	XSP pages.
        </p>
  
        <p>
          In general, languages supporting compilation to
  	bytecodes, such as Java itself, Netscape's
  	<jump href="http://www.mozilla.org/rhino/">Rhino Javascript</jump>
  	or IBM's
  	<jump href="http://www2.hursley.ibm.com/netrexx/">NetRexx</jump>,
  	perform significantly better than interpreted
  	languages like
  	<jump href="http://home.worldcom.ch/jmlugrin/fesi/">FESI Javascript</jump>
  	or
  	<jump href="http://www.research.digital.com/SRC/WebL/">WebL</jump>.
        </p>
  
        <p>
          Interpreted languages, however, are expected to
  	play an important role in XSP scripting.
  	This is so because (in addition to their typical
  	ease of use) more and more field-specialized
  	languages are being developed for the JVM.
          Such specialized scripting languages usually
  	offer more expressive power and conciseness
  	than strictly object-oriented languages.
        </p>
  
        <p> 
          For a fairly complete list of such languages
  	see
  	<jump href="http://grunge.cs.tu-berlin.de/~tolk/vmlanguages.html">Programming Languages for the Java Virtual Machine</jump>.
        </p>
  
        <p>
  	Until recently, Java lacked a well-defined
  	scripting architecture that allowed applications
  	to incorporate scripting easily.
  	IBM's
  	<jump href="http://www.alphaworks.ibm.com/tech/bsf">Bean Scripting Framework</jump>
  	(BSF) is an Alphaworks project providing such architecture.
        </p>
  
        <p>
          BSF supports a growing number of
  	scripting languages including
  	<jump href="http://www.mozilla.org/rhino/">Rhino</jump>,
  	<jump href="http://www2.hursley.ibm.com/netrexx/">NetRexx</jump>,
  	<jump href="http://www.scriptics.com/java">Jacl</jump>
  	and
  	<jump href="http://www.jpython.org">JPython</jump>.
  	On the Windows platform,
  	BSF also supports
  	<jump href="http://msdn.microsoft.com/scripting/default.htm?/scripting/jscript/default.htm">JScript</jump>,
  	<jump href="http://msdn.microsoft.com/scripting/default.htm?/scripting/vbscript/default.htm">VBScript</jump>,
  	and
  	<jump href="http://www.activestate.com/activeperl">PerlScript</jump>.
        </p>
  
        <p>
          Currently, XSP only supports Java as a scripting language,
  	though its design allows for an easy integration of
  	other languages.
        </p>
  
        <p>
  	In the near future, BSF will be integrated to XSP's own
  	language abstraction mechanism so that most (if not all)
  	of the above mentioned languages may become available
  	for XSP scripting.
        </p>
  
        <p>
          XSP tag libraries are language-dependent. Thus, the
  	addition of a new language involves (at the very
  	least) porting the XSP built-in libraries. An XSP library is 
  	composed of a code-generation XSLT sylesheet and an 
  	optional <ref>library preprocessor</ref> class.
        </p>
  
        <p>
          A library's code-generation stylesheet is simply a
  	"regular" XSLT stylesheet responsible for translating
  	user-defined dynamic tags into equivalent XSP tags
  	for a given scripting language (sometimes called <ref>logicsheet</ref>). 
  	While a preprocessor is an optional library Java class
  	used to augment an XSP page DOM tree prior to
  	applying the library code-generation stylesheet.
        </p>
  
        <p>
          Library preprocessors <ref>may</ref> be
  	language-dependent. Early experience
  	suggests, though, that the same preprocessor
  	class will be typically shared by different
  	languages for the same dynamic tagset.
        </p>
  
        <p>
          XSLT <ref>extension functions</ref> and
  	<ref>extension elements</ref> may replace
  	library preprocessors in the future. In
  	this case, all code-generation logic would
  	reside in the library's stylesheet.
        </p>
        
        <p>
         At this early development stage, we still don't know how the
         implementation will evolve and we look forward for public feedback
         before going any further along with the implementation details.
        </p>
      </s2>
  
      <s2 title="Acknowledgements">
        <p>
          This initial implementation of XSP has
  	been developed by
  	<jump href="http://www.exolab.org/">Exolab</jump>
  	and is being donated to the
  	Apache project as part of Exoffice's
  	commitment to the open source movement.
        </p>
  
        <p>
          Special thanks must be given to
  	<jump href="mailto:ghalimi@exoffice.com">Ismael Ghalimi</jump>
  	for sponsoring and supporting XSP development.
        </p>
  
        <p>
          Last, but not least, cheers to
  	<jump href="mailto:stefano@apache.org">Stefano Mazzocchi</jump>,
  	founder and leader of the Cocoon project and original author of
  	the XSP specification. Thanks!!!
        </p>
      </s2>
  
    
  </s1>
  
  

Mime
View raw message