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:  
---------

/* 
 * xslTransletFactory.java
 * Bryan K. Hunter
 */


// Import standard Java (JDK) packages
import java.util.HashMap;
import javax.xml.transform.stream.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;

// Import 3rd party commercial packages
import org.xml.sax.*;
import org.apache.xalan.xsltc.dom.*;

/** ********************************************************************** 
 *  This class serves as a factory to return the proper instance of a
 *  Transformer given the translet String literal name.
 *  @author Bryan K. Hunter ([EMAIL PROTECTED])
 *  **********************************************************************/
public class xslTransletFactory
{
    private static HashMap _transletsHM = new HashMap();

    private static BuildxslTemplate _btt = null;

    public synchronized static Transformer getTransformer(String
transletName)
        throws TransformerException
    {
        Transformer transformer = null;
        Templates templates = null;

        if (_transletsHM == null) {
            _transletsHM = new HashMap();
        } // end if

        if (_transletsHM.containsKey(transletName)) {
            templates = (Templates)_transletsHM.get(transletName);
        } else {
            // create a new Transformer and add it to transletsHM
            if (_btt == null) {
                _btt = new BuildxslTemplate();
            } // end if
            templates = _btt.execute(transletName);
            _transletsHM.put(transletName, templates);
        } // end if-else

        if (templates == null) {
            throw new TransformerException("Unable to create and return the
requested Transformer for " + 
                                           transletName);
        } // end if

        transformer = templates.newTransformer();
        return transformer;
    } // end public static Transformer getTransformer(String)
} // end public class xslTransletFactory


-------
/* 
 * BuildxslTemplate.java
 * Bryan K. Hunter
 */

// Import standard Java (JDK) packages
import java.io.*;
import javax.xml.transform.stream.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;

// Import 3rd party commercial packages
import org.xml.sax.*;
import org.apache.xalan.xsltc.dom.*;

/** ********************************************************************** 
 *  Helper class to build Transformer instances
 *  @author Bryan K. Hunter ([EMAIL PROTECTED])
 *  **********************************************************************/
public class BuildxslTemplate
{
    public BuildxslTemplate() {}

    public Templates execute(String transletName)
        throws TransformerException
    {
        Templates templates = null;
        try {
            templates = readTemplates(transletName);
        } catch (Exception e) {
            throw new TransformerException(e);
        } // end try-catch
        return templates;
    } // end public Templates execute(String)


    /**
     * Reads a Templates object from a file
     */
    private Templates readTemplates(String file) {
        try {
            /*
              FileInputStream ostream = new FileInputStream(file);
              ObjectInputStream p = new ObjectInputStream(ostream);
              Templates templates = (Templates)p.readObject();
              ostream.close();
              return(templates);
            */

            /* Failed because the ".translet" file is not a valid class
              ClassLoader loader = this.getClass().getClassLoader();
              Class clazz = loader.loadClass(getBaseName(file));
              return (Templates)clazz.newInstance();
            */

            // this code works!
            ClassLoader loader = this.getClass().getClassLoader();
            InputStream isTranslet = loader.getResourceAsStream(file);
            ObjectInputStream p = new ObjectInputStream(isTranslet);
            Templates templates = (Templates)p.readObject();
            isTranslet.close();
            return (templates);

        } catch (Exception e) {
            System.err.println(e);
            e.printStackTrace();
            System.err.println("Could not read file "+file);
            return null;
        } // end the-catch
    }

    /**
     * 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);
    }

} // end public class BuildTransletTransformer

-------
Here is the method to do the actual transformation:

    /**
     * Return String of XSL Transformation
     * @param sXML the XML String
     * @param sXSL the XSL Translet file name
     * @return String of XSL Transformation result
     * @exception TransformerException
     * @exception TransformerConfigurationException
     * @exception FileNotFoundException
     * @exception IOException
     */
    public String processTranslet(String sXML, String sXSL)
        throws TransformerException, TransformerConfigurationException, 
               FileNotFoundException, IOException
    {
        String resultString = null;
        Transformer transformer = xslTransletFactory.getTransformer(sXSL);
        StreamResult result = null;
        if (transformer == null) {
            throw new TransformerException("Unable to create new
Transformer");
        } else {
            StreamSource document = new StreamSource(new
StringReader(sXML));
            result = new StreamResult(new StringWriter());
            transformer.transform(document, result);
        } //end if-else
        if (result != null) {
            resultString = ((StringWriter)result.getWriter()).toString();
        } else {
            resultString = null;
        } // end if-else
        return resultString;
    } // end public String process(String, String)

------
This is how I call the processTranslet code (SimpleTransform is my class
where I've placed processTranslet and xmlString is my xml as a String:

SimpleTransform st = new SimpleTransform();
String resultsBody = st.processTranslet(xmlString, "mytranslet.translet");


------

Hope this helps.

Bryan Hunter (bryan.hunter 'at' omnichoice.com)


> -----Original Message-----
> From: Douglas Conklin [mailto:[EMAIL PROTECTED]
> Sent: Friday, January 25, 2002 3:03 PM
> To: [EMAIL PROTECTED]
> Subject: Getting a transformer from a translet. 
> 
> 
> I am attempting to use the XSLTC API to apply compiled style 
> sheets to XML.
> 
> Some instances of my component will want to use a compiled 
> stylesheet, and
> some a plain text style sheet. For this reason I would like to cache a
> Transformer in each instance for the transformation to employ 
> as much code
> reuse as I can.
> 
> I know I can get a Transformer from a Templates object, but I 
> don't want to
> compile the style sheets at runtime. 
> 
> The command line compiler will only compile to Translets.
> 
> Is there anyway to get a Transformer object given only a 
> Translet, or are my
> two choices to serialize Templates for reading at runtime, or 
> using two
> separate transformation methods depending on compiled or not?
> 
> Thanks in advance.
> 
>       easy,
>       douglas d
> 
> 
> 
> 
> 
> 

Reply via email to