You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by dl...@apache.org on 2001/05/14 18:07:45 UTC

cvs commit: xml-xalan/java/xdocs/sources/xsltc xsltc_trax.xml index.xml xsl_whitespace_design.xml xsltc_compiler.xml

dleslie     01/05/14 09:07:44

  Modified:    java/xdocs/sources xalan-collate.xsl xalan-jlocal.xml
                        xsltc.xml
               java/xdocs/sources/xalan xsltc_usage.xml
               java/xdocs/sources/xsltc index.xml xsl_whitespace_design.xml
                        xsltc_compiler.xml
  Added:       java/xdocs/sources/xsltc xsltc_trax.xml
  Log:
  Added Todd Miller's "Integration of the Translet API and TrAX"
  
  Revision  Changes    Path
  1.4       +1 -0      xml-xalan/java/xdocs/sources/xalan-collate.xsl
  
  Index: xalan-collate.xsl
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xalan-collate.xsl,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- xalan-collate.xsl	2001/01/26 14:31:06	1.3
  +++ xalan-collate.xsl	2001/05/14 16:06:59	1.4
  @@ -12,6 +12,7 @@
       <chapter id="samples"><xsl:copy-of select="document('xalan/samples.xml')"/></chapter>
       <chapter id="commandline"><xsl:copy-of select="document('xalan/commandline.xml')"/></chapter>
       <chapter id="usagepatterns"><xsl:copy-of select="document('xalan/usagepatterns.xml')"/></chapter>
  +    <chapter id="trax"><xsl:copy-of select="document('xalan/trax.xml')"/></chapter>
       <chapter id="extensions"><xsl:copy-of select="document('xalan/extensions.xml')"/></chapter>
       <chapter id="extensionslib"><xsl:copy-of select="document('xalan/extensionslib.xml')"/></chapter>
       <chapter id="readme"><xsl:copy-of select="document('xalan/readme.xml')"/></chapter>
  
  
  
  1.16      +4 -2      xml-xalan/java/xdocs/sources/xalan-jlocal.xml
  
  Index: xalan-jlocal.xml
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xalan-jlocal.xml,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- xalan-jlocal.xml	2001/05/04 20:22:16	1.15
  +++ xalan-jlocal.xml	2001/05/14 16:07:02	1.16
  @@ -61,7 +61,7 @@
   <book title="Xalan XSL Transformer User's Guide" copyright="2000 The Apache Software Foundation">
     <resources source="sbk:/sources/xalan/resources.xml"/>
     <document id="whatsnew" label="What's New" source="xalan/whatsnew.xml"/>
  -  <external href="xsltc/index.html" label="XSLTC Translets"/>  
  +  <document id="xsltc_usage" label="XSLTC Translets" source="xalan/xsltc_usage.xml"/>
     <separator/>
     <document id="overview" label="Overview" source="xalan/overview.xml"/>
     <document id="getstarted" label="Getting Started" source="xalan/getstarted.xml"/>
  @@ -82,9 +82,11 @@
     <document id="readme" label="Release Notes" source="xalan/readme.xml"/>
     <separator/>
     <external href="design/design2_0_0.html" label="Xalan 2 Design"/>
  +  <external href="xsltc/index.html" label="XSLTC Design"/>
     <separator/>
     <external href="readme.html#bugs" label="Bugs"/>
     <external href="http://xml.apache.org/xalan-j/test/overview.html" label="Testing"/>
     <separator/>
  -  <external href="todo.html#developer-list" label="Credits"/>  
  +  <external href="todo.html#developer-list" label="Credits"/>
  +  <external href="xsltc/todo.html#developer-list" label="XSLTC Credits"/>  
   </book>
  
  
  
  1.2       +4 -0      xml-xalan/java/xdocs/sources/xsltc.xml
  
  Index: xsltc.xml
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xsltc.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- xsltc.xml	2001/05/04 20:22:19	1.1
  +++ xsltc.xml	2001/05/14 16:07:04	1.2
  @@ -59,6 +59,10 @@
               
    <separator/>
    
  +   <document id="xsltc_trax"
  +             label="Translet &amp; TrAX"
  +             source="xsltc/xsltc_trax.xml"/>
  + <separator/>
    <external href="todo.html" label="To-do list"/>
               
   </book>
  
  
  
  1.3       +4 -3      xml-xalan/java/xdocs/sources/xalan/xsltc_usage.xml
  
  Index: xsltc_usage.xml
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xalan/xsltc_usage.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- xsltc_usage.xml	2001/05/10 18:23:19	1.2
  +++ xsltc_usage.xml	2001/05/14 16:07:21	1.3
  @@ -64,7 +64,7 @@
     <li><link anchor="classpath">Setting the system classpath for XSLTC</link></li>
     <li><link anchor="compile">Compiling translets from the command line</link></li>
     <li><link anchor="run">Running translets from the command line</link></li>
  -  <li><link anchor="api">Using the XSLTC API</link></li>
  +  <li><link anchor="api">Calling XSLTC with the TrAX/JAXP API</link></li>
     <li><link anchor="constraints">XSLTC usage constraints</link></li>  
   </ul>
   <p>See also: <jump href="xsltc/index.html">XSLTC Design</jump></p>
  @@ -293,8 +293,9 @@
       the flag (-u) is optional.</p>
   </s3>
   </s2><anchor name="api"/>
  -<s2 title="Using the translet API">
  -<p></p>
  +<s2 title="Calling XSLTC with the TrAX/JAXP API">
  +<p>G. Todd Miller has begun integrating the translet with the TrAX/JAXP API. Accordingly, it is now possible to set a system property and use a TransformerFactory to generate a Transformer that performs a transformation by compiling and running a translet. He plans to add support soon for wrapping a translet with the Templates interface, which may then be used for repeated transformations.</p>
  +<p><ref>Details coming soon!</ref></p>
   </s2><anchor name="constraints"/>
   &xsltc_constraints;
   </s1>
  
  
  
  1.3       +3 -1      xml-xalan/java/xdocs/sources/xsltc/index.xml
  
  Index: index.xml
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xsltc/index.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- index.xml	2001/05/10 18:07:44	1.2
  +++ index.xml	2001/05/14 16:07:28	1.3
  @@ -61,7 +61,9 @@
       - updated 06.03.2001</ref></p>
   <ul>
     <li><link anchor="compiler">Compiler design</link></li>
  -  <li><link anchor="runtime">Runtime library/DOM design</link></li>  
  +  <li><link anchor="runtime">Runtime library/DOM design</link></li>
  +  <li><link idref="xsltc_trax">Integration of the Translet API and TrAX</link> (by G Todd Miller)</li> 
  +   
   </ul>
   <p>See also <jump href="../xsltc_usage.html">Using XSLTC</jump>.</p>
   <anchor name="compiler"/>
  
  
  
  1.2       +3 -3      xml-xalan/java/xdocs/sources/xsltc/xsl_whitespace_design.xml
  
  Index: xsl_whitespace_design.xml
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xsltc/xsl_whitespace_design.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- xsl_whitespace_design.xml	2001/05/04 20:20:43	1.1
  +++ xsl_whitespace_design.xml	2001/05/14 16:07:30	1.2
  @@ -108,7 +108,7 @@
       }
   </source>
   
  -  <p>The characters are checked in proable order.</p>
  +  <p>The characters are checked in probable order.</p>
   
     <p> The DOM has a bit-array that is used to  tag text-nodes as strippable
     whitespace nodes:</p>
  @@ -128,7 +128,7 @@
     works in a way as a stack, where you "push" a new strip/preserve setting
     together with the node in which this setting was determined. This means that
     for every time the DOM builder encounters an <code>xml:space</code> attribute
  -  it will invoke a method on an instance of teh WhitespaceHandler class to
  +  it will invoke a method on an instance of the WhitespaceHandler class to
     signal that a new preserve/strip setting has been encountered. This is done
     in the <code>makeAttributeNode()</code> method. The whitespace handler stores the
     new setting and pushes the current element node on its stack. When the
  @@ -243,7 +243,7 @@
       <li>
         The translet can, prior to starting to traverse the DOM, send a reference
         to the tables containing information on which nodes we want stripped to
  -      the DOM interface. The DOM interface is the responsible for hiding all
  +      the DOM interface. The DOM interface is then responsible for hiding all
         stripped whitespace nodes from the iterators and the translet. A problem
         with this approach is that we want to omit the DOM interface layer if
         the translet is only accessing a single DOM. The DOM interface layer will
  
  
  
  1.2       +5 -5      xml-xalan/java/xdocs/sources/xsltc/xsltc_compiler.xml
  
  Index: xsltc_compiler.xml
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xsltc/xsltc_compiler.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- xsltc_compiler.xml	2001/05/04 20:20:43	1.1
  +++ xsltc_compiler.xml	2001/05/14 16:07:32	1.2
  @@ -79,7 +79,7 @@
       <ul>
         <li><code>com.sun.xslt.compiler.XPathParser</code></li>
       </ul>
  -    <p>Both parsers are encapsulates in XSLTC's parser class:</p>
  +    <p>Both parsers are encapsulated in XSLTC's parser class:</p>
       <ul>
         <li><code>com.sun.xslt.compiler.Parser</code></li>
       </ul>
  @@ -147,10 +147,10 @@
       </s3>
        <s3 title="Creating the Abstract Syntax Tree from the DOM">
       <p>What we have to do next is to create a tree that also holds the XSL
  -    specific elements; XPath expressions and patters (with possible filters)
  +    specific elements; XPath expressions and patterns (with possible filters)
       and calls to XSL functions. This is done by parsing the DOM and creating an
       instance of a subclass of 'SyntaxTreeNode' for each node in the DOM. A node
  -    in the DOM containing an XSL instruction (ex. "xsl:template") results in an
  +    in the DOM containing an XSL instruction (for example, "xsl:template") results in an
       instance of the correspoding class derived from the HashTable created by
       the parser (in this case in instance of the 'Template' class).</p>
   
  @@ -179,7 +179,7 @@
       expression. This is done by calling 'typeCheck()' on the root-node in the
       XSL tree. Each SyntaxTree node is responsible for its own type checking
       (ie. the <code>typeCheck()</code> method must be overridden). Let us say that
  -    out pattern was:</p>
  +    our pattern was:</p>
       <p><code>&lt;xsl:value-of select=&quot;1+2.73&quot;/&gt;</code></p>
       <p><img src="typecast.gif" alt="typecast.gif"/></p>
       <p><ref>Figure 3: XPath expression type conflict</ref></p>
  @@ -202,7 +202,7 @@
         <li><link anchor="instrfunc">Compiling XSL instructions and functions</link></li>            
       </ul>
       <p>A general rule is that all classes that represent elements in the XSL
  -    tree/document, i.e. classes that inherit from SyntaxTreeNode output
  +    tree/document, i.e., classes that inherit from SyntaxTreeNode, output
       bytecode in the 'translate()' method.</p>
       <anchor name="toplevelelem"/>
       <s3 title="Compiling top-level elements">
  
  
  
  1.1                  xml-xalan/java/xdocs/sources/xsltc/xsltc_trax.xml
  
  Index: xsltc_trax.xml
  ===================================================================
  <?xml version="1.0" standalone="no"?>
  <!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
  <!-- 
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, Sun
   * Microsystems., http://www.sun.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   -->
  <s1 title="The Translet API &amp; TrAX">
  <p><ref>By</ref> <jump href="mailto:todd.miller@east.sun.com">G. Todd Miller</jump> -updated May 11, 2001</p>
  <ul>
    <li><link anchor="abstract">Abstract</link></li>
    <li><link anchor="trax">TrAX</link></li>
    <li><link anchor="integrate">Translet Integration</link></li>
    <li><link anchor="factory">SAXTransformerFactory for Translets</link></li>
    <li><link anchor="transform">AbstractTranslet transform() method</link></li>
    <li><link anchor="conclusion">Conclusion</link></li>
    <li><link anchor="appendix">Appendix</link></li>      
  </ul>
  <anchor name="abstract"/>
  <s2 title="Abstract">
  <p>This document describes what I have so far as a prototype for integrating
  Translets with the JAXP TrAX. In a nutshell, a new Transformer factory
  class has be written that extends the JAXP SAXTransformerFactory class.
  The newfactory delivers Translets as Transformers, and creates Templates.
  Calling the Transformer transform() method will cause the given XML
  document to be transformed by a translet that has been compiled from the
  supplied stylesheet. The switch that determines what XSLT processor gets
  to transform the XML document is based on the value of a JAXP system
  property for the Transformers factory.</p>
  </s2><anchor name="trax"/>
  <s2 title="TrAX">
  <p>The Java API for XML Processing (JAXP) includes an XSLT framework based on the
  Transformation API for XML (TrAX). In a typical JAXP transformation application
  the steps involved in transforming an XML document with an XSLT stylesheet are: (1)
  create an instance of the TransformerFactory class, (2) from the factory instance and
  a given XSLT stylesheet, create a new Transformer object, (3) call the Transformer
  objects transform() method on a given XML document and a specified Result object.
  Alternatively, one could also ask the instance of the TransformerFactory for
  a Templates object given an XSLT stylesheet. From the Templates object, a new
  Transformer can be created, and again, its transform() method can be called with
  an XML document and specified Result object.</p>
  <p>The code below illustrates a simple JAXP transformation application (Proto.java)
  that creates the Transformer directly.</p>
  <source>import javax.xml.transform.stream.StreamSource;
  import javax.xml.transform.stream.StreamResult;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerFactory;
  
  public class Proto {
    public static void main(String[] args){
      Proto app = new Proto();
      app.run(args);
    }
  
    public void run(String[] args){
      if (args.length != 2) {
        usage();
      }
      String inputFilename = args[0];
      String stylesheet = args[1];
      Transformer transformer;
      TransformerFactory factory = TransformerFactory.newInstance();
      try {
        transformer = factory.newTransformer(new StreamSource(stylesheet));
        transformer.transform(new StreamSource(inputFilename),
                              new StreamResult(System.out));
      } catch (Exception e) {
        // nothing...
      }
    }
  
    public void usage() {
      System.err.println(
         "Usage: run &lt;xml_file&gt; &lt;xsl_file&gt;");
      System.exit(1);
    }
  }</source>
  <p>The use of Templates is useful when multiple instances of the same transformer
  are needed. For example transforming multiple documents by the same transformer,
  each working in a separate thread. In this case, the TransformerFactory is used to
  create a Templates object for a given stylesheet. Each Transformer instance is then
  created by the Templates object. In this way the Templates object can compile the
  stylesheet once, and each time a new instance of the transformer is asked for, a clone is
  provided rather than recompile the stylesheet again and again. The Proto class above
  would be modified as follows:</p>
  <source>try {
    Templates templates = factory.newTemplates(new StreamSource(stylesheet));
    transformer = templates.newTransformer();
    transformer.transform(new StreamSource(inputFilename),
                          new StreamResult(System.out));
  } catch (Exception e) {
    // nothing...
  }</source>
  <p>The JAXP TransformerFactory is configurable. The API supports configuring the
  factory to: (1) use attributes which are passed down to the underlying XSL processor,
  these are vendor dependent, (2) register an ErrorListener that provides callbacks
  to handle error and warning message generated by the XSL processor, (3) register
  an URIResolver which can be used to resolve URIs encountered in xsl:include,
  xsl:import,anddocument() functions.</p>
  <p>The JAXP TransformerFactory can be queried at runtme to discover what features
  it supports. For example, an application might want to know if a particular factory
  implementation supports the use of SAX events as a source, or whether it can write
  out transformation results as a DOM. The factory API queries with the getFeature()
  method. In the Proto code above, I could add the following code before the try-catch
  block:</p>
  <source>if (!(factory.getFeature(StreamSource.FEATURE)) ||
      !(factory.getFeature(StreamResult.FEATURE))) {
         System.err.println(
           "Stream Source/Result not supported by Transformer Factory\n" +
           "exiting.");
         System.exit(1);
  }</source>
  </s2><anchor name="integrate"/>
  <s2 title="Translet Integration">
  <p>The crux of the integration strategy is the pluggable TransformerFactory class. The
  JAXP specifies that the actual TransformerFactory implementation be controlled by the
  a Java system property (javax.xml.transformer.TransformerFactory) . This system property can be specified in the usual ways, for
  example in a properties file or on the command line as a -D optionpassed to thejava
  engine itself. The strategy involves writing a TransformerFactory for Translets.
  In the JAXP the TransformerFactory is an abstract class. In Xalan, the system
  property specifies the implementation class TransformerFactoryImpl (org.apache.xalan.processor.TransformerFactoryImpl).
   This implementation is an extension of the abstract SAXTransformerFactory class, which in
  turn is an extension of the abstract TransformerFactory class (javax.xml.transform.sax.SAXTransformerFactory).</p>
  <p>In this prototype integration I have constructed an XSLTC TransformerFactory as
  an extension of the abstract SAXTransformerFactory class.</p>
  
  </s2><anchor name="factory"/>
  <s2 title="SAXTransformerFactory for Translets">
  <p>The prototype XSLTC TransformerFactory needs to accomplish the following:</p>
   <ul>
     <li><link anchor="saxtransformerfactory">Implement the abstract methods of the SAXTransformerFactory class</link></li>
     <li><link anchor="transformerfactory">Implement the abstract methods of the TransformerFactory class</link></li></ul>
  <anchor name="saxtransformerfactory"/>
  <s3 title="SAXTransformerFactory Methods">
  
  <p>The methods of the abstract SAXTransformerFactory class have been stubbed out as
  follows.</p>
  <source>public TemplatesHandler newTemplatesHandler() { return null; }
  public TransformerHandler newTransformerHandler() { return null; }
  public TransformerHandler newTransformerHandler(Source src) {
  return null;
  }
  public TransformerHandler newTransformerHandler(Templates templates) {
  return null;
  }
  public XMLFilter newXMLFilter(Source src) { return null; }
  public XMLFilter newXMLFilter(Templates templates) { return null; }</source>
  <p>These stubbed out methods will need to be replaced with real implementations.</p>
  </s3><anchor name="transformerfactory"/>
  <s3 title="TransformerFactory Methods">
  <p>The methods of the abstract TransformerFactory class have been stubbed out as
  follows:</p>
  <source>public ErrorListener getErrorListener() { return null; }
  public void setErrorListener(ErrorListener listener) { }
  public Object getAttribute(String name) { return null; }
  public void setAttribute(String name, Object value) { }
  public boolean getFeature(String name) { return false; }
  public URIResolver getURIResolver() { return null; }
  public void setURIResolver(URIResolver resolver) { }
  public Source getAssociatedStylesheet(Source src, String media,
  String title, String charset) { return null; }
  public Templates newTemplates(Source xslSrc) throws
  TransformerConfigurationException { return null; }
  public Transformer newTransformer() throws
  TransformerConfigurationException { return null; }</source>
  <p>The methods listed above fall into 4 categories: (1) <link anchor="transformcreation">Transform creation</link>, 
  (2) <link anchor="templatescreation">Templates creation</link>, (3) <link anchor="featurediscovery">feature discovery</link>, 
  and (4) <link anchor="limitations">others that will remain unimplemented at this time</link>.</p>
  <anchor name="transformercreation"/>
  <s4 title="Transformer Creation">
  <p>The JAXP specifies a method that takes the stylesheet as a Source object and returns a
  Transformer.</p>
  <p><code>public Transformer newTransformer(Source xslSrc)</code></p>
  <p>This method needs to return a Transformer to comply with the JAXP API, but also
  needs to return a Translet. In the XSLTC/Xalan API, a Translet is an interface that is
  implemented by the runtime abstract class AbstractTranslet (org.apache.xalan.xsltc.Translet and org.apache.xalan.xsltc.runtime.AbstractTranslet, repectively). Therefore, I had to
  change the AbstractTranslet class so that it will extend the abstract Transformer
  class while still implementing the Translet interface. Once this is done, then the
  newTransformer() method of the new TransformerFactory can return a Translet that
  is a Transformer.</p>
  <p>In order to have AbstractTranslet extend Transformer, several abstract methods
  have to be implemented in AbstractTranslet class. These are:</p>
  <source>public void clearParameters() { }
  public ErrorListener getErrorListener() { return null; }
  public Properties getOutputProperties() throws IllegalArgumentException {
    return null;
  }
  public String getOutputProperty(String name)
    throws IllegalArgumentException{ return ""; }
  //public Object getParameter(String name) { return null; }
  public URIResolver getURIResolver() { return null; }
  public void setErrorListener(ErrorListener listener)
    throws IllegalArgumentException { }
  public void setOutputProperties(Properties props)
    throws IllegalArgumentException { }
  public void setOutputProperty(String name, String value)
    throws IllegalArgumentException { }
  public void setParameter(String name, Object value) { }
  public void setURIResolver(URIResolver resolver) { }
  public void transform(Source xmlsrc, Result outputTarget)
    throws TransformerException { ... }</source>
  <p>Mapping these methods to some existing ones in AbstractTranslet still has to be
  done. In particular the transform() method which is explained further in a following
  section.</p>
  <p>Now that XSLTC�s AbstractTranslet is a Transformer, the new Transformer
  factory class can implement the newTransformer() method. This method needs to do
  two fundamental things: (1) create a translet from the given XSLT stylesheet and (2)
  instantiate the translet so it can be returned as a Transformer.</p>
  <p>The code belows hows my current implementation of the newTransformer() method
  in the new factory class:</p>
  <source>public class ToddsTransformerFactoryImpl extends SAXTransformerFactory {
    ...
    public Transformer newTransformer(Source stylesheet) throws
      TransformerConfigurationException
    {
      XSLTC xsltc = new XSLTC();
      xsltc.init();
      String stylesheetName = stylesheet.getSystemId();
      int index = stylesheetName.indexOf(�.�);
      String transletName = stylesheetName.substring(0,index);
      boolean isSuccessful = true;
      try {
        File file = new File(stylesheetName);
        URL url = file.toURL();
        isSuccessful = xsltc.compile(url);
      } catch (MalformedURLException e) {
          throw new TransformerConfigurationException(
                 "URL for stylesheet �" + stylesheetName +
                 "� can not be formed.");
      }
  
      if (!isSuccessful) {
        throw new TransformerConfigurationException(
            "Compilation of stylesheet �" + stylesheetName + "� failed.");
      }
      
      Translet translet = null;
      try {
        Class clazz = Class.forName(transletName);
        translet = (Translet)clazz.newInstance();
        ((AbstractTranslet)translet).setTransletName(transletName);
       } catch (ClassNotFoundException e) {
           throw new TransformerConfigurationException(
                "Translet class �" + transletName + "� not found.");
       } catch (InstantiationException e) {
           throw new TransformerConfigurationException(
                "Translet class �" + transletName +
                "� could not be instantiated");
       } catch (IllegalAccessException e) {
           throw new TransformerConfigurationException(
               "Translet class �" + transletName + "� could not be accessed.");
       }
       return (AbstractTranslet)translet;
    }
  }</source>
  </s4><anchor name="templatescreation"/>
  <s4 title="Templates Creation">
  <p>The JAXP specifies a method that takes the stylesheet as a Source object and returns a
  Templates object.</p>
  <p><code>public Templates newTemplates(Source xslSrc)</code></p>
  <p>To implement this method I needed to create a new class that would be a Templates
  for Translets object. The new class TransletTemplates (org.apache.xalan.xsltc.runtime.TransletTemplates) implements the Templates
  interface as is shown below:</p>
  <source>package org.apache.xalan.xsltc.runtime;
  
  import javax.xml.transform.Templates;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerConfigurationException;
  import javax.xml.transform.sax.SAXTransformerFactory;
  import org.apache.xalan.xsltc.runtime.AbstractTranslet;
  import java.util.Properties;
  
  public class TransletTemplates implements Templates {
    public TransletTemplates(Transformer translet) {
      _translet = (AbstractTranslet)translet;
    }
  
    public Properties getOutputProperties() { /*TBD*/ return null; }
  
    public Transformer newTransformer() throws
      TransformerConfigurationException
    {
      if (_translet == null) {
        throw new TransformerConfigurationException(
                "Error: Null Translet");
      }
      return _translet;
    }
    private AbstractTranslet _translet = null;
  }</source>
  <p>The factory method newTemplates() simply creates a Transformer for the stylesheet,
  and returns a newTransletTemplates object. The implementation of newTemplates()
  is shown below:</p>
  <source>public class TransformerFactoryImpl extends SAXTransformerFactory {
  ...
    public Templates newTemplates(Source stylesheet) throws
      TransformerConfigurationException
    {
      Transformer translet = newTransformer(stylesheet);
      return new TransletTemplates(translet);
    }
  }</source>
  <p>This implementation only satisfies the JAXP, it does not address caching of previously
  created translets. This type of mechanism belongs in Templates,where a given
  stylesheet will be compiled one time only, but the generated translet can be cloned to
  create multiple instances upon demand.</p>
  </s4><anchor name="featurediscovery"/>
  <s4 title="Feature Discovery">
  <p>The JAXP specifies a method that allows programs to discover what features the factory
  is capable of supporting.</p>
  <p><code>public boolean getFeature(String featureName)</code></p>
  <p>At this time the new transformer factory supports Stream sources and results, and
  the SAX Transform factory feature. The getFeature() implementation is shown below:</p>
  <source>public class TransformerFactoryImpl extends SAXTransformerFactory {
    ...
    public boolean getFeature(String name) {
      if ((StreamSource.FEATURE == name) ||
          (StreamResult.FEATURE == name) ||
          (SAXTransformerFactory.FEATURE == name)) {
          return true;
      } else if ((StreamSource.FEATURE.equals(name))
              || (StreamResult.FEATURE.equals(name))
              || (SAXTransformerFactory.FEATURE.equals(name))) {
           return true;
      } else {
           return false;
      }
    }
  }</source>
  <p>As the other features are implemented, this methods will need to be updated.</p>
  
  </s4><anchor name="limitations"/>
  <s4 title="Limitations">
  <p>As you can see, the prototype will compile the stylesheet everytime. This obviously
  needs to be smarter. This is where the question �do I already have this translet?� needs
  to be answered. Also for now the translet bytecodes are written out to a File in the current
  working directory, and then instantiated using a Class.forName, newInstance()
  pair. This also needs work. Note the return statement, the Translet is cast to an AbstractTranslet
  which now is a Transformer.</p>
  </s4>
  </s3>
  </s2><anchor name="transform"/>
  <s2 title="AbstractTranslet�s transform() Method">
  <p>Now the JAXP program (Proto) shown in the first section has a way to get a Transformer
  factory that can return Translets. The next step of the Proto.java program is
  calling the transform() method and having the Translet process the given XML
  document.</p>
  <p>This requires some surgery in the AbstractTranslet class again. The AbstractTranslet
  already has a transform() method, but its signature is not the same as the
  JAXP Transform signature. In the AbstractTranslet, transform methods expect a DOM
  argument, in some cases a NodeIterator, and a TransletOutputHandler argument. The
  JAXP Transform�s transform() signature requires only the XML document as a Source
  object reference and an outputTarget as a Result object reference. My implementation
  of the JAXP transform() signature is as shown:</p>
  
  <source>public void transform(Source xmlsrc, Result outputTarget)
    throws TransformerException
  {
    doTransform( xmlsrc.getSystemId(),
      ((StreamResult)outputTarget).getOutputStream() );
  }</source>
  <p>This implementation leverages code derived from XSLTC�s DefaultRun class. In
  that class there is a doTransform() method that carries out the work of: (1) parsing the
  input XML document (using a JAXP SAXParserFactory and SAXParser), (2) creating
  a DOMImpl (org.apache.xalan.xsltc.dom.DOMImpl), (3) creating a SAXOutputHandler, and finally (4) calling the translet to
  transform the input XML document (from the DOMImpl).</p>
  <p>The code for doTransform is shown below:</p>
  <source>public abstract class AbstractTranslet extends Transformer implements Translet{
    ...
    private void doTransform(String xmlDocName, OutputStream ostream) {
      try {
        final Translet translet = (Translet)this; // GTM added
  
        // Create a SAX parser and get the XMLReader object it uses
        final SAXParserFactory factory = SAXParserFactory.newInstance();
        final SAXParser parser = factory.newSAXParser();
        final XMLReader reader = parser.getXMLReader();
  
        // Set the DOM�s DOM builder as the XMLReader�s SAX2 content handler
        final DOMImpl dom = new DOMImpl();
        reader.setContentHandler(dom.getBuilder());
        // Create a DTD monitor and pass it to the XMLReader object
        final DTDMonitor dtdMonitor = new DTDMonitor();
        dtdMonitor.handleDTD(reader);
        dom.setDocumentURI(xmlDocName);
        /****************
        if (_uri)
          reader.parse(xmlDocName);
        else
        *******************/
        reader.parse("file:"+(new File(xmlDocName).getAbsolutePath()));
  
        // Set size of key/id indices
        setIndexSize(dom.getSize());
        // If there are any elements with ID attributes, build an index
        dtdMonitor.buildIdIndex(dom, 0, this);
  
        setUnparsedEntityURIs(dtdMonitor.getUnparsedEntityURIs());
      
        // Transform the document
        String encoding = translet.getOutputEncoding();
        if (encoding == null) encoding = "UTF-8";
      
        //TextOutput textOutput = new TextOutput(System.out, encoding);
        DefaultSAXOutputHandler saxHandler = new
           DefaultSAXOutputHandler(ostream, encoding);
        TextOutput textOutput = new TextOutput(saxHandler, encoding);
        translet.transform(dom, textOutput);
        textOutput.flush();
      }
      catch (TransletException e) {
        ...
      }
      catch (RuntimeException e) {
        ...
      }
      catch (FileNotFoundException e) {
        ...
      }
      catch (MalformedURLException e) {
        ...
      }
      catch (UnknownHostException e) {
        ...
      }
      catch (Exception e) {
        ...
      }
    }
  }</source>
  </s2><anchor name="conclusion"/>
  <s2 title="Conclusion">
  <p>This is the current state of the integration of Translet and TrAX. The JAXP program
  illustrated in the first section (Proto.java) compiles and runs with the changes outlined
  above. The new transformer factory TransformerFactoryImpl supports transformer,
  templates creation, and the feature discovery mechanism. The transformers
  returned from the factory are in fact AbstractTranslet objects. The new class
  TransletTemplates implements the Templates interface for translets. This is the
  result of a first pass implementation, there are many stubbed out methods that need to
  be implemented, translet caching in Templates needs to be implemented and support
  for Source and Result types beyond simple stream types, such as DOM and SAX.</p>
  
  </s2><anchor name="appendix"/>
  <s2 title="Appendix">
  <ul>
    <li><link anchor="runscript">The Run script</link></li>
    <li><link anchor="transformerfactoryimpl">TransformerFactoryImpl.java</link></li>
    <li><link anchor="TransletTemplates">TransletTemplates.java</link></li>
    <li><link anchor="makefile">The Makefile</link></li>
  </ul>
  <anchor name="runscript"/>
  <s3 title="The Run script">
  <p>By changing the FAC variable I can switch between the two Transformer factory implementations
  for testing.</p>
  <source>#!/bin/ksh
  JAXP=/usr/local/jaxp-1.1/jaxp.jar
  CRIMSON=/usr/local/jaxp-1.1/crimson.jar
  XSLT=/net/bigblock/files18/tmiller/xml-xalan/java/build/classes
  XML=/net/bigblock/files18/tmiller/xml-xalan/java/bin/xml.jar
  BCEL=/net/bigblock/files18/tmiller/xml-xalan/java/bin/BCEL.jar
  JCUP=/net/bigblock/files18/tmiller/xml-xalan/java/bin/java_cup.jar
  JCUPRT=/net/bigblock/files18/tmiller/xml-xalan/java/bin/runtime.jar
  CLASSPATH=${JAXP}:${CRIMSON}:${XSLT}:${XML}:${BCEL}:${JCUP}:${JCUPRT}:.
  FAC=org.apache.xalan.xsltc.runtime.TransformerFactoryImpl
  #FAC=org.apache.xalan.processor.TransformerFactoryImpl
  java -classpath ${CLASSPATH} \
       -Djavax.xml.transform.TransformerFactory=${FAC} \
       Proto $@</source>
  </s3><anchor name="transformerfactoryimpl"/>
  <s3 title="TransformerFactoryImpl.java">
  
  <source>package org.apache.xalan.xsltc.runtime;
  
  import javax.xml.transform.Templates;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.ErrorListener;
  import javax.xml.transform.Source;
  import javax.xml.transform.stream.StreamSource;
  import javax.xml.transform.stream.StreamResult;
  import javax.xml.transform.URIResolver;
  import javax.xml.transform.TransformerConfigurationException;
  import javax.xml.transform.sax.SAXTransformerFactory;
  import javax.xml.transform.sax.TemplatesHandler;
  import javax.xml.transform.sax.TransformerHandler;
  
  import org.xml.sax.XMLFilter;
  
  import org.apache.xalan.xsltc.Translet;
  import org.apache.xalan.xsltc.compiler.XSLTC;
  import org.apache.xalan.xsltc.runtime.AbstractTranslet;
  
  import java.io.File;
  import java.net.URL;
  import java.net.MalformedURLException;
  
  /**
   * Implementation of a JAXP1.1 SAXTransformerFactory for Translets.
   */
  public class TransformerFactoryImpl extends SAXTransformerFactory {
    public TransformerFactoryImpl() { /* nothing yet */ }
  
    //////////////////////////////////////////////////////
    // SAXTransformerFactory (subclass of TransformerFactory)
    //
    public TemplatesHandler newTemplatesHandler() { /*TBD*/ return null; }
    public TransformerHandler newTransformerHandler() { /*TBD*/ return null; }
    public TransformerHandler newTransformerHandler(Source src) {
       /*TBD*/ return null;
    }
    public TransformerHandler newTransformerHandler(Templates templates) {
       /*TBD*/ return null;
    }
    public XMLFilter newXMLFilter(Source src) { /*TBD*/ return null; }
    public XMLFilter newXMLFilter(Templates templates) { /*TBD*/ return null; }
  
    //
    // End SAXTransformerFactory methods
    //////////////////////////////////////////////////////
    //////////////////////////////////////////////////////
    // TransformerFactory
    //
    public ErrorListener getErrorListener() { /*TBD*/ return null; }
    public void setErrorListener(ErrorListener listener) {/*TBD*/ }
    public Object getAttribute(String name) { /*TBD*/ return null; }
    public void setAttribute(String name, Object value) { /*TBD*/ }
    public boolean getFeature(String name) {
      if ((StreamSource.FEATURE == name) ||
          (StreamResult.FEATURE == name) ||
          (SAXTransformerFactory.FEATURE == name)) {
          return true;
       } else if ((StreamSource.FEATURE.equals(name))
               || (StreamResult.FEATURE.equals(name))
               || (SAXTransformerFactory.FEATURE.equals(name))) {
          return true;
       } else {
          return false;
      }
    }
    public URIResolver getURIResolver() { /*TBD*/ return null; }
    public void setURIResolver(URIResolver resolver) {/*TBD*/ }
    public Source getAssociatedStylesheet(Source src, String media,
         String title, String charset) { /*TBD*/ return null; }
    public Transformer newTransformer() throws
      TransformerConfigurationException { /*TBD*/ return null; }
    //
    // End TransformerFactory methods
    //////////////////////////////////////////////////////
    public Transformer newTransformer(Source stylesheet) throws
    TransformerConfigurationException
    {
      XSLTC xsltc = new XSLTC();
      xsltc.init();
      String stylesheetName = stylesheet.getSystemId();
      int index = stylesheetName.indexOf(�.�);
      String transletName = stylesheetName.substring(0,index);
      boolean isSuccessful = true;
      try {
        File file = new File(stylesheetName);
        URL url = file.toURL();
        isSuccessful = xsltc.compile(url);
      } catch (MalformedURLException e) {
          throw new TransformerConfigurationException(
              "URL for stylesheet �" + stylesheetName +
              "� can not be formed.");
      }
      if (!isSuccessful) {
        throw new TransformerConfigurationException(
             "Compilation of stylesheet �" + stylesheetName + "� failed.");
      }
      
      Translet translet = null;
      try {
        Class clazz = Class.forName(transletName);
        translet = (Translet)clazz.newInstance();
        ((AbstractTranslet)translet).setTransletName(transletName);
      } catch (ClassNotFoundException e) {
         throw new TransformerConfigurationException(
              "Translet class �" + transletName + "� not found.");
      } catch (InstantiationException e) {
          throw new TransformerConfigurationException(
              "Translet class �" + transletName +
              "� could not be instantiated");
      } catch (IllegalAccessException e) {
          throw new TransformerConfigurationException(
              "Translet class �" + transletName + "� could not be accessed.");
      }
      return (AbstractTranslet)translet;
    }
    public Templates newTemplates(Source stylesheet) throws
    TransformerConfigurationException
    {
    Transformer translet = newTransformer(stylesheet);
    return new TransletTemplates(translet);
    }
  }</source>
  </s3><anchor name="translettemplates"/>
  <s3 title="TransletTemplates.java">
  <source>package org.apache.xalan.xsltc.runtime;
  
  import javax.xml.transform.Templates;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerConfigurationException;
  import javax.xml.transform.sax.SAXTransformerFactory;
  
  import org.apache.xalan.xsltc.runtime.AbstractTranslet;
  import java.util.Properties;
  
  /**
   * Implementation of a JAXP1.1 Templates object for Translets.
   */
  public class TransletTemplates implements Templates {
    public TransletTemplates(Transformer translet) {
      _translet = (AbstractTranslet)translet;
    }
    public Properties getOutputProperties() { /*TBD*/ return null; }
    public Transformer newTransformer() throws
      TransformerConfigurationException
    {
      if (_translet == null) {
        throw new TransformerConfigurationException(
             "Error: Null Translet");
      }
      return _translet;
    }
    private AbstractTranslet _translet = null;
  }</source>
  </s3><anchor name="makefile"/> 
  <s3 title="The Makefile">
  <source>JAXP=/usr/local/jaxp-1.1/jaxp.jar
  CRIMSON=/usr/local/jaxp-1.1/crimson.jar
  XSLT=/net/bigblock/files18/tmiller/xml-xalan/java/build/classes
  CLASSPATH=${JAXP}:${CRIMSON}:${XSLT}
  SRCS=\
  Proto.java
  all:
  javac -classpath ${CLASSPATH} ${SRCS}</source>
  </s3>
  </s2>
  </s1>
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org