Douglas,
Almost correct, the compiled Translet *object* implements the Templates
interface.
To answer your second question, you have to read the object stream in
because the Translet (as I've chosen to do it) is not a Class but rather a
compiled Object. I tested this theory by trying to do a class load, call
newInstance and got an exception stating that the object was not a class.
I suppose you could reuse the Transformer instance, but I couldn't get that
to work properly without calling clearParameters() on it between each call
to transform(...).
As a reference, here is the code I use to create the compiled translets.
Please note that this has been implemented as an Ant Task.
Mind you that I've only just begun to learn all this myself over the last
two weeks so my solution may not be the optimum solution but it does seem to
work for me.
---------------------------------
/*
* PerformXSLTC.java
* Bryan K. Hunter, OmniChoice (1/22/02)
*/
// Import standard Java (JDK) packages
import java.io.*;
import java.util.Vector;
import java.net.MalformedURLException;
// Import 3rd party commercial packages
import org.apache.xalan.xsltc.compiler.XSLTC;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import org.apache.tools.ant.util.*;
import org.apache.tools.ant.taskdefs.*;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
import org.apache.xalan.xsltc.trax.TransformerFactoryImpl;
import javax.xml.transform.stream.*;
import javax.xml.transform.*;
/** **********************************************************************
* Perform XSLTC (XSL Template Compilation).
* This is also an ANT task extension.
* @author Bryan K. Hunter (bryan.hunter 'at' omnichoice.com)
* **********************************************************************/
public class PerformXSLTC extends org.apache.tools.ant.taskdefs.MatchingTask
{
private String _xslName = "";
// private String _packageName = "";
private String _srcDir = "";
private String _destDir = "";
protected File[] compileList = new File[0];
public PerformXSLTC() {} // default constructor
public void execute()
throws BuildException
{
try {
File srcDir = (File)project.resolveFile(_srcDir);
File destDir = (File)project.resolveFile(_destDir);
if (!srcDir.exists()) {
throw new BuildException("srcdir \"" +
srcDir.getPath() +
"\" does not exist",
location);
} // end if
DirectoryScanner ds = this.getDirectoryScanner(srcDir);
String[] files = ds.getIncludedFiles();
System.out.println("Compiling " + files.length + " XSL files.");
String fullName = "";
boolean success = false;
Vector xslVector = new Vector();
StreamSource stylesheet = null;
TransformerFactory factory = TransformerFactory.newInstance();
Templates templates = null;
for (int i = 0; i < files.length; i++) {
fullName = _srcDir + File.separator + (String)files[i];
stylesheet = new StreamSource(fullName);
templates = factory.newTemplates(stylesheet);
dumpTemplate(_destDir, getBaseName(fullName) + ".translet",
templates);
} // end for
} catch (Exception e) {
throw new BuildException(e);
} // end try-catch block
} // end public void execute
/**
* Returns the base-name of a file/url
*/
private String getBaseName(String filename) {
int start = filename.lastIndexOf(File.separatorChar);
int stop = filename.lastIndexOf('.');
if (stop <= start) stop = filename.length() - 1;
return filename.substring(start+1, stop);
}
/**
* Writes a Templates object to a file
*/
private void dumpTemplate(String destDir, String file, Templates
templates) {
try {
String fullpath = destDir + File.separator + file;
FileOutputStream ostream = new FileOutputStream(fullpath);
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeObject(templates);
p.flush();
ostream.close();
}
catch (Exception e) {
System.err.println(e);
e.printStackTrace();
System.err.println("Could not write file "+file);
}
}
public void setXSLName(String xslName)
{
_xslName = xslName;
}
public void setsrcdir(String srcDir)
{
_srcDir = srcDir;
}
public void setdestdir(String destDir)
{
_destDir = destDir;
}
} // end public class PerformXSLTC
---------------------------------------
example of calling from Ant file
<taskdef name="xsltc" classname="PerformXSLTC" classpath="{your
classpath here}"/>
<xsltc
srcdir="${build}/${cingular}/XSL"
destdir="${build}/${cingular}"
includes="*.xsl"
excludes="*_cingdemo.xsl"/>
-----------------------------------------
> -----Original Message-----
> From: Douglas Conklin [mailto:[EMAIL PROTECTED]
> Sent: Friday, January 25, 2002 4:47 PM
> To: [EMAIL PROTECTED]
> Subject: RE: Getting a transformer from a translet.
>
>
> Thanks. This makes sense. It seems like the key part of the
> code is this:
>
> ObjectInputStream p = new ObjectInputStream(isTranslet);
> Templates templates = (Templates)p.readObject();
>
> So this means that the compiled Translet Class implements the
> Templates
> interface? It doesn't in the JavaDoc, so this is part of what
> I was missing
> if it's true.
>
> Why read the stream, instead of just call newInstance on the
> Class Object,
> as is done in a different example, then cast it to Templates?
>
> On a note related to Transformer usage: I see from the docs that the
> Templates object is a compiled representation of the style sheet.
> Unfortunately, the compiler docs mention several XSL
> constructs which are
> not handled (Conformance issues and Known Problems). Are
> these issues only
> present with the Translet, or will they also manifest if I use the
> TransformerFactory to obtain Templates directly from a Source?
>
> I understand the warnings about not reusing Transformers, but
> if I can't
> support all of the un-compiled style sheets we currently have without
> reparsing them for each use (as I believe would happen if I
> obtained a new
> Transformer from the TransformerFactory each time), I'm
> inclined to take the
> risk. The code I am replacing already is reusing a transformer and we
> haven't had any problems with it yet.
>
> Hope this question make sense.
>
> easy,
> douglas d
>
>
> -----Original Message-----
> From: Hunter, Bryan [mailto:[EMAIL PROTECTED]
> Sent: Friday, January 25, 2002 12:41 PM
> To: Xalan-J-Users (E-mail)
> Subject: RE: Getting a transformer from a translet.
>
>
> Douglas,
>
> I recently had to do something very similar, except I'm using
> translets
> wrapped in a Templates.
>
> The approach I took was to write a factory class that holds a
> static HashMap
> of translet name:template instance pairs. Whenever I need a
> transformer - I
> call my method in the factory to get transformers, it checks
> its hashmap to
> see if it already has a templates instance for the requested
> translet, if it
> does it'll return it, otherwise it'll create one add it to
> the hashmap and
> then return it.
>
> I'm using this in a J2EE application and everything appears
> to be working
> fine
>
> Keep in mind that a Transformer is a lightweight object that
> tracks state
> information during the transformation and that for each
> transformation, a
> new Transformer should be created. Because of this, I hold
> the Templates
> instances in my static hashmap and not a Transformer.
>
> I also have a class that build translets (Templates) that is
> an ANT task if
> you need it.
>
> Below is the code I wrote:
> ---------
>
> [snip]
>