garyp       00/11/22 20:51:19

  Modified:    java/xdocs/sources/xalan extensions.xml
  Log:
  Explain cleaned-up extension support.
  
  Revision  Changes    Path
  1.7       +191 -84   xml-xalan/java/xdocs/sources/xalan/extensions.xml
  
  Index: extensions.xml
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xalan/extensions.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- extensions.xml    2000/10/17 12:54:57     1.6
  +++ extensions.xml    2000/11/23 04:51:18     1.7
  @@ -15,19 +15,19 @@
   <li><link anchor="basic-syntax">Syntax</link></li>
   <li><link anchor="ext-elements">Using an extension element</link></li>
   <li><link anchor="ext-functions">Using extension functions</link></li>
  -<li><link anchor="java-namespace">Alternative: using the predefined java 
extension namespace</link></li>
  +<li><link anchor="java-namespace">Alternative: using the abbreviated syntax 
for extensions implemented in Java</link></li>
   <li>Examples: <link anchor="ex-basic">basic JavaScript example</link>, <link 
anchor="ex-java-namespace">using the java namespace</link>, <link 
anchor="ex-java">using a Java Hashtable</link>, <link 
anchor="ex-javascript">using a JavaScript array</link></li>
   </ul><anchor name="intro"/>
     <s2 title="Introduction">
  -  <p>For those situations where you would like to augment the functionality 
of XSLT with calls to a procedural language, &xslt4j; supports the creation and 
use of extension elements and extension functions. &xslt4j; also provides a 
growing <link idref="extensionslib">extensions library</link> available for 
your use. An extension (a collection of elements and functions) inhabits a 
namespace, either a namespace you declare and designate as an extensions 
namespace, or the predefined java namespace that &xslt4j; provides. For 
information about XML namespaces, see <jump 
href="http://www.w3.org/TR/REC-xml-names/";>Namespaces in XML</jump>.</p>
  +  <p>For those situations where you would like to augment the functionality 
of XSLT with calls to a procedural language, &xslt4j; supports the creation and 
use of extension elements and extension functions. &xslt4j; also provides a 
growing <link idref="extensionslib">extensions library</link> available for 
your use. An extension (a collection of elements and functions) inhabits a 
namespace, either a namespace you declare and designate as an extensions 
namespace, or one of the predefined namespaces that &xslt4j; provides. For 
information about XML namespaces, see <jump 
href="http://www.w3.org/TR/REC-xml-names/";>Namespaces in XML</jump>.</p>
   
   <p><em>Extension elements</em>  Unlike a literal result element, which the 
stylesheet simply transfers to the result tree, an extension element performs 
an action. For example, you can use the Redirect extension elements shipped 
with &xslt4j; to redirect portions of your transformation output to one or more 
files. Extension elements may contain attributes, text nodes, other elements, 
basically any valid XML. Extension elements may perform quite sophisticated 
actions, given that the extension routine (the implementation) has direct 
access to the XSLT processor context object and to the element. In many cases 
the implementation returns void or null; if it does return a value, that value 
is placed in the transformation result tree.</p>
   
  -<p><em>Extension functions</em>You can think of extension functions as 
extending the core library of functions that XPath provides. An extension 
function passes arguments to the extension implementation and returns a value. 
You can use extension functions to return values that XSLT can interact with 
directly (node-set, result tree fragment, string, boolean, and number) as well 
as values (of any type) that you pass in turn to other extension functions.</p>
  +<p><em>Extension functions</em>You can think of extension functions as 
extending the core library of functions that XPath provides. An extension 
function passes arguments to the extension implementation and returns a value. 
You can use extension functions to return values that XSLT can interact with 
directly (node-set, result tree fragment, string, boolean, and number) as well 
as values (of any type) that you pass in turn to other extension functions. 
Extension functions written in Java can also access certain items in the XSLT 
execution environment through an <jump 
href="apidocs/org/apache/xalan/extensions/ExpressionContext.html">ExpressionContext</jump>
 interface.</p>
   </s2><anchor name="supported-lang"/>
   <s2 title="Supported languages">
  -<p>&xslt4j; uses the <jump 
href="http://www.alphaworks.ibm.com/tech/bsf";>Bean Scripting Framework 
(BSF)</jump>, an architecture for incorporating scripting into Java 
applications and applets. BSF allows an application to take advantage of 
scripting while being independent of any specific scripting language. To date, 
we have tested extensions implemented in Java and JavaScript. Other languages 
with BSF support appear in the table below.</p>
  -<p>BSF requires bsf.jar on the class path. This JAR file is shipped with 
&xslt4j;, and that is all that is required for Java extensions. The additional 
JAR files or DLLs required to support extensions in other languages are listed 
in the table below. These files are available from the sources indicated and 
are not shipped with &xslt4j;.</p>
  +<p>Extensions written in Java are directly supported by &xslt4j;.  For 
extensions written in languages other than Java, &xslt4j; uses the <jump 
href="http://www.alphaworks.ibm.com/tech/bsf";>Bean Scripting Framework 
(BSF)</jump>, an architecture for incorporating scripting into Java 
applications and applets. BSF allows an application to take advantage of 
scripting while being independent of any specific scripting language. To date, 
we have tested extensions implemented in JavaScript. Other languages with BSF 
support appear in the table below.</p>
  +<p>BSF requires bsf.jar on the class path. This JAR file is shipped with 
&xslt4j; and is required only if you have extensions written in languages other 
than Java. The additional JAR files or DLLs required to support extensions 
written in other languages are listed in the table below. These files are 
available from the sources indicated and are not shipped with &xslt4j;.</p>
   <table>
     <tr>
       <td><em>Language</em></td>
  @@ -77,8 +77,8 @@
   <s2 title="The basic pattern">
   <p>Let's examine a simple example. The stylesheet below uses an extension 
element and an extension function to transform an element in the XML source 
into a statement in the output indicating the date by which a customer can 
expect a response to a given enquiry.</p>
   
  -<p>The source element contains a numdays attribute. The extension element 
contains a multiplier attribute, which is used to set a variable in the 
extension. The extension function computes the deadline, that is the current 
date plus numdays * multiplier. So for &lt;deadline numdays="3"/&gt; (in the 
XML source) and &lt;timelapse multiplier="2"/&gt; (in the stylesheet), the 
extension computes a deadline 6 days from now, and the stylesheet template  
transform the deadline element into a string along the lines of 
<code>&lt;p&gt;We have received your enquiry and will respond by April 29, 2000 
12:07:16 PM EST.&lt;/p&gt;</code></p>
  -<note>The extension function could include both numdays and multiplier as 
arguments, thus bypassing the need for the extension element, but the purpose 
here is to illustrate the usage pattern for both extension elements and 
extension functions.</note>
  +<p>The source element contains a numdays attribute. The extension element 
contains a multiplier attribute, which is used to set a variable in the 
extension. The extension function computes the deadline, that is the current 
date plus numdays * multiplier. So for &lt;deadline numdays="3"/&gt; (in the 
XML source) and &lt;my-ext:timelapse multiplier="2"/&gt; (in the stylesheet), 
the extension computes a deadline 6 days from now, and the stylesheet template 
transforms the deadline element into a string along the lines of 
<code>&lt;p&gt;We have logged your enquiry and will respond by April 29, 2000 
12:07:16 PM EST.&lt;/p&gt;</code></p>
  +<note>The extension function could include both numdays and multiplier as 
arguments, thus bypassing the need for the extension element, but the purpose 
here is to illustrate the usage pattern for extension elements.</note>
   <p>As you review this stylesheet, please note the following:</p>
   <ol>
          <li>The declaration of the Xalan lxslt namespace, which provides 
support for the component and
  @@ -86,13 +86,13 @@
       <code>xmlns:lxslt="http://xml.apache.org/xslt";</code><br/><br/></li>
       <li>The declaration of a namespace for this extension:<br/><br/>
       <code>xmlns:my-ext="ext1"</code><br/><br/></li>
  -     <li>The designation of this namespace prefix as an extension 
prefix:<br/><br/>
  +     <li>The designation of this namespace prefix as an extension prefix. 
This causes any element in the namespace associated with this prefix to be 
treated as an extension element rather than a literal result element.<br/><br/>
        <code>extension-element-prefixes="my-ext"</code><br/><br/></li>
          <li>The lxslt:component with attributes designating the namespace 
prefix and the elements and
        functions this extension provides.<br/><br/></li>
        <li>The lxslt:script subelement with a JavaScript implementation of the 
extension. For Java
        extensions, the lxslt:script element has a src attribute that you set 
to identify the Java class.</li>
  -  </ol><anchor name="ex-basic"/>   
  +</ol><anchor name="ex-basic"/>   
   <source>&lt;?xml version="1.0"?&gt;
   &lt;!--Namespaces are global if you set them in the stylesheet element--&gt;
   &lt;xsl:stylesheet 
  @@ -136,73 +136,69 @@
   </source>
   </s2><anchor name="setup-runtime"/>
   <s2 title="Setting up the runtime environment">
  -<p>To run the preceding example, bsf.jar and js.jar must be on the class 
path. Remember that bsf.jar must be on the class path to run any extension. For 
extensions implemented in a scripting language, see the additional requirements 
in <link anchor="supported-lang">Supported languages</link>.</p>
  +<p>To run the preceding example, bsf.jar and js.jar must be on the class 
path. Remember that bsf.jar must be on the class path to run any extension 
written in a language other than Java. For extensions implemented in a 
scripting language, see the additional requirements in <link 
anchor="supported-lang">Supported languages</link>.</p>
   </s2><anchor name="basic-syntax"/>
   <s2 title="Syntax">
  -<p>You can always use the pattern illustrated above to set up and use 
extension elements and extension functions. For extension functions implemented 
in Java, you can also use the java namespace, described in <link 
anchor="java-namespace">Alternative: using the predefined java extension 
namespace</link>. Unless you are using the predefined java extension namespace, 
do the following:</p>
  +<p>You can always use the pattern illustrated above to set up and use 
extension elements and extension functions. For extension elements and 
functions implemented in Java, you can also use an abbreviated syntax, 
described in <link anchor="java-namespace">Alternative: using the abbreviated 
syntax for extensions implemented in Java</link>. Unless you are using the 
abbreviated syntax, do the following:</p>
   <s3 title="1. Declare the lxslt namespace">
   <p><br/><code>xmlns:lxslt="http://xml.apache.org/xslt";</code></p>
   <p>The lxslt namespace provides support for the lxslt:component element and 
lxslt:script subelement.</p>
   </s3>
   <s3 title="2. Declare a unique namespace for each extension prefix">
   <p><br/><code>xmlns:<ref>prefix</ref>=<ref>URI</ref></code></p>
  -<p>The <ref>prefix</ref> identifies the namespace, and <ref>URI</ref> is one 
of the following:</p>
  -<ul>
  -  <li>An arbitrary (but unique) string that matches the prefix attribute of 
an lxslt:component element in the stylesheet.<br/>
  -  Example: <code>xmlns:ext1="xyz"</code><br/><br/></li>
  -  <li><code>[class:]<ref>FQCN</ref></code><br/>
  -   where <ref>FQCN</ref> is a Java fully qualified class name. If the 
extension only involves static class method
  -   calls (no instance constructors or instance method calls) precede the 
class name with <code>class:</code>.<br/>
  -   Example: <code>xmlns:ext2="java.util.Hashtable"</code><br/><br/></li>
  -  <li>The file name or URL for another document that contains the 
lxslt:component element.<br/>
  -  Example: <code>xmlns:ext3="my-component.txt"</code></li>
  -</ul>
  -<note>&xslt4j; identifies the URI by working through the list above. In 
other words, if the URI does not match an lxslt:component element prefix in the 
stylesheet, &xslt4j; attempts to map the URI to a fully qualified class name on 
the class path, and so on.</note>
  -<p>If the stylesheet contains an lxslt:component element with a prefix 
attribute set to the extension prefix, the only function of the URI is to 
provide a unique namespace. If the stylesheet does not contain an 
lxslt:component, the URI must identify a Java class or a document containing 
the lxslt:component.</p>
  +<p>The <ref>prefix</ref> identifies the namespace, and <ref>URI</ref> is an 
arbitrary (but unique) string that matches the value of the prefix attribute of 
an lxslt:component element in the stylesheet.<br/>
  +Example: <code>xmlns:ext1="xyz"</code><br/><br/></p>
   </s3>
  -<s3 title="3. Designate the extension prefixes">
  -<p>In the stylesheet element:</p> 
  +<s3 title="3. If you are using extension elements, designate the extension 
element prefixes">
  +<p><br/>This step is required only if you are using extension elements.  If 
you are using extension functions only and are not using any extension 
elements, then you can skip this step.</p>
  +<p>In the stylesheet element, write:</p> 
   <p><code>extension-element-prefixes="<ref>prefix-1 prefix-2 
...</ref>"</code></p>
   <p>In a literal result element or extension element include the xsl 
prefix:</p>
   <p><code>xsl:extension-element-prefixes="<ref>prefix1 prefix2 
...</ref>"</code></p>
   <p>Keep in mind that where you declare namespaces and designate extension 
prefixes determines the scope of those namespaces.To make your extensions 
available throughout the stylesheet, include these settings and attribute in 
the stylesheet element.</p>
  -<p>By default, namespace declarations are included in the transformation 
output. To exclude namespaces from the output, use</p>
  +</s3>
  +<s3 title="4. Exclude the extension namespace declaration from the result 
tree">
  +<p><br/>By default, namespace declarations are included in the 
transformation output. To exclude namespaces from the output, use</p>
   <p><code>exclude-result-prefixes="<ref>prefix-1 prefix-2 
...</ref>"</code></p>
   <p>in the stylesheet element or</p>
   <p><code>xsl:exclude-result-prefixes="<ref>prefix-1 prefix-2 
...</ref>"</code></p> 
   <p>in a literal result element or extension element.</p>
   </s3>
  -<s3 title="4. Set up an lxslt:component">
  -<p>In the scope of the xslt namespace declaration:</p>
  +<s3 title="5. Set up an lxslt:component">
  +<p><br/>In the scope of the lxslt namespace declaration:</p>
   <p><code>&lt;lxslt:component prefix="<ref>prefix</ref>" </code><br/>
      <code>&nbsp;&nbsp;&nbsp;&nbsp;functions="<ref>func-1 func-2 
...func-n</ref>"</code><br/> 
      <code>&nbsp;&nbsp;&nbsp;&nbsp;elements="<ref>elem-1 elem-2 
...elem-n</ref>"&gt;</code><br/>
      <code>&nbsp;&nbsp;&lt;!--See lxslt:script below--&gt;</code><br/>
      <code>&lt;/lxslt:component&gt;</code></p>
   <p>where <ref>func-1 func-2 ... func-n</ref> and <ref>elem-1 elem-2 ... 
elem-n</ref> designate the functions and elements the extension provides and 
the stylesheet uses. You can use the function-available and element-available 
functions to determine at run time whether a function or element designated in 
the lxslt:component is actually available.</p>
  -<note>If your extension namespace is a fully qualified class name, you do 
not need to include the lxslt:component. If you do not include it, you cannot 
use the function-available and element-available functions to determine whether 
a given element or function is actually available at runtime.</note>
  +<note>If the component is implemented in Java, the values of the 
<code>functions</code> and <code>elements</code> attributes are ignored. The 
function-available and element-available functions will use reflection to 
examine the actual Java methods.</note>
   </s3>
  -<s3 title="5. Set up the lxslt:script element">
  -<p>In each lxslt:component, you must include an lxslt:script element. If the 
extension is implemented in Java:</p>
  -<p><code>&lt;lxslt:script lang="javaclass" 
src="<ref>[class:]FQCN</ref>"/&gt;</code></p>
  -<p>where <ref>FQCN</ref> is the fully qualified class name. If the extension 
only involves static class method calls (no instance constructors or instance 
method calls) precede the class name with <code>class:</code>.<br/>
  -Example: <code>&lt;lxslt:script lang="javaclass"</code><br/>
  
-<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src="java.util.Hashtable"/&gt;</code></p>
  -<p>If the extension is implemented in JavaScript:</p>
  +<anchor name="setup-script"/>
  +<s3 title="6. Set up the lxslt:script element">
  +<p><br/>In each lxslt:component, you must include exactly one lxslt:script 
element. If the extension is implemented in JavaScript:</p>
   <p><code>&lt;lxslt:script lang="javascript" &gt;</code><br/>
   <code>&nbsp;&nbsp;&lt;!--The implementation script--&gt;</code><br/>
   <code>&lt;/lxslt:script&gt;</code></p>
   <p>For other scripting languages supported by BSF, use the same approach as 
for JavaScript. &xslt4j; plans to add support for using the src attribute to 
identify another document that contains the implementation script; this feature 
is not yet supported.</p>
  +<p>If the extension is implemented in Java, you have three choices for the 
format of the src attribute in the lxslt:script element.</p>
  +<p><code>&lt;lxslt:script lang="javaclass" 
src="xalan://<ref>FQCN</ref>"/&gt;</code>
  +<br/>where <ref>FQCN</ref> is the fully qualified class name.
  +<br/>Example: <code>&lt;lxslt:script lang="javaclass" 
src="xalan://java.util.Hashtable"/&gt;</code></p>
  +<p><code>&lt;lxslt:script lang="javaclass" 
src="xalan://<ref>PJPN</ref>"/&gt;</code>
  +<br/>where <ref>PJPN</ref> is the beginning of or the complete name of a 
java package.
  +<br/>Example: <code>&lt;lxslt:script lang="javaclass" 
src="java.util"/&gt;</code></p>
  +<p><code>&lt;lxslt:script lang="javaclass" 
src="http://xml.apache.org/xslt/java"/&gt;</code></p>
  +<p>The different formats for the value of the src attribute when using Java 
extensions are more fully explained in <link 
anchor="java-namespace-declare">Declare the namespace</link>.</p>
   </s3>
   <s3 title="Implicit DTD for lxslt:component">
   <source>&lt;!ELEMENT lxslt:component (lxslt:script)&gt;
   &lt;!ATTLIST lxslt:component
  -  prefix CDATA #IMPLIED
  -  namespace-uri CDATA #IMPLIED
  -  elements NMTOKENS #REQUIRED
  -  functions NMTOKENS #REQUIRED&gt;
  +  prefix CDATA #REQUIRED
  +  elements NMTOKENS #IMPLIED
  +  functions NMTOKENS #IMPLIED&gt;
   
  -&lt;!ELEMENT lxslt:script EMPTY)&gt;
  +&lt;!ELEMENT lxslt:script (#PCDATA | EMPTY)?&gt;
   &lt;!ATTLIST lxslt:script
     lang CDATA #REQUIRED
     src CDATA #IMPLIED&gt;</source>
  @@ -212,19 +208,19 @@
   <p>Extension elements pass the extension two objects:</p>
   <ul>
   <li><jump 
href="apidocs/org/apache/xalan/extensions/XSLProcessorContext.html">org.apache.xalan.extensions.XSLProcessorContext</jump>,
 which provides access to the XSL processor, the XML source tree, the 
stylesheet tree, the current context node, and the current mode (if 
any).<br/><br/></li>
  -<li>org.w3c.dom.Element, which provides the API for interacting with the 
extension element.</li>
  +<li><jump 
href="apidocs/org/apache/xalan/xslt/ElemExtensionCall.html">org.apache.xalan.xslt.ElemExtensionCall</jump>,
 which provides the API for interacting with the extension element.</li>
   </ul>
  -<p>You can use the Element getAttribute(String name) method, for example, to 
read element attributes.</p>
  +<p>You can use the ElemExtensionCall getAttribute(String name) method, for 
example, to read element attributes in their raw form.  Use the 
getAttribute(String name, Node sourceNode, XSLTEngineImpl processor) method to 
evaluate the attribute as an attribute value template.  Note that the method 
names are the same but the method signatures are different.  For full details, 
see the <jump 
href="apidocs/org/apache/xalan/xslt/ElemExtensionCall.html">Javadoc</jump> for 
the ElemExtensionCall class.</p>
   <s3 title="Implementing an extension element">
   <p>For each extension element in a namespace, the implementation must be a 
Java method with the following signature, or the scripting language 
equivalent:</p>
   <p><code><ref>Type 
element</ref>(org.apache.xalan.extensions.XSLProcessorContext, </code><br/>
  
-<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.w3c.dom.Element
 extensionElement)</code></p>
  -<p>where <ref>Type</ref> designates the return type and <ref>element</ref> 
is the local part of the extension element name (the element name without the 
namespace prefix).</p>
  
+<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.apache.xalan.xslt.ElemExtensionCall
 extensionElement)</code></p>
  +<p>where <ref>Type</ref> designates the return type and <ref>element</ref> 
is the local part of the extension element name (the element name without the 
namespace prefix). In the method signature, you may also use superclasses of 
the indicated types.</p>
   <p>If the extension element is implemented in a loosely typed scripting 
language, such as JavaScript, the arguments and return value are untyped.</p>
   <p><em>Caution:</em> The value returned by an extension element is placed in 
the transformation result. If you are not interested in a return value, use a 
public void Java method or return null from a scripting language function.</p>
   <p>Java example: <code>public void myElement</code><br/>
   
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(org.apache.xalan.xslt.XSLProcessorContext,
 </code><br/>
  
-<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.w3c.dom.Element
 extensionElement)</code></p>
  
+<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.apache.xalan.xslt.ElemExtensionCall
 extensionElement)</code></p>
   <p>JavaScript example: <code>function myElement(xslProcContext, 
element)</code></p>
   <p>The <link idref="extensionslib" anchor="redirect">Redirect 
extension</link> in the extensions library contains three extension 
elements.</p>
   </s3>
  @@ -233,8 +229,8 @@
   <s2 title="Using extension functions">
   <p>Extension functions may include arguments of any type and return a value 
of any type.</p>
   <p>XSLT recognizes five data types: node-set, result-tree-fragment, string, 
boolean, and number. You can use XPath expressions to set variables with values 
of these types. You can also pass literals for string, boolean, and number 
arguments. If you want to pass an argument of a type that XSLT does not 
recognize, use another extension function to return an object of that type. The 
stylesheet that appears in <link anchor="format-date-stylesheet">Formatting a 
date</link>, for example uses extension functions to return a Date object and a 
SimpleDateFormat object, and then uses these objects to call another extension 
function.</p>
  -<s3 title="Data type mapping">
  -<p>The XSLT data types map to Java data types as follows:</p>
  +<s3 title="Data type mapping and method selection">
  +<p>When calling an extension function written in a language other than Java, 
objects of the following Java classes will always be passed to the extension 
function:</p>
     <table>
       <tr>
         <th>XSLT Type</th>
  @@ -242,7 +238,7 @@
       </tr>
       <tr>
          <td>Node-Set</td>
  -       <td>org.w3c.dom.NodeList</td>
  +       <td>org.w3c.dom.traversal.NodeIterator</td>
       </tr>
       <tr>
          <td>String</td>
  @@ -250,43 +246,139 @@
       </tr>
       <tr>
          <td>Boolean</td>
  -       <td>boolean or Boolean</td>
  +       <td>java.lang.Boolean</td>
       </tr>
       <tr>
          <td>Number</td>
  -       <td>double or Double</td>
  +       <td>java.lang.Double</td>
       </tr>
       <tr>
          <td>Result Tree Fragment</td>
          <td>org.w3c.dom.DocumentFragment</td>
       </tr>
     </table>
  -<p>For the XSLT boolean and number types, &xslt4j; first looks for a method 
with the corresponding Java primitive type. If it does not find such a method, 
it looks for a method with the object type. In the case of the foo:bar(10) 
static method call, for example, &xslt4j; first looks for bar(double). If it 
does not find such a method, it looks for for bar(java.lang.Double).</p>
  -<p>When an extension function is invoked, the arguments are converted as 
indicated above, and sent to the extension. No conversion takes place for 
arguments of non-XSLT types.</p>
  -<anchor name="ext-func-calls"/>
  +<p>Any non-XSLT type is passed without coversion.</p>
  +<p>When calling an extension function written in Java, the extension 
function signature can specify any of the indicated Java types, as explained 
below:</p>
  +  <table>
  +    <tr>
  +      <th>XSLT Type</th>
  +      <th>Java Types</th>
  +    </tr>
  +    <tr>
  +       <td>Node-Set</td>
  +       <td>org.w3c.dom.traversal.NodeIterator, org.w3c.dom.NodeList, 
org.w3c.dom.Node or its subclasses, java.lang.String, java.lang.Object, char, 
[double, float, long, int, short, byte,] boolean</td>
  +    </tr>
  +    <tr>
  +       <td>String</td>
  +       <td>java.lang.String, java.lang.Object, char, [double, float, long, 
int, short, byte,] boolean</td>
  +    </tr>
  +    <tr>
  +       <td>Boolean</td>
  +       <td>boolean, [java.lang.Boolean, java.lang.Object,] 
java.lang.String</td>
  +    </tr>
  +    <tr>
  +       <td>Number</td>
  +       <td>double, java.lang.Double, float, long, int, short,char, byte, 
boolean, java.lang.String, java.lang.Object</td>
  +    </tr>
  +    <tr>
  +       <td>Result Tree Fragment</td>
  +       <td>org.w3c.dom.traversal.NodeIterator, org.w3c.dom.DocumentFragment, 
org.w3c.dom.Node or its other subclasses, java.lang.string, java.lang.Object, 
char, [double, float, long, int, short, byte,] boolean</td>
  +    </tr>
  +    <tr>
  +       <td>Non-XSLT Type</td>
  +       <td>the native type or any of its superclasses, double, float, long, 
int, short, char, byte, java.lang.String</td>
  +    </tr>
  +  </table>
  +<p>When calling extension functions written in Java, &xslt4j; selects the 
method to call as follows:</p>
  +<ol>
  +  <li>&xslt4j; selects all methods whose name matches the extension function 
name as specified in <link anchor="ext-func-calls">Extension function Java 
calls</link>.</li>
  +  <li>From this list of methods, &xslt4j; determines which methods are 
<ref>qualified</ref>.</li>
  +  <li>Each qualified method is assigned a score based on the table shown 
above. To assign the score to a given method, &xslt4j; examines each of the 
XSLT argument types in the function invocation in the stylesheet. For each 
argument, the appropriate row in the table above is selected. Then, the 
corresponding Java parameter type in the method signature in the Java program 
is scored. Types which appear earlier in the list are given a higher score.  
That is, the list appears in order of scoring preference from highest to 
lowest. Types shown in square brackets have equal priority.</li>
  +  <li>The method with the highest score is invoked after the arguments are 
converted to the appropriate type. If more than one method has the highest 
score, an exception is thrown.</li>
  +</ol>
  +<p>Any extension function written in Java can have a first parameter of type 
<code>org.apache.xalan.extensions.ExpressionContext</code>. Any method with an 
ExpressionContext as the first parameter will score higher than any method 
which does not have an ExpressionContext as a first parameter.</p>
   </s3>
  +<anchor name="ext-func-calls"/>
   <s3 title="Extension function Java calls">
  -<p>Use the following syntax to instantiate Java objects and to call 
methods:</p>
  -<p><code><ref>prefix</ref>:<ref>FQCN</ref>.new (<ref>args</ref>)</code></p>
  -<p>where <ref>prefix</ref> is the extension namespace prefix and 
<ref>FQCN</ref> is the fully qualified class name of which a new instance is to 
be created with the <ref>args</ref> constructor arguments (if any).<br/>
  -Example: <code>variable myHash</code><br/>
  
-<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select"my-ext:java.util.Hashtable.new()"</code></p>
  -
  -<p><code><ref>prefix</ref>:<ref>FQCN.methodName</ref> 
(<ref>args</ref>)</code></p>
  -<p>where <ref>FQCN</ref> is the fully qualified class name whose static 
method <ref>methodName</ref> is to be invoked using the <ref>args</ref> 
arguments.<br/>
  -Example: <code>variable new-pop</code><br/>
  
-<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-ext:java.lang.Integer.valueOf(string(@population))"</code></p>
  -
  -<p><code><ref>prefix</ref>:<ref>methodName</ref> (<ref>object</ref>, 
<ref>args</ref>)</code></p>
  -<p>where <ref>methodName</ref> is the name of the method to invoke on 
<ref>object</ref> with the <ref>args</ref> arguments.<br/>
  -Example: <code>variable old-pop </code><br/>
  -<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-ext:put($myHash, 
string(@region), $new-pop)"</code></p>
  +<p>The technique for instantiating Java objects and calling Java methods 
depends on the format of the extension namespace that was declared.  See <link 
anchor="java-namespace-declare">Declare the namespace</link> for the three 
different formats of namespace declarations for Java extensions. For each 
namespace format, the section below describes how to instantiate an object, how 
to invoke an instance method, and how to invoke a static method. The sections 
below explain, for each syntax, which methods are <ref>qualified</ref> for 
method selection as described in the preceeding section.</p>
  +<s4 title="Class format namespace">
  +<p><br/><em>To create an instance of an object</em>:
  +<br/><code><ref>prefix</ref>:new (<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix. A new instance 
is to be created with the <ref>args</ref> constructor arguments (if any). All 
constructor methods are qualified for method selection.
  +<br/>Example: <code>&lt;xsl:variable name="myType"</code>
  
+<br/><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-class:new()"&gt;</code></p>
  +
  +<p><em>To invoke an instance method on a specified object</em>:
  +<br/><code><ref>prefix</ref>:<ref>methodName</ref> (<ref>object</ref>, 
<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix and 
<ref>methodName</ref> is the name of the method to invoke on <ref>object</ref> 
with the <ref>args</ref> arguments. <ref>object</ref> must be an object of the 
class indicated by the namespace declaration.  Otherwise, the case shown 
immediately below will apply. Only instance methods with  the name 
<ref>methodName</ref> are qualified methods. If a matching method is found, 
<ref>object</ref> will be used to identify the object instance and 
<ref>args</ref> will be passed to the invoked method.
  +<br/>
  +Example: <code>&lt;xsl:variable name="new-pop"</code><br/>
  +<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-class:valueOf($myType, 
string(@population))"&gt;</code></p>
  +
  +<p><em>To invoke an instance method on a default object</em>:
  +<br/><code><ref>prefix</ref>:<ref>methodName</ref> 
(<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix and 
<ref>methodName</ref> is the name of the method to invoke with the 
<ref>args</ref> arguments. The first <ref>arg</ref>, if any, must not be an 
object of the class indicated by the namespace declaration.  Otherwise, the 
case shown immediately above will apply. Only instance methods with the name 
<ref>methodName</ref> are qualified methods. If a matching method is found, a 
default instance of the class will be created if it does not already exist.
  +<br/>
  +Example: <code>&lt;xsl:variable name="new-pop"</code><br/>
  
+<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-class:valueOf(string(@population))"&gt;</code></p>
  +
  +<p><em>To invoke a static method</em>:
  +<br/><code><ref>prefix</ref>:<ref>methodName</ref> 
(<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix and 
<ref>methodName</ref> is the name of the method to invoke with the 
<ref>args</ref> arguments. Only static methods with the name 
<ref>methodName</ref> are qualified methods. If a matching method is found, 
<ref>args</ref> will be passed to the invoked static method.
  +<br/>
  +Example: <code>&lt;xsl:variable name="new-pop"</code><br/>
  
+<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-class:printit(string(@population))"&gt;</code></p>
  +</s4>
  +<s4 title="Package format namespace">
  +<p><br/><em>To create an instance of an object</em>:
  +<br/><code><ref>prefix</ref>:<ref>subpackage</ref>.<ref>class</ref>.new 
(<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix, 
<ref>subpackage</ref> is the rest of the package name (the beginning of the 
package name was in the namespace declaration), and <ref>class</ref> is the 
name of the class. A new instance is to be created with the <ref>args</ref> 
constructor arguments (if any). All constructor methods are qualified for 
method selection.
  +<br/>Example: <code>&lt;xsl:variable name="myType"</code>
  
+<br/><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-package:extclass.new()"&gt;</code></p>
  +
  +<p><em>To invoke an instance method on a specified instance</em>:
  +<br/><code><ref>prefix</ref>:<ref>methodName</ref> (<ref>object</ref>, 
<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix and 
<ref>methodName</ref> is the name of the method to invoke on <ref>object</ref> 
with the <ref>args</ref> arguments. Only instance methods of the 
<ref>object</ref> with the name <ref>methodName</ref> are qualified methods. If 
a matching method is found, <ref>object</ref> will be used to identify the 
object instance and <ref>args</ref> will be passed to the invoked method.
  +<br/>
  +Example: <code>&lt;xsl:variable name="new-pop"</code><br/>
  +<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-package:valueOf($myType, 
string(@population))"&gt;</code></p>
  +
  +<p><em>To invoke a static method</em>:
  
+<br/><code><ref>prefix</ref>:<ref>subpackage</ref>.<ref>class</ref>.<ref>methodName</ref>
 (<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix, 
<ref>subpackage</ref> is the rest of the package name (the beginning of the 
package name was in the namespace declaration), <ref>class</ref> is the name of 
the class, and <ref>methodName</ref> is the name of the method to invoke with 
the <ref>args</ref> arguments. Only static methods with the name 
<ref>methodName</ref> are qualified methods. If a matching method is found, 
<ref>args</ref> will be passed to the invoked static method.
  +<br/>
  +Example: <code>&lt;xsl:variable name="new-pop"</code><br/>
  
+<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="my-package:extclass.printit(string(@population))"&gt;</code></p>
  +<note>Unlike the class format namespace, there is no concept of a default 
object since the namespace declaration does not identify a unique class.</note>
  +</s4>
  +<s4 title="Java format namespace">
  +<p><br/><em>To create an instance of an object</em>:
  +<br/><code><ref>prefix</ref>:<ref>FQCN</ref>.new (<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix for the Java 
namespace and <ref>FQCN</ref> is the fully qualified class name of the class 
whose constructor is to be called. A new instance is to be created with the 
<ref>args</ref> constructor arguments (if any). All constructor methods are 
qualified for method selection.
  +<br/>Example: <code>&lt;xsl:variable name="myHash"</code>
  
+<br/><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="java:java.util.Hashtable.new()"&gt;</code></p>
  +
  +<p><em>To invoke an instance method on a specified instance</em>:
  +<br/><code><ref>prefix</ref>:<ref>methodName</ref> (<ref>object</ref>, 
<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix and 
<ref>methodName</ref> is the name of the method to invoke on <ref>object</ref> 
with the <ref>args</ref> arguments. Only instance methods of the 
<ref>object</ref> with the name <ref>methodName</ref> are qualified methods. If 
a matching method is found, <ref>object</ref> will be used to identify the 
object instance and <ref>args</ref> will be passed to the invoked method.
  +<br/>
  +Example: <code>&lt;xsl:variable name="new-pop"</code><br/>
  +<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="java:put($myHash, 
string(@region), $newpop)"&gt;</code></p>
  +
  +<p><em>To invoke a static method</em>:
  +<br/><code><ref>prefix</ref>:<ref>FQCN</ref>.<ref>methodName</ref> 
(<ref>args</ref>)</code></p>
  +<p>where <ref>prefix</ref> is the extension namespace prefix, 
<ref>FQCN</ref> is the fully qualified class name of the class whose static 
method is to be called, and <ref>methodName</ref> is the name of the method to 
invoke with the <ref>args</ref> arguments. Only static methods with the name 
<ref>methodName</ref> are qualified methods. If a matching method is found, 
<ref>args</ref> will be passed to the invoked static method.
  +<br/>
  +Example: <code>&lt;xsl:variable name="new-pop"</code><br/>
  
+<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select="java:java.lang.Integer.valueOf(string(@population))"&gt;</code></p>
  +<note>Unlike the class format namespace, there is no concept of a default 
object since the namespace declaration does not identify a unique class.</note>
  +</s4>
   </s3>
   
   <s3 title="Passing Nodes to java">
   <p>Please keep in mind that <em>all</em> LocationPath expressions return a 
node-set, even if the expression only returns a single attribute or a text node 
(node-sets with one member). You can use the XSLT string() function (as in the 
syntax examples above) to convert a node-set value to string, and the number() 
function to convert a node-set value to number (a double).</p>
   <p>If you want to pass a node-set to an extension function, set up a Java 
method to accept an 
  -org.w3c.dom.NodeList (or an org.apache.xalan.xpath.MutableNodeList, which 
extends NodeList, if you want to modify the nodes).</p>
  +org.w3c.dom.NodeList (or an org.apache.xpath.NodeSet, which implements 
NodeList, if you want to modify the nodes).</p>
   <p>Suppose, for example, you have a myExtensions.ProcessNodes class with the 
following doSomething method:</p>
   <p><code>public static boolean doSomething(org.w3c.dom.NodeList 
nList)</code></p>
   <p>Assuming you set up this extension in the node-ext namespace, any of the 
following extension calls from a stylesheet are syntactically possible:</p>
  @@ -303,21 +395,36 @@
   <p>The NodeList is in fact a list of references into the XML document, so 
keep in mind that getNextSibling(), for example, gets you the next sibling in 
the document, which may not be the next Node in the NodeList.</p>
   </s3>
   <s3 title="Implementing extension functions">
  -<p>For each extension function in a namespace, the implementation must 
include a Java method with the following signature, or the scripting language 
equivalent:</p>
  +<p>For each extension function in a namespace which is implemented in a 
language other than Java, the implementation must include a method with the 
following signature, or the scripting language equivalent:</p>
   <p><code>public <ref> object function</ref>(<ref>args</ref>)</code></p>
   <p>where <ref>object</ref> is the return type, <ref>function</ref> is the 
local part of the extension function name (the function name without the 
namespace prefix), and <ref>args</ref> correspond to the arguments in the 
function call.</p>
  +<p>In addition, for extension functions implemented in Java, the 
implementation may include either a Java method with the signature shown above 
or one with the following signature:</p>
  +<p><code>public <ref> object 
function</ref>(org.apache.xalan.extensions.ExpressionContext, 
<ref>args</ref>)</code></p>
   </s3>
   </s2><anchor name="java-namespace"/>
  -<s2 title="Alternative: using the predefined java extension namespace">
  -<p>For extension functions implemented in Java, Xalan provides a java 
namespace. When you declare and use the java namespace, you do not use an 
lxslt:component to designate the functions.</p>
  -<p>The java namespace supports the use of extension functions implemented in 
Java. You cannot use this syntax with extension elements or with extensions 
implemented in JavaScript or another scripting language.</p>
  -<s3 title="Declare the Xalan java namespace">
  -<p><code>xmlns:lxslt="http://xml.apache.org/xslt/java";</code></p>
  -</s3>
  -<s3 title="Use the java namespace when you make extension function calls">
  -<p>Use "java" as the prefix with the syntax described in <link 
anchor="ext-func-calls">Extension function Java calls</link>.</p>
  -<p>That is all. You do not need to set an extension-element-prefixes 
attribute, and you do not include an lxslt:component element. Given the absence 
of the lxslt:component element, you cannot use the function-available method to 
determine at runtime whether a Java method call is actually available. </p>
  -<p>Using the java namespace clearly involves less setup than using your own 
namespace, as long as these restrictions are not a problem. Remember that you 
always have the option of setting up your own namespace and extra overhead is 
really minimal.</p>
  +<s2 title="Alternative: using the abbreviated syntax for extensions 
implemented in Java">
  +<p>For extension functions and extension elements implemented in Java, Xalan 
permits an abbreviated syntax. When you use the abbreviated syntax, you do not 
use an lxslt:component to designate the functions.</p>
  +<p>The abbreviated syntax supports the use of extension functions and 
extension elements implemented in Java. You cannot use this syntax with 
extensions implemented in JavaScript or another scripting language.</p>
  +<anchor name="java-namespace-declare"/>
  +<s3 title="Declare the namespace">
  +<p>Declare the namespace for your extensions using one of the following 
three formats. The technique for invoking an extension for each format is 
explained in <link anchor="ext-func-calls">Extension function Java 
calls</link>.</p>
  +<p><em>class format:</em> 
<code>xmlns:my-class="xalan://<ref>FQCN</ref>"</code></p>
  +<p>where <ref>FQCN</ref> is the fully qualified class name.
  +<br/>Examples: <code>xmlns:my-class="xalan://java.util.Hashtable"</code>
  
+<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>xmlns:my-class="xalan://mypackage.myclass"</code></p>
  +<p><em>package format:</em> 
<code>xmlns:my-class="xalan://<ref>PJPN</ref>"</code></p>
  +<p>where <ref>PJPN</ref> is a partial java package name.  That is, it is the 
beginning of or the complete name of a java package.
  +<br/>Examples: <code>xmlns:my-package="xalan://java.util"</code>
  
+<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>xmlns:my-package="xalan://mypackage"</code></p>
  +<p><em>Java format:</em> 
<code>xmlns:java="http://xml.apache.org/xslt/java";</code></p>
  +<note>Although the namespace declarations for the class and package formats 
are shown with the xalan:// prefix, the current implementation for those 
formats will simply use the string to the right of the rightmost forward slash 
as the Java class name. This format is shown in order to comply with W3C 
recommendations for namespace declarations.</note>
  +<note>The class: prefix which was sometimes required in earlier versions of 
&xslt4j; is no longer required.</note>
  +<note>These formats are also available when coding the src attribute of the 
lxslt:script element as explained in <link anchor="setup-script">Set up the 
lxslt:script element</link>.</note>
  +</s3>
  +<s3 title="Use the namespace when you make extension calls">
  +<p>Use the declared prefix with the syntax described in <link 
anchor="ext-func-calls">Extension function Java calls</link>.</p>
  +<p>That is all. You do not include an lxslt:component element. Using the 
abbreviated syntax clearly involves less setup than using the 
lxslt:component/lxslt:script approach.</p>
  +<note>We recommend that, for extensions coded in Java, the abbreviated 
syntax should always be used since the lxslt:component/lxslt:script constructs 
add no functionality.</note>
   </s3><anchor name="ex-java-namespace"/> 
   <s3 title="Example: Formatting a date">
   <p>This example uses extension functions to call the SimpleDateFormat class 
and the IntDate class. IntDate uses String arguments to set up a Date 
object:</p>
  @@ -456,7 +563,7 @@
   
     &lt;lxslt:component prefix="counter"
                      elements="init incr" functions="read"&gt;
  -    &lt;lxslt:script lang="javaclass" src="MyCounter"/&gt;
  +    &lt;lxslt:script lang="javaclass" src="xalan://MyCounter"/&gt;
     &lt;/lxslt:component&gt;
   
     &lt;xsl:template match="/"&gt;
  @@ -556,4 +663,4 @@
   <p>This stylesheet produces the same output as the preceding example with 
the Java extension.</p>
   </s3>
   </s2>
  -</s1>
  \ No newline at end of file
  +</s1>
  
  
  

Reply via email to