Extensions

  1. Xalan Extensions
  2. Extension Libraries
  3. Automatic Java Extensions
  4. Web Framework Extensions
    • web:service
    • web:action
    • web:include
 

Xalan Extensions

Xalan is the XSL processor used within the web framework. It provides an extension mechanism which can be used to extend standard XSL processing. The extension mechanism works well, but is somewhat cumbersome for the following reasons:
  • No support for extension libraries. Extensions must be declared whereever they are used.
  • Appropriate namespace declaration is required wherever extensions are used.
  • No correspondance to extension implementation. If the implementation changes, the extension declaration must be changed accordingly
  • No standard descriptor for extension usage, attributes, etc.
These issues limit the use of extensions, which is unfortunate, as they allow developers to really customize the processing.

Example

Despite the limitations, I'll show the Xalan mechanism, as it is the foundation for extension libraries and the java extensions. In practice, you shouldn't need to use Xalan extensions directly, but rather use the java extension mechanism or extension libraries. Here's how to use Xalan extensions if you need to:
[xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xalan="http://xml.apache.org/xalan"
                xmlns:xcounter="test.org.benow.web.Counter"
                extension-element-prefixes="xcounter"
                version="1.0"]
                
  [xalan:component prefix="xcounter"
                   elements="init incr" functions="read"]
    [xalan:script lang="javaclass" src="xalan://test.org.benow.web.Counter"/]
  [/xalan:component]
  
  [xsl:template match="/"]
    [xcounter:init name="index" value="1"/]
    [xsl:for-each select="result/item"]
      [xsl:sort select="name"/]
      [p]
      [xsl:text][[/xsl:text]
      [xsl:value-of select="xcounter:read('index')"/]
      [xsl:text]]. [/xsl:text]
      [xsl:value-of select="name"/]
      [/p]
      [xcounter:incr name="index"/]
    [/xsl:for-each]
  [/xsl:template]
[/xsl:stylesheet]
    
The extension namespace and exclusion is defined in the stylesheet and the xalan:component block defines the extension. It identified the prefix, the elements and functions and defines the source to be the test.org.benow.web.Counter java class.

The xcounter extension is then used to initialize, increment and dump a counter.

The output of the processing is:

[ ].

This works well, but is cumbersome for the developer for the above reasons. Extension libraries have been introduced to reduce the implementation overhead.  

Extension Libraries

This is a demo of facililated xalan extension libraries. The grouping of Xalan extensions as shown in the previous section is faciltated by the framework, so that extensions are easier to group, declare and import. By default, there is no support for extension libraries in xalan. They cannot be included via xsl:include or xsl:import and must be defined wherever they are used. The concept of extension libraries has been implemented as part of the BeNOW web framework.

To use an extension library, include the library in the namespace declaration for the stylesheet. At template read time, the library will be parsed and all contents included in the stylesheet. There are several points of note for extension libraries:

  • extensions live in the lib/java/extension/ directory (or subdirectories).
  • extensions in this directory will be packaged using the package mechanism during ant jar build
  • packaged extensions may be reused by having the containg jar on the classpath
  • extensions must be named ext[name].xsl. If it doesn't start with' ext or end with .xsl it will not be recognised.
  • the namespace for the extension must be declared within the stylesheet declaration: ie
  • The extension-element-prefixes attribute is not required, as it is generated during extension inclusion. The prefix in the namespace (ie counter, as given in xmlns:counter) should correspond to the prefix in the extension xsl
  • The xmlns:xalan="http://xml.apache.org/xalan" namespace declaration is not needed. It will automatically be added.
  • the web helper extensions defined in the web framework (ie web:service, web:actions, web:*) are always included in pages, and need not be declared
  • To see the final stylesheet after extensions have been included, turn on debugging for the org.benow.web.path.page package.

Example

The framework automatically inserts extensions which are defined in the style sheet namespace declaration. In this example, xmlns:counter="extsample.xsl" is declared in the xsl:stylesheet. The frameworks sees that lib/xsl/extension/extsample.xsl exists and absorbs the declarations within into the stylesheet before transformation. The extensions declared within the referenced extension xsl can then be used during transformation.

In this example, extsample.xsl declares the counter operations init, read and incr, which correspond to methods within the test.org.benow.web.Counter class. Additionally, templates and other content declared in the extension xsl are also included and may be used in support of the extension.

The output including of the counter extension is:
commented

)

 

Automatic Java Extensions

The extension libraries are nicer, as they reduce the overhead of implementing and reusing extensions, but they still rely on an XSL file which declares the extensions. This file must be updated as the java source changes or as more extensions are added.

Automatic Java extensions were added to overcome this problem. These extensions are declared in java code only, and the Xalan extension declaration is automatically generated. This really eases the overhead of implementing extensions, as only a java class must be created for an extension to be usable. For this reason, automatic Java extensions are the preferred way to implement extensions written in java.

Extensions are declared in code by implementing the Extension interface. The class is then parsed with the following process

  • The namespace of the class is determined by the containing parent package name. For test.org.benow.web.extensions.sample.Counter the namespace is sample which corresponds to a sample: prefix.
  • The name of the extension corresponds to the class names as declared in the extension class. The Init extension class within the test.org.benow.web.extensions.sample.Counter class would be referenced as sample:init.
  • Attributes and elements which serve as input to the extension correspond to fields within the extension