blob: 14eb801760d744ebb4e53b63d391ef4b7138bfbe [file] [log] [blame]
<?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>
<p>See also: <jump href="../xsltc_usage.html#api">Calling XSLTC with the TrAX/JAXP API</jump></p>
<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.trax.TransletTemplates) implements the Templates
interface as is shown below:</p>
<source>package org.apache.xalan.xsltc.trax;
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.trax.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.trax;
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.trax;
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>